@rushstack/webpack5-localization-plugin 0.13.16 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.json CHANGED
@@ -1,6 +1,39 @@
1
1
  {
2
2
  "name": "@rushstack/webpack5-localization-plugin",
3
3
  "entries": [
4
+ {
5
+ "version": "0.14.1",
6
+ "tag": "@rushstack/webpack5-localization-plugin_v0.14.1",
7
+ "date": "Wed, 23 Jul 2025 20:55:57 GMT",
8
+ "comments": {
9
+ "dependency": [
10
+ {
11
+ "comment": "Updating dependency \"@rushstack/localization-utilities\" to `0.13.17`"
12
+ },
13
+ {
14
+ "comment": "Updating dependency \"@rushstack/node-core-library\" to `5.14.0`"
15
+ },
16
+ {
17
+ "comment": "Updating dependency \"@rushstack/terminal\" to `0.15.4`"
18
+ },
19
+ {
20
+ "comment": "Updating dependency \"@rushstack/heft\" to `0.74.1`"
21
+ }
22
+ ]
23
+ }
24
+ },
25
+ {
26
+ "version": "0.14.0",
27
+ "tag": "@rushstack/webpack5-localization-plugin_v0.14.0",
28
+ "date": "Mon, 30 Jun 2025 22:04:32 GMT",
29
+ "comments": {
30
+ "minor": [
31
+ {
32
+ "comment": "Add a feature for injecting custom localized values into a compilation via the `getCustomDataPlaceholderForValueFunction` function on an instance of the `LocalizationPlugin`."
33
+ }
34
+ ]
35
+ }
36
+ },
4
37
  {
5
38
  "version": "0.13.16",
6
39
  "tag": "@rushstack/webpack5-localization-plugin_v0.13.16",
package/CHANGELOG.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # Change Log - @rushstack/webpack5-localization-plugin
2
2
 
3
- This log was last generated on Sat, 21 Jun 2025 00:13:15 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 23 Jul 2025 20:55:57 GMT and should not be manually modified.
4
+
5
+ ## 0.14.1
6
+ Wed, 23 Jul 2025 20:55:57 GMT
7
+
8
+ _Version update only_
9
+
10
+ ## 0.14.0
11
+ Mon, 30 Jun 2025 22:04:32 GMT
12
+
13
+ ### Minor changes
14
+
15
+ - Add a feature for injecting custom localized values into a compilation via the `getCustomDataPlaceholderForValueFunction` function on an instance of the `LocalizationPlugin`.
4
16
 
5
17
  ## 0.13.16
6
18
  Sat, 21 Jun 2025 00:13:15 GMT
package/README.md CHANGED
@@ -209,6 +209,17 @@ use the true hash of the content, rather than an intermediate hash that is share
209
209
  Note that this option is not compatible with the `runtimeLocaleExpression` option and will cause an error if
210
210
  both are set.
211
211
 
212
+ ## Custom Localized Data
213
+
214
+ If you need to provide custom localized data, you can use the `getCustomDataPlaceholderForValueFunction` method
215
+ of the plugin. This method takes a function that receives a locale name and the chunk
216
+ that the placeholder is used in and returns a string that will be used as a placeholder for the localized data.
217
+ The provided function will be called for each locale that is used in the build and the returned value will replace
218
+ the returned placeholder in the output.
219
+
220
+ Note that this may produce unexpected results if there are no other localized values in the chunk that the
221
+ placeholder is used in.
222
+
212
223
  ## Links
213
224
 
214
225
  - [CHANGELOG.md](https://github.com/microsoft/rushstack/blob/main/webpack/localization-plugin/CHANGELOG.md) - Find
@@ -8,6 +8,17 @@ import type { IPseudolocaleOptions } from '@rushstack/localization-utilities';
8
8
  import type { LoaderContext } from 'webpack';
9
9
  import type { WebpackPluginInstance } from 'webpack';
10
10
 
11
+ /**
12
+ * @internal
13
+ */
14
+ export declare interface _ICustomDataPlaceholder extends IValuePlaceholderBase {
15
+ /**
16
+ * The function that will be invoked to get the value for this placeholder.
17
+ * The function will be invoked with the locale name as the first argument.
18
+ */
19
+ valueForLocaleFn: ValueForLocaleFn;
20
+ }
21
+
11
22
  /**
12
23
  * @public
13
24
  */
@@ -218,15 +229,7 @@ export declare type IResolvedMissingTranslations = ReadonlyMap<string, ILocaleFi
218
229
  /**
219
230
  * @public
220
231
  */
221
- export declare interface _IStringPlaceholder {
222
- /**
223
- * The literal string that will be injected for later replacement.
224
- */
225
- value: string;
226
- /**
227
- * The identifier for this particular placeholder, for lookup.
228
- */
229
- suffix: string;
232
+ declare interface IStringPlaceholder extends IValuePlaceholderBase {
230
233
  /**
231
234
  * The values of this string in each output locale.
232
235
  */
@@ -240,6 +243,8 @@ export declare interface _IStringPlaceholder {
240
243
  */
241
244
  stringName: string;
242
245
  }
246
+ export { IStringPlaceholder }
247
+ export { IStringPlaceholder as _IStringPlaceholder }
243
248
 
244
249
  /**
245
250
  * @public
@@ -255,6 +260,20 @@ export declare interface ITrueHashPluginOptions {
255
260
  stageOverride?: number;
256
261
  }
257
262
 
263
+ /**
264
+ * @public
265
+ */
266
+ export declare interface IValuePlaceholderBase {
267
+ /**
268
+ * The literal string that will be injected for later replacement.
269
+ */
270
+ value: string;
271
+ /**
272
+ * The identifier for this particular placeholder, for lookup.
273
+ */
274
+ suffix: string;
275
+ }
276
+
258
277
  /**
259
278
  * This plugin facilitates localization in webpack.
260
279
  *
@@ -267,11 +286,18 @@ export declare class LocalizationPlugin implements WebpackPluginInstance {
267
286
  */
268
287
  readonly _options: ILocalizationPluginOptions;
269
288
  private readonly _resolvedTranslatedStringsFromOptions;
270
- private readonly _stringPlaceholderMap;
289
+ private readonly _stringPlaceholderBySuffix;
290
+ private readonly _customDataPlaceholderBySuffix;
291
+ private readonly _customDataPlaceholderByUniqueId;
271
292
  private _passthroughLocaleName;
272
293
  private _defaultLocale;
273
294
  private _noStringsLocaleName;
274
295
  private _fillMissingTranslationStrings;
296
+ /**
297
+ * @remarks
298
+ * Include the `chunk` parameter so that the functions arity is the same as the
299
+ * `ValueForLocaleFn` type.
300
+ */
275
301
  private _formatLocaleForFilename;
276
302
  private readonly _pseudolocalizers;
277
303
  /**
@@ -292,13 +318,20 @@ export declare class LocalizationPlugin implements WebpackPluginInstance {
292
318
  /**
293
319
  * @public
294
320
  */
295
- getPlaceholder(localizedFileKey: string, stringName: string): _IStringPlaceholder | undefined;
321
+ getPlaceholder(localizedFileKey: string, stringName: string): IStringPlaceholder | undefined;
322
+ /**
323
+ * @beta
324
+ */
325
+ getCustomDataPlaceholderForValueFunction(valueForLocaleFn: ValueForLocaleFn, placeholderUniqueId: string): string;
326
+ /**
327
+ * @internal
328
+ */
329
+ _getStringDataForSerialNumber(suffix: string): IStringPlaceholder | undefined;
296
330
  /**
297
331
  * @internal
298
332
  */
299
- getDataForSerialNumber(serialNumber: string): _IStringPlaceholder | undefined;
333
+ _getCustomDataForSerialNumber(suffix: string): _ICustomDataPlaceholder | undefined;
300
334
  private _addLocFileAndGetPlaceholders;
301
- private _addTranslations;
302
335
  private _initializeAndValidateOptions;
303
336
  }
304
337
 
@@ -311,4 +344,9 @@ export declare class TrueHashPlugin implements WebpackPluginInstance {
311
344
  apply(compiler: Compiler): void;
312
345
  }
313
346
 
347
+ /**
348
+ * @public
349
+ */
350
+ export declare type ValueForLocaleFn = (locale: string, chunk: Chunk) => string;
351
+
314
352
  export { }
@@ -1,6 +1,11 @@
1
1
  import type { Asset, AssetInfo, Chunk, Compilation, sources } from 'webpack';
2
2
  import type { LocalizationPlugin } from './LocalizationPlugin';
3
- type FormatLocaleForFilenameFn = (locale: string) => string;
3
+ /**
4
+ * @remarks
5
+ * Include the `chunk` parameter so that the functions arity is the same as the
6
+ * `ValueForLocaleFn` type.
7
+ */
8
+ type FormatLocaleForFilenameFn = (locale: string, chunk: unknown) => string;
4
9
  export interface IProcessAssetOptionsBase {
5
10
  plugin: LocalizationPlugin;
6
11
  compilation: Compilation;
@@ -22,17 +27,12 @@ export interface IProcessLocalizedAssetOptions extends IProcessAssetOptionsBase
22
27
  filenameTemplate: Parameters<typeof Compilation.prototype.getAssetPath>[0];
23
28
  formatLocaleForFilenameFn: FormatLocaleForFilenameFn;
24
29
  }
25
- export interface IProcessAssetResult {
26
- filename: string;
27
- asset: sources.Source;
28
- }
29
- export declare const PLACEHOLDER_REGEX: RegExp;
30
- export interface IProcessedAsset {
30
+ interface IProcessedAsset {
31
31
  filename: string;
32
32
  source: sources.CachedSource;
33
33
  info: AssetInfo;
34
34
  }
35
- export interface IProcessLocalizedAssetResult {
35
+ interface IProcessLocalizedAssetResult {
36
36
  localizedFiles: Record<string, string>;
37
37
  processedAssets: IProcessedAsset[];
38
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssetProcessor.d.ts","sourceRoot":"","sources":["../src/AssetProcessor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG7E,OAAO,KAAK,EAAE,kBAAkB,EAAsB,MAAM,sBAAsB,CAAC;AAmBnF,KAAK,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;AAiB5D,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,gCAAiC,SAAQ,wBAAwB;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,yBAAyB,CAAC;CACtD;AAED,MAAM,WAAW,6BAA8B,SAAQ,wBAAwB;IAC7E,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,6BAA6B,EAAE,OAAO,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,gBAAgB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,yBAAyB,EAAE,yBAAyB,CAAC;CACtD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC;CACvB;AAED,eAAO,MAAM,iBAAiB,EAAE,MAG/B,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC;IAC7B,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,MAAM,WAAW,4BAA4B;IAC3C,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,eAAe,EAAE,eAAe,EAAE,CAAC;CACpC;AAID,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,6BAA6B,GAAG,4BAA4B,CAsF1G;AAED,wBAAsB,mCAAmC,CACvD,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gCAAgC,GAAG,eAAe,CAsDnG"}
1
+ {"version":3,"file":"AssetProcessor.d.ts","sourceRoot":"","sources":["../src/AssetProcessor.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG7E,OAAO,KAAK,EACV,kBAAkB,EAInB,MAAM,sBAAsB,CAAC;AAsB9B;;;;GAIG;AACH,KAAK,yBAAyB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,MAAM,CAAC;AAiB5E,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,kBAAkB,CAAC;IAC3B,WAAW,EAAE,WAAW,CAAC;IACzB,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC;IAC3C,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;CACd;AAED,MAAM,WAAW,gCAAiC,SAAQ,wBAAwB;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,OAAO,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,yBAAyB,EAAE,yBAAyB,CAAC;CACtD;AAED,MAAM,WAAW,6BAA8B,SAAQ,wBAAwB;IAC7E,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IACrB,6BAA6B,EAAE,OAAO,CAAC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,qBAAqB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1C,gBAAgB,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC3E,yBAAyB,EAAE,yBAAyB,CAAC;CACtD;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC,YAAY,CAAC;IAC7B,IAAI,EAAE,SAAS,CAAC;CACjB;AAED,UAAU,4BAA4B;IACpC,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,eAAe,EAAE,eAAe,EAAE,CAAC;CACpC;AAID,wBAAsB,gCAAgC,CACpD,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgCjC;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,6BAA6B,GAAG,4BAA4B,CAiG1G;AAED,wBAAsB,mCAAmC,CACvD,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,gCAAgC,GAAG,eAAe,CAuDnG"}
@@ -35,13 +35,13 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  };
36
36
  })();
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.PLACEHOLDER_REGEX = void 0;
39
38
  exports.processLocalizedAssetCachedAsync = processLocalizedAssetCachedAsync;
40
39
  exports.processLocalizedAsset = processLocalizedAsset;
41
40
  exports.processNonLocalizedAssetCachedAsync = processNonLocalizedAssetCachedAsync;
42
41
  exports.processNonLocalizedAsset = processNonLocalizedAsset;
43
42
  const Constants = __importStar(require("./utilities/Constants"));
44
- exports.PLACEHOLDER_REGEX = new RegExp(`${Constants.STRING_PLACEHOLDER_PREFIX}_([A-C])_(\\\\*)_([0-9a-f$]+)_`, 'g');
43
+ const LOCALIZED_RECONSTRUCTION_ELEMENT_KIND = 1;
44
+ const DYNAMIC_RECONSTRUCTION_ELEMENT_KIND = 2;
45
45
  async function processLocalizedAssetCachedAsync(options) {
46
46
  const { compilation, asset, cache, chunk } = options;
47
47
  const { source: originalSource } = asset;
@@ -70,14 +70,15 @@ async function processLocalizedAssetCachedAsync(options) {
70
70
  return localizedFiles;
71
71
  }
72
72
  function processLocalizedAsset(options) {
73
- const { compilation, asset, chunk, filenameTemplate, locales, formatLocaleForFilenameFn } = options;
73
+ const { compilation, asset, chunk, filenameTemplate, locales, formatLocaleForFilenameFn, plugin, fillMissingTranslationStrings, defaultLocale, passthroughLocaleName } = options;
74
74
  const { sources, WebpackError } = compilation.compiler.webpack;
75
75
  const { source: originalSource } = asset;
76
+ const fallbackLocale = fillMissingTranslationStrings ? defaultLocale : undefined;
76
77
  const rawSource = originalSource instanceof sources.CachedSource
77
78
  ? originalSource
78
79
  : new sources.CachedSource(originalSource);
79
80
  const assetSource = rawSource.source().toString();
80
- const parsedAsset = _parseStringToReconstructionSequence(options.plugin, assetSource, formatLocaleForFilenameFn);
81
+ const parsedAsset = _parseStringToReconstructionSequence(plugin, assetSource, formatLocaleForFilenameFn);
81
82
  const { issues } = parsedAsset;
82
83
  const localizedFiles = {};
83
84
  const processedAssets = [];
@@ -86,7 +87,7 @@ function processLocalizedAsset(options) {
86
87
  originInfo.related = {};
87
88
  }
88
89
  for (const locale of locales) {
89
- const { issues: localeIssues, result: localeResult } = _reconstructLocalized(new sources.ReplaceSource(rawSource, locale), parsedAsset.reconstructionSeries, locale, options.fillMissingTranslationStrings ? options.defaultLocale : undefined, options.passthroughLocaleName);
90
+ const { issues: localeIssues, result: localeResult } = _reconstructLocalized(new sources.ReplaceSource(rawSource, locale), parsedAsset.reconstructionSeries, locale, fallbackLocale, passthroughLocaleName, chunk);
90
91
  for (const issue of localeIssues) {
91
92
  issues.push(issue);
92
93
  }
@@ -143,7 +144,7 @@ async function processNonLocalizedAssetCachedAsync(options) {
143
144
  }
144
145
  }
145
146
  function processNonLocalizedAsset(options) {
146
- const { asset, fileName, compilation, formatLocaleForFilenameFn, hasUrlGenerator } = options;
147
+ const { asset, fileName, compilation, formatLocaleForFilenameFn, hasUrlGenerator, chunk } = options;
147
148
  const { sources, WebpackError } = compilation.compiler.webpack;
148
149
  const rawSource = asset.source;
149
150
  let cachedSource = rawSource instanceof sources.CachedSource ? rawSource : new sources.CachedSource(rawSource);
@@ -153,7 +154,7 @@ function processNonLocalizedAsset(options) {
153
154
  const assetSource = cachedSource.source().toString();
154
155
  const parsedAsset = _parseStringToReconstructionSequence(options.plugin, assetSource, formatLocaleForFilenameFn);
155
156
  const { issues } = parsedAsset;
156
- const { issues: localeIssues, result } = _reconstructNonLocalized(new sources.ReplaceSource(cachedSource, locale), parsedAsset.reconstructionSeries, locale);
157
+ const { issues: localeIssues, result } = _reconstructNonLocalized(new sources.ReplaceSource(cachedSource, locale), parsedAsset.reconstructionSeries, locale, chunk);
157
158
  for (const issue of localeIssues) {
158
159
  issues.push(issue);
159
160
  }
@@ -185,13 +186,14 @@ const ESCAPE_MAP = new Map([
185
186
  ]);
186
187
  const BACKSLASH_REGEX = /\\/g;
187
188
  const ESCAPE_REGEX = /[\r\n\t"']/g;
188
- function _reconstructLocalized(result, reconstructionSeries, locale, fallbackLocale, passthroughLocale) {
189
+ function _reconstructLocalized(result, reconstructionSeries, locale, fallbackLocale, passthroughLocale, chunk) {
189
190
  var _a, _b;
190
191
  const issues = [];
191
192
  for (const element of reconstructionSeries) {
192
- switch (element.kind) {
193
- case 'localized': {
194
- const { data } = element;
193
+ const { kind, start, end } = element;
194
+ switch (kind) {
195
+ case LOCALIZED_RECONSTRUCTION_ELEMENT_KIND: {
196
+ const { data, escapedBackslash } = element;
195
197
  const { stringName, translations } = data;
196
198
  let newValue = locale === passthroughLocale ? stringName : (_a = translations.get(locale)) === null || _a === void 0 ? void 0 : _a.get(stringName);
197
199
  if (fallbackLocale && newValue === undefined) {
@@ -201,7 +203,6 @@ function _reconstructLocalized(result, reconstructionSeries, locale, fallbackLoc
201
203
  issues.push(`The string "${stringName}" in "${data.locFilePath}" is missing in the locale ${locale}`);
202
204
  newValue = '-- MISSING STRING --';
203
205
  }
204
- const escapedBackslash = element.escapedBackslash || '\\';
205
206
  if (newValue.includes('\\')) {
206
207
  // The vast majority of localized strings do not contain `\\`, so this check avoids an allocation.
207
208
  // Replace backslashes with the properly escaped backslash
@@ -217,12 +218,12 @@ function _reconstructLocalized(result, reconstructionSeries, locale, fallbackLoc
217
218
  const escapingCharacterSequence = escapedBackslash.slice(escapedBackslash.length / 2);
218
219
  newValue = newValue.replace(ESCAPE_REGEX, (match) => `${escapingCharacterSequence}${ESCAPE_MAP.get(match)}`);
219
220
  }
220
- result.replace(element.start, element.end - 1, newValue);
221
+ result.replace(start, end - 1, newValue);
221
222
  break;
222
223
  }
223
- case 'dynamic': {
224
- const newValue = element.valueFn(locale);
225
- result.replace(element.start, element.end - 1, newValue);
224
+ case DYNAMIC_RECONSTRUCTION_ELEMENT_KIND: {
225
+ const newValue = element.valueFn(locale, chunk);
226
+ result.replace(start, end - 1, newValue);
226
227
  break;
227
228
  }
228
229
  }
@@ -232,19 +233,19 @@ function _reconstructLocalized(result, reconstructionSeries, locale, fallbackLoc
232
233
  result
233
234
  };
234
235
  }
235
- function _reconstructNonLocalized(result, reconstructionSeries, noStringsLocaleName) {
236
+ function _reconstructNonLocalized(result, reconstructionSeries, noStringsLocaleName, chunk) {
236
237
  const issues = [];
237
238
  for (const element of reconstructionSeries) {
238
239
  switch (element.kind) {
239
- case 'localized': {
240
+ case LOCALIZED_RECONSTRUCTION_ELEMENT_KIND: {
240
241
  issues.push(`The string "${element.data.stringName}" in "${element.data.locFilePath}" appeared in an asset ` +
241
242
  'that is not expected to contain localized resources.');
242
243
  const newValue = '-- NOT EXPECTED TO BE LOCALIZED --';
243
244
  result.replace(element.start, element.end - 1, newValue);
244
245
  break;
245
246
  }
246
- case 'dynamic': {
247
- const newValue = element.valueFn(noStringsLocaleName);
247
+ case DYNAMIC_RECONSTRUCTION_ELEMENT_KIND: {
248
+ const newValue = element.valueFn(noStringsLocaleName, chunk);
248
249
  result.replace(element.start, element.end - 1, newValue);
249
250
  break;
250
251
  }
@@ -269,18 +270,18 @@ function _parseStringToReconstructionSequence(plugin, source, formatLocaleForFil
269
270
  switch (elementLabel) {
270
271
  case Constants.STRING_PLACEHOLDER_LABEL: {
271
272
  const backslashEnd = source.indexOf('_', end);
272
- const escapedBackslash = source.slice(end, backslashEnd);
273
+ const escapedBackslash = source.slice(end, backslashEnd) || '\\';
273
274
  end = backslashEnd + 1;
274
- const serialEnd = source.indexOf('_', end);
275
- const serial = source.slice(end, serialEnd);
276
- end = serialEnd + 1;
277
- const stringData = plugin.getDataForSerialNumber(serial);
275
+ const suffixEnd = source.indexOf('_', end);
276
+ const suffix = source.slice(end, suffixEnd);
277
+ end = suffixEnd + 1;
278
+ const stringData = plugin._getStringDataForSerialNumber(suffix);
278
279
  if (!stringData) {
279
- issues.push(`Missing placeholder ${serial}`);
280
+ issues.push(`Missing placeholder ${suffix}`);
280
281
  }
281
282
  else {
282
283
  const localizedElement = {
283
- kind: 'localized',
284
+ kind: LOCALIZED_RECONSTRUCTION_ELEMENT_KIND,
284
285
  start,
285
286
  end,
286
287
  escapedBackslash,
@@ -292,7 +293,7 @@ function _parseStringToReconstructionSequence(plugin, source, formatLocaleForFil
292
293
  }
293
294
  case Constants.LOCALE_NAME_PLACEHOLDER_LABEL: {
294
295
  const dynamicElement = {
295
- kind: 'dynamic',
296
+ kind: DYNAMIC_RECONSTRUCTION_ELEMENT_KIND,
296
297
  start,
297
298
  end,
298
299
  valueFn: formatLocaleForFilenameFn
@@ -301,9 +302,9 @@ function _parseStringToReconstructionSequence(plugin, source, formatLocaleForFil
301
302
  break;
302
303
  }
303
304
  case Constants.JSONP_PLACEHOLDER_LABEL: {
304
- jsonStringifyFormatLocaleForFilenameFn || (jsonStringifyFormatLocaleForFilenameFn = (locale) => JSON.stringify(formatLocaleForFilenameFn(locale)));
305
+ jsonStringifyFormatLocaleForFilenameFn || (jsonStringifyFormatLocaleForFilenameFn = (locale, chunk) => JSON.stringify(formatLocaleForFilenameFn(locale, chunk)));
305
306
  const dynamicElement = {
306
- kind: 'dynamic',
307
+ kind: DYNAMIC_RECONSTRUCTION_ELEMENT_KIND,
307
308
  start,
308
309
  end,
309
310
  valueFn: jsonStringifyFormatLocaleForFilenameFn
@@ -311,6 +312,25 @@ function _parseStringToReconstructionSequence(plugin, source, formatLocaleForFil
311
312
  reconstructionSeries.push(dynamicElement);
312
313
  break;
313
314
  }
315
+ case Constants.CUSTOM_PLACEHOLDER_LABEL: {
316
+ const serialEnd = source.indexOf('_', end);
317
+ const serial = source.slice(end, serialEnd);
318
+ end = serialEnd + 1;
319
+ const customData = plugin._getCustomDataForSerialNumber(serial);
320
+ if (!customData) {
321
+ issues.push(`Missing custom placeholder ${serial}`);
322
+ }
323
+ else {
324
+ const dynamicElement = {
325
+ kind: DYNAMIC_RECONSTRUCTION_ELEMENT_KIND,
326
+ start,
327
+ end,
328
+ valueFn: customData.valueForLocaleFn
329
+ };
330
+ reconstructionSeries.push(dynamicElement);
331
+ }
332
+ break;
333
+ }
314
334
  default: {
315
335
  throw new Error(`Unexpected label ${elementLabel} in pattern ${source.slice(start, end)}`);
316
336
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssetProcessor.js","sourceRoot":"","sources":["../src/AssetProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { Asset, AssetInfo, Chunk, Compilation, sources } from 'webpack';\n\nimport * as Constants from './utilities/Constants';\nimport type { LocalizationPlugin, IStringPlaceholder } from './LocalizationPlugin';\nimport type { ILocalizedWebpackChunk, IAssetPathOptions } from './webpackInterfaces';\n\ninterface ILocalizedReconstructionElement {\n kind: 'localized';\n start: number;\n end: number;\n escapedBackslash: string;\n data: IStringPlaceholder;\n}\n\ninterface IDynamicReconstructionElement {\n kind: 'dynamic';\n start: number;\n end: number;\n valueFn: (locale: string) => string;\n}\n\ntype IReconstructionElement = ILocalizedReconstructionElement | IDynamicReconstructionElement;\ntype FormatLocaleForFilenameFn = (locale: string) => string;\n\ninterface IParseResult {\n issues: string[];\n reconstructionSeries: IReconstructionElement[];\n}\n\ninterface ILocalizedReconstructionResult {\n result: sources.ReplaceSource;\n issues: string[];\n}\n\ninterface INonLocalizedReconstructionResult {\n result: sources.ReplaceSource;\n issues: string[];\n}\n\nexport interface IProcessAssetOptionsBase {\n plugin: LocalizationPlugin;\n compilation: Compilation;\n cache: ReturnType<Compilation['getCache']>;\n chunk: Chunk;\n asset: Asset;\n}\n\nexport interface IProcessNonLocalizedAssetOptions extends IProcessAssetOptionsBase {\n fileName: string;\n hasUrlGenerator: boolean;\n noStringsLocaleName: string;\n formatLocaleForFilenameFn: FormatLocaleForFilenameFn;\n}\n\nexport interface IProcessLocalizedAssetOptions extends IProcessAssetOptionsBase {\n locales: Set<string>;\n fillMissingTranslationStrings: boolean;\n defaultLocale: string;\n passthroughLocaleName: string | undefined;\n filenameTemplate: Parameters<typeof Compilation.prototype.getAssetPath>[0];\n formatLocaleForFilenameFn: FormatLocaleForFilenameFn;\n}\n\nexport interface IProcessAssetResult {\n filename: string;\n asset: sources.Source;\n}\n\nexport const PLACEHOLDER_REGEX: RegExp = new RegExp(\n `${Constants.STRING_PLACEHOLDER_PREFIX}_([A-C])_(\\\\\\\\*)_([0-9a-f$]+)_`,\n 'g'\n);\n\nexport interface IProcessedAsset {\n filename: string;\n source: sources.CachedSource;\n info: AssetInfo;\n}\n\nexport interface IProcessLocalizedAssetResult {\n localizedFiles: Record<string, string>;\n processedAssets: IProcessedAsset[];\n}\n\ntype ItemCacheFacade = ReturnType<ReturnType<Compilation['getCache']>['getItemCache']>;\n\nexport async function processLocalizedAssetCachedAsync(\n options: IProcessLocalizedAssetOptions\n): Promise<Record<string, string>> {\n const { compilation, asset, cache, chunk } = options;\n const { source: originalSource } = asset;\n\n type ETag = NonNullable<ReturnType<typeof cache.getLazyHashedEtag>>;\n const eTag: ETag | null = cache.getLazyHashedEtag(originalSource);\n const { name: originName } = asset;\n const cacheItem: ItemCacheFacade = cache.getItemCache(originName, eTag);\n let output: IProcessLocalizedAssetResult | undefined = await cacheItem.getPromise();\n\n if (!output) {\n output = processLocalizedAsset(options);\n await cacheItem.storePromise(output);\n }\n\n const { localizedFiles, processedAssets } = output;\n\n (chunk as ILocalizedWebpackChunk).localizedFiles = localizedFiles;\n\n for (const { filename, source, info } of processedAssets) {\n if (originName === filename) {\n // This helper throws if the asset doesn't already exist\n // Use the function form so that the object identity of `related` is preserved.\n // Since we already read the original info, we don't need fancy merge logic.\n compilation.updateAsset(filename, source, () => info);\n } else {\n // This helper throws if the asset already exists\n compilation.emitAsset(filename, source, info);\n }\n }\n\n return localizedFiles;\n}\n\nexport function processLocalizedAsset(options: IProcessLocalizedAssetOptions): IProcessLocalizedAssetResult {\n const { compilation, asset, chunk, filenameTemplate, locales, formatLocaleForFilenameFn } = options;\n\n const { sources, WebpackError } = compilation.compiler.webpack;\n\n const { source: originalSource } = asset;\n\n const rawSource: sources.CachedSource =\n originalSource instanceof sources.CachedSource\n ? originalSource\n : new sources.CachedSource(originalSource);\n const assetSource: string = rawSource.source().toString();\n\n const parsedAsset: IParseResult = _parseStringToReconstructionSequence(\n options.plugin,\n assetSource,\n formatLocaleForFilenameFn\n );\n\n const { issues } = parsedAsset;\n\n const localizedFiles: Record<string, string> = {};\n\n const processedAssets: IProcessedAsset[] = [];\n\n const { info: originInfo, name: originName } = asset;\n if (!originInfo.related) {\n originInfo.related = {};\n }\n\n for (const locale of locales) {\n const { issues: localeIssues, result: localeResult } = _reconstructLocalized(\n new sources.ReplaceSource(rawSource, locale),\n parsedAsset.reconstructionSeries,\n locale,\n options.fillMissingTranslationStrings ? options.defaultLocale : undefined,\n options.passthroughLocaleName\n );\n\n for (const issue of localeIssues) {\n issues.push(issue);\n }\n\n const data: IAssetPathOptions = {\n chunk,\n contentHashType: 'javascript',\n // The locale property will get processed by the extension to the getAssetPath hook\n locale\n };\n\n const fileName: string = compilation.getAssetPath(filenameTemplate, data);\n\n const info: AssetInfo & { locale: string } = {\n ...originInfo,\n locale\n };\n\n const wrapped: sources.CachedSource = new sources.CachedSource(localeResult);\n localizedFiles[locale] = fileName;\n\n processedAssets.push({\n filename: fileName,\n source: wrapped,\n info\n });\n\n // If file already exists\n if (originName !== fileName) {\n // If A.related points to B, B.related can't point to A or the stats emitter explodes\n // So just strip the related object for the localized assets\n info.related = undefined;\n // We omit the `related` property that does a self-reference.\n originInfo.related[locale] = fileName;\n }\n }\n\n if (issues.length > 0) {\n compilation.errors.push(\n new WebpackError(`localization:\\n${issues.map((issue) => ` ${issue}`).join('\\n')}`)\n );\n }\n\n return {\n localizedFiles,\n processedAssets\n };\n}\n\nexport async function processNonLocalizedAssetCachedAsync(\n options: IProcessNonLocalizedAssetOptions\n): Promise<void> {\n const { compilation, asset, cache } = options;\n const { source: originalSource } = asset;\n\n type ETag = NonNullable<ReturnType<typeof cache.getLazyHashedEtag>>;\n const eTag: ETag | null = cache.getLazyHashedEtag(originalSource);\n const { name: originName } = asset;\n const cacheItem: ItemCacheFacade = cache.getItemCache(originName, eTag);\n let output: IProcessedAsset | undefined = await cacheItem.getPromise();\n\n if (!output) {\n output = processNonLocalizedAsset(options);\n await cacheItem.storePromise(output);\n }\n\n const { filename, source, info } = output;\n compilation.updateAsset(originName, source, info);\n if (originName !== filename) {\n compilation.renameAsset(originName, filename);\n }\n}\n\nexport function processNonLocalizedAsset(options: IProcessNonLocalizedAssetOptions): IProcessedAsset {\n const { asset, fileName, compilation, formatLocaleForFilenameFn, hasUrlGenerator } = options;\n\n const { sources, WebpackError } = compilation.compiler.webpack;\n\n const rawSource: sources.Source = asset.source;\n let cachedSource: sources.CachedSource =\n rawSource instanceof sources.CachedSource ? rawSource : new sources.CachedSource(rawSource);\n\n const { info: originInfo } = asset;\n const locale: string = options.noStringsLocaleName;\n\n if (hasUrlGenerator) {\n const assetSource: string = cachedSource.source().toString();\n const parsedAsset: IParseResult = _parseStringToReconstructionSequence(\n options.plugin,\n assetSource,\n formatLocaleForFilenameFn\n );\n\n const { issues } = parsedAsset;\n\n const { issues: localeIssues, result } = _reconstructNonLocalized(\n new sources.ReplaceSource(cachedSource, locale),\n parsedAsset.reconstructionSeries,\n locale\n );\n\n for (const issue of localeIssues) {\n issues.push(issue);\n }\n\n if (issues.length > 0) {\n options.compilation.errors.push(\n new WebpackError(`localization:\\n${issues.map((issue) => ` ${issue}`).join('\\n')}`)\n );\n }\n\n cachedSource = new sources.CachedSource(result);\n } else {\n // Force the CachedSource to cache the concatenated *string*, so that the subsequent ask for the buffer is fast\n cachedSource.source();\n }\n\n const info: AssetInfo = {\n ...originInfo,\n locale\n };\n\n return {\n filename: fileName,\n source: cachedSource,\n info\n };\n}\n\nconst ESCAPE_MAP: Map<string, string> = new Map([\n ['\\r', 'r'],\n ['\\n', 'n'],\n ['\\t', 't'],\n ['\"', 'u0022'],\n [\"'\", 'u0027']\n]);\n\nconst BACKSLASH_REGEX: RegExp = /\\\\/g;\nconst ESCAPE_REGEX: RegExp = /[\\r\\n\\t\"']/g;\n\nfunction _reconstructLocalized(\n result: sources.ReplaceSource,\n reconstructionSeries: IReconstructionElement[],\n locale: string,\n fallbackLocale: string | undefined,\n passthroughLocale: string | undefined\n): ILocalizedReconstructionResult {\n const issues: string[] = [];\n\n for (const element of reconstructionSeries) {\n switch (element.kind) {\n case 'localized': {\n const { data } = element;\n const { stringName, translations } = data;\n let newValue: string | undefined =\n locale === passthroughLocale ? stringName : translations.get(locale)?.get(stringName);\n if (fallbackLocale && newValue === undefined) {\n newValue = translations.get(fallbackLocale)?.get(stringName);\n }\n\n if (newValue === undefined) {\n issues.push(\n `The string \"${stringName}\" in \"${data.locFilePath}\" is missing in the locale ${locale}`\n );\n\n newValue = '-- MISSING STRING --';\n }\n\n const escapedBackslash: string = element.escapedBackslash || '\\\\';\n\n if (newValue.includes('\\\\')) {\n // The vast majority of localized strings do not contain `\\\\`, so this check avoids an allocation.\n // Replace backslashes with the properly escaped backslash\n BACKSLASH_REGEX.lastIndex = -1;\n newValue = newValue.replace(BACKSLASH_REGEX, escapedBackslash);\n }\n\n // Ensure the the quotemark, apostrophe, tab, and newline characters are properly escaped\n ESCAPE_REGEX.lastIndex = -1;\n if (ESCAPE_REGEX.test(newValue)) {\n // The majority of localized strings do not contain the characters that need to be escaped,\n // so this check avoids an allocation.\n // @todo: look into using JSON.parse(...) to get the escaping characters\n const escapingCharacterSequence: string = escapedBackslash.slice(escapedBackslash.length / 2);\n newValue = newValue.replace(\n ESCAPE_REGEX,\n (match) => `${escapingCharacterSequence}${ESCAPE_MAP.get(match)}`\n );\n }\n\n result.replace(element.start, element.end - 1, newValue);\n break;\n }\n\n case 'dynamic': {\n const newValue: string = element.valueFn(locale);\n result.replace(element.start, element.end - 1, newValue);\n break;\n }\n }\n }\n\n return {\n issues,\n result\n };\n}\n\nfunction _reconstructNonLocalized(\n result: sources.ReplaceSource,\n reconstructionSeries: IReconstructionElement[],\n noStringsLocaleName: string\n): INonLocalizedReconstructionResult {\n const issues: string[] = [];\n\n for (const element of reconstructionSeries) {\n switch (element.kind) {\n case 'localized': {\n issues.push(\n `The string \"${element.data.stringName}\" in \"${element.data.locFilePath}\" appeared in an asset ` +\n 'that is not expected to contain localized resources.'\n );\n\n const newValue: string = '-- NOT EXPECTED TO BE LOCALIZED --';\n result.replace(element.start, element.end - 1, newValue);\n break;\n }\n\n case 'dynamic': {\n const newValue: string = element.valueFn(noStringsLocaleName);\n result.replace(element.start, element.end - 1, newValue);\n break;\n }\n }\n }\n\n return {\n issues,\n result\n };\n}\n\nfunction _parseStringToReconstructionSequence(\n plugin: LocalizationPlugin,\n source: string,\n formatLocaleForFilenameFn: FormatLocaleForFilenameFn\n): IParseResult {\n const issues: string[] = [];\n const reconstructionSeries: IReconstructionElement[] = [];\n\n let jsonStringifyFormatLocaleForFilenameFn: FormatLocaleForFilenameFn | undefined;\n\n let index: number = source.indexOf(Constants.STRING_PLACEHOLDER_PREFIX);\n const increment: number = Constants.STRING_PLACEHOLDER_PREFIX.length + 1;\n while (index >= 0) {\n const start: number = index;\n const elementStart: number = index + increment;\n const elementLabel: string = source.charAt(elementStart);\n let end: number = elementStart + 2;\n\n switch (elementLabel) {\n case Constants.STRING_PLACEHOLDER_LABEL: {\n const backslashEnd: number = source.indexOf('_', end);\n const escapedBackslash: string = source.slice(end, backslashEnd);\n end = backslashEnd + 1;\n const serialEnd: number = source.indexOf('_', end);\n const serial: string = source.slice(end, serialEnd);\n end = serialEnd + 1;\n\n const stringData: IStringPlaceholder | undefined = plugin.getDataForSerialNumber(serial);\n if (!stringData) {\n issues.push(`Missing placeholder ${serial}`);\n } else {\n const localizedElement: ILocalizedReconstructionElement = {\n kind: 'localized',\n start,\n end,\n escapedBackslash,\n data: stringData\n };\n reconstructionSeries.push(localizedElement);\n }\n break;\n }\n case Constants.LOCALE_NAME_PLACEHOLDER_LABEL: {\n const dynamicElement: IDynamicReconstructionElement = {\n kind: 'dynamic',\n start,\n end,\n valueFn: formatLocaleForFilenameFn\n };\n reconstructionSeries.push(dynamicElement);\n break;\n }\n case Constants.JSONP_PLACEHOLDER_LABEL: {\n jsonStringifyFormatLocaleForFilenameFn ||= (locale: string) =>\n JSON.stringify(formatLocaleForFilenameFn(locale));\n const dynamicElement: IDynamicReconstructionElement = {\n kind: 'dynamic',\n start,\n end,\n valueFn: jsonStringifyFormatLocaleForFilenameFn\n };\n reconstructionSeries.push(dynamicElement);\n break;\n }\n default: {\n throw new Error(`Unexpected label ${elementLabel} in pattern ${source.slice(start, end)}`);\n }\n }\n\n index = source.indexOf(Constants.STRING_PLACEHOLDER_PREFIX, end);\n }\n\n return {\n issues,\n reconstructionSeries\n };\n}\n"]}
1
+ {"version":3,"file":"AssetProcessor.js","sourceRoot":"","sources":["../src/AssetProcessor.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport type { Asset, AssetInfo, Chunk, Compilation, sources } from 'webpack';\n\nimport * as Constants from './utilities/Constants';\nimport type {\n LocalizationPlugin,\n IStringPlaceholder,\n ValueForLocaleFn,\n ICustomDataPlaceholder\n} from './LocalizationPlugin';\nimport type { ILocalizedWebpackChunk, IAssetPathOptions } from './webpackInterfaces';\n\nconst LOCALIZED_RECONSTRUCTION_ELEMENT_KIND: 1 = 1;\nconst DYNAMIC_RECONSTRUCTION_ELEMENT_KIND: 2 = 2;\n\ninterface ILocalizedReconstructionElement {\n kind: typeof LOCALIZED_RECONSTRUCTION_ELEMENT_KIND;\n start: number;\n end: number;\n escapedBackslash: string;\n data: IStringPlaceholder;\n}\n\ninterface IDynamicReconstructionElement {\n kind: typeof DYNAMIC_RECONSTRUCTION_ELEMENT_KIND;\n start: number;\n end: number;\n valueFn: ValueForLocaleFn;\n}\n\ntype IReconstructionElement = ILocalizedReconstructionElement | IDynamicReconstructionElement;\n/**\n * @remarks\n * Include the `chunk` parameter so that the functions arity is the same as the\n * `ValueForLocaleFn` type.\n */\ntype FormatLocaleForFilenameFn = (locale: string, chunk: unknown) => string;\n\ninterface IParseResult {\n issues: string[];\n reconstructionSeries: IReconstructionElement[];\n}\n\ninterface ILocalizedReconstructionResult {\n result: sources.ReplaceSource;\n issues: string[];\n}\n\ninterface INonLocalizedReconstructionResult {\n result: sources.ReplaceSource;\n issues: string[];\n}\n\nexport interface IProcessAssetOptionsBase {\n plugin: LocalizationPlugin;\n compilation: Compilation;\n cache: ReturnType<Compilation['getCache']>;\n chunk: Chunk;\n asset: Asset;\n}\n\nexport interface IProcessNonLocalizedAssetOptions extends IProcessAssetOptionsBase {\n fileName: string;\n hasUrlGenerator: boolean;\n noStringsLocaleName: string;\n formatLocaleForFilenameFn: FormatLocaleForFilenameFn;\n}\n\nexport interface IProcessLocalizedAssetOptions extends IProcessAssetOptionsBase {\n locales: Set<string>;\n fillMissingTranslationStrings: boolean;\n defaultLocale: string;\n passthroughLocaleName: string | undefined;\n filenameTemplate: Parameters<typeof Compilation.prototype.getAssetPath>[0];\n formatLocaleForFilenameFn: FormatLocaleForFilenameFn;\n}\n\ninterface IProcessedAsset {\n filename: string;\n source: sources.CachedSource;\n info: AssetInfo;\n}\n\ninterface IProcessLocalizedAssetResult {\n localizedFiles: Record<string, string>;\n processedAssets: IProcessedAsset[];\n}\n\ntype ItemCacheFacade = ReturnType<ReturnType<Compilation['getCache']>['getItemCache']>;\n\nexport async function processLocalizedAssetCachedAsync(\n options: IProcessLocalizedAssetOptions\n): Promise<Record<string, string>> {\n const { compilation, asset, cache, chunk } = options;\n const { source: originalSource } = asset;\n\n type ETag = NonNullable<ReturnType<typeof cache.getLazyHashedEtag>>;\n const eTag: ETag | null = cache.getLazyHashedEtag(originalSource);\n const { name: originName } = asset;\n const cacheItem: ItemCacheFacade = cache.getItemCache(originName, eTag);\n let output: IProcessLocalizedAssetResult | undefined = await cacheItem.getPromise();\n\n if (!output) {\n output = processLocalizedAsset(options);\n await cacheItem.storePromise(output);\n }\n\n const { localizedFiles, processedAssets } = output;\n\n (chunk as ILocalizedWebpackChunk).localizedFiles = localizedFiles;\n\n for (const { filename, source, info } of processedAssets) {\n if (originName === filename) {\n // This helper throws if the asset doesn't already exist\n // Use the function form so that the object identity of `related` is preserved.\n // Since we already read the original info, we don't need fancy merge logic.\n compilation.updateAsset(filename, source, () => info);\n } else {\n // This helper throws if the asset already exists\n compilation.emitAsset(filename, source, info);\n }\n }\n\n return localizedFiles;\n}\n\nexport function processLocalizedAsset(options: IProcessLocalizedAssetOptions): IProcessLocalizedAssetResult {\n const {\n compilation,\n asset,\n chunk,\n filenameTemplate,\n locales,\n formatLocaleForFilenameFn,\n plugin,\n fillMissingTranslationStrings,\n defaultLocale,\n passthroughLocaleName\n } = options;\n const { sources, WebpackError } = compilation.compiler.webpack;\n const { source: originalSource } = asset;\n\n const fallbackLocale: string | undefined = fillMissingTranslationStrings ? defaultLocale : undefined;\n const rawSource: sources.CachedSource =\n originalSource instanceof sources.CachedSource\n ? originalSource\n : new sources.CachedSource(originalSource);\n const assetSource: string = rawSource.source().toString();\n\n const parsedAsset: IParseResult = _parseStringToReconstructionSequence(\n plugin,\n assetSource,\n formatLocaleForFilenameFn\n );\n\n const { issues } = parsedAsset;\n\n const localizedFiles: Record<string, string> = {};\n\n const processedAssets: IProcessedAsset[] = [];\n\n const { info: originInfo, name: originName } = asset;\n if (!originInfo.related) {\n originInfo.related = {};\n }\n\n for (const locale of locales) {\n const { issues: localeIssues, result: localeResult } = _reconstructLocalized(\n new sources.ReplaceSource(rawSource, locale),\n parsedAsset.reconstructionSeries,\n locale,\n fallbackLocale,\n passthroughLocaleName,\n chunk\n );\n\n for (const issue of localeIssues) {\n issues.push(issue);\n }\n\n const data: IAssetPathOptions = {\n chunk,\n contentHashType: 'javascript',\n // The locale property will get processed by the extension to the getAssetPath hook\n locale\n };\n\n const fileName: string = compilation.getAssetPath(filenameTemplate, data);\n\n const info: AssetInfo & { locale: string } = {\n ...originInfo,\n locale\n };\n\n const wrapped: sources.CachedSource = new sources.CachedSource(localeResult);\n localizedFiles[locale] = fileName;\n\n processedAssets.push({\n filename: fileName,\n source: wrapped,\n info\n });\n\n // If file already exists\n if (originName !== fileName) {\n // If A.related points to B, B.related can't point to A or the stats emitter explodes\n // So just strip the related object for the localized assets\n info.related = undefined;\n // We omit the `related` property that does a self-reference.\n originInfo.related[locale] = fileName;\n }\n }\n\n if (issues.length > 0) {\n compilation.errors.push(\n new WebpackError(`localization:\\n${issues.map((issue) => ` ${issue}`).join('\\n')}`)\n );\n }\n\n return {\n localizedFiles,\n processedAssets\n };\n}\n\nexport async function processNonLocalizedAssetCachedAsync(\n options: IProcessNonLocalizedAssetOptions\n): Promise<void> {\n const { compilation, asset, cache } = options;\n const { source: originalSource } = asset;\n\n type ETag = NonNullable<ReturnType<typeof cache.getLazyHashedEtag>>;\n const eTag: ETag | null = cache.getLazyHashedEtag(originalSource);\n const { name: originName } = asset;\n const cacheItem: ItemCacheFacade = cache.getItemCache(originName, eTag);\n let output: IProcessedAsset | undefined = await cacheItem.getPromise();\n\n if (!output) {\n output = processNonLocalizedAsset(options);\n await cacheItem.storePromise(output);\n }\n\n const { filename, source, info } = output;\n compilation.updateAsset(originName, source, info);\n if (originName !== filename) {\n compilation.renameAsset(originName, filename);\n }\n}\n\nexport function processNonLocalizedAsset(options: IProcessNonLocalizedAssetOptions): IProcessedAsset {\n const { asset, fileName, compilation, formatLocaleForFilenameFn, hasUrlGenerator, chunk } = options;\n\n const { sources, WebpackError } = compilation.compiler.webpack;\n\n const rawSource: sources.Source = asset.source;\n let cachedSource: sources.CachedSource =\n rawSource instanceof sources.CachedSource ? rawSource : new sources.CachedSource(rawSource);\n\n const { info: originInfo } = asset;\n const locale: string = options.noStringsLocaleName;\n\n if (hasUrlGenerator) {\n const assetSource: string = cachedSource.source().toString();\n const parsedAsset: IParseResult = _parseStringToReconstructionSequence(\n options.plugin,\n assetSource,\n formatLocaleForFilenameFn\n );\n\n const { issues } = parsedAsset;\n\n const { issues: localeIssues, result } = _reconstructNonLocalized(\n new sources.ReplaceSource(cachedSource, locale),\n parsedAsset.reconstructionSeries,\n locale,\n chunk\n );\n\n for (const issue of localeIssues) {\n issues.push(issue);\n }\n\n if (issues.length > 0) {\n options.compilation.errors.push(\n new WebpackError(`localization:\\n${issues.map((issue) => ` ${issue}`).join('\\n')}`)\n );\n }\n\n cachedSource = new sources.CachedSource(result);\n } else {\n // Force the CachedSource to cache the concatenated *string*, so that the subsequent ask for the buffer is fast\n cachedSource.source();\n }\n\n const info: AssetInfo = {\n ...originInfo,\n locale\n };\n\n return {\n filename: fileName,\n source: cachedSource,\n info\n };\n}\n\nconst ESCAPE_MAP: Map<string, string> = new Map([\n ['\\r', 'r'],\n ['\\n', 'n'],\n ['\\t', 't'],\n ['\"', 'u0022'],\n [\"'\", 'u0027']\n]);\n\nconst BACKSLASH_REGEX: RegExp = /\\\\/g;\nconst ESCAPE_REGEX: RegExp = /[\\r\\n\\t\"']/g;\n\nfunction _reconstructLocalized(\n result: sources.ReplaceSource,\n reconstructionSeries: IReconstructionElement[],\n locale: string,\n fallbackLocale: string | undefined,\n passthroughLocale: string | undefined,\n chunk: Chunk\n): ILocalizedReconstructionResult {\n const issues: string[] = [];\n\n for (const element of reconstructionSeries) {\n const { kind, start, end } = element;\n switch (kind) {\n case LOCALIZED_RECONSTRUCTION_ELEMENT_KIND: {\n const { data, escapedBackslash } = element;\n const { stringName, translations } = data;\n let newValue: string | undefined =\n locale === passthroughLocale ? stringName : translations.get(locale)?.get(stringName);\n if (fallbackLocale && newValue === undefined) {\n newValue = translations.get(fallbackLocale)?.get(stringName);\n }\n\n if (newValue === undefined) {\n issues.push(\n `The string \"${stringName}\" in \"${data.locFilePath}\" is missing in the locale ${locale}`\n );\n\n newValue = '-- MISSING STRING --';\n }\n\n if (newValue.includes('\\\\')) {\n // The vast majority of localized strings do not contain `\\\\`, so this check avoids an allocation.\n // Replace backslashes with the properly escaped backslash\n BACKSLASH_REGEX.lastIndex = -1;\n newValue = newValue.replace(BACKSLASH_REGEX, escapedBackslash);\n }\n\n // Ensure the the quotemark, apostrophe, tab, and newline characters are properly escaped\n ESCAPE_REGEX.lastIndex = -1;\n if (ESCAPE_REGEX.test(newValue)) {\n // The majority of localized strings do not contain the characters that need to be escaped,\n // so this check avoids an allocation.\n // @todo: look into using JSON.parse(...) to get the escaping characters\n const escapingCharacterSequence: string = escapedBackslash.slice(escapedBackslash.length / 2);\n newValue = newValue.replace(\n ESCAPE_REGEX,\n (match) => `${escapingCharacterSequence}${ESCAPE_MAP.get(match)}`\n );\n }\n\n result.replace(start, end - 1, newValue);\n break;\n }\n\n case DYNAMIC_RECONSTRUCTION_ELEMENT_KIND: {\n const newValue: string = element.valueFn(locale, chunk);\n result.replace(start, end - 1, newValue);\n break;\n }\n }\n }\n\n return {\n issues,\n result\n };\n}\n\nfunction _reconstructNonLocalized(\n result: sources.ReplaceSource,\n reconstructionSeries: IReconstructionElement[],\n noStringsLocaleName: string,\n chunk: Chunk\n): INonLocalizedReconstructionResult {\n const issues: string[] = [];\n\n for (const element of reconstructionSeries) {\n switch (element.kind) {\n case LOCALIZED_RECONSTRUCTION_ELEMENT_KIND: {\n issues.push(\n `The string \"${element.data.stringName}\" in \"${element.data.locFilePath}\" appeared in an asset ` +\n 'that is not expected to contain localized resources.'\n );\n\n const newValue: string = '-- NOT EXPECTED TO BE LOCALIZED --';\n result.replace(element.start, element.end - 1, newValue);\n break;\n }\n\n case DYNAMIC_RECONSTRUCTION_ELEMENT_KIND: {\n const newValue: string = element.valueFn(noStringsLocaleName, chunk);\n result.replace(element.start, element.end - 1, newValue);\n break;\n }\n }\n }\n\n return {\n issues,\n result\n };\n}\n\nfunction _parseStringToReconstructionSequence(\n plugin: LocalizationPlugin,\n source: string,\n formatLocaleForFilenameFn: FormatLocaleForFilenameFn\n): IParseResult {\n const issues: string[] = [];\n const reconstructionSeries: IReconstructionElement[] = [];\n\n let jsonStringifyFormatLocaleForFilenameFn: FormatLocaleForFilenameFn | undefined;\n\n let index: number = source.indexOf(Constants.STRING_PLACEHOLDER_PREFIX);\n const increment: number = Constants.STRING_PLACEHOLDER_PREFIX.length + 1;\n while (index >= 0) {\n const start: number = index;\n const elementStart: number = index + increment;\n const elementLabel: string = source.charAt(elementStart);\n let end: number = elementStart + 2;\n\n switch (elementLabel) {\n case Constants.STRING_PLACEHOLDER_LABEL: {\n const backslashEnd: number = source.indexOf('_', end);\n const escapedBackslash: string = source.slice(end, backslashEnd) || '\\\\';\n end = backslashEnd + 1;\n const suffixEnd: number = source.indexOf('_', end);\n const suffix: string = source.slice(end, suffixEnd);\n end = suffixEnd + 1;\n\n const stringData: IStringPlaceholder | undefined = plugin._getStringDataForSerialNumber(suffix);\n if (!stringData) {\n issues.push(`Missing placeholder ${suffix}`);\n } else {\n const localizedElement: ILocalizedReconstructionElement = {\n kind: LOCALIZED_RECONSTRUCTION_ELEMENT_KIND,\n start,\n end,\n escapedBackslash,\n data: stringData\n };\n reconstructionSeries.push(localizedElement);\n }\n break;\n }\n\n case Constants.LOCALE_NAME_PLACEHOLDER_LABEL: {\n const dynamicElement: IDynamicReconstructionElement = {\n kind: DYNAMIC_RECONSTRUCTION_ELEMENT_KIND,\n start,\n end,\n valueFn: formatLocaleForFilenameFn\n };\n reconstructionSeries.push(dynamicElement);\n break;\n }\n\n case Constants.JSONP_PLACEHOLDER_LABEL: {\n jsonStringifyFormatLocaleForFilenameFn ||= (locale: string, chunk: unknown) =>\n JSON.stringify(formatLocaleForFilenameFn(locale, chunk));\n const dynamicElement: IDynamicReconstructionElement = {\n kind: DYNAMIC_RECONSTRUCTION_ELEMENT_KIND,\n start,\n end,\n valueFn: jsonStringifyFormatLocaleForFilenameFn\n };\n reconstructionSeries.push(dynamicElement);\n break;\n }\n\n case Constants.CUSTOM_PLACEHOLDER_LABEL: {\n const serialEnd: number = source.indexOf('_', end);\n const serial: string = source.slice(end, serialEnd);\n end = serialEnd + 1;\n const customData: ICustomDataPlaceholder | undefined = plugin._getCustomDataForSerialNumber(serial);\n if (!customData) {\n issues.push(`Missing custom placeholder ${serial}`);\n } else {\n const dynamicElement: IDynamicReconstructionElement = {\n kind: DYNAMIC_RECONSTRUCTION_ELEMENT_KIND,\n start,\n end,\n valueFn: customData.valueForLocaleFn\n };\n reconstructionSeries.push(dynamicElement);\n }\n break;\n }\n\n default: {\n throw new Error(`Unexpected label ${elementLabel} in pattern ${source.slice(start, end)}`);\n }\n }\n\n index = source.indexOf(Constants.STRING_PLACEHOLDER_PREFIX, end);\n }\n\n return {\n issues,\n reconstructionSeries\n };\n}\n"]}
@@ -1,10 +1,14 @@
1
- import type { Compiler, LoaderContext, WebpackPluginInstance } from 'webpack';
1
+ import type { Chunk, Compiler, LoaderContext, WebpackPluginInstance } from 'webpack';
2
2
  import { type ILocalizationFile } from '@rushstack/localization-utilities';
3
3
  import type { ILocalizationPluginOptions } from './interfaces';
4
4
  /**
5
5
  * @public
6
6
  */
7
- export interface IStringPlaceholder {
7
+ export type ValueForLocaleFn = (locale: string, chunk: Chunk) => string;
8
+ /**
9
+ * @public
10
+ */
11
+ export interface IValuePlaceholderBase {
8
12
  /**
9
13
  * The literal string that will be injected for later replacement.
10
14
  */
@@ -13,6 +17,11 @@ export interface IStringPlaceholder {
13
17
  * The identifier for this particular placeholder, for lookup.
14
18
  */
15
19
  suffix: string;
20
+ }
21
+ /**
22
+ * @public
23
+ */
24
+ export interface IStringPlaceholder extends IValuePlaceholderBase {
16
25
  /**
17
26
  * The values of this string in each output locale.
18
27
  */
@@ -26,10 +35,20 @@ export interface IStringPlaceholder {
26
35
  */
27
36
  stringName: string;
28
37
  }
38
+ /**
39
+ * @internal
40
+ */
41
+ export interface ICustomDataPlaceholder extends IValuePlaceholderBase {
42
+ /**
43
+ * The function that will be invoked to get the value for this placeholder.
44
+ * The function will be invoked with the locale name as the first argument.
45
+ */
46
+ valueForLocaleFn: ValueForLocaleFn;
47
+ }
29
48
  export interface IFileTranslationInfo {
30
49
  placeholders: Map<string, IStringPlaceholder>;
31
50
  translations: Map<string, ReadonlyMap<string, string>>;
32
- renderedPlacholders: Record<string, string>;
51
+ renderedPlaceholders: Record<string, string>;
33
52
  }
34
53
  /**
35
54
  * Gets the instance of the LocalizationPlugin bound to the specified webpack compiler.
@@ -48,11 +67,18 @@ export declare class LocalizationPlugin implements WebpackPluginInstance {
48
67
  */
49
68
  readonly _options: ILocalizationPluginOptions;
50
69
  private readonly _resolvedTranslatedStringsFromOptions;
51
- private readonly _stringPlaceholderMap;
70
+ private readonly _stringPlaceholderBySuffix;
71
+ private readonly _customDataPlaceholderBySuffix;
72
+ private readonly _customDataPlaceholderByUniqueId;
52
73
  private _passthroughLocaleName;
53
74
  private _defaultLocale;
54
75
  private _noStringsLocaleName;
55
76
  private _fillMissingTranslationStrings;
77
+ /**
78
+ * @remarks
79
+ * Include the `chunk` parameter so that the functions arity is the same as the
80
+ * `ValueForLocaleFn` type.
81
+ */
56
82
  private _formatLocaleForFilename;
57
83
  private readonly _pseudolocalizers;
58
84
  /**
@@ -74,12 +100,19 @@ export declare class LocalizationPlugin implements WebpackPluginInstance {
74
100
  * @public
75
101
  */
76
102
  getPlaceholder(localizedFileKey: string, stringName: string): IStringPlaceholder | undefined;
103
+ /**
104
+ * @beta
105
+ */
106
+ getCustomDataPlaceholderForValueFunction(valueForLocaleFn: ValueForLocaleFn, placeholderUniqueId: string): string;
107
+ /**
108
+ * @internal
109
+ */
110
+ _getStringDataForSerialNumber(suffix: string): IStringPlaceholder | undefined;
77
111
  /**
78
112
  * @internal
79
113
  */
80
- getDataForSerialNumber(serialNumber: string): IStringPlaceholder | undefined;
114
+ _getCustomDataForSerialNumber(suffix: string): ICustomDataPlaceholder | undefined;
81
115
  private _addLocFileAndGetPlaceholders;
82
- private _addTranslations;
83
116
  private _initializeAndValidateOptions;
84
117
  }
85
118
  //# sourceMappingURL=LocalizationPlugin.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LocalizationPlugin.d.ts","sourceRoot":"","sources":["../src/LocalizationPlugin.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAKV,QAAQ,EACR,aAAa,EAIb,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAsB,KAAK,iBAAiB,EAAgB,MAAM,mCAAmC,CAAC;AAI7G,OAAO,KAAK,EACV,0BAA0B,EAK3B,MAAM,cAAc,CAAC;AAOtB;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;OAEG;IACH,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/D;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB;;OAEG;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IAC9C,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7C;AAMD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,GAAG,SAAS,GAAG,kBAAkB,CAMpF;AAED;;;;GAIG;AACH,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgD;IAE1E;;OAEG;IACH,SAAgB,QAAQ,EAAE,0BAA0B,CAAC;IACrD,OAAO,CAAC,QAAQ,CAAC,qCAAqC,CAGxC;IACd,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAA8C;IACpF,OAAO,CAAC,sBAAsB,CAAU;IACxC,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,oBAAoB,CAAU;IACtC,OAAO,CAAC,8BAA8B,CAAW;IACjD,OAAO,CAAC,wBAAwB,CAA2B;IAC3D,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAmD;IAErF;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAA0B;gBAEjC,OAAO,EAAE,0BAA0B;IAItD;;OAEG;IACI,KAAK,CAAC,QAAQ,EAAE,QAAQ,GAAG,IAAI;IA4UtC;;;;OAIG;IACU,sBAAsB,CACjC,OAAO,EAAE,aAAa,CAAC,EAAE,CAAC,EAC1B,gBAAgB,EAAE,MAAM,EACxB,qBAAqB,EAAE,iBAAiB,GACvC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAsElC;;OAEG;IACI,cAAc,CAAC,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAQnG;;OAEG;IACI,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAInF,OAAO,CAAC,6BAA6B;IA4CrC,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,6BAA6B;CAmLtC"}
1
+ {"version":3,"file":"LocalizationPlugin.d.ts","sourceRoot":"","sources":["../src/LocalizationPlugin.ts"],"names":[],"mappings":"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"}
@@ -67,7 +67,9 @@ class LocalizationPlugin {
67
67
  constructor(options) {
68
68
  this._locFiles = new Map();
69
69
  this._resolvedTranslatedStringsFromOptions = new Map();
70
- this._stringPlaceholderMap = new Map();
70
+ this._stringPlaceholderBySuffix = new Map();
71
+ this._customDataPlaceholderBySuffix = new Map();
72
+ this._customDataPlaceholderByUniqueId = new Map();
71
73
  this._pseudolocalizers = new Map();
72
74
  /**
73
75
  * The set of locales that have translations provided.
@@ -166,7 +168,7 @@ class LocalizationPlugin {
166
168
  chunksWithUrlGenerators.add(activeChunkWithAsyncUrlGenerator);
167
169
  }
168
170
  if (chunkIdsWithStrings.size === 0) {
169
- return this._formatLocaleForFilename(this._noStringsLocaleName);
171
+ return this._formatLocaleForFilename(this._noStringsLocaleName, undefined);
170
172
  }
171
173
  else if (chunkIdsWithoutStrings.size === 0) {
172
174
  return `" + ${localeExpression} + "`;
@@ -189,7 +191,7 @@ class LocalizationPlugin {
189
191
  for (const id of smallerSet) {
190
192
  chunkMapping[id] = 1;
191
193
  }
192
- const noLocaleExpression = JSON.stringify(this._formatLocaleForFilename(this._noStringsLocaleName));
194
+ const noLocaleExpression = JSON.stringify(this._formatLocaleForFilename(this._noStringsLocaleName, undefined));
193
195
  return `" + (${JSON.stringify(chunkMapping)}[chunkId]?${isLocalizedSmaller ? localeExpression : noLocaleExpression}:${isLocalizedSmaller ? noLocaleExpression : localeExpression}) + "`;
194
196
  }
195
197
  });
@@ -201,7 +203,7 @@ class LocalizationPlugin {
201
203
  // Ensure that the initial name maps to a file that should exist in the final output
202
204
  locale = isLocalized ? this._defaultLocale : this._noStringsLocaleName;
203
205
  }
204
- return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, this._formatLocaleForFilename(locale));
206
+ return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, this._formatLocaleForFilename(locale, undefined));
205
207
  }
206
208
  }
207
209
  else {
@@ -373,7 +375,7 @@ class LocalizationPlugin {
373
375
  fileInfo.translations.set(pseudolocaleName, pseudolocFileData);
374
376
  }
375
377
  (0, EntityMarker_1.markEntity)(context._module, true);
376
- return fileInfo.renderedPlacholders;
378
+ return fileInfo.renderedPlaceholders;
377
379
  }
378
380
  /**
379
381
  * @public
@@ -385,11 +387,39 @@ class LocalizationPlugin {
385
387
  }
386
388
  return file.placeholders.get(stringName);
387
389
  }
390
+ /**
391
+ * @beta
392
+ */
393
+ getCustomDataPlaceholderForValueFunction(valueForLocaleFn, placeholderUniqueId) {
394
+ let placeholder = this._customDataPlaceholderByUniqueId.get(placeholderUniqueId);
395
+ if (!placeholder) {
396
+ // Get a hash of the unique ID to make sure its value doesn't interfere with our placeholder tokens
397
+ const suffix = Buffer.from(placeholderUniqueId, 'utf-8').toString('hex');
398
+ placeholder = {
399
+ value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.CUSTOM_PLACEHOLDER_LABEL}_${suffix}_`,
400
+ suffix,
401
+ valueForLocaleFn
402
+ };
403
+ this._customDataPlaceholderBySuffix.set(suffix, placeholder);
404
+ this._customDataPlaceholderByUniqueId.set(placeholderUniqueId, placeholder);
405
+ }
406
+ else if (placeholder.valueForLocaleFn !== valueForLocaleFn) {
407
+ throw new Error(`${this.getCustomDataPlaceholderForValueFunction.name} has already been called with "${placeholderUniqueId}" ` +
408
+ `and a different valueForLocaleFn.`);
409
+ }
410
+ return placeholder.value;
411
+ }
388
412
  /**
389
413
  * @internal
390
414
  */
391
- getDataForSerialNumber(serialNumber) {
392
- return this._stringPlaceholderMap.get(serialNumber);
415
+ _getStringDataForSerialNumber(suffix) {
416
+ return this._stringPlaceholderBySuffix.get(suffix);
417
+ }
418
+ /**
419
+ * @internal
420
+ */
421
+ _getCustomDataForSerialNumber(suffix) {
422
+ return this._customDataPlaceholderBySuffix.get(suffix);
393
423
  }
394
424
  _addLocFileAndGetPlaceholders(localeName, localizedFileKey, localizedFileData) {
395
425
  let fileInfo = this._locFiles.get(localizedFileKey);
@@ -397,7 +427,7 @@ class LocalizationPlugin {
397
427
  fileInfo = {
398
428
  placeholders: new Map(),
399
429
  translations: new Map(),
400
- renderedPlacholders: {}
430
+ renderedPlaceholders: {}
401
431
  };
402
432
  this._locFiles.set(localizedFileKey, fileInfo);
403
433
  }
@@ -411,22 +441,19 @@ class LocalizationPlugin {
411
441
  placeholder = {
412
442
  value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.STRING_PLACEHOLDER_LABEL}_\\_${suffix}_`,
413
443
  suffix,
414
- translations,
444
+ translations: translations,
415
445
  locFilePath: localizedFileKey,
416
446
  stringName
417
447
  };
418
448
  placeholders.set(stringName, placeholder);
419
- this._stringPlaceholderMap.set(suffix, placeholder);
449
+ this._stringPlaceholderBySuffix.set(suffix, placeholder);
420
450
  }
421
451
  resultObject[stringName] = placeholder.value;
422
452
  }
423
453
  translations.set(localeName, localizedFileData);
424
- fileInfo.renderedPlacholders = resultObject;
454
+ fileInfo.renderedPlaceholders = resultObject;
425
455
  return fileInfo;
426
456
  }
427
- _addTranslations(localeName, fileInfo, localizedFileData) {
428
- fileInfo.translations.set(localeName, localizedFileData);
429
- }
430
457
  _initializeAndValidateOptions(compiler, isWebpackDevServer) {
431
458
  var _a;
432
459
  const errors = [];
@@ -1 +1 @@
1
- {"version":3,"file":"LocalizationPlugin.js","sourceRoot":"","sources":["../src/LocalizationPlugin.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0E3D,8CAMC;AA9ED,2CAA6B;AAe7B,8EAA6G;AAC7G,kEAA+D;AAE/D,iEAAmD;AASnD,2DAA+D;AAC/D,qDAAyG;AACzG,6CAA+E;AAC/E,+DAAuD;AAkCvD,MAAM,WAAW,GAAmB,cAAc,CAAC;AAEnD,MAAM,iBAAiB,GAA0C,IAAI,OAAO,EAAE,CAAC;AAE/E;;;GAGG;AACH,SAAgB,iBAAiB,CAAC,QAA8B;IAC9D,MAAM,QAAQ,GAAmC,QAAQ,IAAI,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,gFAAgF,CAAC,CAAC;IACpG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;;;GAIG;AACH,MAAa,kBAAkB;IAwB7B,YAAmB,OAAmC;QAvBrC,cAAS,GAAsC,IAAI,GAAG,EAAE,CAAC;QAMzD,0CAAqC,GAGlD,IAAI,GAAG,EAAE,CAAC;QACG,0BAAqB,GAAoC,IAAI,GAAG,EAAE,CAAC;QAMnE,sBAAiB,GAAyC,IAAI,GAAG,EAAE,CAAC;QAErF;;WAEG;QACK,uBAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAGlD,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;OAEG;IACI,KAAK,CAAC,QAAkB;QAC7B,iBAAiB,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAEtC,yGAAyG;QACzG,MAAM,kBAAkB,GAAY,OAAO,CAAC,GAAG,CAAC,kBAAkB,KAAK,MAAM,CAAC;QAE9E,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,6BAA6B,CAAC,QAAQ,EAAE,kBAAkB,CAAC,CAAC;QAE9F,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,WAAwB,EAAE,EAAE;gBACvE,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;gBACnC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC,CAAC;YACzC,CAAC,CAAC,CAAC;YAEH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACtB,sFAAsF;gBACtF,2BAA2B;gBAC3B,OAAO;YACT,CAAC;QACH,CAAC;QAED,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,GAAG,QAAQ,CAAC;QAC1C,MAAM,EACJ,YAAY,EACZ,OAAO,EAAE,EAAE,6BAA6B,EAAE,EAC3C,GAAG,WAAW,CAAC;QAEhB,sGAAsG;QACtG,8EAA8E;QAC9E,IAAI,0BAA6C,CAAC;QAElD,MAAM,gBAAgB,GACpB,6BAA6B,CAAC,SAAS,CAAC,QAAQ,CAAC;QACnD,6BAA6B,CAAC,SAAS,CAAC,QAAQ,GAAG;YAGjD,mFAAmF;YACnF,mGAAmG;YACnG,0BAA0B,GAAG,IAAI,CAAC,KAAK,CAAC;YACxC,MAAM,MAAM,GAAkB,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1D,yFAAyF;YACzF,0BAA0B,GAAG,SAAS,CAAC;YACvC,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,MAAM,kBAAkB,GAAW,QAAQ,CAAC;QAE5C,MAAM,EAAE,uBAAuB,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAElD,QAAQ,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,WAAwB,EAAE,EAAE;;YAC3E,IAAI,MAA0B,CAAC;YAC/B,IAAI,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;gBAClC,IAAI,uBAAuB,EAAE,CAAC;oBAC5B,WAAW,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,YAAY,CACd,4FAA4F,CAC7F,CACF,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,MAAM,GAAG,IAAA,4BAAe,EAAC,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC,CAAC;gBACzD,CAAC;YACH,CAAC;iBAAM,IAAI,MAAA,QAAQ,CAAC,OAAO,CAAC,YAAY,0CAAE,eAAe,EAAE,CAAC;gBAC1D,WAAW,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,WAAW,CAAC,YAAY,CAC1B,8DAA8D,kBAAkB,CAAC,IAAI,KAAK;oBACxF,sGAAsG;oBACtG,qCAAqC,kBAAkB,CAAC,IAAI,UAAU,CACzE,CACF,CAAC;YACJ,CAAC;YAED,MAAM,uBAAuB,GAAmB,IAAI,OAAO,EAAE,CAAC;YAE9D,WAAW,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAC7B,WAAW,EACX,CAAC,SAAiB,EAAE,OAA0B,EAAU,EAAE;;gBACxD,MAAM,EAAE,UAAU,EAAE,GAAG,WAAW,CAAC;gBAEnC,IACE,OAAO,CAAC,eAAe,KAAK,YAAY;oBACxC,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,2BAA2B,CAAC,EACtD,CAAC;oBACD,oDAAoD;oBACpD,IAAI,OAAO,CAAA,MAAA,OAAO,CAAC,KAAK,0CAAE,EAAE,CAAA,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,EAAE,CAAC;wBACxF,MAAM,mBAAmB,GAAyB,IAAI,GAAG,EAAmB,CAAC;wBAC7E,MAAM,sBAAsB,GAAyB,IAAI,GAAG,EAAmB,CAAC;wBAEhF,MAAM,gCAAgC,GAAsB,0BAA0B,CAAC;wBAEvF,IAAI,CAAC,gCAAgC,EAAE,CAAC;4BACtC,WAAW,CAAC,MAAM,CAAC,IAAI,CACrB,IAAI,YAAY,CAAC,+DAA+D,CAAC,CAClF,CAAC;4BACF,OAAO,SAAS,CAAC;wBACnB,CAAC;wBAED,MAAM,WAAW,GAAe,gCAAgC,CAAC,iBAAiB,EAAE,CAAC;wBACrF,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;4BACrC,MAAM,OAAO,GAA2B,UAAU,CAAC,EAAE,CAAC;4BAEtD,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gCAC9C,MAAM,IAAI,KAAK,CAAC,UAAU,UAAU,CAAC,IAAI,8BAA8B,CAAC,CAAC;4BAC3E,CAAC;4BAED,IAAI,yBAAyB,CAAC,UAAU,EAAE,UAAU,EAAE,uBAAuB,CAAC,EAAE,CAAC;gCAC/E,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;4BACnC,CAAC;iCAAM,CAAC;gCACN,sBAAsB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;4BACtC,CAAC;wBACH,CAAC;wBAED,OAAO,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,2BAA2B,EAAE,GAAG,EAAE;4BACnE,uFAAuF;4BAEvF,2FAA2F;4BAC3F,uDAAuD;4BACvD,MAAM,gBAAgB,GACpB,CAAC,CAAC,yBAAyB,CACzB,UAAU,EACV,gCAAgC,EAChC,uBAAuB,CACxB;gCACC,uBAAuB,CAAC;gCAC1B,SAAS,CAAC,iBAAiB,CAAC;4BAC9B,IAAI,gBAAgB,KAAK,SAAS,CAAC,iBAAiB,EAAE,CAAC;gCACrD,uBAAuB,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;4BAChE,CAAC;4BAED,IAAI,mBAAmB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gCACnC,OAAO,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;4BAClE,CAAC;iCAAM,IAAI,sBAAsB,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gCAC7C,OAAO,OAAO,gBAAgB,MAAM,CAAC;4BACvC,CAAC;iCAAM,CAAC;gCACN,sGAAsG;gCACtG,gGAAgG;gCAChG,kGAAkG;gCAClG,wBAAwB;gCACxB,EAAE;gCACF,2GAA2G;gCAC3G,oDAAoD;gCACpD,MAAM,YAAY,GAA6B,EAAE,CAAC;gCAClD,+DAA+D;gCAC/D,MAAM,kBAAkB,GAAY,mBAAmB,CAAC,IAAI,IAAI,sBAAsB,CAAC,IAAI,CAAC;gCAC5F,+EAA+E;gCAC/E,MAAM,UAAU,GAAyB,kBAAkB;oCACzD,CAAC,CAAC,mBAAmB;oCACrB,CAAC,CAAC,sBAAsB,CAAC;gCAC3B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;oCAC5B,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gCACvB,CAAC;gCAED,MAAM,kBAAkB,GAAW,IAAI,CAAC,SAAS,CAC/C,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,oBAAoB,CAAC,CACzD,CAAC;gCAEF,OAAO,QAAQ,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,aACzC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAC1C,IAAI,kBAAkB,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,gBAAgB,OAAO,CAAC;4BACxE,CAAC;wBACH,CAAC,CAAC,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACN,IAAI,MAAM,GAAuB,OAAO,CAAC,MAAM,CAAC;wBAChD,IAAI,CAAC,MAAM,EAAE,CAAC;4BACZ,MAAM,WAAW,GAAY,yBAAyB,CACpD,UAAU,EACV,OAAO,CAAC,KAAc,EACtB,uBAAuB,CACxB,CAAC;4BACF,oFAAoF;4BACpF,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC;wBACzE,CAAC;wBACD,OAAO,SAAS,CAAC,OAAO,CACtB,SAAS,CAAC,2BAA2B,EACrC,IAAI,CAAC,wBAAwB,CAAC,MAAM,CAAC,CACtC,CAAC;oBACJ,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC,CACF,CAAC;YAEF,MAAM,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC;YAEtC,2GAA2G;YAC3G,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,UAAU,CACxC;gBACE,IAAI,EAAE,WAAW;gBACjB,2FAA2F;gBAC3F,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,gCAAgC,GAAG,CAAC;aACzE,EACD,KAAK,IAAmB,EAAE;gBACxB,MAAM,OAAO,GAAgB,IAAI,CAAC,kBAAkB,CAAC;gBAErD,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC;gBAC3C,MAAM,EAAE,iBAAiB,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;gBAE1D,MAAM,gBAAgB,GAAoD,YAAY;oBACpF,CAAC,CAAC,IAAI,GAAG,EAAE;oBACX,CAAC,CAAC,SAAS,CAAC;gBACd,MAAM,wBAAwB,GAAa,EAAE,CAAC;gBAC9C,MAAM,mBAAmB,GAAa,EAAE,CAAC;gBAGzC,MAAM,KAAK,GAAgB,WAAW,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAE7D,MAAM,aAAK,CAAC,YAAY,CACtB,MAAM,EACN,KAAK,EAAE,KAAY,EAAE,EAAE;oBACrB,IAAI,CAAC,IAAA,0BAAS,EAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;wBAClC,OAAO;oBACT,CAAC;oBAED,MAAM,WAAW,GAAY,yBAAyB,CACpD,UAAU,EACV,KAAK,EACL,uBAAuB,CACxB,CAAC;oBAEF,MAAM,QAAQ,GACZ,KAAK,CAAC,gBAAgB;wBACtB,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,aAAa,CAAE,CAAC;oBAE/E,MAAM,gBAAgB,GAAW,WAAW,CAAC,OAAO,CAAC,QAAQ,EAAE;wBAC7D,KAAK;wBACL,eAAe,EAAE,YAAY;wBAC7B,kEAAkE;qBACnE,CAAC,CAAC;oBAEH,MAAM,KAAK,GAAsB,WAAW,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;oBACxE,IAAI,CAAC,KAAK,EAAE,CAAC;wBACX,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,gCAAgC,gBAAgB,EAAE,CAAC,CAAC,CAAC;wBAC9F,OAAO;oBACT,CAAC;oBAED,IAAI,WAAW,EAAE,CAAC;wBAChB,MAAM,eAAe,GAA2B,MAAM,IAAA,iDAAgC,EAAC;4BACrF,gBAAgB;4BAChB,MAAM,EAAE,IAAI;4BACZ,WAAW;4BACX,KAAK;4BACL,OAAO;4BACP,aAAa,EAAE,IAAI,CAAC,cAAc;4BAClC,qBAAqB,EAAE,IAAI,CAAC,sBAAsB;4BAClD,6BAA6B,EAAE,IAAI,CAAC,8BAA8B;4BAClE,yBAAyB,EAAE,IAAI,CAAC,wBAAwB;4BACxD,wBAAwB;4BACxB,KAAK;4BACL,KAAK;4BACL,gBAAgB,EAAE,QAAQ;yBAC3B,CAAC,CAAC;wBAEH,IAAI,gBAAgB,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC;4BACnC,gBAAgB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;4BAClD,CAAC,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBACzF,CAAC;oBACH,CAAC;yBAAM,CAAC;wBACN,MAAM,IAAA,oDAAmC,EAAC;4BACxC,gBAAgB;4BAChB,MAAM,EAAE,IAAI;4BACZ,WAAW;4BACX,KAAK;4BACL,eAAe,EAAE,uBAAuB,CAAC,GAAG,CAAC,KAAK,CAAC;4BACnD,mBAAmB,EAAE,IAAI,CAAC,oBAAoB;4BAC9C,yBAAyB,EAAE,IAAI,CAAC,wBAAwB;4BACxD,wBAAwB;4BACxB,KAAK;4BACL,KAAK;4BACL,QAAQ,EAAE,gBAAgB;yBAC3B,CAAC,CAAC;oBACL,CAAC;gBACH,CAAC,EACD;oBACE,0CAA0C;oBAC1C,WAAW,EAAE,EAAE;iBAChB,CACF,CAAC;gBAEF,IAAI,MAAM,EAAE,CAAC;oBACX,IAAA,8BAAiB,EAAC;wBAChB,WAAW;wBACX,WAAW;wBACX,MAAM;wBACN,gBAAgB;qBACjB,CAAC,CAAC;gBACL,CAAC;gBAED,0EAA0E;gBAC1E,IAAI,YAAY,IAAI,gBAAgB,EAAE,CAAC;oBACrC,MAAM,iBAAiB,GAAuB;wBAC5C,WAAW,EAAE,EAAE;wBACf,gBAAgB,EAAE,EAAE;qBACrB,CAAC;oBAEF,sDAAsD;oBACtD,mBAAmB,CAAC,IAAI,EAAE,CAAC;oBAC3B,KAAK,MAAM,SAAS,IAAI,mBAAmB,EAAE,CAAC;wBAC5C,iBAAiB,CAAC,gBAAgB,CAAC,SAAS,CAAC,GAAG;4BAC9C,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE;yBAClD,CAAC;oBACJ,CAAC;oBAED,sDAAsD;oBACtD,wBAAwB,CAAC,IAAI,EAAE,CAAC;oBAChC,KAAK,MAAM,SAAS,IAAI,wBAAwB,EAAE,CAAC;wBACjD,iBAAiB,CAAC,WAAW,CAAC,SAAS,CAAC,GAAG;4BACzC,eAAe,EAAE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAE;yBAClD,CAAC;oBACJ,CAAC;oBAED,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC;oBAE5C,IAAI,QAAQ,EAAE,CAAC;wBACb,WAAW,CAAC,SAAS,CACnB,QAAQ,EACR,IAAI,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC,CAC1E,CAAC;oBACJ,CAAC;oBAED,IAAI,QAAQ,EAAE,CAAC;wBACb,IAAI,CAAC;4BACH,QAAQ,CAAC,iBAAiB,EAAE,WAAW,CAAC,CAAC;wBAC3C,CAAC;wBAAC,OAAO,CAAC,EAAE,CAAC;4BACX,sCAAsC;wBACxC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC,CACF,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,sBAAsB,CACjC,OAA0B,EAC1B,gBAAwB,EACxB,qBAAwC;QAExC,MAAM,WAAW,GAAgC,gCAAgC,CAAC,qBAAqB,CAAC,CAAC;QACzG,MAAM,QAAQ,GAAyB,IAAI,CAAC,6BAA6B,CACvE,IAAI,CAAC,cAAc,EACnB,gBAAgB,EAChB,WAAW,CACZ,CAAC;QAEF,MAAM,cAAc,GAAa,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,oBAAoB,EAAE,iBAAiB,CAAC,IAAI,IAAI,CAAC,qCAAqC,EAAE,CAAC;YACnG,MAAM,4BAA4B,GAChC,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;YAE1C,IAAI,CAAC,4BAA4B,EAAE,CAAC;gBAClC,cAAc,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;YAC5C,CAAC;iBAAM,CAAC;gBACN,MAAM,qBAAqB,GAAgC,MAAM,2BAA2B,CAC1F,OAAO,EACP,4BAA4B,CAC7B,CAAC;gBACF,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,oBAAoB,EAAE,qBAAqB,CAAC,CAAC;YACzE,CAAC;QACH,CAAC;QAED,MAAM,EAAE,+BAA+B,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;QAExE,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC,IAAI,+BAA+B,EAAE,CAAC;YACjE,IAAI,sBAAsB,GAA6C,SAAS,CAAC;YACjF,IAAI,CAAC;gBACH,sBAAsB,GAAG,MAAM,+BAA+B,CAC5D,cAAc,EACd,gBAAgB,EAChB,OAAO,CACR,CAAC;YACJ,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACX,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;YAED,IAAI,sBAAsB,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GACZ,sBAAsB,YAAY,GAAG;oBACnC,CAAC,CAAC,sBAAsB,CAAC,OAAO,EAAE;oBAClC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;gBAC7C,KAAK,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,CAAC,IAAI,QAAQ,EAAE,CAAC;oBAChE,IAAI,kBAAkB,EAAE,CAAC;wBACvB,MAAM,qBAAqB,GAAgC,MAAM,2BAA2B,CAC1F,OAAO,EACP,kBAAkB,CACnB,CAAC;wBACF,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,CAAC;oBACvE,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QAED,KAAK,MAAM,CAAC,gBAAgB,EAAE,eAAe,CAAC,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzE,MAAM,iBAAiB,GAAwB,IAAI,GAAG,EAAE,CAAC;YAEzD,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,WAAW,EAAE,CAAC;gBACpD,iBAAiB,CAAC,GAAG,CAAC,UAAU,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC,CAAC;YAClE,CAAC;YAED,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;QACjE,CAAC;QAED,IAAA,yBAAU,EAAC,OAAO,CAAC,OAAQ,EAAE,IAAI,CAAC,CAAC;QAEnC,OAAO,QAAQ,CAAC,mBAAmB,CAAC;IACtC,CAAC;IAED;;OAEG;IACI,cAAc,CAAC,gBAAwB,EAAE,UAAkB;QAChE,MAAM,IAAI,GAAqC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACpF,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAC3C,CAAC;IAED;;OAEG;IACI,sBAAsB,CAAC,YAAoB;QAChD,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;IACtD,CAAC;IAEO,6BAA6B,CACnC,UAAkB,EAClB,gBAAwB,EACxB,iBAA8C;QAE9C,IAAI,QAAQ,GAAqC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;QACtF,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,QAAQ,GAAG;gBACT,YAAY,EAAE,IAAI,GAAG,EAAE;gBACvB,YAAY,EAAE,IAAI,GAAG,EAAE;gBACvB,mBAAmB,EAAE,EAAE;aACxB,CAAC;YACF,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC;QAChD,MAAM,aAAa,GAAW,MAAM,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC;QAE3F,MAAM,YAAY,GAA2B,EAAE,CAAC;QAChD,KAAK,MAAM,UAAU,IAAI,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC;YAClD,IAAI,WAAW,GAAmC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC/E,IAAI,CAAC,WAAW,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAW,GAAG,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBAE7F,WAAW,GAAG;oBACZ,KAAK,EAAE,GAAG,SAAS,CAAC,yBAAyB,IAAI,SAAS,CAAC,wBAAwB,OAAO,MAAM,GAAG;oBACnG,MAAM;oBACN,YAAY;oBACZ,WAAW,EAAE,gBAAgB;oBAC7B,UAAU;iBACX,CAAC;gBAEF,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;gBAC1C,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;YACtD,CAAC;YAED,YAAY,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC;QAC/C,CAAC;QAED,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;QAChD,QAAQ,CAAC,mBAAmB,GAAG,YAAY,CAAC;QAE5C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAEO,gBAAgB,CACtB,UAAkB,EAClB,QAA8B,EAC9B,iBAA8C;QAE9C,QAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAC;IAC3D,CAAC;IAEO,6BAA6B,CACnC,QAAkB,EAClB,kBAA2B;;QAE3B,MAAM,MAAM,GAAmB,EAAE,CAAC;QAClC,MAAM,QAAQ,GAAmB,EAAE,CAAC;QAEpC,MAAM,EAAE,YAAY,EAAE,GAAG,QAAQ,CAAC,OAAO,CAAC;QAC1C,MAAM,EAAE,OAAO,EAAE,aAAa,EAAE,GAAG,QAAQ,CAAC;QAE5C,MAAM,iBAAiB,GAAW,SAAS,CAAC;QAC5C,SAAS,qBAAqB,CAAC,UAAkB;YAC/C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACzC,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,wBAAwB,UAAU,sDAAsD,CACzF,CACF,CAAC;gBACF,OAAO,KAAK,CAAC;YACf,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,IACE,CAAC,aAAa,CAAC,MAAM;YACrB,CAAC,aAAa,CAAC,MAAM,CAAC,QAAQ;YAC9B,OAAO,aAAa,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ;YACjD,aAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,KAAK,CAAC,CAAC,EAC7E,CAAC;YACD,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,kGAAkG;gBAChG,OAAO,SAAS,CAAC,qBAAqB,cAAc,CACvD,CACF,CAAC;QACJ,CAAC;QACD,oBAAoB;QAEpB,qBAAqB;QACrB,8BAA8B;QAC9B,MAAM,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACxC,IAAI,aAAa,EAAE,CAAC;YAClB,gDAAgD;YAChD,MAAM,EAAE,iBAAiB,EAAE,GAAG,aAAa,CAAC;YAC5C,IAAI,iBAAiB,EAAE,CAAC;gBACtB,MAAM,EAAE,oBAAoB,EAAE,qBAAqB,GAAG,aAAa,EAAE,GAAG,iBAAiB,CAAC;gBAC1F,IAAI,oBAAoB,EAAE,CAAC;oBACzB,IAAI,CAAC,sBAAsB,GAAG,qBAAqB,CAAC;oBACpD,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;YACD,8CAA8C;YAE9C,gDAAgD;YAChD,MAAM,wBAAwB,GAAiC,CAC7D,CAAA,MAAA,aAAa,CAAC,OAAO,0CAAE,UAAU,CAAC,GAAG,CAAC,EAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAC3E,CAAC,IAAI,CAAC,CAAC,EAAE,aAAa,CAAC,OAAQ,CAAC,CAAC;YAClC,MAAM,EAAE,iBAAiB,EAAE,GAAG,aAAa,CAAC;YAC5C,IAAI,CAAC,qCAAqC,CAAC,KAAK,EAAE,CAAC;YACnD,IAAI,iBAAiB,EAAE,CAAC;gBACtB,KAAK,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;oBACrE,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC5C,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,eAAe,UAAU,4BAA4B;4BACnD,wDAAwD,CAC3D,CACF,CAAC;wBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;wBACvC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACxC,MAAM,4BAA4B,GAAiC,IAAI,GAAG,EAAE,CAAC;oBAC7E,IAAI,CAAC,qCAAqC,CAAC,GAAG,CAAC,UAAU,EAAE,4BAA4B,CAAC,CAAC;oBAEzF,KAAK,MAAM,CAAC,WAAW,EAAE,sBAAsB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;wBAC3E,MAAM,qBAAqB,GAAW,wBAAwB,CAAC,WAAW,CAAC,CAAC;wBAE5E,IAAI,4BAA4B,CAAC,GAAG,CAAC,qBAAqB,CAAC,EAAE,CAAC;4BAC5D,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,+BAA+B,WAAW,sCAAsC,UAAU,IAAI;gCAC5F,wDAAwD,CAC3D,CACF,CAAC;4BACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;wBAC9B,CAAC;wBAED,MAAM,gCAAgC,GACpC,OAAO,sBAAsB,KAAK,QAAQ;4BACxC,CAAC,CAAC,wBAAwB,CAAC,sBAAsB,CAAC;4BAClD,CAAC,CAAC,sBAAsB,CAAC;wBAE7B,4BAA4B,CAAC,GAAG,CAAC,qBAAqB,EAAE,gCAAgC,CAAC,CAAC;oBAC5F,CAAC;gBACH,CAAC;YACH,CAAC;YACD,8CAA8C;YAE9C,4CAA4C;YAC5C,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;YACxC,IAAI,aAAa,EAAE,CAAC;gBAClB,MAAM,EAAE,UAAU,EAAE,6BAA6B,EAAE,GAAG,aAAa,CAAC;gBACpE,IAAI,UAAU,EAAE,CAAC;oBACf,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC5C,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,iEAAiE,CAAC,CAAC,CAAC;wBACjG,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;yBAAM,IAAI,CAAC,qBAAqB,CAAC,UAAU,CAAC,EAAE,CAAC;wBAC9C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;oBACxC,IAAI,CAAC,cAAc,GAAG,UAAU,CAAC;oBACjC,IAAI,CAAC,8BAA8B,GAAG,CAAC,CAAC,6BAA6B,CAAC;gBACxE,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,6BAA6B,CAAC,CAAC,CAAC;oBAC7D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;gBAC9B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,IAAI,CAAC,IAAI,YAAY,CAAC,iCAAiC,CAAC,CAAC,CAAC;gBACjE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YAC9B,CAAC;YACD,0CAA0C;YAE1C,4CAA4C;YAC5C,MAAM,EAAE,aAAa,EAAE,GAAG,aAAa,CAAC;YACxC,IAAI,aAAa,EAAE,CAAC;gBAClB,KAAK,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;oBACjF,IAAI,IAAI,CAAC,cAAc,KAAK,gBAAgB,EAAE,CAAC;wBAC7C,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CAAC,mBAAmB,gBAAgB,yCAAyC,CAAC,CAC/F,CAAC;wBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,gBAAgB,CAAC,EAAE,CAAC;wBAClD,MAAM,CAAC,IAAI,CACT,IAAI,YAAY,CACd,mBAAmB,gBAAgB,qDAAqD,CACzF,CACF,CAAC;wBACF,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;oBAC9B,CAAC;oBAED,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAA,2CAAkB,EAAC,gBAAgB,CAAC,CAAC,CAAC;oBACnF,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YACD,0CAA0C;QAC5C,CAAC;aAAM,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;QAC3F,CAAC;QACD,4BAA4B;QAE5B,oCAAoC;QACpC,MAAM,EAAE,mBAAmB,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9C,IACE,mBAAmB,KAAK,SAAS;YACjC,mBAAmB,KAAK,IAAI;YAC5B,CAAC,qBAAqB,CAAC,mBAAmB,CAAC,EAC3C,CAAC;YACD,IAAI,CAAC,oBAAoB,GAAG,MAAM,CAAC;QACrC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,oBAAoB,GAAG,mBAAmB,CAAC;QAClD,CAAC;QACD,kCAAkC;QAElC,wCAAwC;QACxC,MAAM,EAAE,uBAAuB,GAAG,CAAC,UAAkB,EAAE,EAAE,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC;QACvF,IAAI,CAAC,wBAAwB,GAAG,uBAAuB,CAAC;QACxD,sCAAsC;QACtC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;IAC9B,CAAC;CACF;AAnrBD,gDAmrBC;AAED,SAAS,yBAAyB,CAChC,UAAsB,EACtB,KAAY,EACZ,uBAA2C;IAE3C,IAAI,qBAAqB,GAAwB,IAAA,sBAAO,EAAC,KAAK,CAAC,CAAC;IAChE,IAAI,qBAAqB,KAAK,SAAS,EAAE,CAAC;QACxC,qBAAqB,GAAG,KAAK,CAAC;QAC9B,MAAM,gBAAgB,GAAiC,UAAU,CAAC,mCAAmC,CACnG,KAAK,EACL,YAAY,CACb,CAAC;QACF,IAAI,gBAAgB,EAAE,CAAC;YACrB,KAAK,EAAE,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;gBAC7C,MAAM,UAAU,GAAwB,IAAA,sBAAO,EAAC,MAAM,CAAC,CAAC;gBACxD,IAAI,UAAU,EAAE,CAAC;oBACf,qBAAqB,GAAG,IAAI,CAAC;oBAC7B,MAAM;gBACR,CAAC;qBAAM,IAAI,UAAU,KAAK,KAAK,EAAE,CAAC;oBAChC,SAAS;gBACX,CAAC;gBAED,iCAAiC;gBACjC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,MAAyC,CAAC;gBACxE,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,MAAM,YAAY,IAAI,OAAO,EAAE,CAAC;wBACnC,IAAI,IAAA,sBAAO,EAAC,YAAY,CAAC,EAAE,CAAC;4BAC1B,IAAA,yBAAU,EAAC,MAAM,EAAE,IAAI,CAAC,CAAC;4BACzB,qBAAqB,GAAG,IAAI,CAAC;4BAC7B,MAAM,KAAK,CAAC;wBACd,CAAC;oBACH,CAAC;oBACD,IAAA,yBAAU,EAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBAC5B,CAAC;YACH,CAAC;QACH,CAAC;QAED,2EAA2E;QAC3E,8EAA8E;QAC9E,uCAAuC;QACvC,yEAAyE;QACzE,mBAAmB;QACnB,IAAI,CAAC,qBAAqB,IAAI,CAAC,uBAAuB,IAAI,KAAK,CAAC,UAAU,EAAE,EAAE,CAAC;YAC7E,KAAK,MAAM,UAAU,IAAI,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC;gBACnD,IAAI,yBAAyB,CAAC,UAAU,EAAE,UAAU,EAAE,uBAAuB,CAAC,EAAE,CAAC;oBAC/E,qBAAqB,GAAG,IAAI,CAAC;oBAC7B,MAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC;QAED,IAAA,yBAAU,EAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IAC3C,CAAC;IAED,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED,SAAS,gCAAgC,CAAC,OAA0B;IAClE,MAAM,WAAW,GAAwB,IAAI,GAAG,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,UAAU,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACjE,WAAW,CAAC,GAAG,CAAC,UAAU,EAAE,YAAY,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,WAAW,CAAC;AACrB,CAAC;AAED,KAAK,UAAU,2BAA2B,CACxC,OAA0B,EAC1B,aAA8B;IAE9B,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE,CAAC;QACtC,+DAA+D;QAC/D,OAAO,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;QACrC,MAAM,OAAO,GAAW,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC5D,2FAA2F;YAC3F,OAAO,CAAC,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE;gBAC/C,IAAI,GAAG,EAAE,CAAC;oBACR,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;gBACrB,CAAC;qBAAM,IAAI,CAAC,IAAI,EAAE,CAAC;oBACjB,OAAO,MAAM,CAAC,IAAI,KAAK,CAAC,cAAc,aAAa,EAAE,CAAC,CAAC,CAAC;gBAC1D,CAAC;gBACD,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;YAC3B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,MAAM,gBAAgB,GAAsB,IAAA,qCAAY,EAAC;YACvD,QAAQ,EAAE,aAAa;YACvB,OAAO;SACR,CAAC,CAAC;QAEH,OAAO,gCAAgC,CAAC,gBAAgB,CAAC,CAAC;IAC5D,CAAC;SAAM,CAAC;QACN,OAAO,aAAa,YAAY,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'path';\n\nimport type {\n Asset,\n Chunk,\n ChunkGraph,\n Compilation,\n Compiler,\n LoaderContext,\n Module,\n runtime,\n WebpackError,\n WebpackPluginInstance\n} from 'webpack';\n\nimport { getPseudolocalizer, type ILocalizationFile, parseResJson } from '@rushstack/localization-utilities';\nimport { Async } from '@rushstack/node-core-library/lib/Async';\n\nimport * as Constants from './utilities/Constants';\nimport type {\n ILocalizationPluginOptions,\n ILocalizationStats,\n ILocaleFileData,\n ILocaleFileObject,\n IResolvedMissingTranslations\n} from './interfaces';\nimport type { IAssetPathOptions } from './webpackInterfaces';\nimport { markEntity, getMark } from './utilities/EntityMarker';\nimport { processLocalizedAssetCachedAsync, processNonLocalizedAssetCachedAsync } from './AssetProcessor';\nimport { getHashFunction, type HashFn, updateAssetHashes } from './trueHashes';\nimport { chunkIsJs } from './utilities/chunkUtilities';\n\n/**\n * @public\n */\nexport interface IStringPlaceholder {\n /**\n * The literal string that will be injected for later replacement.\n */\n value: string;\n /**\n * The identifier for this particular placeholder, for lookup.\n */\n suffix: string;\n /**\n * The values of this string in each output locale.\n */\n translations: ReadonlyMap<string, ReadonlyMap<string, string>>;\n /**\n * The key used to identify the source file containing the string.\n */\n locFilePath: string;\n /**\n * The identifier of the string within its original source file.\n */\n stringName: string;\n}\n\nexport interface IFileTranslationInfo {\n placeholders: Map<string, IStringPlaceholder>;\n translations: Map<string, ReadonlyMap<string, string>>;\n renderedPlacholders: Record<string, string>;\n}\n\nconst PLUGIN_NAME: 'localization' = 'localization';\n\nconst pluginForCompiler: WeakMap<Compiler, LocalizationPlugin> = new WeakMap();\n\n/**\n * Gets the instance of the LocalizationPlugin bound to the specified webpack compiler.\n * Used by loaders.\n */\nexport function getPluginInstance(compiler: Compiler | undefined): LocalizationPlugin {\n const instance: LocalizationPlugin | undefined = compiler && pluginForCompiler.get(compiler);\n if (!instance) {\n throw new Error(`Could not find a LocalizationPlugin instance for the current webpack compiler!`);\n }\n return instance;\n}\n\n/**\n * This plugin facilitates localization in webpack.\n *\n * @public\n */\nexport class LocalizationPlugin implements WebpackPluginInstance {\n private readonly _locFiles: Map<string, IFileTranslationInfo> = new Map();\n\n /**\n * @internal\n */\n public readonly _options: ILocalizationPluginOptions;\n private readonly _resolvedTranslatedStringsFromOptions: Map<\n string,\n Map<string, ILocaleFileObject | string | ReadonlyMap<string, string>>\n > = new Map();\n private readonly _stringPlaceholderMap: Map<string, IStringPlaceholder> = new Map();\n private _passthroughLocaleName!: string;\n private _defaultLocale!: string;\n private _noStringsLocaleName!: string;\n private _fillMissingTranslationStrings!: boolean;\n private _formatLocaleForFilename!: (loc: string) => string;\n private readonly _pseudolocalizers: Map<string, (str: string) => string> = new Map();\n\n /**\n * The set of locales that have translations provided.\n */\n private _translatedLocales: Set<string> = new Set();\n\n public constructor(options: ILocalizationPluginOptions) {\n this._options = options;\n }\n\n /**\n * Apply this plugin to the specified webpack compiler.\n */\n public apply(compiler: Compiler): void {\n pluginForCompiler.set(compiler, this);\n\n // https://github.com/webpack/webpack-dev-server/pull/1929/files#diff-15fb51940da53816af13330d8ce69b4eR66\n const isWebpackDevServer: boolean = process.env.WEBPACK_DEV_SERVER === 'true';\n\n const { errors, warnings } = this._initializeAndValidateOptions(compiler, isWebpackDevServer);\n\n if (errors.length > 0 || warnings.length > 0) {\n compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n compilation.errors.push(...errors);\n compilation.warnings.push(...warnings);\n });\n\n if (errors.length > 0) {\n // If there are any errors, just pass through the resources in source and don't do any\n // additional configuration\n return;\n }\n }\n\n const { webpack: thisWebpack } = compiler;\n const {\n WebpackError,\n runtime: { GetChunkFilenameRuntimeModule }\n } = thisWebpack;\n\n // Side-channel for async chunk URL generator chunk, since the actual chunk is completely inaccessible\n // from the assetPath hook below when invoked to build the async URL generator\n let chunkWithAsyncURLGenerator: Chunk | undefined;\n\n const originalGenerate: typeof GetChunkFilenameRuntimeModule.prototype.generate =\n GetChunkFilenameRuntimeModule.prototype.generate;\n GetChunkFilenameRuntimeModule.prototype.generate = function (\n this: runtime.GetChunkFilenameRuntimeModule\n ): string | null {\n // `originalGenerate` will invoke `getAssetPath` to produce the async URL generator\n // Need to know the identity of the containing chunk to correctly produce the asset path expression\n chunkWithAsyncURLGenerator = this.chunk;\n const result: string | null = originalGenerate.call(this);\n // Unset after the call finishes because we are no longer generating async URL generators\n chunkWithAsyncURLGenerator = undefined;\n return result;\n };\n\n const asyncGeneratorTest: RegExp = /^\\\" \\+/;\n\n const { runtimeLocaleExpression } = this._options;\n\n compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n let hashFn: HashFn | undefined;\n if (this._options.realContentHash) {\n if (runtimeLocaleExpression) {\n compilation.errors.push(\n new WebpackError(\n `The \"realContentHash\" option cannot be used in conjunction with \"runtimeLocaleExpression\".`\n )\n );\n } else {\n hashFn = getHashFunction({ thisWebpack, compilation });\n }\n } else if (compiler.options.optimization?.realContentHash) {\n compilation.errors.push(\n new thisWebpack.WebpackError(\n `The \\`optimization.realContentHash\\` option is set and the ${LocalizationPlugin.name}'s ` +\n '`realContentHash` option is not set. This will likely produce invalid results. Consider setting the ' +\n `\\`realContentHash\\` option in the ${LocalizationPlugin.name} plugin.`\n )\n );\n }\n\n const chunksWithUrlGenerators: WeakSet<Chunk> = new WeakSet();\n\n compilation.hooks.assetPath.tap(\n PLUGIN_NAME,\n (assetPath: string, options: IAssetPathOptions): string => {\n const { chunkGraph } = compilation;\n\n if (\n options.contentHashType === 'javascript' &&\n assetPath.match(Constants.LOCALE_FILENAME_TOKEN_REGEX)\n ) {\n // Does this look like an async chunk URL generator?\n if (typeof options.chunk?.id === 'string' && options.chunk.id.match(asyncGeneratorTest)) {\n const chunkIdsWithStrings: Set<number | string> = new Set<number | string>();\n const chunkIdsWithoutStrings: Set<number | string> = new Set<number | string>();\n\n const activeChunkWithAsyncUrlGenerator: Chunk | undefined = chunkWithAsyncURLGenerator;\n\n if (!activeChunkWithAsyncUrlGenerator) {\n compilation.errors.push(\n new WebpackError(`No active chunk while constructing async chunk URL generator!`)\n );\n return assetPath;\n }\n\n const asyncChunks: Set<Chunk> = activeChunkWithAsyncUrlGenerator.getAllAsyncChunks();\n for (const asyncChunk of asyncChunks) {\n const chunkId: number | string | null = asyncChunk.id;\n\n if (chunkId === null || chunkId === undefined) {\n throw new Error(`Chunk \"${asyncChunk.name}\"'s ID is null or undefined.`);\n }\n\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkIdsWithStrings.add(chunkId);\n } else {\n chunkIdsWithoutStrings.add(chunkId);\n }\n }\n\n return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, () => {\n // Use a replacer function so that we don't need to escape anything in the return value\n\n // If the runtime chunk is itself localized, forcibly match the locale of the runtime chunk\n // Otherwise prefer the runtime expression if specified\n const localeExpression: string =\n (!_chunkHasLocalizedModules(\n chunkGraph,\n activeChunkWithAsyncUrlGenerator,\n runtimeLocaleExpression\n ) &&\n runtimeLocaleExpression) ||\n Constants.JSONP_PLACEHOLDER;\n if (localeExpression === Constants.JSONP_PLACEHOLDER) {\n chunksWithUrlGenerators.add(activeChunkWithAsyncUrlGenerator);\n }\n\n if (chunkIdsWithStrings.size === 0) {\n return this._formatLocaleForFilename(this._noStringsLocaleName);\n } else if (chunkIdsWithoutStrings.size === 0) {\n return `\" + ${localeExpression} + \"`;\n } else {\n // Generate an object that is used to select between <locale> and <nostrings locale> for each chunk ID\n // Method: pick the smaller set of (localized, non-localized) and map that to 1 (a truthy value)\n // All other IDs map to `undefined` (a falsy value), so we then use the ternary operator to select\n // the appropriate token\n //\n // This can be improved in the future. We can maybe sort the chunks such that the chunks below a certain ID\n // number are localized and the those above are not.\n const chunkMapping: { [chunkId: string]: 1 } = {};\n // Use the map with the fewest values to shorten the expression\n const isLocalizedSmaller: boolean = chunkIdsWithStrings.size <= chunkIdsWithoutStrings.size;\n // These are the ids for which the expression should evaluate to a truthy value\n const smallerSet: Set<number | string> = isLocalizedSmaller\n ? chunkIdsWithStrings\n : chunkIdsWithoutStrings;\n for (const id of smallerSet) {\n chunkMapping[id] = 1;\n }\n\n const noLocaleExpression: string = JSON.stringify(\n this._formatLocaleForFilename(this._noStringsLocaleName)\n );\n\n return `\" + (${JSON.stringify(chunkMapping)}[chunkId]?${\n isLocalizedSmaller ? localeExpression : noLocaleExpression\n }:${isLocalizedSmaller ? noLocaleExpression : localeExpression}) + \"`;\n }\n });\n } else {\n let locale: string | undefined = options.locale;\n if (!locale) {\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n options.chunk as Chunk,\n runtimeLocaleExpression\n );\n // Ensure that the initial name maps to a file that should exist in the final output\n locale = isLocalized ? this._defaultLocale : this._noStringsLocaleName;\n }\n return assetPath.replace(\n Constants.LOCALE_FILENAME_TOKEN_REGEX,\n this._formatLocaleForFilename(locale)\n );\n }\n } else {\n return assetPath;\n }\n }\n );\n\n const { outputOptions } = compilation;\n\n // For compatibility with minifiers, need to generate the additional assets after the optimize process runs\n compilation.hooks.processAssets.tapPromise(\n {\n name: PLUGIN_NAME,\n // Generating derived assets, but explicitly want to create them *after* asset optimization\n stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1\n },\n async (): Promise<void> => {\n const locales: Set<string> = this._translatedLocales;\n\n const { chunkGraph, chunks } = compilation;\n const { localizationStats: statsOptions } = this._options;\n\n const filesByChunkName: Map<string, Record<string, string>> | undefined = statsOptions\n ? new Map()\n : undefined;\n const localizedEntryPointNames: string[] = [];\n const localizedChunkNames: string[] = [];\n\n type CacheFacade = ReturnType<Compilation['getCache']>;\n const cache: CacheFacade = compilation.getCache(PLUGIN_NAME);\n\n await Async.forEachAsync(\n chunks,\n async (chunk: Chunk) => {\n if (!chunkIsJs(chunk, chunkGraph)) {\n return;\n }\n\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n chunk,\n runtimeLocaleExpression\n );\n\n const template: Parameters<typeof Compilation.prototype.getAssetPath>[0] =\n chunk.filenameTemplate ||\n (chunk.hasRuntime() ? outputOptions.filename : outputOptions.chunkFilename)!;\n\n const defaultAssetName: string = compilation.getPath(template, {\n chunk,\n contentHashType: 'javascript'\n // Without locale this should return the name of the default asset\n });\n\n const asset: Asset | undefined = compilation.getAsset(defaultAssetName);\n if (!asset) {\n compilation.errors.push(new WebpackError(`Missing expected chunk asset ${defaultAssetName}`));\n return;\n }\n\n if (isLocalized) {\n const localizedAssets: Record<string, string> = await processLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n locales,\n defaultLocale: this._defaultLocale,\n passthroughLocaleName: this._passthroughLocaleName,\n fillMissingTranslationStrings: this._fillMissingTranslationStrings,\n formatLocaleForFilenameFn: this._formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n filenameTemplate: template\n });\n\n if (filesByChunkName && chunk.name) {\n filesByChunkName.set(chunk.name, localizedAssets);\n (chunk.hasRuntime() ? localizedEntryPointNames : localizedChunkNames).push(chunk.name);\n }\n } else {\n await processNonLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n hasUrlGenerator: chunksWithUrlGenerators.has(chunk),\n noStringsLocaleName: this._noStringsLocaleName,\n formatLocaleForFilenameFn: this._formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n fileName: defaultAssetName\n });\n }\n },\n {\n // Only async component is the cache layer\n concurrency: 20\n }\n );\n\n if (hashFn) {\n updateAssetHashes({\n thisWebpack,\n compilation,\n hashFn,\n filesByChunkName\n });\n }\n\n // Since the stats generation doesn't depend on content, do it immediately\n if (statsOptions && filesByChunkName) {\n const localizationStats: ILocalizationStats = {\n entrypoints: {},\n namedChunkGroups: {}\n };\n\n // Sort in lexicographic order to ensure stable output\n localizedChunkNames.sort();\n for (const chunkName of localizedChunkNames) {\n localizationStats.namedChunkGroups[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n // Sort in lexicographic order to ensure stable output\n localizedEntryPointNames.sort();\n for (const chunkName of localizedEntryPointNames) {\n localizationStats.entrypoints[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n const { dropPath, callback } = statsOptions;\n\n if (dropPath) {\n compilation.emitAsset(\n dropPath,\n new compiler.webpack.sources.RawSource(JSON.stringify(localizationStats))\n );\n }\n\n if (callback) {\n try {\n callback(localizationStats, compilation);\n } catch (e) {\n /* swallow errors from the callback */\n }\n }\n }\n }\n );\n });\n }\n\n /**\n * @public\n *\n * @returns An object mapping the string keys to placeholders\n */\n public async addDefaultLocFileAsync(\n context: LoaderContext<{}>,\n localizedFileKey: string,\n localizedResourceData: ILocalizationFile\n ): Promise<Record<string, string>> {\n const locFileData: ReadonlyMap<string, string> = convertLocalizationFileToLocData(localizedResourceData);\n const fileInfo: IFileTranslationInfo = this._addLocFileAndGetPlaceholders(\n this._defaultLocale,\n localizedFileKey,\n locFileData\n );\n\n const missingLocales: string[] = [];\n for (const [translatedLocaleName, translatedStrings] of this._resolvedTranslatedStringsFromOptions) {\n const translatedLocFileFromOptions: ILocaleFileData | undefined =\n translatedStrings.get(localizedFileKey);\n\n if (!translatedLocFileFromOptions) {\n missingLocales.push(translatedLocaleName);\n } else {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n translatedLocFileFromOptions\n );\n fileInfo.translations.set(translatedLocaleName, translatedLocFileData);\n }\n }\n\n const { resolveMissingTranslatedStrings } = this._options.localizedData;\n\n if (missingLocales.length > 0 && resolveMissingTranslatedStrings) {\n let resolvedTranslatedData: IResolvedMissingTranslations | undefined = undefined;\n try {\n resolvedTranslatedData = await resolveMissingTranslatedStrings(\n missingLocales,\n localizedFileKey,\n context\n );\n } catch (e) {\n context.emitError(e);\n }\n\n if (resolvedTranslatedData) {\n const iterable: Iterable<[string, ILocaleFileData]> =\n resolvedTranslatedData instanceof Map\n ? resolvedTranslatedData.entries()\n : Object.entries(resolvedTranslatedData);\n for (const [resolvedLocaleName, resolvedLocaleData] of iterable) {\n if (resolvedLocaleData) {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n resolvedLocaleData\n );\n fileInfo.translations.set(resolvedLocaleName, translatedLocFileData);\n }\n }\n }\n }\n\n for (const [pseudolocaleName, pseudolocalizer] of this._pseudolocalizers) {\n const pseudolocFileData: Map<string, string> = new Map();\n\n for (const [stringName, stringValue] of locFileData) {\n pseudolocFileData.set(stringName, pseudolocalizer(stringValue));\n }\n\n fileInfo.translations.set(pseudolocaleName, pseudolocFileData);\n }\n\n markEntity(context._module!, true);\n\n return fileInfo.renderedPlacholders;\n }\n\n /**\n * @public\n */\n public getPlaceholder(localizedFileKey: string, stringName: string): IStringPlaceholder | undefined {\n const file: IFileTranslationInfo | undefined = this._locFiles.get(localizedFileKey);\n if (!file) {\n return undefined;\n }\n return file.placeholders.get(stringName);\n }\n\n /**\n * @internal\n */\n public getDataForSerialNumber(serialNumber: string): IStringPlaceholder | undefined {\n return this._stringPlaceholderMap.get(serialNumber);\n }\n\n private _addLocFileAndGetPlaceholders(\n localeName: string,\n localizedFileKey: string,\n localizedFileData: ReadonlyMap<string, string>\n ): IFileTranslationInfo {\n let fileInfo: IFileTranslationInfo | undefined = this._locFiles.get(localizedFileKey);\n if (!fileInfo) {\n fileInfo = {\n placeholders: new Map(),\n translations: new Map(),\n renderedPlacholders: {}\n };\n this._locFiles.set(localizedFileKey, fileInfo);\n }\n const { placeholders, translations } = fileInfo;\n const locFilePrefix: string = Buffer.from(localizedFileKey, 'utf-8').toString('hex') + '$';\n\n const resultObject: Record<string, string> = {};\n for (const stringName of localizedFileData.keys()) {\n let placeholder: IStringPlaceholder | undefined = placeholders.get(stringName);\n if (!placeholder) {\n const suffix: string = `${locFilePrefix}${Buffer.from(stringName, 'utf-8').toString('hex')}`;\n\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.STRING_PLACEHOLDER_LABEL}_\\\\_${suffix}_`,\n suffix,\n translations,\n locFilePath: localizedFileKey,\n stringName\n };\n\n placeholders.set(stringName, placeholder);\n this._stringPlaceholderMap.set(suffix, placeholder);\n }\n\n resultObject[stringName] = placeholder.value;\n }\n\n translations.set(localeName, localizedFileData);\n fileInfo.renderedPlacholders = resultObject;\n\n return fileInfo;\n }\n\n private _addTranslations(\n localeName: string,\n fileInfo: IFileTranslationInfo,\n localizedFileData: ReadonlyMap<string, string>\n ): void {\n fileInfo.translations.set(localeName, localizedFileData);\n }\n\n private _initializeAndValidateOptions(\n compiler: Compiler,\n isWebpackDevServer: boolean\n ): { errors: WebpackError[]; warnings: WebpackError[] } {\n const errors: WebpackError[] = [];\n const warnings: WebpackError[] = [];\n\n const { WebpackError } = compiler.webpack;\n const { options: configuration } = compiler;\n\n const LOCALE_NAME_REGEX: RegExp = /[a-z-]/i;\n function ensureValidLocaleName(localeName: string): boolean {\n if (!localeName.match(LOCALE_NAME_REGEX)) {\n errors.push(\n new WebpackError(\n `Invalid locale name: ${localeName}. Locale names may only contain letters and hyphens.`\n )\n );\n return false;\n } else {\n return true;\n }\n }\n\n // START configuration\n if (\n !configuration.output ||\n !configuration.output.filename ||\n typeof configuration.output.filename !== 'string' ||\n configuration.output.filename.indexOf(Constants.LOCALE_FILENAME_TOKEN) === -1\n ) {\n errors.push(\n new WebpackError(\n 'The configuration.output.filename property must be provided, must be a string, and must include ' +\n `the ${Constants.LOCALE_FILENAME_TOKEN} placeholder`\n )\n );\n }\n // END configuration\n\n // START misc options\n // START options.localizedData\n const { localizedData } = this._options;\n if (localizedData) {\n // START options.localizedData.passthroughLocale\n const { passthroughLocale } = localizedData;\n if (passthroughLocale) {\n const { usePassthroughLocale, passthroughLocaleName = 'passthrough' } = passthroughLocale;\n if (usePassthroughLocale) {\n this._passthroughLocaleName = passthroughLocaleName;\n this._translatedLocales.add(passthroughLocaleName);\n }\n }\n // END options.localizedData.passthroughLocale\n\n // START options.localizedData.translatedStrings\n const resolveRelativeToContext: (relative: string) => string = (\n configuration.context?.startsWith('/') ? path.posix.resolve : path.resolve\n ).bind(0, configuration.context!);\n const { translatedStrings } = localizedData;\n this._resolvedTranslatedStringsFromOptions.clear();\n if (translatedStrings) {\n for (const [localeName, locale] of Object.entries(translatedStrings)) {\n if (this._translatedLocales.has(localeName)) {\n errors.push(\n new WebpackError(\n `The locale \"${localeName}\" appears multiple times. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this._translatedLocales.add(localeName);\n const resolvedFromOptionsForLocale: Map<string, ILocaleFileData> = new Map();\n this._resolvedTranslatedStringsFromOptions.set(localeName, resolvedFromOptionsForLocale);\n\n for (const [locFilePath, locFileDataFromOptions] of Object.entries(locale)) {\n const normalizedLocFilePath: string = resolveRelativeToContext(locFilePath);\n\n if (resolvedFromOptionsForLocale.has(normalizedLocFilePath)) {\n errors.push(\n new WebpackError(\n `The localization file path \"${locFilePath}\" appears multiple times in locale ${localeName}. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n const normalizedLocFileDataFromOptions: ILocaleFileData =\n typeof locFileDataFromOptions === 'string'\n ? resolveRelativeToContext(locFileDataFromOptions)\n : locFileDataFromOptions;\n\n resolvedFromOptionsForLocale.set(normalizedLocFilePath, normalizedLocFileDataFromOptions);\n }\n }\n }\n // END options.localizedData.translatedStrings\n\n // START options.localizedData.defaultLocale\n const { defaultLocale } = localizedData;\n if (defaultLocale) {\n const { localeName, fillMissingTranslationStrings } = defaultLocale;\n if (localeName) {\n if (this._translatedLocales.has(localeName)) {\n errors.push(new WebpackError('The default locale is also specified in the translated strings.'));\n return { errors, warnings };\n } else if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this._translatedLocales.add(localeName);\n this._defaultLocale = localeName;\n this._fillMissingTranslationStrings = !!fillMissingTranslationStrings;\n } else {\n errors.push(new WebpackError('Missing default locale name'));\n return { errors, warnings };\n }\n } else {\n errors.push(new WebpackError('Missing default locale options.'));\n return { errors, warnings };\n }\n // END options.localizedData.defaultLocale\n\n // START options.localizedData.pseudoLocales\n const { pseudolocales } = localizedData;\n if (pseudolocales) {\n for (const [pseudolocaleName, pseudoLocaleOpts] of Object.entries(pseudolocales)) {\n if (this._defaultLocale === pseudolocaleName) {\n errors.push(\n new WebpackError(`A pseudolocale (${pseudolocaleName}) name is also the default locale name.`)\n );\n return { errors, warnings };\n }\n\n if (this._translatedLocales.has(pseudolocaleName)) {\n errors.push(\n new WebpackError(\n `A pseudolocale (${pseudolocaleName}) name is also specified in the translated strings.`\n )\n );\n return { errors, warnings };\n }\n\n this._pseudolocalizers.set(pseudolocaleName, getPseudolocalizer(pseudoLocaleOpts));\n this._translatedLocales.add(pseudolocaleName);\n }\n }\n // END options.localizedData.pseudoLocales\n } else if (!isWebpackDevServer) {\n throw new Error('Localized data must be provided unless webpack dev server is running.');\n }\n // END options.localizedData\n\n // START options.noStringsLocaleName\n const { noStringsLocaleName } = this._options;\n if (\n noStringsLocaleName === undefined ||\n noStringsLocaleName === null ||\n !ensureValidLocaleName(noStringsLocaleName)\n ) {\n this._noStringsLocaleName = 'none';\n } else {\n this._noStringsLocaleName = noStringsLocaleName;\n }\n // END options.noStringsLocaleName\n\n // START options.formatLocaleForFilename\n const { formatLocaleForFilename = (localeName: string) => localeName } = this._options;\n this._formatLocaleForFilename = formatLocaleForFilename;\n // END options.formatLocaleForFilename\n return { errors, warnings };\n }\n}\n\nfunction _chunkHasLocalizedModules(\n chunkGraph: ChunkGraph,\n chunk: Chunk,\n runtimeLocaleExpression: string | undefined\n): boolean {\n let chunkHasAnyLocModules: boolean | undefined = getMark(chunk);\n if (chunkHasAnyLocModules === undefined) {\n chunkHasAnyLocModules = false;\n const candidateModules: Iterable<Module> | undefined = chunkGraph.getChunkModulesIterableBySourceType(\n chunk,\n 'javascript'\n );\n if (candidateModules) {\n outer: for (const module of candidateModules) {\n const moduleMark: boolean | undefined = getMark(module);\n if (moduleMark) {\n chunkHasAnyLocModules = true;\n break;\n } else if (moduleMark === false) {\n continue;\n }\n\n // Is this a concatenated module?\n const { _modules: modules } = module as { _modules?: Iterable<Module> };\n if (modules) {\n for (const nestedModule of modules) {\n if (getMark(nestedModule)) {\n markEntity(module, true);\n chunkHasAnyLocModules = true;\n break outer;\n }\n }\n markEntity(module, false);\n }\n }\n }\n\n // If this chunk doesn't directly contain any localized resources, it still\n // needs to be localized if it's an entrypoint chunk (i.e. - it has a runtime)\n // and it loads localized async chunks.\n // In that case, the generated chunk URL generation code needs to contain\n // the locale name.\n if (!chunkHasAnyLocModules && !runtimeLocaleExpression && chunk.hasRuntime()) {\n for (const asyncChunk of chunk.getAllAsyncChunks()) {\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkHasAnyLocModules = true;\n break;\n }\n }\n }\n\n markEntity(chunk, chunkHasAnyLocModules);\n }\n\n return chunkHasAnyLocModules;\n}\n\nfunction convertLocalizationFileToLocData(locFile: ILocalizationFile): ReadonlyMap<string, string> {\n const locFileData: Map<string, string> = new Map();\n for (const [stringName, locFileEntry] of Object.entries(locFile)) {\n locFileData.set(stringName, locFileEntry.value);\n }\n\n return locFileData;\n}\n\nasync function normalizeLocalizedDataAsync(\n context: LoaderContext<{}>,\n localizedData: ILocaleFileData\n): Promise<ReadonlyMap<string, string>> {\n if (typeof localizedData === 'string') {\n // The value is the path to a file. Add it as a file dependency\n context.addDependency(localizedData);\n const content: string = await new Promise((resolve, reject) => {\n // Use context.fs so that the plugin is compatible with overriding compiler.inputFileSystem\n context.fs.readFile(localizedData, (err, data) => {\n if (err) {\n return reject(err);\n } else if (!data) {\n return reject(new Error(`No data in ${localizedData}`));\n }\n resolve(data.toString());\n });\n });\n\n const localizationFile: ILocalizationFile = parseResJson({\n filePath: localizedData,\n content\n });\n\n return convertLocalizationFileToLocData(localizationFile);\n } else {\n return localizedData instanceof Map ? localizedData : new Map(Object.entries(localizedData));\n }\n}\n"]}
1
+ {"version":3,"file":"LocalizationPlugin.js","sourceRoot":"","sources":["../src/LocalizationPlugin.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nimport * as path from 'path';\n\nimport type {\n Asset,\n Chunk,\n ChunkGraph,\n Compilation,\n Compiler,\n LoaderContext,\n Module,\n runtime,\n WebpackError,\n WebpackPluginInstance\n} from 'webpack';\n\nimport { getPseudolocalizer, type ILocalizationFile, parseResJson } from '@rushstack/localization-utilities';\nimport { Async } from '@rushstack/node-core-library/lib/Async';\n\nimport * as Constants from './utilities/Constants';\nimport type {\n ILocalizationPluginOptions,\n ILocalizationStats,\n ILocaleFileData,\n ILocaleFileObject,\n IResolvedMissingTranslations\n} from './interfaces';\nimport type { IAssetPathOptions } from './webpackInterfaces';\nimport { markEntity, getMark } from './utilities/EntityMarker';\nimport { processLocalizedAssetCachedAsync, processNonLocalizedAssetCachedAsync } from './AssetProcessor';\nimport { getHashFunction, type HashFn, updateAssetHashes } from './trueHashes';\nimport { chunkIsJs } from './utilities/chunkUtilities';\n\n/**\n * @public\n */\nexport type ValueForLocaleFn = (locale: string, chunk: Chunk) => string;\n\n/**\n * @public\n */\nexport interface IValuePlaceholderBase {\n /**\n * The literal string that will be injected for later replacement.\n */\n value: string;\n\n /**\n * The identifier for this particular placeholder, for lookup.\n */\n suffix: string;\n}\n\n/**\n * @public\n */\nexport interface IStringPlaceholder extends IValuePlaceholderBase {\n /**\n * The values of this string in each output locale.\n */\n translations: ReadonlyMap<string, ReadonlyMap<string, string>>;\n\n /**\n * The key used to identify the source file containing the string.\n */\n locFilePath: string;\n\n /**\n * The identifier of the string within its original source file.\n */\n stringName: string;\n}\n\n/**\n * @internal\n */\nexport interface ICustomDataPlaceholder extends IValuePlaceholderBase {\n /**\n * The function that will be invoked to get the value for this placeholder.\n * The function will be invoked with the locale name as the first argument.\n */\n valueForLocaleFn: ValueForLocaleFn;\n}\n\nexport interface IFileTranslationInfo {\n placeholders: Map<string, IStringPlaceholder>;\n translations: Map<string, ReadonlyMap<string, string>>;\n renderedPlaceholders: Record<string, string>;\n}\n\nconst PLUGIN_NAME: 'localization' = 'localization';\n\nconst pluginForCompiler: WeakMap<Compiler, LocalizationPlugin> = new WeakMap();\n\n/**\n * Gets the instance of the LocalizationPlugin bound to the specified webpack compiler.\n * Used by loaders.\n */\nexport function getPluginInstance(compiler: Compiler | undefined): LocalizationPlugin {\n const instance: LocalizationPlugin | undefined = compiler && pluginForCompiler.get(compiler);\n if (!instance) {\n throw new Error(`Could not find a LocalizationPlugin instance for the current webpack compiler!`);\n }\n return instance;\n}\n\n/**\n * This plugin facilitates localization in webpack.\n *\n * @public\n */\nexport class LocalizationPlugin implements WebpackPluginInstance {\n private readonly _locFiles: Map<string, IFileTranslationInfo> = new Map();\n\n /**\n * @internal\n */\n public readonly _options: ILocalizationPluginOptions;\n private readonly _resolvedTranslatedStringsFromOptions: Map<\n string,\n Map<string, ILocaleFileObject | string | ReadonlyMap<string, string>>\n > = new Map();\n private readonly _stringPlaceholderBySuffix: Map<string, IStringPlaceholder> = new Map();\n private readonly _customDataPlaceholderBySuffix: Map<string, ICustomDataPlaceholder> = new Map();\n private readonly _customDataPlaceholderByUniqueId: Map<string, ICustomDataPlaceholder> = new Map();\n private _passthroughLocaleName!: string;\n private _defaultLocale!: string;\n private _noStringsLocaleName!: string;\n private _fillMissingTranslationStrings!: boolean;\n /**\n * @remarks\n * Include the `chunk` parameter so that the functions arity is the same as the\n * `ValueForLocaleFn` type.\n */\n private _formatLocaleForFilename!: (loc: string, chunk: unknown) => string;\n private readonly _pseudolocalizers: Map<string, (str: string) => string> = new Map();\n\n /**\n * The set of locales that have translations provided.\n */\n private _translatedLocales: Set<string> = new Set();\n\n public constructor(options: ILocalizationPluginOptions) {\n this._options = options;\n }\n\n /**\n * Apply this plugin to the specified webpack compiler.\n */\n public apply(compiler: Compiler): void {\n pluginForCompiler.set(compiler, this);\n\n // https://github.com/webpack/webpack-dev-server/pull/1929/files#diff-15fb51940da53816af13330d8ce69b4eR66\n const isWebpackDevServer: boolean = process.env.WEBPACK_DEV_SERVER === 'true';\n\n const { errors, warnings } = this._initializeAndValidateOptions(compiler, isWebpackDevServer);\n\n if (errors.length > 0 || warnings.length > 0) {\n compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n compilation.errors.push(...errors);\n compilation.warnings.push(...warnings);\n });\n\n if (errors.length > 0) {\n // If there are any errors, just pass through the resources in source and don't do any\n // additional configuration\n return;\n }\n }\n\n const { webpack: thisWebpack } = compiler;\n const {\n WebpackError,\n runtime: { GetChunkFilenameRuntimeModule }\n } = thisWebpack;\n\n // Side-channel for async chunk URL generator chunk, since the actual chunk is completely inaccessible\n // from the assetPath hook below when invoked to build the async URL generator\n let chunkWithAsyncURLGenerator: Chunk | undefined;\n\n const originalGenerate: typeof GetChunkFilenameRuntimeModule.prototype.generate =\n GetChunkFilenameRuntimeModule.prototype.generate;\n GetChunkFilenameRuntimeModule.prototype.generate = function (\n this: runtime.GetChunkFilenameRuntimeModule\n ): string | null {\n // `originalGenerate` will invoke `getAssetPath` to produce the async URL generator\n // Need to know the identity of the containing chunk to correctly produce the asset path expression\n chunkWithAsyncURLGenerator = this.chunk;\n const result: string | null = originalGenerate.call(this);\n // Unset after the call finishes because we are no longer generating async URL generators\n chunkWithAsyncURLGenerator = undefined;\n return result;\n };\n\n const asyncGeneratorTest: RegExp = /^\\\" \\+/;\n\n const { runtimeLocaleExpression } = this._options;\n\n compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation: Compilation) => {\n let hashFn: HashFn | undefined;\n if (this._options.realContentHash) {\n if (runtimeLocaleExpression) {\n compilation.errors.push(\n new WebpackError(\n `The \"realContentHash\" option cannot be used in conjunction with \"runtimeLocaleExpression\".`\n )\n );\n } else {\n hashFn = getHashFunction({ thisWebpack, compilation });\n }\n } else if (compiler.options.optimization?.realContentHash) {\n compilation.errors.push(\n new thisWebpack.WebpackError(\n `The \\`optimization.realContentHash\\` option is set and the ${LocalizationPlugin.name}'s ` +\n '`realContentHash` option is not set. This will likely produce invalid results. Consider setting the ' +\n `\\`realContentHash\\` option in the ${LocalizationPlugin.name} plugin.`\n )\n );\n }\n\n const chunksWithUrlGenerators: WeakSet<Chunk> = new WeakSet();\n\n compilation.hooks.assetPath.tap(\n PLUGIN_NAME,\n (assetPath: string, options: IAssetPathOptions): string => {\n const { chunkGraph } = compilation;\n\n if (\n options.contentHashType === 'javascript' &&\n assetPath.match(Constants.LOCALE_FILENAME_TOKEN_REGEX)\n ) {\n // Does this look like an async chunk URL generator?\n if (typeof options.chunk?.id === 'string' && options.chunk.id.match(asyncGeneratorTest)) {\n const chunkIdsWithStrings: Set<number | string> = new Set<number | string>();\n const chunkIdsWithoutStrings: Set<number | string> = new Set<number | string>();\n\n const activeChunkWithAsyncUrlGenerator: Chunk | undefined = chunkWithAsyncURLGenerator;\n\n if (!activeChunkWithAsyncUrlGenerator) {\n compilation.errors.push(\n new WebpackError(`No active chunk while constructing async chunk URL generator!`)\n );\n return assetPath;\n }\n\n const asyncChunks: Set<Chunk> = activeChunkWithAsyncUrlGenerator.getAllAsyncChunks();\n for (const asyncChunk of asyncChunks) {\n const chunkId: number | string | null = asyncChunk.id;\n\n if (chunkId === null || chunkId === undefined) {\n throw new Error(`Chunk \"${asyncChunk.name}\"'s ID is null or undefined.`);\n }\n\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkIdsWithStrings.add(chunkId);\n } else {\n chunkIdsWithoutStrings.add(chunkId);\n }\n }\n\n return assetPath.replace(Constants.LOCALE_FILENAME_TOKEN_REGEX, () => {\n // Use a replacer function so that we don't need to escape anything in the return value\n\n // If the runtime chunk is itself localized, forcibly match the locale of the runtime chunk\n // Otherwise prefer the runtime expression if specified\n const localeExpression: string =\n (!_chunkHasLocalizedModules(\n chunkGraph,\n activeChunkWithAsyncUrlGenerator,\n runtimeLocaleExpression\n ) &&\n runtimeLocaleExpression) ||\n Constants.JSONP_PLACEHOLDER;\n if (localeExpression === Constants.JSONP_PLACEHOLDER) {\n chunksWithUrlGenerators.add(activeChunkWithAsyncUrlGenerator);\n }\n\n if (chunkIdsWithStrings.size === 0) {\n return this._formatLocaleForFilename(this._noStringsLocaleName, undefined);\n } else if (chunkIdsWithoutStrings.size === 0) {\n return `\" + ${localeExpression} + \"`;\n } else {\n // Generate an object that is used to select between <locale> and <nostrings locale> for each chunk ID\n // Method: pick the smaller set of (localized, non-localized) and map that to 1 (a truthy value)\n // All other IDs map to `undefined` (a falsy value), so we then use the ternary operator to select\n // the appropriate token\n //\n // This can be improved in the future. We can maybe sort the chunks such that the chunks below a certain ID\n // number are localized and the those above are not.\n const chunkMapping: { [chunkId: string]: 1 } = {};\n // Use the map with the fewest values to shorten the expression\n const isLocalizedSmaller: boolean = chunkIdsWithStrings.size <= chunkIdsWithoutStrings.size;\n // These are the ids for which the expression should evaluate to a truthy value\n const smallerSet: Set<number | string> = isLocalizedSmaller\n ? chunkIdsWithStrings\n : chunkIdsWithoutStrings;\n for (const id of smallerSet) {\n chunkMapping[id] = 1;\n }\n\n const noLocaleExpression: string = JSON.stringify(\n this._formatLocaleForFilename(this._noStringsLocaleName, undefined)\n );\n\n return `\" + (${JSON.stringify(chunkMapping)}[chunkId]?${\n isLocalizedSmaller ? localeExpression : noLocaleExpression\n }:${isLocalizedSmaller ? noLocaleExpression : localeExpression}) + \"`;\n }\n });\n } else {\n let locale: string | undefined = options.locale;\n if (!locale) {\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n options.chunk as Chunk,\n runtimeLocaleExpression\n );\n // Ensure that the initial name maps to a file that should exist in the final output\n locale = isLocalized ? this._defaultLocale : this._noStringsLocaleName;\n }\n return assetPath.replace(\n Constants.LOCALE_FILENAME_TOKEN_REGEX,\n this._formatLocaleForFilename(locale, undefined)\n );\n }\n } else {\n return assetPath;\n }\n }\n );\n\n const { outputOptions } = compilation;\n\n // For compatibility with minifiers, need to generate the additional assets after the optimize process runs\n compilation.hooks.processAssets.tapPromise(\n {\n name: PLUGIN_NAME,\n // Generating derived assets, but explicitly want to create them *after* asset optimization\n stage: compiler.webpack.Compilation.PROCESS_ASSETS_STAGE_DEV_TOOLING - 1\n },\n async (): Promise<void> => {\n const locales: Set<string> = this._translatedLocales;\n\n const { chunkGraph, chunks } = compilation;\n const { localizationStats: statsOptions } = this._options;\n\n const filesByChunkName: Map<string, Record<string, string>> | undefined = statsOptions\n ? new Map()\n : undefined;\n const localizedEntryPointNames: string[] = [];\n const localizedChunkNames: string[] = [];\n\n type CacheFacade = ReturnType<Compilation['getCache']>;\n const cache: CacheFacade = compilation.getCache(PLUGIN_NAME);\n\n await Async.forEachAsync(\n chunks,\n async (chunk: Chunk) => {\n if (!chunkIsJs(chunk, chunkGraph)) {\n return;\n }\n\n const isLocalized: boolean = _chunkHasLocalizedModules(\n chunkGraph,\n chunk,\n runtimeLocaleExpression\n );\n\n const template: Parameters<typeof Compilation.prototype.getAssetPath>[0] =\n chunk.filenameTemplate ||\n (chunk.hasRuntime() ? outputOptions.filename : outputOptions.chunkFilename)!;\n\n const defaultAssetName: string = compilation.getPath(template, {\n chunk,\n contentHashType: 'javascript'\n // Without locale this should return the name of the default asset\n });\n\n const asset: Asset | undefined = compilation.getAsset(defaultAssetName);\n if (!asset) {\n compilation.errors.push(new WebpackError(`Missing expected chunk asset ${defaultAssetName}`));\n return;\n }\n\n if (isLocalized) {\n const localizedAssets: Record<string, string> = await processLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n locales,\n defaultLocale: this._defaultLocale,\n passthroughLocaleName: this._passthroughLocaleName,\n fillMissingTranslationStrings: this._fillMissingTranslationStrings,\n formatLocaleForFilenameFn: this._formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n filenameTemplate: template\n });\n\n if (filesByChunkName && chunk.name) {\n filesByChunkName.set(chunk.name, localizedAssets);\n (chunk.hasRuntime() ? localizedEntryPointNames : localizedChunkNames).push(chunk.name);\n }\n } else {\n await processNonLocalizedAssetCachedAsync({\n // Global values\n plugin: this,\n compilation,\n cache,\n hasUrlGenerator: chunksWithUrlGenerators.has(chunk),\n noStringsLocaleName: this._noStringsLocaleName,\n formatLocaleForFilenameFn: this._formatLocaleForFilename,\n // Chunk-specific values\n chunk,\n asset,\n fileName: defaultAssetName\n });\n }\n },\n {\n // Only async component is the cache layer\n concurrency: 20\n }\n );\n\n if (hashFn) {\n updateAssetHashes({\n thisWebpack,\n compilation,\n hashFn,\n filesByChunkName\n });\n }\n\n // Since the stats generation doesn't depend on content, do it immediately\n if (statsOptions && filesByChunkName) {\n const localizationStats: ILocalizationStats = {\n entrypoints: {},\n namedChunkGroups: {}\n };\n\n // Sort in lexicographic order to ensure stable output\n localizedChunkNames.sort();\n for (const chunkName of localizedChunkNames) {\n localizationStats.namedChunkGroups[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n // Sort in lexicographic order to ensure stable output\n localizedEntryPointNames.sort();\n for (const chunkName of localizedEntryPointNames) {\n localizationStats.entrypoints[chunkName] = {\n localizedAssets: filesByChunkName.get(chunkName)!\n };\n }\n\n const { dropPath, callback } = statsOptions;\n\n if (dropPath) {\n compilation.emitAsset(\n dropPath,\n new compiler.webpack.sources.RawSource(JSON.stringify(localizationStats))\n );\n }\n\n if (callback) {\n try {\n callback(localizationStats, compilation);\n } catch (e) {\n /* swallow errors from the callback */\n }\n }\n }\n }\n );\n });\n }\n\n /**\n * @public\n *\n * @returns An object mapping the string keys to placeholders\n */\n public async addDefaultLocFileAsync(\n context: LoaderContext<{}>,\n localizedFileKey: string,\n localizedResourceData: ILocalizationFile\n ): Promise<Record<string, string>> {\n const locFileData: ReadonlyMap<string, string> = convertLocalizationFileToLocData(localizedResourceData);\n const fileInfo: IFileTranslationInfo = this._addLocFileAndGetPlaceholders(\n this._defaultLocale,\n localizedFileKey,\n locFileData\n );\n\n const missingLocales: string[] = [];\n for (const [translatedLocaleName, translatedStrings] of this._resolvedTranslatedStringsFromOptions) {\n const translatedLocFileFromOptions: ILocaleFileData | undefined =\n translatedStrings.get(localizedFileKey);\n\n if (!translatedLocFileFromOptions) {\n missingLocales.push(translatedLocaleName);\n } else {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n translatedLocFileFromOptions\n );\n fileInfo.translations.set(translatedLocaleName, translatedLocFileData);\n }\n }\n\n const { resolveMissingTranslatedStrings } = this._options.localizedData;\n\n if (missingLocales.length > 0 && resolveMissingTranslatedStrings) {\n let resolvedTranslatedData: IResolvedMissingTranslations | undefined = undefined;\n try {\n resolvedTranslatedData = await resolveMissingTranslatedStrings(\n missingLocales,\n localizedFileKey,\n context\n );\n } catch (e) {\n context.emitError(e);\n }\n\n if (resolvedTranslatedData) {\n const iterable: Iterable<[string, ILocaleFileData]> =\n resolvedTranslatedData instanceof Map\n ? resolvedTranslatedData.entries()\n : Object.entries(resolvedTranslatedData);\n for (const [resolvedLocaleName, resolvedLocaleData] of iterable) {\n if (resolvedLocaleData) {\n const translatedLocFileData: ReadonlyMap<string, string> = await normalizeLocalizedDataAsync(\n context,\n resolvedLocaleData\n );\n fileInfo.translations.set(resolvedLocaleName, translatedLocFileData);\n }\n }\n }\n }\n\n for (const [pseudolocaleName, pseudolocalizer] of this._pseudolocalizers) {\n const pseudolocFileData: Map<string, string> = new Map();\n\n for (const [stringName, stringValue] of locFileData) {\n pseudolocFileData.set(stringName, pseudolocalizer(stringValue));\n }\n\n fileInfo.translations.set(pseudolocaleName, pseudolocFileData);\n }\n\n markEntity(context._module!, true);\n\n return fileInfo.renderedPlaceholders;\n }\n\n /**\n * @public\n */\n public getPlaceholder(localizedFileKey: string, stringName: string): IStringPlaceholder | undefined {\n const file: IFileTranslationInfo | undefined = this._locFiles.get(localizedFileKey);\n if (!file) {\n return undefined;\n }\n return file.placeholders.get(stringName);\n }\n\n /**\n * @beta\n */\n public getCustomDataPlaceholderForValueFunction(\n valueForLocaleFn: ValueForLocaleFn,\n placeholderUniqueId: string\n ): string {\n let placeholder: ICustomDataPlaceholder | undefined =\n this._customDataPlaceholderByUniqueId.get(placeholderUniqueId);\n if (!placeholder) {\n // Get a hash of the unique ID to make sure its value doesn't interfere with our placeholder tokens\n const suffix: string = Buffer.from(placeholderUniqueId, 'utf-8').toString('hex');\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.CUSTOM_PLACEHOLDER_LABEL}_${suffix}_`,\n suffix,\n valueForLocaleFn\n };\n this._customDataPlaceholderBySuffix.set(suffix, placeholder);\n this._customDataPlaceholderByUniqueId.set(placeholderUniqueId, placeholder);\n } else if (placeholder.valueForLocaleFn !== valueForLocaleFn) {\n throw new Error(\n `${this.getCustomDataPlaceholderForValueFunction.name} has already been called with \"${placeholderUniqueId}\" ` +\n `and a different valueForLocaleFn.`\n );\n }\n\n return placeholder.value;\n }\n\n /**\n * @internal\n */\n public _getStringDataForSerialNumber(suffix: string): IStringPlaceholder | undefined {\n return this._stringPlaceholderBySuffix.get(suffix);\n }\n\n /**\n * @internal\n */\n public _getCustomDataForSerialNumber(suffix: string): ICustomDataPlaceholder | undefined {\n return this._customDataPlaceholderBySuffix.get(suffix);\n }\n\n private _addLocFileAndGetPlaceholders(\n localeName: string,\n localizedFileKey: string,\n localizedFileData: ReadonlyMap<string, string>\n ): IFileTranslationInfo {\n let fileInfo: IFileTranslationInfo | undefined = this._locFiles.get(localizedFileKey);\n if (!fileInfo) {\n fileInfo = {\n placeholders: new Map(),\n translations: new Map(),\n renderedPlaceholders: {}\n };\n this._locFiles.set(localizedFileKey, fileInfo);\n }\n const { placeholders, translations } = fileInfo;\n const locFilePrefix: string = Buffer.from(localizedFileKey, 'utf-8').toString('hex') + '$';\n\n const resultObject: Record<string, string> = {};\n for (const stringName of localizedFileData.keys()) {\n let placeholder: IStringPlaceholder | undefined = placeholders.get(stringName);\n if (!placeholder) {\n const suffix: string = `${locFilePrefix}${Buffer.from(stringName, 'utf-8').toString('hex')}`;\n\n placeholder = {\n value: `${Constants.STRING_PLACEHOLDER_PREFIX}_${Constants.STRING_PLACEHOLDER_LABEL}_\\\\_${suffix}_`,\n suffix,\n translations: translations,\n locFilePath: localizedFileKey,\n stringName\n };\n\n placeholders.set(stringName, placeholder);\n this._stringPlaceholderBySuffix.set(suffix, placeholder);\n }\n\n resultObject[stringName] = placeholder.value;\n }\n\n translations.set(localeName, localizedFileData);\n fileInfo.renderedPlaceholders = resultObject;\n\n return fileInfo;\n }\n\n private _initializeAndValidateOptions(\n compiler: Compiler,\n isWebpackDevServer: boolean\n ): { errors: WebpackError[]; warnings: WebpackError[] } {\n const errors: WebpackError[] = [];\n const warnings: WebpackError[] = [];\n\n const { WebpackError } = compiler.webpack;\n const { options: configuration } = compiler;\n\n const LOCALE_NAME_REGEX: RegExp = /[a-z-]/i;\n function ensureValidLocaleName(localeName: string): boolean {\n if (!localeName.match(LOCALE_NAME_REGEX)) {\n errors.push(\n new WebpackError(\n `Invalid locale name: ${localeName}. Locale names may only contain letters and hyphens.`\n )\n );\n return false;\n } else {\n return true;\n }\n }\n\n // START configuration\n if (\n !configuration.output ||\n !configuration.output.filename ||\n typeof configuration.output.filename !== 'string' ||\n configuration.output.filename.indexOf(Constants.LOCALE_FILENAME_TOKEN) === -1\n ) {\n errors.push(\n new WebpackError(\n 'The configuration.output.filename property must be provided, must be a string, and must include ' +\n `the ${Constants.LOCALE_FILENAME_TOKEN} placeholder`\n )\n );\n }\n // END configuration\n\n // START misc options\n // START options.localizedData\n const { localizedData } = this._options;\n if (localizedData) {\n // START options.localizedData.passthroughLocale\n const { passthroughLocale } = localizedData;\n if (passthroughLocale) {\n const { usePassthroughLocale, passthroughLocaleName = 'passthrough' } = passthroughLocale;\n if (usePassthroughLocale) {\n this._passthroughLocaleName = passthroughLocaleName;\n this._translatedLocales.add(passthroughLocaleName);\n }\n }\n // END options.localizedData.passthroughLocale\n\n // START options.localizedData.translatedStrings\n const resolveRelativeToContext: (relative: string) => string = (\n configuration.context?.startsWith('/') ? path.posix.resolve : path.resolve\n ).bind(0, configuration.context!);\n const { translatedStrings } = localizedData;\n this._resolvedTranslatedStringsFromOptions.clear();\n if (translatedStrings) {\n for (const [localeName, locale] of Object.entries(translatedStrings)) {\n if (this._translatedLocales.has(localeName)) {\n errors.push(\n new WebpackError(\n `The locale \"${localeName}\" appears multiple times. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this._translatedLocales.add(localeName);\n const resolvedFromOptionsForLocale: Map<string, ILocaleFileData> = new Map();\n this._resolvedTranslatedStringsFromOptions.set(localeName, resolvedFromOptionsForLocale);\n\n for (const [locFilePath, locFileDataFromOptions] of Object.entries(locale)) {\n const normalizedLocFilePath: string = resolveRelativeToContext(locFilePath);\n\n if (resolvedFromOptionsForLocale.has(normalizedLocFilePath)) {\n errors.push(\n new WebpackError(\n `The localization file path \"${locFilePath}\" appears multiple times in locale ${localeName}. ` +\n 'There may be multiple instances with different casing.'\n )\n );\n return { errors, warnings };\n }\n\n const normalizedLocFileDataFromOptions: ILocaleFileData =\n typeof locFileDataFromOptions === 'string'\n ? resolveRelativeToContext(locFileDataFromOptions)\n : locFileDataFromOptions;\n\n resolvedFromOptionsForLocale.set(normalizedLocFilePath, normalizedLocFileDataFromOptions);\n }\n }\n }\n // END options.localizedData.translatedStrings\n\n // START options.localizedData.defaultLocale\n const { defaultLocale } = localizedData;\n if (defaultLocale) {\n const { localeName, fillMissingTranslationStrings } = defaultLocale;\n if (localeName) {\n if (this._translatedLocales.has(localeName)) {\n errors.push(new WebpackError('The default locale is also specified in the translated strings.'));\n return { errors, warnings };\n } else if (!ensureValidLocaleName(localeName)) {\n return { errors, warnings };\n }\n\n this._translatedLocales.add(localeName);\n this._defaultLocale = localeName;\n this._fillMissingTranslationStrings = !!fillMissingTranslationStrings;\n } else {\n errors.push(new WebpackError('Missing default locale name'));\n return { errors, warnings };\n }\n } else {\n errors.push(new WebpackError('Missing default locale options.'));\n return { errors, warnings };\n }\n // END options.localizedData.defaultLocale\n\n // START options.localizedData.pseudoLocales\n const { pseudolocales } = localizedData;\n if (pseudolocales) {\n for (const [pseudolocaleName, pseudoLocaleOpts] of Object.entries(pseudolocales)) {\n if (this._defaultLocale === pseudolocaleName) {\n errors.push(\n new WebpackError(`A pseudolocale (${pseudolocaleName}) name is also the default locale name.`)\n );\n return { errors, warnings };\n }\n\n if (this._translatedLocales.has(pseudolocaleName)) {\n errors.push(\n new WebpackError(\n `A pseudolocale (${pseudolocaleName}) name is also specified in the translated strings.`\n )\n );\n return { errors, warnings };\n }\n\n this._pseudolocalizers.set(pseudolocaleName, getPseudolocalizer(pseudoLocaleOpts));\n this._translatedLocales.add(pseudolocaleName);\n }\n }\n // END options.localizedData.pseudoLocales\n } else if (!isWebpackDevServer) {\n throw new Error('Localized data must be provided unless webpack dev server is running.');\n }\n // END options.localizedData\n\n // START options.noStringsLocaleName\n const { noStringsLocaleName } = this._options;\n if (\n noStringsLocaleName === undefined ||\n noStringsLocaleName === null ||\n !ensureValidLocaleName(noStringsLocaleName)\n ) {\n this._noStringsLocaleName = 'none';\n } else {\n this._noStringsLocaleName = noStringsLocaleName;\n }\n // END options.noStringsLocaleName\n\n // START options.formatLocaleForFilename\n const { formatLocaleForFilename = (localeName: string) => localeName } = this._options;\n this._formatLocaleForFilename = formatLocaleForFilename;\n // END options.formatLocaleForFilename\n return { errors, warnings };\n }\n}\n\nfunction _chunkHasLocalizedModules(\n chunkGraph: ChunkGraph,\n chunk: Chunk,\n runtimeLocaleExpression: string | undefined\n): boolean {\n let chunkHasAnyLocModules: boolean | undefined = getMark(chunk);\n if (chunkHasAnyLocModules === undefined) {\n chunkHasAnyLocModules = false;\n const candidateModules: Iterable<Module> | undefined = chunkGraph.getChunkModulesIterableBySourceType(\n chunk,\n 'javascript'\n );\n if (candidateModules) {\n outer: for (const module of candidateModules) {\n const moduleMark: boolean | undefined = getMark(module);\n if (moduleMark) {\n chunkHasAnyLocModules = true;\n break;\n } else if (moduleMark === false) {\n continue;\n }\n\n // Is this a concatenated module?\n const { _modules: modules } = module as { _modules?: Iterable<Module> };\n if (modules) {\n for (const nestedModule of modules) {\n if (getMark(nestedModule)) {\n markEntity(module, true);\n chunkHasAnyLocModules = true;\n break outer;\n }\n }\n markEntity(module, false);\n }\n }\n }\n\n // If this chunk doesn't directly contain any localized resources, it still\n // needs to be localized if it's an entrypoint chunk (i.e. - it has a runtime)\n // and it loads localized async chunks.\n // In that case, the generated chunk URL generation code needs to contain\n // the locale name.\n if (!chunkHasAnyLocModules && !runtimeLocaleExpression && chunk.hasRuntime()) {\n for (const asyncChunk of chunk.getAllAsyncChunks()) {\n if (_chunkHasLocalizedModules(chunkGraph, asyncChunk, runtimeLocaleExpression)) {\n chunkHasAnyLocModules = true;\n break;\n }\n }\n }\n\n markEntity(chunk, chunkHasAnyLocModules);\n }\n\n return chunkHasAnyLocModules;\n}\n\nfunction convertLocalizationFileToLocData(locFile: ILocalizationFile): ReadonlyMap<string, string> {\n const locFileData: Map<string, string> = new Map();\n for (const [stringName, locFileEntry] of Object.entries(locFile)) {\n locFileData.set(stringName, locFileEntry.value);\n }\n\n return locFileData;\n}\n\nasync function normalizeLocalizedDataAsync(\n context: LoaderContext<{}>,\n localizedData: ILocaleFileData\n): Promise<ReadonlyMap<string, string>> {\n if (typeof localizedData === 'string') {\n // The value is the path to a file. Add it as a file dependency\n context.addDependency(localizedData);\n const content: string = await new Promise((resolve, reject) => {\n // Use context.fs so that the plugin is compatible with overriding compiler.inputFileSystem\n context.fs.readFile(localizedData, (err, data) => {\n if (err) {\n return reject(err);\n } else if (!data) {\n return reject(new Error(`No data in ${localizedData}`));\n }\n resolve(data.toString());\n });\n });\n\n const localizationFile: ILocalizationFile = parseResJson({\n filePath: localizedData,\n content\n });\n\n return convertLocalizationFileToLocData(localizationFile);\n } else {\n return localizedData instanceof Map ? localizedData : new Map(Object.entries(localizedData));\n }\n}\n"]}
package/lib/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /// <reference types="node" preserve="true" />
2
- export { LocalizationPlugin, type IStringPlaceholder as _IStringPlaceholder } from './LocalizationPlugin';
2
+ export { LocalizationPlugin, type IStringPlaceholder as _IStringPlaceholder, type IStringPlaceholder, type ICustomDataPlaceholder as _ICustomDataPlaceholder, type IValuePlaceholderBase, type ValueForLocaleFn } from './LocalizationPlugin';
3
3
  export { TrueHashPlugin, type ITrueHashPluginOptions } from './TrueHashPlugin';
4
4
  export type { IDefaultLocaleOptions, ILocaleData, ILocaleElementMap, ILocaleFileData, ILocaleFileObject, ILocalizationPluginOptions, ILocalizationStats, ILocalizationStatsChunkGroup, ILocalizationStatsEntrypoint, ILocalizationStatsOptions, ILocalizedData, ILocalizedStrings, IPassthroughLocaleOptions, IPseudolocalesOptions, IResolvedMissingTranslations } from './interfaces';
5
5
  export type { ILocalizedWebpackChunk } from './webpackInterfaces';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,IAAI,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,YAAY,EACV,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAKA,OAAO,EACL,kBAAkB,EAElB,KAAK,kBAAkB,IAAI,mBAAmB,EAC9C,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,IAAI,uBAAuB,EACtD,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,KAAK,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAE/E,YAAY,EACV,qBAAqB,EACrB,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,4BAA4B,EAC5B,4BAA4B,EAC5B,yBAAyB,EACzB,cAAc,EACd,iBAAiB,EACjB,yBAAyB,EACzB,qBAAqB,EACrB,4BAA4B,EAC7B,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC"}
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,8CAA8C;AAE9C,2DAA0G;AAAjG,wHAAA,kBAAkB,OAAA;AAC3B,mDAA+E;AAAtE,gHAAA,cAAc,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/// <reference types=\"node\" preserve=\"true\" />\n\nexport { LocalizationPlugin, type IStringPlaceholder as _IStringPlaceholder } from './LocalizationPlugin';\nexport { TrueHashPlugin, type ITrueHashPluginOptions } from './TrueHashPlugin';\n\nexport type {\n IDefaultLocaleOptions,\n ILocaleData,\n ILocaleElementMap,\n ILocaleFileData,\n ILocaleFileObject,\n ILocalizationPluginOptions,\n ILocalizationStats,\n ILocalizationStatsChunkGroup,\n ILocalizationStatsEntrypoint,\n ILocalizationStatsOptions,\n ILocalizedData,\n ILocalizedStrings,\n IPassthroughLocaleOptions,\n IPseudolocalesOptions,\n IResolvedMissingTranslations\n} from './interfaces';\nexport type { ILocalizedWebpackChunk } from './webpackInterfaces';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE3D,8CAA8C;AAE9C,2DAQ8B;AAP5B,wHAAA,kBAAkB,OAAA;AAQpB,mDAA+E;AAAtE,gHAAA,cAAc,OAAA","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\n/// <reference types=\"node\" preserve=\"true\" />\n\nexport {\n LocalizationPlugin,\n // TODO: Remove this export in the next major version\n type IStringPlaceholder as _IStringPlaceholder,\n type IStringPlaceholder,\n type ICustomDataPlaceholder as _ICustomDataPlaceholder,\n type IValuePlaceholderBase,\n type ValueForLocaleFn\n} from './LocalizationPlugin';\nexport { TrueHashPlugin, type ITrueHashPluginOptions } from './TrueHashPlugin';\n\nexport type {\n IDefaultLocaleOptions,\n ILocaleData,\n ILocaleElementMap,\n ILocaleFileData,\n ILocaleFileObject,\n ILocalizationPluginOptions,\n ILocalizationStats,\n ILocalizationStatsChunkGroup,\n ILocalizationStatsEntrypoint,\n ILocalizationStatsOptions,\n ILocalizedData,\n ILocalizedStrings,\n IPassthroughLocaleOptions,\n IPseudolocalesOptions,\n IResolvedMissingTranslations\n} from './interfaces';\nexport type { ILocalizedWebpackChunk } from './webpackInterfaces';\n"]}
@@ -7,6 +7,7 @@ export declare const RESOURCE_FILE_NAME_REGEXP: RegExp;
7
7
  export declare const STRING_PLACEHOLDER_LABEL: 'A';
8
8
  export declare const LOCALE_NAME_PLACEHOLDER_LABEL: 'B';
9
9
  export declare const JSONP_PLACEHOLDER_LABEL: 'C';
10
+ export declare const CUSTOM_PLACEHOLDER_LABEL: 'D';
10
11
  export declare const LOCALE_NAME_PLACEHOLDER: `${typeof STRING_PLACEHOLDER_PREFIX}_${typeof LOCALE_NAME_PLACEHOLDER_LABEL}_`;
11
12
  export declare const JSONP_PLACEHOLDER: `${typeof STRING_PLACEHOLDER_PREFIX}_${typeof JSONP_PLACEHOLDER_LABEL}_`;
12
13
  //# sourceMappingURL=Constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Constants.d.ts","sourceRoot":"","sources":["../../src/utilities/Constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,EAAE,UAAuB,CAAC;AAC5D,eAAO,MAAM,2BAA2B,EAAE,MAAuB,CAAC;AAClE,eAAO,MAAM,mCAAmC,EAAE,kBAAuC,CAAC;AAC1F,eAAO,MAAM,yCAAyC,EAAE,MAA+B,CAAC;AACxF,eAAO,MAAM,yBAAyB,EAAE,wDACkB,CAAC;AAE3D,eAAO,MAAM,yBAAyB,EAAE,MAAkD,CAAC;AAE3F,eAAO,MAAM,wBAAwB,EAAE,GAAS,CAAC;AACjD,eAAO,MAAM,6BAA6B,EAAE,GAAS,CAAC;AACtD,eAAO,MAAM,uBAAuB,EAAE,GAAS,CAAC;AAGhD,eAAO,MAAM,uBAAuB,EAAE,GAAG,OAAO,yBAAyB,IAAI,OAAO,6BAA6B,GAAsE,CAAC;AAGxL,eAAO,MAAM,iBAAiB,EAAE,GAAG,OAAO,yBAAyB,IAAI,OAAO,uBAAuB,GAAgE,CAAC"}
1
+ {"version":3,"file":"Constants.d.ts","sourceRoot":"","sources":["../../src/utilities/Constants.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,qBAAqB,EAAE,UAAuB,CAAC;AAC5D,eAAO,MAAM,2BAA2B,EAAE,MAAuB,CAAC;AAClE,eAAO,MAAM,mCAAmC,EAAE,kBAAuC,CAAC;AAC1F,eAAO,MAAM,yCAAyC,EAAE,MAA+B,CAAC;AACxF,eAAO,MAAM,yBAAyB,EAAE,wDACkB,CAAC;AAE3D,eAAO,MAAM,yBAAyB,EAAE,MAAkD,CAAC;AAE3F,eAAO,MAAM,wBAAwB,EAAE,GAAS,CAAC;AACjD,eAAO,MAAM,6BAA6B,EAAE,GAAS,CAAC;AACtD,eAAO,MAAM,uBAAuB,EAAE,GAAS,CAAC;AAChD,eAAO,MAAM,wBAAwB,EAAE,GAAS,CAAC;AAGjD,eAAO,MAAM,uBAAuB,EAAE,GAAG,OAAO,yBAAyB,IAAI,OAAO,6BAA6B,GAAsE,CAAC;AAGxL,eAAO,MAAM,iBAAiB,EAAE,GAAG,OAAO,yBAAyB,IAAI,OAAO,uBAAuB,GAAgE,CAAC"}
@@ -2,7 +2,7 @@
2
2
  // Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
3
3
  // See LICENSE in the project root for license information.
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.JSONP_PLACEHOLDER = exports.LOCALE_NAME_PLACEHOLDER = exports.JSONP_PLACEHOLDER_LABEL = exports.LOCALE_NAME_PLACEHOLDER_LABEL = exports.STRING_PLACEHOLDER_LABEL = exports.RESOURCE_FILE_NAME_REGEXP = exports.STRING_PLACEHOLDER_PREFIX = exports.NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN_REGEX = exports.NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN = exports.LOCALE_FILENAME_TOKEN_REGEX = exports.LOCALE_FILENAME_TOKEN = void 0;
5
+ exports.JSONP_PLACEHOLDER = exports.LOCALE_NAME_PLACEHOLDER = exports.CUSTOM_PLACEHOLDER_LABEL = exports.JSONP_PLACEHOLDER_LABEL = exports.LOCALE_NAME_PLACEHOLDER_LABEL = exports.STRING_PLACEHOLDER_LABEL = exports.RESOURCE_FILE_NAME_REGEXP = exports.STRING_PLACEHOLDER_PREFIX = exports.NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN_REGEX = exports.NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN = exports.LOCALE_FILENAME_TOKEN_REGEX = exports.LOCALE_FILENAME_TOKEN = void 0;
6
6
  exports.LOCALE_FILENAME_TOKEN = '[locale]';
7
7
  exports.LOCALE_FILENAME_TOKEN_REGEX = /\[locale\]/gi;
8
8
  exports.NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN = '[no-locale-file]';
@@ -12,6 +12,7 @@ exports.RESOURCE_FILE_NAME_REGEXP = /\.(resx|resx\.json|loc\.json|resjson)$/i;
12
12
  exports.STRING_PLACEHOLDER_LABEL = 'A';
13
13
  exports.LOCALE_NAME_PLACEHOLDER_LABEL = 'B';
14
14
  exports.JSONP_PLACEHOLDER_LABEL = 'C';
15
+ exports.CUSTOM_PLACEHOLDER_LABEL = 'D';
15
16
  // _LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9_B_
16
17
  exports.LOCALE_NAME_PLACEHOLDER = `${exports.STRING_PLACEHOLDER_PREFIX}_${exports.LOCALE_NAME_PLACEHOLDER_LABEL}_`;
17
18
  // _LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9_C_
@@ -1 +1 @@
1
- {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../src/utilities/Constants.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE9C,QAAA,qBAAqB,GAAe,UAAU,CAAC;AAC/C,QAAA,2BAA2B,GAAW,cAAc,CAAC;AACrD,QAAA,mCAAmC,GAAuB,kBAAkB,CAAC;AAC7E,QAAA,yCAAyC,GAAW,sBAAsB,CAAC;AAC3E,QAAA,yBAAyB,GACpC,wDAAwD,CAAC;AAE9C,QAAA,yBAAyB,GAAW,yCAAyC,CAAC;AAE9E,QAAA,wBAAwB,GAAQ,GAAG,CAAC;AACpC,QAAA,6BAA6B,GAAQ,GAAG,CAAC;AACzC,QAAA,uBAAuB,GAAQ,GAAG,CAAC;AAEhD,4DAA4D;AAC/C,QAAA,uBAAuB,GAAmF,GAAG,iCAAyB,IAAI,qCAA6B,GAAG,CAAC;AAExL,4DAA4D;AAC/C,QAAA,iBAAiB,GAA6E,GAAG,iCAAyB,IAAI,+BAAuB,GAAG,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nexport const LOCALE_FILENAME_TOKEN: '[locale]' = '[locale]';\nexport const LOCALE_FILENAME_TOKEN_REGEX: RegExp = /\\[locale\\]/gi;\nexport const NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN: '[no-locale-file]' = '[no-locale-file]';\nexport const NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN_REGEX: RegExp = /\\[no-locale-file\\]/gi;\nexport const STRING_PLACEHOLDER_PREFIX: '_LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9' =\n '_LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9';\n\nexport const RESOURCE_FILE_NAME_REGEXP: RegExp = /\\.(resx|resx\\.json|loc\\.json|resjson)$/i;\n\nexport const STRING_PLACEHOLDER_LABEL: 'A' = 'A';\nexport const LOCALE_NAME_PLACEHOLDER_LABEL: 'B' = 'B';\nexport const JSONP_PLACEHOLDER_LABEL: 'C' = 'C';\n\n// _LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9_B_\nexport const LOCALE_NAME_PLACEHOLDER: `${typeof STRING_PLACEHOLDER_PREFIX}_${typeof LOCALE_NAME_PLACEHOLDER_LABEL}_` = `${STRING_PLACEHOLDER_PREFIX}_${LOCALE_NAME_PLACEHOLDER_LABEL}_`;\n\n// _LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9_C_\nexport const JSONP_PLACEHOLDER: `${typeof STRING_PLACEHOLDER_PREFIX}_${typeof JSONP_PLACEHOLDER_LABEL}_` = `${STRING_PLACEHOLDER_PREFIX}_${JSONP_PLACEHOLDER_LABEL}_`;\n"]}
1
+ {"version":3,"file":"Constants.js","sourceRoot":"","sources":["../../src/utilities/Constants.ts"],"names":[],"mappings":";AAAA,4FAA4F;AAC5F,2DAA2D;;;AAE9C,QAAA,qBAAqB,GAAe,UAAU,CAAC;AAC/C,QAAA,2BAA2B,GAAW,cAAc,CAAC;AACrD,QAAA,mCAAmC,GAAuB,kBAAkB,CAAC;AAC7E,QAAA,yCAAyC,GAAW,sBAAsB,CAAC;AAC3E,QAAA,yBAAyB,GACpC,wDAAwD,CAAC;AAE9C,QAAA,yBAAyB,GAAW,yCAAyC,CAAC;AAE9E,QAAA,wBAAwB,GAAQ,GAAG,CAAC;AACpC,QAAA,6BAA6B,GAAQ,GAAG,CAAC;AACzC,QAAA,uBAAuB,GAAQ,GAAG,CAAC;AACnC,QAAA,wBAAwB,GAAQ,GAAG,CAAC;AAEjD,4DAA4D;AAC/C,QAAA,uBAAuB,GAAmF,GAAG,iCAAyB,IAAI,qCAA6B,GAAG,CAAC;AAExL,4DAA4D;AAC/C,QAAA,iBAAiB,GAA6E,GAAG,iCAAyB,IAAI,+BAAuB,GAAG,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.\n// See LICENSE in the project root for license information.\n\nexport const LOCALE_FILENAME_TOKEN: '[locale]' = '[locale]';\nexport const LOCALE_FILENAME_TOKEN_REGEX: RegExp = /\\[locale\\]/gi;\nexport const NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN: '[no-locale-file]' = '[no-locale-file]';\nexport const NO_LOCALE_SOURCE_MAP_FILENAME_TOKEN_REGEX: RegExp = /\\[no-locale-file\\]/gi;\nexport const STRING_PLACEHOLDER_PREFIX: '_LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9' =\n '_LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9';\n\nexport const RESOURCE_FILE_NAME_REGEXP: RegExp = /\\.(resx|resx\\.json|loc\\.json|resjson)$/i;\n\nexport const STRING_PLACEHOLDER_LABEL: 'A' = 'A';\nexport const LOCALE_NAME_PLACEHOLDER_LABEL: 'B' = 'B';\nexport const JSONP_PLACEHOLDER_LABEL: 'C' = 'C';\nexport const CUSTOM_PLACEHOLDER_LABEL: 'D' = 'D';\n\n// _LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9_B_\nexport const LOCALE_NAME_PLACEHOLDER: `${typeof STRING_PLACEHOLDER_PREFIX}_${typeof LOCALE_NAME_PLACEHOLDER_LABEL}_` = `${STRING_PLACEHOLDER_PREFIX}_${LOCALE_NAME_PLACEHOLDER_LABEL}_`;\n\n// _LOCALIZED_STRING_f12dy0i7_n4bo_dqwj_39gf_sasqehjmihz9_C_\nexport const JSONP_PLACEHOLDER: `${typeof STRING_PLACEHOLDER_PREFIX}_${typeof JSONP_PLACEHOLDER_LABEL}_` = `${STRING_PLACEHOLDER_PREFIX}_${JSONP_PLACEHOLDER_LABEL}_`;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rushstack/webpack5-localization-plugin",
3
- "version": "0.13.16",
3
+ "version": "0.14.1",
4
4
  "description": "This plugin facilitates localization with Webpack.",
5
5
  "main": "lib/index.js",
6
6
  "typings": "dist/webpack5-localization-plugin.d.ts",
@@ -15,16 +15,17 @@
15
15
  "@types/node": "*"
16
16
  },
17
17
  "dependencies": {
18
- "@rushstack/localization-utilities": "0.13.16",
19
- "@rushstack/node-core-library": "5.13.1",
20
- "@rushstack/terminal": "0.15.3"
18
+ "@rushstack/terminal": "0.15.4",
19
+ "@rushstack/node-core-library": "5.14.0",
20
+ "@rushstack/localization-utilities": "0.13.17"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@types/node": "20.17.19",
24
+ "eslint": "~9.25.1",
24
25
  "memfs": "4.12.0",
25
26
  "webpack": "~5.98.0",
26
- "local-node-rig": "1.0.0",
27
- "@rushstack/heft": "0.74.0"
27
+ "@rushstack/heft": "0.74.1",
28
+ "local-node-rig": "1.0.0"
28
29
  },
29
30
  "peerDependenciesMeta": {
30
31
  "@types/node": {