fcis 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/.plans/001-fcis-analyzer.md +832 -0
  2. package/.plans/002-fcis-analyzer-improvements.md +205 -0
  3. package/README.md +272 -0
  4. package/TECHNICAL.md +386 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +1836 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/index.d.ts +709 -0
  9. package/dist/index.js +1845 -0
  10. package/dist/index.js.map +1 -0
  11. package/package.json +47 -0
  12. package/pnpm-workspace.yaml +0 -0
  13. package/src/analyzer.ts +266 -0
  14. package/src/classification/classifier.ts +156 -0
  15. package/src/classification/derive-status.ts +171 -0
  16. package/src/classification/quality-scorer.ts +481 -0
  17. package/src/cli.ts +286 -0
  18. package/src/detection/detect-markers.ts +480 -0
  19. package/src/detection/markers.ts +332 -0
  20. package/src/extraction/extract-functions.ts +570 -0
  21. package/src/extraction/extractor.ts +188 -0
  22. package/src/index.ts +111 -0
  23. package/src/reporting/report-console.ts +416 -0
  24. package/src/reporting/report-json.ts +232 -0
  25. package/src/scoring/scorer.ts +504 -0
  26. package/src/types.ts +248 -0
  27. package/tests/classifier.test.ts +480 -0
  28. package/tests/derive-status.test.ts +464 -0
  29. package/tests/detect-markers.test.ts +639 -0
  30. package/tests/extractor.test.ts +155 -0
  31. package/tests/integration.test.ts +706 -0
  32. package/tests/quality-scorer.test.ts +650 -0
  33. package/tests/scorer.test.ts +768 -0
  34. package/tsconfig.json +34 -0
  35. package/tsup.config.ts +17 -0
  36. package/vendor/ts-morph/.editorconfig +10 -0
  37. package/vendor/ts-morph/.gitattributes +11 -0
  38. package/vendor/ts-morph/.github/CODE_OF_CONDUCT.md +77 -0
  39. package/vendor/ts-morph/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  40. package/vendor/ts-morph/.github/ISSUE_TEMPLATE/custom.md +4 -0
  41. package/vendor/ts-morph/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
  42. package/vendor/ts-morph/.github/workflows/ci.yml +50 -0
  43. package/vendor/ts-morph/.github/workflows/publish.yml +53 -0
  44. package/vendor/ts-morph/.vscode/settings.json +10 -0
  45. package/vendor/ts-morph/CONTRIBUTING.md +23 -0
  46. package/vendor/ts-morph/DEVELOPMENT.md +32 -0
  47. package/vendor/ts-morph/LICENSE +21 -0
  48. package/vendor/ts-morph/deno.json +8 -0
  49. package/vendor/ts-morph/deno.lock +1233 -0
  50. package/vendor/ts-morph/docs/CNAME +1 -0
  51. package/vendor/ts-morph/docs/Gemfile +2 -0
  52. package/vendor/ts-morph/docs/_config.yml +5 -0
  53. package/vendor/ts-morph/docs/_layouts/default.html +159 -0
  54. package/vendor/ts-morph/docs/_script-templates/main.ts +116 -0
  55. package/vendor/ts-morph/docs/assets/css/style.scss +212 -0
  56. package/vendor/ts-morph/docs/details/ambient.md +38 -0
  57. package/vendor/ts-morph/docs/details/async.md +31 -0
  58. package/vendor/ts-morph/docs/details/classes.md +314 -0
  59. package/vendor/ts-morph/docs/details/comment-ranges.md +7 -0
  60. package/vendor/ts-morph/docs/details/comments.md +122 -0
  61. package/vendor/ts-morph/docs/details/decorators.md +119 -0
  62. package/vendor/ts-morph/docs/details/documentation.md +73 -0
  63. package/vendor/ts-morph/docs/details/enums.md +117 -0
  64. package/vendor/ts-morph/docs/details/exports.md +308 -0
  65. package/vendor/ts-morph/docs/details/expressions.md +46 -0
  66. package/vendor/ts-morph/docs/details/functions.md +150 -0
  67. package/vendor/ts-morph/docs/details/generators.md +27 -0
  68. package/vendor/ts-morph/docs/details/identifiers.md +79 -0
  69. package/vendor/ts-morph/docs/details/imports.md +191 -0
  70. package/vendor/ts-morph/docs/details/index.md +52 -0
  71. package/vendor/ts-morph/docs/details/initializers.md +40 -0
  72. package/vendor/ts-morph/docs/details/interfaces.md +218 -0
  73. package/vendor/ts-morph/docs/details/literals.md +20 -0
  74. package/vendor/ts-morph/docs/details/modifiers.md +38 -0
  75. package/vendor/ts-morph/docs/details/modules.md +113 -0
  76. package/vendor/ts-morph/docs/details/namespaces.md +7 -0
  77. package/vendor/ts-morph/docs/details/object-literal-expressions.md +106 -0
  78. package/vendor/ts-morph/docs/details/parameters.md +64 -0
  79. package/vendor/ts-morph/docs/details/signatures.md +41 -0
  80. package/vendor/ts-morph/docs/details/source-files.md +292 -0
  81. package/vendor/ts-morph/docs/details/type-aliases.md +34 -0
  82. package/vendor/ts-morph/docs/details/type-parameters.md +72 -0
  83. package/vendor/ts-morph/docs/details/types.md +254 -0
  84. package/vendor/ts-morph/docs/details/variables.md +110 -0
  85. package/vendor/ts-morph/docs/emitting.md +151 -0
  86. package/vendor/ts-morph/docs/index.md +25 -0
  87. package/vendor/ts-morph/docs/manipulation/code-writer.md +20 -0
  88. package/vendor/ts-morph/docs/manipulation/formatting.md +76 -0
  89. package/vendor/ts-morph/docs/manipulation/index.md +136 -0
  90. package/vendor/ts-morph/docs/manipulation/order.md +14 -0
  91. package/vendor/ts-morph/docs/manipulation/performance.md +222 -0
  92. package/vendor/ts-morph/docs/manipulation/removing.md +31 -0
  93. package/vendor/ts-morph/docs/manipulation/renaming.md +106 -0
  94. package/vendor/ts-morph/docs/manipulation/settings.md +76 -0
  95. package/vendor/ts-morph/docs/manipulation/structures.md +117 -0
  96. package/vendor/ts-morph/docs/manipulation/transforms.md +84 -0
  97. package/vendor/ts-morph/docs/metrics/performance.json +4 -0
  98. package/vendor/ts-morph/docs/navigation/ambient-modules.md +22 -0
  99. package/vendor/ts-morph/docs/navigation/compiler-nodes.md +82 -0
  100. package/vendor/ts-morph/docs/navigation/directories.md +287 -0
  101. package/vendor/ts-morph/docs/navigation/example.md +50 -0
  102. package/vendor/ts-morph/docs/navigation/finding-references.md +53 -0
  103. package/vendor/ts-morph/docs/navigation/getting-source-files.md +59 -0
  104. package/vendor/ts-morph/docs/navigation/images/getChildrenVsForEachChild.gif +0 -0
  105. package/vendor/ts-morph/docs/navigation/index.md +94 -0
  106. package/vendor/ts-morph/docs/navigation/language-service.md +23 -0
  107. package/vendor/ts-morph/docs/navigation/program.md +25 -0
  108. package/vendor/ts-morph/docs/navigation/type-checker.md +33 -0
  109. package/vendor/ts-morph/docs/setup/adding-source-files.md +145 -0
  110. package/vendor/ts-morph/docs/setup/ast-viewers.md +46 -0
  111. package/vendor/ts-morph/docs/setup/diagnostics.md +109 -0
  112. package/vendor/ts-morph/docs/setup/file-system.md +106 -0
  113. package/vendor/ts-morph/docs/setup/images/atom-ast.png +0 -0
  114. package/vendor/ts-morph/docs/setup/images/atom-ast_small.png +0 -0
  115. package/vendor/ts-morph/docs/setup/images/atom-command-palette.png +0 -0
  116. package/vendor/ts-morph/docs/setup/images/atom-file.png +0 -0
  117. package/vendor/ts-morph/docs/setup/images/ts-ast-viewer.png +0 -0
  118. package/vendor/ts-morph/docs/setup/index.md +94 -0
  119. package/vendor/ts-morph/docs/utilities.md +55 -0
  120. package/vendor/ts-morph/dprint.json +23 -0
  121. package/vendor/ts-morph/package.json +30 -0
  122. package/vendor/ts-morph/packages/bootstrap/LICENSE +21 -0
  123. package/vendor/ts-morph/packages/bootstrap/lib/ts-morph-bootstrap.d.ts +397 -0
  124. package/vendor/ts-morph/packages/bootstrap/package.json +46 -0
  125. package/vendor/ts-morph/packages/bootstrap/readme.md +200 -0
  126. package/vendor/ts-morph/packages/common/LICENSE +21 -0
  127. package/vendor/ts-morph/packages/common/lib/ts-morph-common.d.ts +1082 -0
  128. package/vendor/ts-morph/packages/common/lib/typescript.d.ts +11439 -0
  129. package/vendor/ts-morph/packages/common/package.json +65 -0
  130. package/vendor/ts-morph/packages/common/readme.md +5 -0
  131. package/vendor/ts-morph/packages/scripts/changeTypeScriptVersion.ts +28 -0
  132. package/vendor/ts-morph/packages/scripts/createDeclarationProject.ts +47 -0
  133. package/vendor/ts-morph/packages/scripts/deps.ts +2 -0
  134. package/vendor/ts-morph/packages/scripts/execScript.ts +31 -0
  135. package/vendor/ts-morph/packages/scripts/folders.ts +11 -0
  136. package/vendor/ts-morph/packages/scripts/getDevCompilerVersions.ts +19 -0
  137. package/vendor/ts-morph/packages/scripts/mod.ts +7 -0
  138. package/vendor/ts-morph/packages/scripts/utils/Memoize.ts +36 -0
  139. package/vendor/ts-morph/packages/scripts/utils/forEachTypeText.ts +23 -0
  140. package/vendor/ts-morph/packages/scripts/utils/makeConstructorsPrivate.ts +26 -0
  141. package/vendor/ts-morph/packages/scripts/utils/mod.ts +4 -0
  142. package/vendor/ts-morph/packages/scripts/utils/printDiagnostics.ts +10 -0
  143. package/vendor/ts-morph/packages/ts-morph/LICENSE +21 -0
  144. package/vendor/ts-morph/packages/ts-morph/lib/ts-morph.d.ts +11198 -0
  145. package/vendor/ts-morph/packages/ts-morph/package.json +78 -0
  146. package/vendor/ts-morph/packages/ts-morph/readme.md +111 -0
  147. package/vendor/ts-morph/readme.md +14 -0
  148. package/vendor/ts-morph/rfcs/README.md +13 -0
  149. package/vendor/ts-morph/rfcs/RFC-0001 - Inserting Into Statements Handling Comments.md +181 -0
  150. package/vendor/ts-morph/tsconfig.common.json +17 -0
  151. package/vitest.config.ts +16 -0
@@ -0,0 +1,84 @@
1
+ ---
2
+ title: Transforms
3
+ ---
4
+
5
+ ## Transforms
6
+
7
+ It is possible to transform the AST using the compiler API, though this is not a typical scenario.
8
+
9
+ For example:
10
+
11
+ ```ts
12
+ import { ts } from "ts-morph";
13
+
14
+ const project = new Project();
15
+ const sourceFile = project.createSourceFile("Example.ts", "1; 2; 3;");
16
+
17
+ // this can be done starting on any node and not just the root node
18
+ sourceFile.transform(traversal => {
19
+ const node = traversal.visitChildren(); // return type is `ts.Node`
20
+
21
+ if (ts.isNumericLiteral(node)) {
22
+ const incrementedValue = parseInt(node.text, 10) + 1;
23
+ return traversal.factory.createNumericLiteral(incrementedValue.toString());
24
+ }
25
+
26
+ return node;
27
+ });
28
+
29
+ // outputs: 2; 3; 4;
30
+ console.log(sourceFile.getFullText());
31
+ ```
32
+
33
+ Doing this is more performant, but you won't have type checking, symbols, and you'll be dealing directly with the TypeScript compiler API nodes. Additionally, all previously wrapped descendant nodes of transformed nodes will be forgotten (using them will result in an error being thrown).
34
+
35
+ ### Conditionally visiting children
36
+
37
+ ```ts
38
+ import { ts } from "ts-morph";
39
+
40
+ const project = new Project();
41
+ const sourceFile = project.createSourceFile(
42
+ "Example.ts",
43
+ `
44
+ class C1 {
45
+ myMethod() {
46
+ function nestedFunction() {
47
+ }
48
+ }
49
+ }
50
+
51
+ class C2 {
52
+ prop1: string;
53
+ }
54
+
55
+ function f1() {
56
+ console.log("1");
57
+
58
+ function nestedFunction() {
59
+ }
60
+ }`,
61
+ );
62
+
63
+ sourceFile.transform(traversal => {
64
+ // this will skip visiting the children of the classes
65
+ if (ts.isClassDeclaration(traversal.currentNode))
66
+ return traversal.currentNode;
67
+
68
+ const node = traversal.visitChildren();
69
+ if (ts.isFunctionDeclaration(node)) {
70
+ return traversal.factory.updateFunctionDeclaration(
71
+ node,
72
+ [],
73
+ [],
74
+ undefined,
75
+ traversal.factory.createIdentifier("newName"),
76
+ [],
77
+ [],
78
+ undefined,
79
+ traversal.factory.createBlock([]),
80
+ );
81
+ }
82
+ return node;
83
+ });
84
+ ```
@@ -0,0 +1,4 @@
1
+ {
2
+ "1": { "name": "Renaming Performance Test", "runs": [{ "dateTime": 1555118846870, "duration": 10905, "version": "1.3.2" }] },
3
+ "2": { "name": "Removing Performance Test", "runs": [{ "dateTime": 1555118846870, "duration": 14834, "version": "1.3.2" }] }
4
+ }
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: Ambient Modules
3
+ ---
4
+
5
+ ## Ambient Modules
6
+
7
+ The ambient module symbols can be retrieved by calling:
8
+
9
+ ```ts
10
+ const ambientModules = project.getAmbientModules();
11
+ ```
12
+
13
+ This will return the ambient modules resolved by the compiler (ex. ambient modules in `@types` or `node_modules`).
14
+
15
+ ### Getting by name
16
+
17
+ Get an ambient module symbol based on its name:
18
+
19
+ ```ts
20
+ const jQuerySymbol = project.getAmbientModule("jquery"); // returns: Symbol | undefined
21
+ const momentSymbol = project.getAmbientModuleOrThrow("moment"); // returns: Symbol
22
+ ```
@@ -0,0 +1,82 @@
1
+ ---
2
+ title: Underlying Compiler Nodes
3
+ ---
4
+
5
+ ## Underlying Compiler Nodes
6
+
7
+ Sometimes it might be useful to get the node from the TypeScript compiler.
8
+
9
+ They're accessible via the `.compilerNode` property that's found on all node objects:
10
+
11
+ ```ts
12
+ const compilerNode = interfaceDeclaration.compilerNode;
13
+ ```
14
+
15
+ **Warning:** When manipulating the AST via this library, the underlying TypeScript AST tree is regenerated each time. For this reason, it's important not
16
+ to hold on to TypeScript compiler nodes between manipulations or you could end up working with out of date information.
17
+
18
+ ### Compiler node properties
19
+
20
+ Sometimes there isn't a helper function in this library for accessing certain properties on the underlying compiler node.
21
+
22
+ In these situations, you can access any underlying compiler node property by using the `.getNodeProperty(propName)` method:
23
+
24
+ ```ts
25
+ const nameNode = propertyAccessExpression.getNodeProperty("name"); // returns: PropertyName
26
+ // also works with arrays and possibly undefined properties
27
+ const typeParameters = classDeclaration.getNodeProperty("typeParameters"); // returns: TypeParameterDeclaration[] | undefined
28
+ ```
29
+
30
+ ...and then please open an issue so that I can implement something I forgot to implement.
31
+
32
+ ## Navigating Existing Compiler Nodes
33
+
34
+ Sometimes you might want to easily navigate an existing compiler node.
35
+
36
+ Do that by using the `createWrappedNode` function:
37
+
38
+ ```ts ignore-error: 1109
39
+ import { createWrappedNode, ClassDeclaration, ts, SyntaxKind } from "ts-morph";
40
+
41
+ // some code that creates a class declaration using the ts object
42
+ const classNode: ts.ClassDeclaration = ...;
43
+
44
+ // create and use a wrapped node
45
+ const classDec = createWrappedNode(classNode).asKindOrThrow(SyntaxKind.ClassDeclaration);
46
+ const firstProperty = classDec.getProperties()[0];
47
+
48
+ // ... do more stuff here ...
49
+ ```
50
+
51
+ **Note:** This is a lightweight way to navigate a node, but there are certian functionalities which will throw an error since there is no
52
+ language service, type checker, or program. For example, finding references will not work because that requires a language service.
53
+
54
+ ### Providing Type Checker
55
+
56
+ If you would like to easily get the type information of the types in the provided source file, then provide a type checker:
57
+
58
+ ```ts ignore-error: 1109
59
+ // given an existing node and type checker
60
+ const classNode: ts.ClassDeclaration = ...;
61
+ const compilerTypeChecker: ts.TypeChecker = ...;
62
+
63
+ // create and use a wrapped node
64
+ const classDec = createWrappedNode(classNode, { typeChecker: compilerTypeChecker }).asKindOrThrow(SyntaxKind.ClassDeclaration);
65
+ console.log(classDec.getPropertyOrThrow("propName").getType().getText()); // ok, because a type checker was provided
66
+ ```
67
+
68
+ ### Important: Using both the TypeScript API and ts-morph
69
+
70
+ It is highly recommended to always use the `ts` named export from ts-morph when
71
+ needing to use the TypeScript Compiler API and ts-morph at the same time:
72
+
73
+ ```ts
74
+ // do this
75
+ import { ts } from "ts-morph";
76
+ // not this
77
+ import * as ts from "typescript";
78
+ ```
79
+
80
+ They're almost identical and the `ts` named export from ts-morph should serve your needs.
81
+
82
+ There's lots of reasons why this is done and it's outlined in [#333](https://github.com/dsherret/ts-morph/issues/333#issuecomment-391182952).
@@ -0,0 +1,287 @@
1
+ ---
2
+ title: Directories
3
+ ---
4
+
5
+ ## Directories
6
+
7
+ Based on the source files created, appropriate directory objects will be created. These objects hold source files and directories that have been added.
8
+
9
+ Note that it's completely fine to ignore the concept of directories and only deal with source files. This is an advanced feature that
10
+ only needs to be used if it will help make solving your problem easier.
11
+
12
+ ### Retrieving
13
+
14
+ Directories can be retrieved from a source file:
15
+
16
+ ```ts
17
+ const directory = sourceFile.getDirectory();
18
+ ```
19
+
20
+ From other directories:
21
+
22
+ ```ts
23
+ directory.getDirectory("childDir");
24
+ directory.getDirectoryOrThrow("childDir");
25
+ // child directories
26
+ directory.getDirectories();
27
+ // parent directory, if it exists
28
+ directory.getParent();
29
+ ```
30
+
31
+ Or from the main `project` object:
32
+
33
+ ```ts
34
+ project.getRootDirectories(); // gets directories without a parent
35
+ project.getDirectories(); // gets all the directories
36
+ project.getDirectory("path/to/directory");
37
+ project.getDirectoryOrThrow("path/to/directory");
38
+ ```
39
+
40
+ ### Adding
41
+
42
+ On a directory:
43
+
44
+ ```ts
45
+ const childDirectory = directory.addDirectoryAtPath("childDir"); // or addDirectoryAtPathIfExists
46
+ ```
47
+
48
+ Or main `project` object:
49
+
50
+ ```ts
51
+ const directory = project.addDirectoryAtPath("path/to/dir"); // or addDirectoryAtPathIfExists
52
+ ```
53
+
54
+ ### Creating
55
+
56
+ On a directory
57
+
58
+ ```ts
59
+ const childDir = directory.createDirectory("childDir");
60
+ ```
61
+
62
+ Or main `project` object:
63
+
64
+ ```ts
65
+ const directory = project.createDirectory("path/to/dir");
66
+ ```
67
+
68
+ ## Directory
69
+
70
+ ### Path and name
71
+
72
+ ```ts
73
+ // returns the full path (ex. /home/david/project/)
74
+ const path = directory.getPath();
75
+
76
+ // returns only the directory name (ex. project)
77
+ const baseName = directory.getBaseName();
78
+ ```
79
+
80
+ ### Parent directory
81
+
82
+ ```ts
83
+ const parentDir = directory.getParent(); // or getParentOrThrow()
84
+ ```
85
+
86
+ ### Child directories
87
+
88
+ ```ts
89
+ const childDirs = directory.getDirectories();
90
+ ```
91
+
92
+ ### Ancestor / Descendant
93
+
94
+ Check if a directory is an ancestor or descendant of another directory:
95
+
96
+ ```ts setup: let grandParentDir: Directory, childDir: Directory;
97
+ grandParentDir.isAncestorOf(childDir); // true
98
+ childDir.isDescendantOf(grandParentDir); // true
99
+ ```
100
+
101
+ Or if a directory is an ancestor of a source file:
102
+
103
+ ```ts setup: let grandParentDir: Directory, parentDir: Directory, childSourceFile: SourceFile;
104
+ grandParentDir.isAncestorOf(childSourceFile); // true
105
+ parentDir.isAncestorOf(childSourceFile); // true
106
+ ```
107
+
108
+ ### Source files
109
+
110
+ ```ts
111
+ const sourceFiles = directory.getSourceFiles();
112
+ const sourceFile = directory.getSourceFile("someFile.ts"); // or getSourceFileOrThrow
113
+ const indexFile = directory.addSourceFileAtPath("index.ts"); // or addSourceFileAtPathIfExists
114
+ const descendantSourceFiles = directory.getDescendantSourceFiles();
115
+
116
+ directory.createSourceFile("someFile.ts");
117
+ directory.createSourceFile("someFile2.ts", "// some text");
118
+ directory.createSourceFile("someFile3.ts", writer => writer.writeLine("// some text"));
119
+ directory.createSourceFile("someFile4.ts", { statements: [{ kind: StructureKind.Enum, name: "MyEnum" }] });
120
+ ```
121
+
122
+ ### Saving
123
+
124
+ Save the directory to the disk and all the unsaved source files:
125
+
126
+ ```ts
127
+ await directory.save();
128
+ directory.saveSync(); // slow
129
+ ```
130
+
131
+ ### Emitting
132
+
133
+ It's possible to only specific directories:
134
+
135
+ ```ts
136
+ // always check result.getEmitSkipped() to make sure the emit was successful
137
+ const result = await directory.emit();
138
+ directory.emitSync(); // slow
139
+ ```
140
+
141
+ Or specify the output directories (specify a path relative from the directory or an absolute paths):
142
+
143
+ ```ts
144
+ directory.emit({
145
+ outDir: "out",
146
+ declarationDir: "declarations",
147
+ });
148
+ ```
149
+
150
+ And of course, specify to only emit declaration files:
151
+
152
+ ```ts
153
+ directory.emit({ emitOnlyDtsFiles: true });
154
+ ```
155
+
156
+ ### Moving
157
+
158
+ Move the directory to a new directory:
159
+
160
+ ```ts setup: const otherDir: Directory;
161
+ // ex. moves C:\MyProject\dir to C:\MyProject\newDir if working directory is C:\MyProject
162
+ directory.move("./newDir");
163
+ // ex. moves C:\MyProject\newDir to C:\MyProject\otherDir using a relative path
164
+ directory.move("../otherDir", { overwrite: true }); // allows overwriting (otherwise it will throw)
165
+ // or specify an absolute path
166
+ directory.move("C:\\finalDir");
167
+ // or specify the directory to move to
168
+ directory.moveToDirectory("some/directory");
169
+ directory.moveToDirectory(otherDir);
170
+ ```
171
+
172
+ ### Moving Immediately
173
+
174
+ Moving a directory immediately can be done by using one of the following methods:
175
+
176
+ ```ts
177
+ await directory.moveImmediately("../newDir");
178
+ // or
179
+ directory.moveImmediatelySync("../newDir2");
180
+ ```
181
+
182
+ ### Copying
183
+
184
+ Copy the directory to a new directory:
185
+
186
+ ```ts setup: const otherDir: Directory;
187
+ // ex. copies C:\MyProject\dir to C:\MyProject\newDir
188
+ directory.copy("../newDir");
189
+ // allows overwriting (otherwise it will throw)
190
+ directory.copy("../nextDir", { overwrite: true });
191
+ // or specify an absolute path
192
+ directory.copy("C:\\test");
193
+ // or specify the directory to copy to
194
+ directory.copyToDirectory("some/directory");
195
+ directory.copyToDirectory(otherDir);
196
+ ```
197
+
198
+ Note that the directory and source files, in all these cases, won't be created until calling save on the project.
199
+
200
+ #### Not including untracked files
201
+
202
+ When moving a directory, it will queue up a file system copy for the directory from to the directory to. If you only wish to copy the source files that are found in memory within the directory, then set the `includeUntrackedFiles` option to false:
203
+
204
+ ```
205
+ directory.copy("../finalDir", { includeUntrackedFiles: false });
206
+ ```
207
+
208
+ ### Copying Immediately
209
+
210
+ Copying a directory immediately can be done by using one of the following methods:
211
+
212
+ ```ts
213
+ await directory.copyImmediately("../otherDir");
214
+ // or
215
+ directory.copyImmediatelySync("../otherDir2");
216
+ ```
217
+
218
+ ### Deleting
219
+
220
+ Call:
221
+
222
+ ```ts
223
+ directory.delete();
224
+ ```
225
+
226
+ This will remove the directory object and all its descendant source files and directories from the main `project` object and queue it up for deletion to the file system.
227
+
228
+ When you're all done your other manipulations, call `project.save()` and at that point the directory will be deleted.
229
+
230
+ #### Deleting immediately
231
+
232
+ If you want to delete a directory immediately from the file system, then use the following:
233
+
234
+ ```ts
235
+ await directory.deleteImmediately();
236
+ // or
237
+ directory.deleteImmediatelySync();
238
+ ```
239
+
240
+ This isn't recommended though because it could possibly leave the file system in a halfway state if your code errors before it's done.
241
+
242
+ ### Clearing
243
+
244
+ Call:
245
+
246
+ ```ts
247
+ directory.clear();
248
+ ```
249
+
250
+ This will delete the directory's descendants in memory and queue a delete and mkdir operation to the file system.
251
+
252
+ #### Clearing immediately
253
+
254
+ If you want to do this operation immediatley to the file system, then use the following:
255
+
256
+ ```ts
257
+ await directory.clearImmediately();
258
+ // or
259
+ directory.clearImmediatelySync();
260
+ ```
261
+
262
+ This isn't recommended though because it could possibly leave the file system in a halfway state if your code errors before it's done.
263
+
264
+ ### Forgetting
265
+
266
+ Forgets the directory from main project object without deleting it:
267
+
268
+ ```ts
269
+ directory.forget();
270
+ ```
271
+
272
+ Note that after doing this, the directory object and all its descendant source files and directories will not be available. If you want to use them again,
273
+ then you will need to re-add them.
274
+
275
+ ### Relative File Paths
276
+
277
+ It might be useful to get the relative path from one directory to another source file or directory.
278
+
279
+ ```ts setup: let directoryFrom: Directory, sourceFileTo: SourceFile;
280
+ const relativePath = directoryFrom.getRelativePathTo(sourceFileTo);
281
+ ```
282
+
283
+ Or to get the module specifier text from one directory to another source file or directory.
284
+
285
+ ```ts setup: let directoryFrom: Directory, sourceFileTo: SourceFile;
286
+ const moduleSpecifier = directoryFrom.getRelativePathAsModuleSpecifierTo(sourceFileTo);
287
+ ```
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Navigation example
3
+ ---
4
+
5
+ ## Example - Navigating Within Source Files
6
+
7
+ ### Setup
8
+
9
+ Given the following file:
10
+
11
+ ```ts
12
+ // Person.ts
13
+
14
+ interface Person {
15
+ name: string;
16
+ age: number;
17
+ }
18
+
19
+ export default Person;
20
+ ```
21
+
22
+ And setup:
23
+
24
+ ```ts
25
+ import { Project } from "ts-morph";
26
+
27
+ const project = new Project();
28
+ project.addSourceFilesAtPaths("**/*.ts");
29
+ ```
30
+
31
+ ### Use
32
+
33
+ First you need to get the source file you would like to look at:
34
+
35
+ ```ts
36
+ const sourceFile = project.getSourceFileOrThrow("Person.ts");
37
+ ```
38
+
39
+ Now inspect what's inside... here's a few examples:
40
+
41
+ ```ts
42
+ const hasClasses = sourceFile.getClasses().length > 0;
43
+ const interfaces = sourceFile.getInterfaces();
44
+
45
+ // person interface
46
+ const personInterface = sourceFile.getInterface("Person")!;
47
+ personInterface.isDefaultExport(); // returns true
48
+ personInterface.getName(); // returns "Person"
49
+ personInterface.getProperties(); // returns the properties
50
+ ```
@@ -0,0 +1,53 @@
1
+ ---
2
+ title: Finding References
3
+ ---
4
+
5
+ ## Finding References
6
+
7
+ Find all the references of a node by calling `.findReferences()` on an identifier or named/nameable declaration.
8
+
9
+ ### Example
10
+
11
+ Simple example:
12
+
13
+ ```ts ignore-error: 1109
14
+ const classDeclaration = ...; // get a class or some other declaration somehow
15
+ const referencedSymbols = classDeclaration.findReferences();
16
+
17
+ for (const referencedSymbol of referencedSymbols) {
18
+ for (const reference of referencedSymbol.getReferences()) {
19
+ console.log("---------")
20
+ console.log("REFERENCE")
21
+ console.log("---------")
22
+ console.log("File path: " + reference.getSourceFile().getFilePath());
23
+ console.log("Start: " + reference.getTextSpan().getStart());
24
+ console.log("Length: " + reference.getTextSpan().getLength());
25
+ console.log("Parent kind: " + reference.getNode().getParentOrThrow().getKindName());
26
+ console.log("\n");
27
+ }
28
+ }
29
+ ```
30
+
31
+ ## Finding Referencing Nodes
32
+
33
+ The `.findReferences()` method returns back a lot of information that might not be necessary.
34
+ If you just want the nodes that reference the named/nameable declaration, then use the
35
+ following method:
36
+
37
+ ```ts
38
+ const nodes = classDeclaration.findReferencesAsNodes();
39
+ ```
40
+
41
+ ## "Go to Definition"
42
+
43
+ Similar to finding references, you can also go to an identifier's definitions:
44
+
45
+ ```ts
46
+ const definitions = identifier.getDefinitions();
47
+ ```
48
+
49
+ Or just get the nodes:
50
+
51
+ ```ts
52
+ const nodes = identifier.getDefinitionNodes();
53
+ ```
@@ -0,0 +1,59 @@
1
+ ---
2
+ title: Getting Source Files
3
+ ---
4
+
5
+ ## Getting Source Files
6
+
7
+ After source files are added, you will need to get them in order to navigate or make changes.
8
+
9
+ ### All
10
+
11
+ Get all the source files:
12
+
13
+ ```ts
14
+ const sourceFiles = project.getSourceFiles();
15
+ ```
16
+
17
+ Or filter by glob:
18
+
19
+ ```ts
20
+ // single
21
+ const testSourceFiles = project.getSourceFiles("src/test/**/*.ts");
22
+ // or multiple
23
+ const nonTestSourceFiles = project.getSourceFiles([
24
+ "src/**/*.ts",
25
+ "!src/test/**/*.ts",
26
+ ]);
27
+ ```
28
+
29
+ Note that the path resolution and matching is done relative to the current working directory.
30
+
31
+ For example, if you load a project from another directory...
32
+
33
+ ```ts
34
+ const project = new Project({
35
+ tsConfigFilePath: `/someDirectory/notCurrent/tsconfig.json`,
36
+ });
37
+ ```
38
+
39
+ ...to match a file from that directory you need to specify a glob that matches based on the current working directory or absolute path...
40
+
41
+ ```ts
42
+ const sourceFile = project.getSourceFiles(`/someDirectory/notCurrent/**/config/index.ts`);
43
+ ```
44
+
45
+ ### By file path
46
+
47
+ Will return the first source file that matches the end of the provided file path:
48
+
49
+ ```ts
50
+ const personFile = project.getSourceFile("Models/Person.ts");
51
+ ```
52
+
53
+ ### By condition
54
+
55
+ Will return the first source file that matches the provided condition:
56
+
57
+ ```ts
58
+ const fileWithFiveClasses = project.getSourceFile(f => f.getClasses().length === 5);
59
+ ```