UNPKG

genaiscript

Version:

A CLI for GenAIScript, a generative AI scripting framework.

104 lines 4.97 kB
// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. // This file contains functions to manage and compile project scripts, // including listing, creating, fixing, and compiling scripts. import { buildProject, genaiscriptDebug } from "@genaiscript/core"; import { RUNTIME_ERROR_CODE, collectFolders, fixPromptDefinitions, logInfo, resolveRuntimeHost, logVerbose, } from "@genaiscript/core"; import { resolve } from "node:path"; const dbg = genaiscriptDebug("compile"); /** * Compiles scripts in specified folders or all if none specified. * Fixes prompt definitions before compiling. * Handles both JavaScript and TypeScript compilation based on folder content. * Logs errors and verbose output during the compilation process. * Exits process with error code if any compilation fails. * * @param folders - An array of folder names to compile. If empty, compiles all available script folders. */ export async function compileScript(folders) { const runtimeHost = resolveRuntimeHost(); const project = await buildProject(); await fixPromptDefinitions(project); const scriptFolders = collectFolders(project); const foldersToCompile = (folders?.length ? folders : scriptFolders.map((f) => f.dirname)) .map((f) => scriptFolders.find((sf) => sf.dirname === f)) .filter((f) => f); if (!foldersToCompile.length) return; const ts = await import("typescript"); let errors = 0; for (const folder of foldersToCompile) { const { dirname, js, ts: isTypeScript } = folder; if (js) { logInfo(`compiling ${dirname}/*.js`); const configPath = resolve(dirname, "jsconfig.json"); const config = ts.readConfigFile(configPath, ts.sys.readFile); if (config.error) { logInfo(config.error.messageText.toString()); errors++; continue; } const parsed = ts.parseJsonConfigFileContent(config.config, ts.sys, dirname); if (parsed.errors.length > 0) { parsed.errors.forEach((error) => logInfo(error.messageText.toString())); errors++; continue; } parsed.options.noEmit = true; dbg(`config: %O`, parsed); const program = ts.createProgram(parsed.fileNames, parsed.options); const emitResult = program.emit(); const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); allDiagnostics.forEach((diagnostic) => { if (diagnostic.file) { const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); logVerbose(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { logVerbose(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")); } }); if (emitResult.emitSkipped) { errors++; } } if (isTypeScript) { logInfo(`compiling ${dirname}/*.{mjs,.mts}`); const configPath = resolve(dirname, "tsconfig.json"); const config = ts.readConfigFile(configPath, ts.sys.readFile); if (config.error) { logVerbose(config.error.messageText.toString()); errors++; continue; } const parsed = ts.parseJsonConfigFileContent(config.config, ts.sys, dirname); if (parsed.errors.length > 0) { parsed.errors.forEach((error) => logVerbose(error.messageText.toString())); errors++; continue; } parsed.options.noEmit = true; dbg(`config: %O`, parsed); const program = ts.createProgram(parsed.fileNames, parsed.options); const emitResult = program.emit(); const allDiagnostics = ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics); allDiagnostics.forEach((diagnostic) => { if (diagnostic.file) { const { line, character } = ts.getLineAndCharacterOfPosition(diagnostic.file, diagnostic.start); const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n"); logVerbose(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { logVerbose(ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")); } }); if (emitResult.emitSkipped) { errors++; } } } if (errors) process.exit(RUNTIME_ERROR_CODE); } //# sourceMappingURL=typescript.js.map