1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.WatchCompiler = void 0;
|
4 | const errors_1 = require("../ui/errors");
|
5 | const get_value_or_default_1 = require("./helpers/get-value-or-default");
|
6 | const tsconfig_paths_hook_1 = require("./hooks/tsconfig-paths.hook");
|
7 | class WatchCompiler {
|
8 | constructor(pluginsLoader, tsConfigProvider, typescriptLoader) {
|
9 | this.pluginsLoader = pluginsLoader;
|
10 | this.tsConfigProvider = tsConfigProvider;
|
11 | this.typescriptLoader = typescriptLoader;
|
12 | }
|
13 | run(configuration, configFilename, appName, tsCompilerOptions, onSuccess) {
|
14 | const tsBin = this.typescriptLoader.load();
|
15 | const configPath = tsBin.findConfigFile(process.cwd(), tsBin.sys.fileExists, configFilename);
|
16 | if (!configPath) {
|
17 | throw new Error(errors_1.CLI_ERRORS.MISSING_TYPESCRIPT(configFilename));
|
18 | }
|
19 | const { projectReferences } = this.tsConfigProvider.getByConfigFilename(configFilename);
|
20 | const createProgram = tsBin.createEmitAndSemanticDiagnosticsBuilderProgram;
|
21 | const origDiagnosticReporter = tsBin.createDiagnosticReporter(tsBin.sys, true);
|
22 | const origWatchStatusReporter = tsBin.createWatchStatusReporter(tsBin.sys, true);
|
23 | const host = tsBin.createWatchCompilerHost(configPath, tsCompilerOptions, tsBin.sys, createProgram, this.createDiagnosticReporter(origDiagnosticReporter), this.createWatchStatusChanged(origWatchStatusReporter, onSuccess));
|
24 | const pluginsConfig = (0, get_value_or_default_1.getValueOrDefault)(configuration, 'compilerOptions.plugins', appName);
|
25 | const plugins = this.pluginsLoader.load(pluginsConfig);
|
26 | const origCreateProgram = host.createProgram;
|
27 | host.createProgram = (rootNames, options,
|
28 |
|
29 | host, oldProgram) => {
|
30 | const tsconfigPathsPlugin = options ? (0, tsconfig_paths_hook_1.tsconfigPathsBeforeHookFactory)(options) : null;
|
31 | const program = origCreateProgram(rootNames, options, host, oldProgram, undefined, projectReferences);
|
32 | const origProgramEmit = program.emit;
|
33 | program.emit = (targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, customTransformers) => {
|
34 | let transforms = customTransformers;
|
35 | transforms = typeof transforms !== 'object' ? {} : transforms;
|
36 | const before = plugins.beforeHooks.map((hook) => hook(program.getProgram()));
|
37 | const after = plugins.afterHooks.map((hook) => hook(program.getProgram()));
|
38 | const afterDeclarations = plugins.afterDeclarationsHooks.map((hook) => hook(program.getProgram()));
|
39 | if (tsconfigPathsPlugin) {
|
40 | before.unshift(tsconfigPathsPlugin);
|
41 | }
|
42 | transforms.before = before.concat(transforms.before || []);
|
43 | transforms.after = after.concat(transforms.after || []);
|
44 | transforms.afterDeclarations = afterDeclarations.concat(transforms.afterDeclarations || []);
|
45 | return origProgramEmit(targetSourceFile, writeFile, cancellationToken, emitOnlyDtsFiles, transforms);
|
46 | };
|
47 | return program;
|
48 | };
|
49 | tsBin.createWatchProgram(host);
|
50 | }
|
51 | createDiagnosticReporter(diagnosticReporter) {
|
52 | return function (diagnostic, ...args) {
|
53 | return diagnosticReporter.call(this, diagnostic, ...args);
|
54 | };
|
55 | }
|
56 | createWatchStatusChanged(watchStatusReporter, onSuccess) {
|
57 | return function (diagnostic, ...args) {
|
58 | const messageText = diagnostic && diagnostic.messageText;
|
59 | const noErrorsMessage = '0 errors';
|
60 | if (messageText &&
|
61 | messageText.includes &&
|
62 | messageText.includes(noErrorsMessage) &&
|
63 | onSuccess) {
|
64 | onSuccess();
|
65 | }
|
66 | return watchStatusReporter.call(this, diagnostic, ...args);
|
67 | };
|
68 | }
|
69 | }
|
70 | exports.WatchCompiler = WatchCompiler;
|