text: "use strict";
  Object.defineProperty(exports, "__esModule", { value: true });
  /**
   * @license
   * Copyright Google Inc. All Rights Reserved.
   *
   * Use of this source code is governed by an MIT-style license that can be
   * found in the LICENSE file at https://angular.io/license
   */
  const fs_1 = require("fs");
  const transform_javascript_1 = require("../helpers/transform-javascript");
  const class_fold_1 = require("../transforms/class-fold");
  const import_tslib_1 = require("../transforms/import-tslib");
  const prefix_classes_1 = require("../transforms/prefix-classes");
  const prefix_functions_1 = require("../transforms/prefix-functions");
  const scrub_file_1 = require("../transforms/scrub-file");
  const wrap_enums_1 = require("../transforms/wrap-enums");
  // Angular packages are known to have no side effects.
  const whitelistedAngularModules = [
      /[\\/]node_modules[\\/]@angular[\\/]animations[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]common[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]compiler[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]core[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]forms[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]http[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]platform-browser-dynamic[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]platform-browser[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]platform-webworker-dynamic[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]platform-webworker[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]router[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]upgrade[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]material[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]cdk[\\/]/,
  ];
  // Factories created by AOT are known to have no side effects.
  // In Angular 2/4 the file path for factories can be `.ts`, but in Angular 5 it is `.js`.
  const ngFactories = [
      /\.ngfactory\.[jt]s/,
      /\.ngstyle\.[jt]s/,
  ];
  // Known locations for the source files of @angular/core.
  const coreFilesRegex = [
      /[\\/]node_modules[\\/]@angular[\\/]core[\\/]esm5[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]core[\\/]fesm5[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]core[\\/]esm2015[\\/]/,
      /[\\/]node_modules[\\/]@angular[\\/]core[\\/]fesm2015[\\/]/,
  ];
  function isKnownCoreFile(filePath) {
      return coreFilesRegex.some(re => re.test(filePath));
  }
  function isKnownSideEffectFree(filePath) {
      return ngFactories.some((re) => re.test(filePath)) ||
          whitelistedAngularModules.some((re) => re.test(filePath));
  }
  function buildOptimizer(options) {
      const { inputFilePath, isAngularCoreFile } = options;
      let { originalFilePath, content } = options;
      if (!originalFilePath && inputFilePath) {
          originalFilePath = inputFilePath;
      }
      if (!inputFilePath && content === undefined) {
          throw new Error('Either filePath or content must be specified in options.');
      }
      if (content === undefined) {
          content = fs_1.readFileSync(inputFilePath, 'UTF-8');
      }
      if (!content) {
          return {
              content: null,
              sourceMap: null,
              emitSkipped: true,
          };
      }
      let selectedGetScrubFileTransformer = scrub_file_1.getScrubFileTransformer;
      if (isAngularCoreFile === true ||
          (isAngularCoreFile === undefined && originalFilePath && isKnownCoreFile(originalFilePath))) {
          selectedGetScrubFileTransformer = scrub_file_1.getScrubFileTransformerForCore;
      }
      const isWebpackBundle = content.indexOf('__webpack_require__') !== -1;
      // Determine which transforms to apply.
      const getTransforms = [];
      let typeCheck = false;
      if (options.isSideEffectFree || originalFilePath && isKnownSideEffectFree(originalFilePath)) {
          getTransforms.push(
          // getPrefixFunctionsTransformer is rather dangerous, apply only to known pure es5 modules.
          // It will mark both `require()` calls and `console.log(stuff)` as pure.
          // We only apply it to whitelisted modules, since we know they are safe.
          // getPrefixFunctionsTransformer needs to be before getFoldFileTransformer.
          prefix_functions_1.getPrefixFunctionsTransformer, selectedGetScrubFileTransformer, class_fold_1.getFoldFileTransformer);
          typeCheck = true;
      }
      else if (scrub_file_1.testScrubFile(content)) {
          // Always test as these require the type checker
          getTransforms.push(selectedGetScrubFileTransformer, class_fold_1.getFoldFileTransformer);
          typeCheck = true;
      }
      // tests are not needed for fast path
      // usage will be expanded once transformers are verified safe
      const ignoreTest = !options.emitSourceMap && !typeCheck;
      if (prefix_classes_1.testPrefixClasses(content)) {
          getTransforms.unshift(prefix_classes_1.getPrefixClassesTransformer);
      }
      // This transform introduces import/require() calls, but this won't work properly on libraries
      // built with Webpack. These libraries use __webpack_require__() calls instead, which will break
      // with a new import that wasn't part of it's original module list.
      // We ignore this transform for such libraries.
      if (!isWebpackBundle && (ignoreTest || import_tslib_1.testImportTslib(content))) {
          getTransforms.unshift(import_tslib_1.getImportTslibTransformer);
      }
      getTransforms.unshift(wrap_enums_1.getWrapEnumsTransformer);
      const transformJavascriptOpts = {
          content: content,
          inputFilePath: options.inputFilePath,
          outputFilePath: options.outputFilePath,
          emitSourceMap: options.emitSourceMap,
          strict: options.strict,
          getTransforms,
          typeCheck,
      };
      return transform_javascript_1.transformJavascript(transformJavascriptOpts);
  }
  exports.buildOptimizer = buildOptimizer;
  