docit-ai 1.0.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.
- package/.env.example +1 -0
- package/INSTRUCTIONS.MD +70 -0
- package/dist/ai/engine.d.ts +24 -0
- package/dist/ai/engine.d.ts.map +1 -0
- package/dist/ai/engine.js +69 -0
- package/dist/ai/engine.js.map +1 -0
- package/dist/ai/prompts.d.ts +11 -0
- package/dist/ai/prompts.d.ts.map +1 -0
- package/dist/ai/prompts.js +116 -0
- package/dist/ai/prompts.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +384 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/formatter/index.d.ts +13 -0
- package/dist/formatter/index.d.ts.map +1 -0
- package/dist/formatter/index.js +76 -0
- package/dist/formatter/index.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/extractor.d.ts +23 -0
- package/dist/parser/extractor.d.ts.map +1 -0
- package/dist/parser/extractor.js +148 -0
- package/dist/parser/extractor.js.map +1 -0
- package/dist/scanner/index.d.ts +11 -0
- package/dist/scanner/index.d.ts.map +1 -0
- package/dist/scanner/index.js +30 -0
- package/dist/scanner/index.js.map +1 -0
- package/package.json +31 -0
- package/server/.env.example +22 -0
- package/server/package-lock.json +4426 -0
- package/server/package.json +31 -0
- package/server/src/config/database.d.ts +18 -0
- package/server/src/config/database.d.ts.map +1 -0
- package/server/src/config/database.js +8 -0
- package/server/src/config/database.js.map +1 -0
- package/server/src/config/database.ts +31 -0
- package/server/src/index.d.ts +2 -0
- package/server/src/index.d.ts.map +1 -0
- package/server/src/index.js +33 -0
- package/server/src/index.js.map +1 -0
- package/server/src/index.ts +55 -0
- package/server/src/middleware/auth.d.ts +12 -0
- package/server/src/middleware/auth.d.ts.map +1 -0
- package/server/src/middleware/auth.js +35 -0
- package/server/src/middleware/auth.js.map +1 -0
- package/server/src/middleware/auth.ts +56 -0
- package/server/src/routes/auth.d.ts +3 -0
- package/server/src/routes/auth.d.ts.map +1 -0
- package/server/src/routes/auth.js +145 -0
- package/server/src/routes/auth.js.map +1 -0
- package/server/src/routes/auth.ts +185 -0
- package/server/src/routes/dashboard.ts +243 -0
- package/server/src/routes/generate.d.ts +3 -0
- package/server/src/routes/generate.d.ts.map +1 -0
- package/server/src/routes/generate.js +55 -0
- package/server/src/routes/generate.js.map +1 -0
- package/server/src/routes/generate.ts +75 -0
- package/server/src/routes/payment.ts +192 -0
- package/server/src/services/ai.d.ts +10 -0
- package/server/src/services/ai.d.ts.map +1 -0
- package/server/src/services/ai.js +75 -0
- package/server/src/services/ai.js.map +1 -0
- package/server/src/services/ai.ts +99 -0
- package/server/src/services/payment.ts +141 -0
- package/server/src/types/flutterwave.d.ts +60 -0
- package/server/supabase_payments.sql +35 -0
- package/server/supabase_schema.sql +90 -0
- package/server/tsconfig.json +17 -0
- package/server/vercel.json +15 -0
- package/server/verify_dashboard.ts +126 -0
- package/src/ai/engine.ts +103 -0
- package/src/ai/prompts.ts +123 -0
- package/src/cli/index.ts +552 -0
- package/src/formatter/index.ts +110 -0
- package/src/index.ts +11 -0
- package/src/parser/extractor.ts +211 -0
- package/src/scanner/index.ts +49 -0
- package/tsconfig.json +43 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { DocumentationResult } from "../ai/engine.js";
|
|
2
|
+
import * as fs from "fs";
|
|
3
|
+
import * as path from "path";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Formatter Module
|
|
7
|
+
* Generates the DOCIT.md documentation file with the three-view hierarchy.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface FormatterOptions {
|
|
11
|
+
outputPath?: string;
|
|
12
|
+
projectName?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function formatDocumentation(
|
|
16
|
+
results: DocumentationResult[],
|
|
17
|
+
options: FormatterOptions = {},
|
|
18
|
+
): string {
|
|
19
|
+
const projectName = options.projectName ?? "Project";
|
|
20
|
+
const timestamp = new Date().toISOString().split("T")[0];
|
|
21
|
+
|
|
22
|
+
const strategicContent =
|
|
23
|
+
results.find((r) => r.view === "strategic")?.content ?? "";
|
|
24
|
+
const technicalContent =
|
|
25
|
+
results.find((r) => r.view === "technical")?.content ?? "";
|
|
26
|
+
const personalContent =
|
|
27
|
+
results.find((r) => r.view === "personal")?.content ?? "";
|
|
28
|
+
|
|
29
|
+
const doc = `# ${projectName} Documentation
|
|
30
|
+
|
|
31
|
+
> Auto-generated by Docit on ${timestamp}
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
1. [PM Dashboard (Strategic View)](#pm-dashboard-strategic-view)
|
|
38
|
+
2. [Developer Reference (Technical View)](#developer-reference-technical-view)
|
|
39
|
+
3. [Personal Roadmap (Individual View)](#personal-roadmap-individual-view)
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
# PM Dashboard (Strategic View)
|
|
44
|
+
|
|
45
|
+
*For Project Managers and Stakeholders*
|
|
46
|
+
|
|
47
|
+
${strategicContent}
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
# Developer Reference (Technical View)
|
|
52
|
+
|
|
53
|
+
*For Developers and Engineers*
|
|
54
|
+
|
|
55
|
+
${technicalContent}
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
# Personal Roadmap (Individual View)
|
|
60
|
+
|
|
61
|
+
*For Solo Developers and Contributors*
|
|
62
|
+
|
|
63
|
+
${personalContent}
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Changelog
|
|
68
|
+
|
|
69
|
+
| Date | Changes |
|
|
70
|
+
|------|---------|
|
|
71
|
+
| ${timestamp} | Documentation generated |
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
*Generated by [Docit](https://github.com/docit) - Your AI-powered documentation companion*
|
|
76
|
+
`;
|
|
77
|
+
|
|
78
|
+
return doc;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function writeDocumentation(
|
|
82
|
+
content: string,
|
|
83
|
+
outputPath: string = "./DOCIT.md",
|
|
84
|
+
): void {
|
|
85
|
+
const absolutePath = path.resolve(outputPath);
|
|
86
|
+
fs.writeFileSync(absolutePath, content, "utf-8");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function appendToChangelog(
|
|
90
|
+
existingContent: string,
|
|
91
|
+
newEntry: string,
|
|
92
|
+
): string {
|
|
93
|
+
const changelogPattern =
|
|
94
|
+
/## Changelog\n\n\| Date \| Changes \|\n\|------\|---------\|\n/;
|
|
95
|
+
const match = existingContent.match(changelogPattern);
|
|
96
|
+
|
|
97
|
+
if (match) {
|
|
98
|
+
const insertPosition = (match.index ?? 0) + match[0].length;
|
|
99
|
+
const timestamp = new Date().toISOString().split("T")[0];
|
|
100
|
+
const newRow = `| ${timestamp} | ${newEntry} |\n`;
|
|
101
|
+
|
|
102
|
+
return (
|
|
103
|
+
existingContent.slice(0, insertPosition) +
|
|
104
|
+
newRow +
|
|
105
|
+
existingContent.slice(insertPosition)
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return existingContent;
|
|
110
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import Parser from "tree-sitter";
|
|
2
|
+
import TypeScript from "tree-sitter-typescript";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Parser Module
|
|
7
|
+
* Uses tree-sitter to extract "Code Skeletons" from TypeScript files.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
export interface CodeSkeleton {
|
|
11
|
+
name: string;
|
|
12
|
+
kind: "function" | "class" | "interface" | "type" | "variable" | "export";
|
|
13
|
+
signature: string;
|
|
14
|
+
parameters?: string[] | undefined;
|
|
15
|
+
returnType?: string | undefined;
|
|
16
|
+
comments?: string | undefined;
|
|
17
|
+
startLine: number;
|
|
18
|
+
endLine: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface FileAnalysis {
|
|
22
|
+
filePath: string;
|
|
23
|
+
skeletons: CodeSkeleton[];
|
|
24
|
+
todos: string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const parser = new Parser();
|
|
28
|
+
parser.setLanguage(TypeScript.typescript);
|
|
29
|
+
|
|
30
|
+
function extractComments(
|
|
31
|
+
node: Parser.SyntaxNode,
|
|
32
|
+
sourceCode: string,
|
|
33
|
+
): string | undefined {
|
|
34
|
+
// Look for preceding comments
|
|
35
|
+
let sibling = node.previousNamedSibling;
|
|
36
|
+
while (sibling && sibling.type === "comment") {
|
|
37
|
+
const commentText = sourceCode.slice(sibling.startIndex, sibling.endIndex);
|
|
38
|
+
return commentText
|
|
39
|
+
.replace(/^\/\*\*?|\*\/$/g, "")
|
|
40
|
+
.replace(/^\s*\* ?/gm, "")
|
|
41
|
+
.trim();
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function extractTodos(sourceCode: string): string[] {
|
|
47
|
+
const todoPattern = /\/\/\s*TODO[:\s](.+)|\/\*\s*TODO[:\s](.+?)\*\//gi;
|
|
48
|
+
const todos: string[] = [];
|
|
49
|
+
let match;
|
|
50
|
+
|
|
51
|
+
while ((match = todoPattern.exec(sourceCode)) !== null) {
|
|
52
|
+
todos.push((match[1] ?? match[2] ?? "").trim());
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return todos;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function getNodeText(
|
|
59
|
+
node: Parser.SyntaxNode | null,
|
|
60
|
+
sourceCode: string,
|
|
61
|
+
): string {
|
|
62
|
+
if (!node) return "";
|
|
63
|
+
return sourceCode.slice(node.startIndex, node.endIndex);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function extractFunctionSkeleton(
|
|
67
|
+
node: Parser.SyntaxNode,
|
|
68
|
+
sourceCode: string,
|
|
69
|
+
): CodeSkeleton {
|
|
70
|
+
const nameNode = node.childForFieldName("name");
|
|
71
|
+
const paramsNode = node.childForFieldName("parameters");
|
|
72
|
+
const returnTypeNode = node.childForFieldName("return_type");
|
|
73
|
+
|
|
74
|
+
const parameters = paramsNode
|
|
75
|
+
? getNodeText(paramsNode, sourceCode)
|
|
76
|
+
.replace(/^\(|\)$/g, "")
|
|
77
|
+
.split(",")
|
|
78
|
+
.map((p) => p.trim())
|
|
79
|
+
.filter((p) => p.length > 0)
|
|
80
|
+
: [];
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
name: nameNode ? getNodeText(nameNode, sourceCode) : "anonymous",
|
|
84
|
+
kind: "function",
|
|
85
|
+
signature: `function ${getNodeText(nameNode, sourceCode)}${getNodeText(paramsNode, sourceCode)}${returnTypeNode ? ": " + getNodeText(returnTypeNode, sourceCode).replace(/^:\s*/, "") : ""}`,
|
|
86
|
+
parameters,
|
|
87
|
+
returnType: returnTypeNode
|
|
88
|
+
? getNodeText(returnTypeNode, sourceCode).replace(/^:\s*/, "")
|
|
89
|
+
: undefined,
|
|
90
|
+
comments: extractComments(node, sourceCode),
|
|
91
|
+
startLine: node.startPosition.row + 1,
|
|
92
|
+
endLine: node.endPosition.row + 1,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function extractClassSkeleton(
|
|
97
|
+
node: Parser.SyntaxNode,
|
|
98
|
+
sourceCode: string,
|
|
99
|
+
): CodeSkeleton {
|
|
100
|
+
const nameNode = node.childForFieldName("name");
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
name: nameNode ? getNodeText(nameNode, sourceCode) : "AnonymousClass",
|
|
104
|
+
kind: "class",
|
|
105
|
+
signature: `class ${getNodeText(nameNode, sourceCode)}`,
|
|
106
|
+
comments: extractComments(node, sourceCode),
|
|
107
|
+
startLine: node.startPosition.row + 1,
|
|
108
|
+
endLine: node.endPosition.row + 1,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function extractInterfaceSkeleton(
|
|
113
|
+
node: Parser.SyntaxNode,
|
|
114
|
+
sourceCode: string,
|
|
115
|
+
): CodeSkeleton {
|
|
116
|
+
const nameNode = node.childForFieldName("name");
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
name: nameNode ? getNodeText(nameNode, sourceCode) : "AnonymousInterface",
|
|
120
|
+
kind: "interface",
|
|
121
|
+
signature: `interface ${getNodeText(nameNode, sourceCode)}`,
|
|
122
|
+
comments: extractComments(node, sourceCode),
|
|
123
|
+
startLine: node.startPosition.row + 1,
|
|
124
|
+
endLine: node.endPosition.row + 1,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function extractTypeSkeleton(
|
|
129
|
+
node: Parser.SyntaxNode,
|
|
130
|
+
sourceCode: string,
|
|
131
|
+
): CodeSkeleton {
|
|
132
|
+
const nameNode = node.childForFieldName("name");
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
name: nameNode ? getNodeText(nameNode, sourceCode) : "AnonymousType",
|
|
136
|
+
kind: "type",
|
|
137
|
+
signature: `type ${getNodeText(nameNode, sourceCode)}`,
|
|
138
|
+
comments: extractComments(node, sourceCode),
|
|
139
|
+
startLine: node.startPosition.row + 1,
|
|
140
|
+
endLine: node.endPosition.row + 1,
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export function extractSkeletons(sourceCode: string): CodeSkeleton[] {
|
|
145
|
+
const tree = parser.parse(sourceCode);
|
|
146
|
+
const skeletons: CodeSkeleton[] = [];
|
|
147
|
+
|
|
148
|
+
function traverse(node: Parser.SyntaxNode) {
|
|
149
|
+
switch (node.type) {
|
|
150
|
+
case "function_declaration":
|
|
151
|
+
case "arrow_function":
|
|
152
|
+
case "method_definition":
|
|
153
|
+
skeletons.push(extractFunctionSkeleton(node, sourceCode));
|
|
154
|
+
break;
|
|
155
|
+
case "class_declaration":
|
|
156
|
+
skeletons.push(extractClassSkeleton(node, sourceCode));
|
|
157
|
+
break;
|
|
158
|
+
case "interface_declaration":
|
|
159
|
+
skeletons.push(extractInterfaceSkeleton(node, sourceCode));
|
|
160
|
+
break;
|
|
161
|
+
case "type_alias_declaration":
|
|
162
|
+
skeletons.push(extractTypeSkeleton(node, sourceCode));
|
|
163
|
+
break;
|
|
164
|
+
case "export_statement":
|
|
165
|
+
// Handle exported declarations
|
|
166
|
+
for (const child of node.children) {
|
|
167
|
+
traverse(child);
|
|
168
|
+
}
|
|
169
|
+
return; // Don't traverse children again
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
for (const child of node.children) {
|
|
173
|
+
traverse(child);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
traverse(tree.rootNode);
|
|
178
|
+
return skeletons;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
export function analyzeFile(filePath: string): FileAnalysis {
|
|
182
|
+
const sourceCode = fs.readFileSync(filePath, "utf-8");
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
filePath,
|
|
186
|
+
skeletons: extractSkeletons(sourceCode),
|
|
187
|
+
todos: extractTodos(sourceCode),
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export function formatSkeletonForLLM(analysis: FileAnalysis): string {
|
|
192
|
+
const lines: string[] = [`File: ${analysis.filePath}`, "---"];
|
|
193
|
+
|
|
194
|
+
for (const skeleton of analysis.skeletons) {
|
|
195
|
+
lines.push(`[${skeleton.kind.toUpperCase()}] ${skeleton.signature}`);
|
|
196
|
+
if (skeleton.comments) {
|
|
197
|
+
lines.push(` Comment: ${skeleton.comments}`);
|
|
198
|
+
}
|
|
199
|
+
lines.push(` Lines: ${skeleton.startLine}-${skeleton.endLine}`);
|
|
200
|
+
lines.push("");
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (analysis.todos.length > 0) {
|
|
204
|
+
lines.push("TODOs:");
|
|
205
|
+
for (const todo of analysis.todos) {
|
|
206
|
+
lines.push(` - ${todo}`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
return lines.join("\n");
|
|
211
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { simpleGit, type SimpleGit } from "simple-git";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Scanner Module
|
|
6
|
+
* Uses simple-git to identify files modified in the last commit.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
export interface ChangedFile {
|
|
10
|
+
path: string;
|
|
11
|
+
status: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function getChangedFiles(
|
|
15
|
+
repoPath: string = ".",
|
|
16
|
+
): Promise<ChangedFile[]> {
|
|
17
|
+
const git: SimpleGit = simpleGit(repoPath);
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
// Get the diff of the last commit
|
|
21
|
+
const diffSummary = await git.diffSummary(["HEAD~1", "HEAD"]);
|
|
22
|
+
|
|
23
|
+
const changedFiles: ChangedFile[] = diffSummary.files.map((file) => ({
|
|
24
|
+
path: path.resolve(repoPath, file.file),
|
|
25
|
+
status: "binary" in file ? "binary" : "modified",
|
|
26
|
+
}));
|
|
27
|
+
|
|
28
|
+
return changedFiles;
|
|
29
|
+
} catch {
|
|
30
|
+
// If there's no previous commit, get all tracked files
|
|
31
|
+
const status = await git.status();
|
|
32
|
+
const allFiles = [...status.modified, ...status.created, ...status.staged];
|
|
33
|
+
|
|
34
|
+
return [...new Set(allFiles)].map((filePath) => ({
|
|
35
|
+
path: path.resolve(repoPath, filePath),
|
|
36
|
+
status: "new",
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function getModifiedTypeScriptFiles(
|
|
42
|
+
repoPath: string = ".",
|
|
43
|
+
): Promise<string[]> {
|
|
44
|
+
const changedFiles = await getChangedFiles(repoPath);
|
|
45
|
+
|
|
46
|
+
return changedFiles
|
|
47
|
+
.filter((file) => file.path.endsWith(".ts") || file.path.endsWith(".tsx"))
|
|
48
|
+
.map((file) => file.path);
|
|
49
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
// File Layout
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
|
|
8
|
+
// Environment Settings
|
|
9
|
+
// See also https://aka.ms/tsconfig/module
|
|
10
|
+
"module": "nodenext",
|
|
11
|
+
"target": "esnext",
|
|
12
|
+
"lib": ["esnext"],
|
|
13
|
+
"types": ["node"],
|
|
14
|
+
|
|
15
|
+
// Other Outputs
|
|
16
|
+
"sourceMap": true,
|
|
17
|
+
"declaration": true,
|
|
18
|
+
"declarationMap": true,
|
|
19
|
+
|
|
20
|
+
// Stricter Typechecking Options
|
|
21
|
+
"noUncheckedIndexedAccess": true,
|
|
22
|
+
"exactOptionalPropertyTypes": true,
|
|
23
|
+
|
|
24
|
+
// Style Options
|
|
25
|
+
// "noImplicitReturns": true,
|
|
26
|
+
// "noImplicitOverride": true,
|
|
27
|
+
// "noUnusedLocals": true,
|
|
28
|
+
// "noUnusedParameters": true,
|
|
29
|
+
// "noFallthroughCasesInSwitch": true,
|
|
30
|
+
// "noPropertyAccessFromIndexSignature": true,
|
|
31
|
+
|
|
32
|
+
// Recommended Options
|
|
33
|
+
"strict": true,
|
|
34
|
+
"jsx": "react-jsx",
|
|
35
|
+
"verbatimModuleSyntax": true,
|
|
36
|
+
"isolatedModules": true,
|
|
37
|
+
"noUncheckedSideEffectImports": true,
|
|
38
|
+
"moduleDetection": "force",
|
|
39
|
+
"skipLibCheck": true
|
|
40
|
+
},
|
|
41
|
+
"include": ["src/**/*"],
|
|
42
|
+
"exclude": ["node_modules", "dist", "server"]
|
|
43
|
+
}
|