tsc-suppress
Version:
Run the Typescript compiler in transpile-only mode
203 lines (200 loc) • 9.48 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
const fs_1 = __importDefault(require("fs"));
const path_1 = __importDefault(require("path"));
const assert_1 = __importDefault(require("assert"));
const chalk_1 = __importDefault(require("chalk"));
const minimist_1 = __importDefault(require("minimist"));
const version = '1.0.2';
const workingDir = process.cwd();
const defaultTsconfigPath = path_1.default.join(workingDir, 'tsconfig.json');
const defaultCompilerPath = path_1.default.join(workingDir, 'node_modules/typescript/lib/typescript.js');
function printUsage() {
const usageMessage = `
${chalk_1.default.bold(`tsc-suppress v${version}`)}
Usage:
tsc-suppress [options]
Options:
-P, --project <path> \t Path to the project's tsconfig.json
\t Default: ${defaultTsconfigPath}
-C, --compiler <path>\t Path to the project's typescript compiler
\t Default: ${defaultCompilerPath}
-W, --watch \t Run in watch mode
Description:
This wrapper executes the Typescript compiler while suppressing all Typescript error messages.
This is useful during development when successful compilation is required for debugging but
type errors are expected.
`;
console.log(usageMessage);
}
module.exports = function tsc(args) {
return __awaiter(this, void 0, void 0, function* () {
const defaultArgs = {
compiler: defaultCompilerPath,
project: defaultTsconfigPath,
watch: false,
help: false,
};
if (args) {
// Validate args if used programmatically
if (args.compiler) {
(0, assert_1.default)(typeof args.compiler === 'string', 'Option "compiler" must be of type string');
}
if (args.project) {
(0, assert_1.default)(typeof args.project === 'string', 'Option "project" must be of type string');
}
if (args.watch) {
(0, assert_1.default)(typeof args.watch === 'boolean', 'Option "watch" must be of type boolean');
}
args = Object.assign(defaultArgs, args);
}
else {
// Parse and validate args if used via CLI
args = (0, minimist_1.default)(process.argv.slice(2), {
string: ['compiler', 'project'],
boolean: ['watch', 'help'],
alias: {
c: 'compiler',
p: 'project',
w: 'watch',
h: 'help',
},
default: defaultArgs,
});
}
if (args.help) {
printUsage();
process.exit(0);
}
const info = chalk_1.default.blue('info');
const warning = chalk_1.default.yellow('warning');
const error = chalk_1.default.red('error');
// Resolve typescript import
const compilerPath = path_1.default.resolve(args.compiler);
const compiler = yield Promise.resolve().then(() => __importStar(require(compilerPath)));
// Ensure compiler path resolves to the typescript compiler
if (!compiler ||
typeof compiler.version !== 'string' ||
typeof compiler.sys !== 'object' ||
typeof compiler.createProgram !== 'function') {
console.error(`${error} Cannot find Typescript compiler at: ${compilerPath}`);
process.exit(1);
}
// Display runtime messages
console.log(chalk_1.default.bold(`tsc-suppress v${version}`));
console.log(`${info} Using Typescript v${compiler.version}`);
console.log(` Compiler: ${compilerPath}`);
console.log(` Project: ${args.project}\n`);
if (args._ && args._.length > 2) {
console.warn(`${warning} Unknown CLI options received: ${args._.join(', ')}\n`);
}
const printSuppression = (numErrors) => {
if (numErrors > 0) {
console.warn(`${warning} Suppressed Typescript errors: ${numErrors}`);
}
else {
console.log(`${info} No Typescript errors found.`);
}
console.log(`${info} Compilation completed successfully.`);
};
const host = {
getCanonicalFileName: (filename) => filename,
getCurrentDirectory: compiler.sys.getCurrentDirectory,
getNewLine: () => compiler.sys.newLine,
};
const assertDiagnostics = (diagnostics) => {
if (!diagnostics) {
return;
}
if (!Array.isArray(diagnostics)) {
diagnostics = [diagnostics];
}
if (!diagnostics.length) {
return;
}
console.log(compiler.formatDiagnosticsWithColorAndContext(diagnostics, host));
};
// Parse tsconfig.json
const tsconfigJsonRaw = fs_1.default.readFileSync(args.project).toString();
const configObject = compiler.parseConfigFileTextToJson(args.project, tsconfigJsonRaw);
const configParseResult = compiler.parseJsonConfigFileContent(configObject.config, compiler.sys, path_1.default.dirname(args.project), // always resolve to directory of tsconfig provided
undefined, args.project);
if (configParseResult.options.noEmitOnError) {
console.warn(`${warning} No files will be emitted even if errors are suppressed when "compilerOptions.noEmitOnError: true"`);
}
if (args.watch) {
// Only assert config parse errors when watching
assertDiagnostics(configParseResult.errors);
const watchDiagnostics = [];
const watchCompilerHost = compiler.createWatchCompilerHost(args.project, {}, compiler.sys, compiler.createSemanticDiagnosticsBuilderProgram, (diagnostic) => {
// Report diagnostic
watchDiagnostics.push(diagnostic);
}, (diagnostic) => {
// Report watch status
if (diagnostic.code === 6031 || diagnostic.code === 6032) {
// Starting compilation || File change detected
process.stdout.write('\u001b[2J\u001b[0;0H'); // Clear console
watchDiagnostics.length = 0; // Empty the array
assertDiagnostics(diagnostic);
}
else if (diagnostic.code === 6194) {
// Compilation done
watchDiagnostics.push(diagnostic);
assertDiagnostics(watchDiagnostics);
printSuppression(watchDiagnostics.length);
console.log(`${info} Watching for file changes...`);
}
});
compiler.createWatchProgram(watchCompilerHost);
}
else {
// Do not watch the project directory
const program = compiler.createProgram({
rootNames: configParseResult.fileNames,
options: configParseResult.options,
projectReferences: configParseResult.projectReferences,
host: compiler.createCompilerHost(configParseResult.options),
configFileParsingDiagnostics: compiler.getConfigFileParsingDiagnostics(configParseResult),
});
const emitResult = program.emit();
const diagnostics = [...compiler.getPreEmitDiagnostics(program)]; // Shallow copy to remove readonly
if (!emitResult.emitSkipped) {
// Only append emit diagnostics if the emit was successful
diagnostics.push(...emitResult.diagnostics);
}
assertDiagnostics(diagnostics);
printSuppression(diagnostics.length);
}
});
};
//# sourceMappingURL=index.js.map