Created
November 10, 2024 11:03
-
-
Save hasenj/2c61559b43ba284ba981bfd80c3ac0ba to your computer and use it in GitHub Desktop.
nodejs script to run a watch mode typescript checker that can optionally output to json for consumption by other programs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Generated by Claude | |
// Some details hand tuned | |
import fs from 'fs' | |
import ts from 'typescript'; | |
import path from 'path'; | |
function getConfig() { | |
const args = process.argv.slice(2); | |
const jsonIndex = args.indexOf('--json'); | |
const useJson = jsonIndex !== -1; | |
const paths = args.filter((arg, i) => !arg.startsWith('--') && i !== jsonIndex + 1); | |
if (paths.length === 0) { | |
paths.push('.'); | |
} | |
const invalidPaths = paths.filter(p => !fs.existsSync(p)); | |
if (invalidPaths.length > 0) { | |
console.error('Invalid paths:', invalidPaths.join(', ')); | |
process.exit(1); | |
} | |
return { paths, useJson }; | |
} | |
const { paths, useJson } = getConfig(); | |
let cwd = process.cwd() | |
function watchProgram(rootFiles) { | |
const configPath = ts.findConfigFile(cwd, ts.sys.fileExists, "tsconfig.json"); | |
if (!configPath) throw new Error("tsconfig.json not found"); | |
const host = ts.createWatchCompilerHost( | |
configPath, | |
{ noEmit: true }, | |
ts.sys, | |
ts.createSemanticDiagnosticsBuilderProgram, | |
reportDiagnostic, | |
reportWatchStatus, | |
); | |
ts.createWatchProgram(host); | |
} | |
function categoryLabel(category) { | |
switch (category) { | |
case 0: return "warning" | |
case 1: return "error" | |
case 2: return "suggestion" | |
case 3: return "message" | |
} | |
} | |
function reportDiagnostic(diagnostic) { | |
if (!diagnostic.file) return; | |
const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); | |
const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); | |
let category = categoryLabel(diagnostic.category) | |
let time = formatDate(new Date()) | |
let fileName = path.relative(cwd, diagnostic.file.fileName) | |
if (diagnostic.category === 1) { // error | |
if (useJson) { | |
console.log(JSON.stringify({ | |
time, | |
category, | |
fileName, | |
line: line+1, | |
character: character+1, | |
code: diagnostic.code, | |
message, | |
})) | |
} else { | |
console.log(`${time} ${category} TS${diagnostic.code} ${fileName}:${line+1}:${character+1}`); | |
console.log(message) | |
} | |
} | |
} | |
// Generated by Claude | |
function formatDate(date) { | |
const pad = n => n.toString().padStart(2, '0'); | |
const year = date.getFullYear(); | |
const month = pad(date.getMonth() + 1); | |
const day = pad(date.getDate()); | |
const hour = pad(date.getHours()); | |
const minute = pad(date.getMinutes()); | |
const second = pad(date.getSeconds()); | |
return `${year}-${month}-${day} ${hour}:${minute}:${second}`; | |
} | |
function reportWatchStatus(diagnostic) { | |
/* | |
if (useJson) { | |
console.log("{}") | |
} else { | |
console.log("----", formatDate(new Date())) | |
} | |
*/ | |
} | |
watchProgram(paths); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment