"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.setDependenciesTsConfigPaths = exports.initializeTsConfig = exports.createDefaultTsConfig = exports.readDefaultTsConfig = void 0;
const ng = require("@angular/compiler-cli");
const path = require("path");
const ts = require("typescript");
const log = require("../utils/log");
/**
 * Reads the default TypeScript configuration.
 */
function readDefaultTsConfig(fileName) {
    if (!fileName) {
        fileName = path.resolve(__dirname, 'conf', 'tsconfig.ngc.json');
    }
    // these options are mandatory
    const extraOptions = {
        moduleResolution: ts.ModuleResolutionKind.NodeJs,
        target: ts.ScriptTarget.ES2015,
        experimentalDecorators: true,
        // sourcemaps
        sourceMap: false,
        inlineSources: true,
        inlineSourceMap: true,
        outDir: '',
        declaration: true,
        // ng compiler to options
        enableResourceInlining: true,
        // these are required to set the appropriate EmitFlags
        flatModuleId: 'AUTOGENERATED',
        flatModuleOutFile: 'AUTOGENERATED',
    };
    const config = ng.readConfiguration(fileName, extraOptions);
    const options = config.options;
    // todo: alanagius4 - the below shouldn't be needed but it seems that setting it only in create-emit-callback.ts
    // is not working correctly
    const transformDecorators = !options.enableIvy && options.annotationsAs !== 'decorators';
    if ((options.annotateForClosureCompiler || options.annotationsAs === 'static fields') && transformDecorators) {
        // This is needed as a workaround for https://github.com/angular/tsickle/issues/635
        // Otherwise tsickle might emit references to non imported values
        // as TypeScript elided the import.
        options.emitDecoratorMetadata = true;
    }
    return config;
}
exports.readDefaultTsConfig = readDefaultTsConfig;
/**
 * Creates a parsed TypeScript configuration object.
 *
 * @param values File path or parsed configuration.
 */
function createDefaultTsConfig(values) {
    if (!values) {
        return readDefaultTsConfig();
    }
    else if (typeof values === 'string') {
        return readDefaultTsConfig(values);
    }
    else {
        return values;
    }
}
exports.createDefaultTsConfig = createDefaultTsConfig;
/**
 * Initializes TypeScript Compiler options and Angular Compiler options by overriding the
 * default config with entry point-specific values.
 */
const initializeTsConfig = (defaultTsConfig, entryPoints) => {
    if (defaultTsConfig.errors.length > 0) {
        throw ng.formatDiagnostics(defaultTsConfig.errors);
    }
    entryPoints.forEach(currentEntryPoint => {
        const { entryPoint } = currentEntryPoint.data;
        log.debug(`Initializing tsconfig for ${entryPoint.moduleId}`);
        const basePath = path.dirname(entryPoint.entryFilePath);
        // Resolve defaults from DI token and create a deep copy of the defaults
        let tsConfig = JSON.parse(JSON.stringify(defaultTsConfig));
        const overrideOptions = {
            flatModuleId: entryPoint.moduleId,
            flatModuleOutFile: `${entryPoint.flatModuleFile}.js`,
            basePath,
            rootDir: basePath,
            sourceRoot: '',
        };
        tsConfig.rootNames = [entryPoint.entryFilePath];
        tsConfig.options = { ...tsConfig.options, ...overrideOptions };
        currentEntryPoint.data.tsConfig = tsConfig;
    });
};
exports.initializeTsConfig = initializeTsConfig;
/**
 * Set the paths for entrypoint dependencies.
 *
 * This doesn't mutate the object.
 *
 * @param parsedTsConfig - A parsed tsconfig
 * @param entryPoints - A list of entryPoints
 * @param pointToSource Point the path mapping to either the source code or emitted declarations.
 * Typically for analysis one should point to the source files while for a compilation once should use the emitted declarations
 */
function setDependenciesTsConfigPaths(parsedTsConfig, entryPoints, pointToSource = false) {
    const tsConfig = JSON.parse(JSON.stringify(parsedTsConfig));
    // Add paths mappings for dependencies
    if (!tsConfig.options.paths) {
        tsConfig.options.paths = {};
    }
    for (let dep of entryPoints) {
        const { entryPoint } = dep.data;
        const { moduleId, destinationFiles, entryFilePath } = entryPoint;
        const mappedPath = [pointToSource ? entryFilePath : destinationFiles.declarations];
        if (!tsConfig.options.paths[moduleId]) {
            tsConfig.options.paths[moduleId] = mappedPath;
        }
        else {
            tsConfig.options.paths[moduleId].unshift(...mappedPath);
        }
    }
    return tsConfig;
}
exports.setDependenciesTsConfigPaths = setDependenciesTsConfigPaths;
//# sourceMappingURL=tsconfig.js.map