Skip to content
File

Blob: types/src/program.ts

typescript80 lines
1// Copyright (c) 2022-2023 Cloudflare, Inc.
2// Licensed under the Apache 2.0 license found in the LICENSE file or at:
3// https://opensource.org/licenses/Apache-2.0
4 
5import assert from "node:assert";
6import ts from "typescript";
7 
8export const SourcesMap = Map<string, string>;
9export type SourcesMap = InstanceType<typeof SourcesMap>;
10 
11const defaultCompilerOpts = ts.getDefaultCompilerOptions();
12 
13// Creates a TypeScript program from in-memory source files. Accepts a Map of
14// fully-resolved "virtual" paths to source code.
15export function createMemoryProgram(
16 sources: SourcesMap,
17 host?: ts.CompilerHost,
18 compilerOpts = defaultCompilerOpts,
19 // Provide additional lib files to TypeScript. These should all be prefixed with
20 // `/node_modules/typescript/lib` (e.g. `/node_modules/typescript/lib/lib.esnext.d.ts`)
21 lib?: SourcesMap
22): ts.Program {
23 const sourceFiles = new Map<string, ts.SourceFile>();
24 for (const [sourcePath, source] of [...sources, ...(lib ?? [])]) {
25 const sourceFile = ts.createSourceFile(
26 sourcePath,
27 source,
28 ts.ScriptTarget.ESNext,
29 false,
30 ts.ScriptKind.TS
31 );
32 sourceFiles.set(sourcePath, sourceFile);
33 }
34 
35 host ??= {
36 getCurrentDirectory(): string {
37 return "/";
38 },
39 getCanonicalFileName(fileName: string): string {
40 return fileName;
41 },
42 getDefaultLibFileName(_options: ts.CompilerOptions): string {
43 return "";
44 },
45 getDefaultLibLocation(): string {
46 return "/node_modules/typescript/lib";
47 },
48 getNewLine(): string {
49 return "\n";
50 },
51 useCaseSensitiveFileNames(): boolean {
52 return true;
53 },
54 fileExists(fileName: string): boolean {
55 return sourceFiles.has(fileName);
56 },
57 readFile(_path: string): string | undefined {
58 assert.fail("readFile() not implemented");
59 },
60 writeFile(
61 _path: string,
62 _data: string,
63 _writeByteOrderMark?: boolean
64 ): void {
65 assert.fail("writeFile() not implemented");
66 },
67 getSourceFile(
68 fileName: string,
69 _languageVersionOrOptions: ts.ScriptTarget | ts.CreateSourceFileOptions,
70 _onError?: (message: string) => void,
71 _shouldCreateNewSourceFile?: boolean
72 ): ts.SourceFile | undefined {
73 return sourceFiles.get(fileName);
74 },
75 };
76 
77 const rootNames = Array.from(sources.keys());
78 return ts.createProgram(rootNames, compilerOpts, host);
79}