async function inlineLocalesDirect()

in packages/angular_devkit/build_angular/src/utils/process-bundle.ts [229:320]


async function inlineLocalesDirect(ast: ParseResult, options: InlineOptions) {
  if (!i18n || i18n.inlineLocales.size === 0) {
    return { file: options.filename, diagnostics: [], count: 0 };
  }

  const { default: generate } = await import('@babel/generator');
  const localizeDiag = await loadLocalizeTools();
  const diagnostics = new localizeDiag.Diagnostics();

  const positions = findLocalizePositions(ast, options, localizeDiag);
  if (positions.length === 0 && !options.setLocale) {
    return inlineCopyOnly(options);
  }

  const inputMap = !!options.map && (JSON.parse(options.map) as { sourceRoot?: string });
  // Cleanup source root otherwise it will be added to each source entry
  const mapSourceRoot = inputMap && inputMap.sourceRoot;
  if (inputMap) {
    delete inputMap.sourceRoot;
  }

  // Load Webpack only when needed
  if (webpackSources === undefined) {
    webpackSources = (await import('webpack')).sources;
  }
  const { ConcatSource, OriginalSource, ReplaceSource, SourceMapSource } = webpackSources;

  for (const locale of i18n.inlineLocales) {
    const content = new ReplaceSource(
      inputMap
        ? new SourceMapSource(options.code, options.filename, inputMap)
        : new OriginalSource(options.code, options.filename),
    );

    const isSourceLocale = locale === i18n.sourceLocale;
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    const translations: any = isSourceLocale ? {} : i18n.locales[locale].translation || {};
    for (const position of positions) {
      const translated = localizeDiag.translate(
        diagnostics,
        translations,
        position.messageParts,
        position.expressions,
        isSourceLocale ? 'ignore' : options.missingTranslation || 'warning',
      );

      const expression = localizeDiag.buildLocalizeReplacement(translated[0], translated[1]);
      const { code } = generate(expression);

      content.replace(position.start, position.end - 1, code);
    }

    let outputSource: import('webpack').sources.Source = content;
    if (options.setLocale) {
      const setLocaleText = `var $localize=Object.assign(void 0===$localize?{}:$localize,{locale:"${locale}"});\n`;

      // If locale data is provided, load it and prepend to file
      let localeDataSource;
      const localeDataPath = i18n.locales[locale] && i18n.locales[locale].dataPath;
      if (localeDataPath) {
        const localeDataContent = await loadLocaleData(localeDataPath, true, options.es5);
        localeDataSource = new OriginalSource(localeDataContent, path.basename(localeDataPath));
      }

      outputSource = localeDataSource
        ? // The semicolon ensures that there is no syntax error between statements
          new ConcatSource(setLocaleText, localeDataSource, ';\n', content)
        : new ConcatSource(setLocaleText, content);
    }

    const { source: outputCode, map: outputMap } = outputSource.sourceAndMap() as {
      source: string;
      map: { file: string; sourceRoot?: string };
    };
    const outputPath = path.join(
      options.outputPath,
      i18n.flatOutput ? '' : locale,
      options.filename,
    );
    fs.writeFileSync(outputPath, outputCode);

    if (inputMap && outputMap) {
      outputMap.file = options.filename;
      if (mapSourceRoot) {
        outputMap.sourceRoot = mapSourceRoot;
      }
      fs.writeFileSync(outputPath + '.map', JSON.stringify(outputMap));
    }
  }

  return { file: options.filename, diagnostics: diagnostics.messages, count: positions.length };
}