0
# File System Operations
1
2
Comprehensive file system operations and directory management capabilities integrated with the project structure. Provides seamless integration between TypeScript code manipulation and file system operations.
3
4
## Capabilities
5
6
### Directory Class
7
8
Represents a directory within the project with full manipulation capabilities.
9
10
```typescript { .api }
11
class Directory {
12
/** Get the directory name */
13
getName(): string;
14
15
/** Get the full path */
16
getPath(): string;
17
18
/** Get the base name (same as getName) */
19
getBaseName(): string;
20
21
/** Get the parent directory */
22
getParent(): Directory | undefined;
23
24
/** Get all child directories */
25
getDirectories(): Directory[];
26
27
/** Get a child directory by name */
28
getDirectory(name: string): Directory | undefined;
29
30
/** Get a child directory by name, throwing if not found */
31
getDirectoryOrThrow(name: string): Directory;
32
33
/** Get all source files in this directory */
34
getSourceFiles(): SourceFile[];
35
36
/** Get a source file by name */
37
getSourceFile(name: string): SourceFile | undefined;
38
39
/** Get a source file by name, throwing if not found */
40
getSourceFileOrThrow(name: string): SourceFile;
41
42
/** Create a child directory */
43
createDirectory(name: string): Directory;
44
45
/** Create a source file in this directory */
46
createSourceFile(fileName: string, text?: string, options?: SourceFileCreateOptions): SourceFile;
47
48
/** Add an existing source file to this directory */
49
addSourceFileAtPath(filePath: string): SourceFile;
50
51
/** Add an existing source file to this directory if it exists */
52
addSourceFileAtPathIfExists(filePath: string): SourceFile | undefined;
53
54
/** Add existing source files matching a glob pattern */
55
addSourceFilesAtPaths(fileGlobs: string | string[]): SourceFile[];
56
57
/** Copy this directory to a new location */
58
copy(dirPath: string, options?: DirectoryCopyOptions): Directory;
59
60
/** Move this directory to a new location */
61
move(dirPath: string, options?: DirectoryMoveOptions): Directory;
62
63
/** Delete this directory */
64
delete(): void;
65
66
/** Check if this directory exists on the file system */
67
exists(): boolean;
68
69
/** Check if this directory exists on the file system asynchronously */
70
existsAsync(): Promise<boolean>;
71
72
/** Emit all TypeScript files in this directory */
73
emit(options?: { emitOnlyDtsFiles?: boolean }): Promise<DirectoryEmitResult>;
74
75
/** Emit all TypeScript files in this directory synchronously */
76
emitSync(options?: { emitOnlyDtsFiles?: boolean }): DirectoryEmitResult;
77
78
/** Save all unsaved source files in this directory */
79
save(): Promise<void>;
80
81
/** Save all unsaved source files in this directory synchronously */
82
saveSync(): void;
83
84
/** Get descendants (all nested directories and files) */
85
getDescendants(): (Directory | SourceFile)[];
86
87
/** Get descendant directories */
88
getDescendantDirectories(): Directory[];
89
90
/** Get descendant source files */
91
getDescendantSourceFiles(): SourceFile[];
92
}
93
94
interface DirectoryCopyOptions {
95
/** Whether to overwrite existing files */
96
overwrite?: boolean;
97
98
/** Whether to include directories */
99
includeUntrackedFiles?: boolean;
100
}
101
102
interface DirectoryMoveOptions {
103
/** Whether to overwrite existing files */
104
overwrite?: boolean;
105
}
106
107
interface DirectoryAddOptions {
108
/** Whether to recursively add subdirectories */
109
recursive?: boolean;
110
}
111
```
112
113
### Directory Emit Result
114
115
Result of emitting TypeScript files in a directory.
116
117
```typescript { .api }
118
class DirectoryEmitResult {
119
/** Get all emit results for files in the directory */
120
getEmitResults(): EmitResult[];
121
122
/** Check if any emits were skipped */
123
getEmitSkipped(): boolean;
124
125
/** Get all diagnostics from the emit operation */
126
getDiagnostics(): Diagnostic[];
127
128
/** Get output file paths that were created */
129
getOutputFilePaths(): string[];
130
}
131
```
132
133
### File System Host
134
135
Interface for custom file system implementations.
136
137
```typescript { .api }
138
interface FileSystemHost {
139
/** Check if a file or directory exists */
140
exists(path: string): boolean;
141
142
/** Check if a file or directory exists asynchronously */
143
existsAsync(path: string): Promise<boolean>;
144
145
/** Read a file as text */
146
readFileSync(path: string, encoding?: string): string;
147
148
/** Read a file as text asynchronously */
149
readFile(path: string, encoding?: string): Promise<string>;
150
151
/** Write text to a file */
152
writeFileSync(path: string, data: string): void;
153
154
/** Write text to a file asynchronously */
155
writeFile(path: string, data: string): Promise<void>;
156
157
/** Create a directory */
158
mkdirSync(path: string): void;
159
160
/** Create a directory asynchronously */
161
mkdir(path: string): Promise<void>;
162
163
/** Delete a file or directory */
164
deleteSync(path: string): void;
165
166
/** Delete a file or directory asynchronously */
167
delete(path: string): Promise<void>;
168
169
/** Get directory entries */
170
readDirSync(path: string): RuntimeDirEntry[];
171
172
/** Copy a file */
173
copySync(srcPath: string, destPath: string): void;
174
175
/** Copy a file asynchronously */
176
copy(srcPath: string, destPath: string): Promise<void>;
177
178
/** Move a file */
179
moveSync(srcPath: string, destPath: string): void;
180
181
/** Move a file asynchronously */
182
move(srcPath: string, destPath: string): Promise<void>;
183
184
/** Get file or directory stats */
185
statSync(path: string): StatSync;
186
187
/** Get file or directory stats asynchronously */
188
stat(path: string): Promise<Stat>;
189
190
/** Resolve a path */
191
realPathSync(path: string): string;
192
193
/** Get current working directory */
194
getCurrentDirectory(): string;
195
196
/** Get the path separator */
197
getPathSeparator(): string;
198
}
199
200
interface RuntimeDirEntry {
201
name: string;
202
isFile(): boolean;
203
isDirectory(): boolean;
204
isSymlink(): boolean;
205
}
206
207
interface StatSync {
208
isFile(): boolean;
209
isDirectory(): boolean;
210
size: number;
211
mtimeMs: number;
212
}
213
214
interface Stat {
215
isFile(): boolean;
216
isDirectory(): boolean;
217
size: number;
218
mtimeMs: number;
219
}
220
```
221
222
### In-Memory File System
223
224
Built-in in-memory file system implementation for testing and virtual file operations.
225
226
```typescript { .api }
227
class InMemoryFileSystemHost implements FileSystemHost {
228
/** Create a new in-memory file system */
229
constructor();
230
231
/** Get all files and directories in memory */
232
getFiles(): { path: string; text: string }[];
233
234
/** Clear all files and directories */
235
clear(): void;
236
237
/** Get a file's text content */
238
getFileText(path: string): string;
239
240
/** Check if path is a directory */
241
isDirectory(path: string): boolean;
242
243
/** Check if path is a file */
244
isFile(path: string): boolean;
245
246
// ... implements all FileSystemHost methods
247
}
248
```
249
250
### Source File Operations
251
252
Extended file operations available on SourceFile instances.
253
254
```typescript { .api }
255
interface SourceFileCopyOptions {
256
/** Whether to overwrite if the target exists */
257
overwrite?: boolean;
258
}
259
260
interface SourceFileMoveOptions {
261
/** Whether to overwrite if the target exists */
262
overwrite?: boolean;
263
}
264
265
// Additional SourceFile methods for file system operations
266
class SourceFile extends Node {
267
/** Get the directory containing this source file */
268
getDirectory(): Directory;
269
270
/** Get the directory path */
271
getDirectoryPath(): string;
272
273
/** Check if the file is in a node_modules directory */
274
isInNodeModules(): boolean;
275
276
/** Check if this is a declaration file (.d.ts) */
277
isDeclarationFile(): boolean;
278
279
/** Check if the file has been modified */
280
isModified(): boolean;
281
282
/** Get the last modified time */
283
getModifiedTime(): Date;
284
285
/** Refresh from file system */
286
refreshFromFileSystemSync(): this;
287
288
/** Refresh from file system asynchronously */
289
refreshFromFileSystem(): Promise<this>;
290
291
/** Get referenced files */
292
getReferencedFiles(): SourceFile[];
293
294
/** Get files that reference this file */
295
getReferencingSourceFiles(): SourceFile[];
296
297
/** Get files that reference this file (including library files) */
298
getReferencingNodesInOtherSourceFiles(): SourceFileReferencingNodes[];
299
300
/** Get the relative path from another source file */
301
getRelativePathTo(sourceFile: SourceFile): string;
302
303
/** Get the relative path from a directory */
304
getRelativePathToDirectory(directory: Directory): string;
305
}
306
307
interface SourceFileReferencingNodes {
308
sourceFile: SourceFile;
309
nodes: Node[];
310
}
311
```
312
313
**Usage Examples:**
314
315
```typescript
316
import { Project, InMemoryFileSystemHost } from "ts-morph";
317
318
// Working with the default file system
319
const project = new Project();
320
321
// Add a directory
322
const srcDir = project.createDirectory("src");
323
const utilsDir = srcDir.createDirectory("utils");
324
325
// Create files in directories
326
const indexFile = srcDir.createSourceFile("index.ts", `
327
export { Logger } from './utils/logger';
328
export { Calculator } from './utils/calculator';
329
`);
330
331
const loggerFile = utilsDir.createSourceFile("logger.ts", `
332
export class Logger {
333
log(message: string): void {
334
console.log(message);
335
}
336
}
337
`);
338
339
const calculatorFile = utilsDir.createSourceFile("calculator.ts", `
340
export class Calculator {
341
add(a: number, b: number): number {
342
return a + b;
343
}
344
345
multiply(a: number, b: number): number {
346
return a * b;
347
}
348
}
349
`);
350
351
// Work with directories
352
console.log("Source directory name:", srcDir.getName());
353
console.log("Source directory path:", srcDir.getPath());
354
355
// Get files and subdirectories
356
const srcFiles = srcDir.getSourceFiles();
357
console.log("Files in src:", srcFiles.map(f => f.getBaseName()));
358
359
const subdirs = srcDir.getDirectories();
360
console.log("Subdirectories:", subdirs.map(d => d.getName()));
361
362
// Get all descendant files
363
const allFiles = srcDir.getDescendantSourceFiles();
364
console.log("All files recursively:", allFiles.map(f => f.getBaseName()));
365
366
// File operations
367
const backupDir = project.createDirectory("backup");
368
loggerFile.copy("backup/logger-backup.ts");
369
370
// Directory operations
371
const utilsCopy = utilsDir.copy("src/utils-backup");
372
console.log("Copied utils to:", utilsCopy.getPath());
373
374
// Save all files
375
project.saveSync();
376
377
// Emit TypeScript files
378
const emitResult = await srcDir.emit();
379
console.log("Emit successful:", !emitResult.getEmitSkipped());
380
console.log("Output files:", emitResult.getOutputFilePaths());
381
```
382
383
**Working with In-Memory File System:**
384
385
```typescript
386
import { Project, InMemoryFileSystemHost } from "ts-morph";
387
388
// Create project with in-memory file system
389
const fileSystem = new InMemoryFileSystemHost();
390
const project = new Project({
391
fileSystem,
392
useInMemoryFileSystem: true,
393
});
394
395
// Create virtual files
396
const sourceFile = project.createSourceFile("/virtual/app.ts", `
397
class VirtualApp {
398
run(): void {
399
console.log('Running in memory!');
400
}
401
}
402
`);
403
404
// Work with virtual directories
405
const virtualDir = project.createDirectory("/virtual");
406
const configFile = virtualDir.createSourceFile("config.ts", `
407
export const config = {
408
port: 3000,
409
host: 'localhost'
410
};
411
`);
412
413
// Check file system state
414
console.log("Virtual files:", fileSystem.getFiles());
415
416
// The files exist only in memory
417
console.log("App file exists:", fileSystem.exists("/virtual/app.ts"));
418
console.log("App file content:", fileSystem.getFileText("/virtual/app.ts"));
419
420
// Clear the virtual file system
421
fileSystem.clear();
422
console.log("Files after clear:", fileSystem.getFiles());
423
```
424
425
**Advanced File System Operations:**
426
427
```typescript
428
import { Project } from "ts-morph";
429
430
const project = new Project();
431
432
// Add files from glob patterns
433
const srcDir = project.createDirectory("src");
434
srcDir.addSourceFilesAtPaths(["**/*.ts", "!**/*.test.ts"]);
435
436
// Get file relationships
437
const indexFile = srcDir.getSourceFile("index.ts");
438
if (indexFile) {
439
// Get files that this file references
440
const referenced = indexFile.getReferencedFiles();
441
console.log("Referenced files:", referenced.map(f => f.getFilePath()));
442
443
// Get files that reference this file
444
const referencing = indexFile.getReferencingSourceFiles();
445
console.log("Files referencing index:", referencing.map(f => f.getFilePath()));
446
447
// Get relative paths
448
const utilsFile = srcDir.getSourceFile("utils/helper.ts");
449
if (utilsFile) {
450
const relativePath = indexFile.getRelativePathTo(utilsFile);
451
console.log("Relative path to utils:", relativePath);
452
}
453
}
454
455
// Monitor file changes
456
const watchedFile = srcDir.getSourceFile("watched.ts");
457
if (watchedFile) {
458
const initialModTime = watchedFile.getModifiedTime();
459
460
// Modify the file
461
watchedFile.addClass({ name: "NewClass" });
462
463
// Check if modified
464
console.log("File is modified:", watchedFile.isModified());
465
console.log("Modified time changed:",
466
watchedFile.getModifiedTime() > initialModTime);
467
}
468
469
// Batch operations on directories
470
const testDir = project.createDirectory("tests");
471
472
// Create multiple test files
473
const testFiles = [
474
"user.test.ts",
475
"auth.test.ts",
476
"api.test.ts"
477
].map(name => testDir.createSourceFile(name, `
478
describe('${name.replace('.test.ts', '')}', () => {
479
test('should work', () => {
480
expect(true).toBe(true);
481
});
482
});
483
`));
484
485
// Save all test files at once
486
await testDir.save();
487
488
// Emit only declaration files
489
const emitResult = await testDir.emit({ emitOnlyDtsFiles: true });
490
console.log("Declaration files emitted:", emitResult.getOutputFilePaths());
491
```