1import * as fs from "node:fs/promises";
2import * as os from "node:os";
3import * as path from "node:path";
4import { API, formatDiagnostics } from "typescript-api/unstable/async";
5
6/** Native syntax-only project: don't load imports, libraries, or inferred types. */
7export async function createSyntaxProject(files: readonly string[]) {
8 const directory = await fs.mkdtemp(
9 path.join(os.tmpdir(), "alchemy-typescript-"),
10 );
11 const configPath = path.join(directory, "tsconfig.json");
12 await fs.writeFile(
13 configPath,
14 JSON.stringify({
15 files,
16 compilerOptions: {
17 noResolve: true,
18 noLib: true,
19 types: [],
20 jsx: "preserve",
21 },
22 }),
23 );
24 const api = new API();
25 try {
26 const snapshot = await api.updateSnapshot({ openProjects: [configPath] });
27 const project = snapshot.getProject(configPath);
28 if (!project)
29 throw new Error(`Failed to open syntax project ${configPath}`);
30 const diagnostics = await project.program.getSyntacticDiagnostics();
31 if (diagnostics.length)
32 throw new Error(formatDiagnostics(diagnostics, api));
33 return {
34 api,
35 project,
36 async [Symbol.asyncDispose]() {
37 try {
38 await api.close();
39 } finally {
40 await fs.rm(directory, { recursive: true, force: true });
41 }
42 },
43 };
44 } catch (error) {
45 try {
46 await api.close();
47 } finally {
48 await fs.rm(directory, { recursive: true, force: true });
49 }
50 throw error;
51 }
52}