Skip to content

Commit 3cc76b5

Browse files
committed
chore: extract adjustments
1 parent 41a035a commit 3cc76b5

File tree

1 file changed

+42
-60
lines changed

1 file changed

+42
-60
lines changed

src/extract.ts

Lines changed: 42 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,25 @@ export async function extractTypeFromSource(filePath: string): Promise<string> {
88
const importMap = new Map<string, Set<string>>()
99

1010
// Handle re-exports
11-
const reExportRegex = /export\s*(?:\*|\{[^}]*\})\s*from\s*['"][^'"]+['"]/g
12-
const reExports = fileContent.match(reExportRegex) || []
13-
declarations += `${reExports.join('\n')}\n`
11+
const reExportRegex = /export\s*(?:\*|\{[^}]*\})\s*from\s*['"]([^'"]+)['"]/g
12+
let reExportMatch
13+
14+
while ((reExportMatch = reExportRegex.exec(fileContent)) !== null) {
15+
declarations += `${reExportMatch[0]}\n`
16+
}
1417

1518
// Capture all imports
1619
const importRegex = /import\s+(?:(type)\s+)?(?:(\{[^}]+\})|(\w+))(?:\s*,\s*(?:(\{[^}]+\})|(\w+)))?\s+from\s+['"]([^'"]+)['"]/g
17-
const imports = Array.from(fileContent.matchAll(importRegex))
18-
19-
imports.forEach(([, isTypeImport, namedImports1, defaultImport1, namedImports2, defaultImport2, from]) => {
20+
let importMatch
21+
// eslint-disable-next-line no-cond-assign
22+
while ((importMatch = importRegex.exec(fileContent)) !== null) {
23+
// eslint-disable-next-line unused-imports/no-unused-vars
24+
const [, isTypeImport, namedImports1, defaultImport1, namedImports2, defaultImport2, from] = importMatch
2025
if (!importMap.has(from)) {
2126
importMap.set(from, new Set())
2227
}
2328

24-
const processImports = (imports: string | undefined, _isType: boolean) => {
29+
const processImports = (imports: string | undefined) => {
2530
if (imports) {
2631
const types = imports.replace(/[{}]/g, '').split(',').map((t) => {
2732
const [name, alias] = t.split(' as ').map(s => s.trim())
@@ -33,70 +38,47 @@ export async function extractTypeFromSource(filePath: string): Promise<string> {
3338
}
3439
}
3540

36-
processImports(namedImports1, !!isTypeImport)
37-
processImports(namedImports2, !!isTypeImport)
41+
processImports(namedImports1)
42+
processImports(namedImports2)
43+
3844
if (defaultImport1)
3945
importMap.get(from)!.add(defaultImport1)
4046
if (defaultImport2)
4147
importMap.get(from)!.add(defaultImport2)
42-
})
48+
}
4349

4450
// Handle exports with comments
45-
const exportLines = fileContent.split('\n')
46-
let i = 0
47-
while (i < exportLines.length) {
48-
let comment = ''
49-
let exportStatement = ''
50-
51-
// Collect comment
52-
if (exportLines[i].trim().startsWith('/**')) {
53-
while (i < exportLines.length && !exportLines[i].includes('*/')) {
54-
comment += `${exportLines[i]}\n`
55-
i++
51+
const exportRegex = /(\/\*\*[\s\S]*?\*\/\s*)?(export\s+(?:async\s+)?(?:function|const|let|var|class|interface|type)\s+\w[\s\S]*?)(?=\n\s*(?:\/\*\*|export|$))/g
52+
let match
53+
// eslint-disable-next-line no-cond-assign
54+
while ((match = exportRegex.exec(fileContent)) !== null) {
55+
const [, comment, exportStatement] = match
56+
const formattedComment = comment ? formatComment(comment.trim()) : ''
57+
let formattedExport = exportStatement.trim()
58+
59+
if (formattedExport.startsWith('export function') || formattedExport.startsWith('export async function')) {
60+
formattedExport = formattedExport.replace(/^export\s+(async\s+)?function/, 'export declare function')
61+
const functionSignature = formattedExport.match(/^.*?\)/)
62+
if (functionSignature) {
63+
let params = functionSignature[0].slice(functionSignature[0].indexOf('(') + 1, -1)
64+
params = params.replace(/\s*=[^,)]+/g, '') // Remove default values
65+
const returnType = formattedExport.match(/\):\s*([^{]+)/)
66+
formattedExport = `export declare function ${formattedExport.split('function')[1].split('(')[0].trim()}(${params})${returnType ? `: ${returnType[1].trim()}` : ''};`
5667
}
57-
comment += `${exportLines[i]}\n`
58-
i++
5968
}
60-
61-
// Collect export statement
62-
if (i < exportLines.length && exportLines[i].trim().startsWith('export')) {
63-
exportStatement = exportLines[i]
64-
i++
65-
while (i < exportLines.length && !exportLines[i].trim().startsWith('export') && !exportLines[i].trim().startsWith('/**')) {
66-
exportStatement += `\n${exportLines[i]}`
67-
i++
68-
}
69+
else if (formattedExport.startsWith('export const') || formattedExport.startsWith('export let') || formattedExport.startsWith('export var')) {
70+
formattedExport = formattedExport.replace(/^export\s+(const|let|var)/, 'export declare $1')
71+
formattedExport = `${formattedExport.split('=')[0].trim()};`
6972
}
7073

71-
if (exportStatement) {
72-
const formattedComment = comment ? formatComment(comment.trim()) : ''
73-
let formattedExport = exportStatement.trim()
74-
75-
if (formattedExport.startsWith('export function') || formattedExport.startsWith('export async function')) {
76-
formattedExport = formattedExport.replace(/^export\s+(async\s+)?function/, 'export declare function')
77-
const functionSignature = formattedExport.match(/^.*?\)/)
78-
if (functionSignature) {
79-
let params = functionSignature[0].slice(functionSignature[0].indexOf('(') + 1, -1)
80-
params = params.replace(/\s*=[^,)]+/g, '') // Remove default values
81-
const returnType = formattedExport.match(/\):\s*([^{]+)/)
82-
formattedExport = `export declare function ${formattedExport.split('function')[1].split('(')[0].trim()}(${params})${returnType ? `: ${returnType[1].trim()}` : ''};`
83-
}
84-
}
85-
else if (formattedExport.startsWith('export const') || formattedExport.startsWith('export let') || formattedExport.startsWith('export var')) {
86-
formattedExport = formattedExport.replace(/^export\s+(const|let|var)/, 'export declare $1')
87-
formattedExport = `${formattedExport.split('=')[0].trim()};`
88-
}
89-
90-
declarations += `${formattedComment}\n${formattedExport}\n\n`
91-
92-
// Add types used in the export to usedTypes
93-
const typeRegex = /\b([A-Z]\w+)(?:<[^>]*>)?/g
94-
const types = Array.from(formattedExport.matchAll(typeRegex))
95-
types.forEach(([, type]) => usedTypes.add(type))
96-
}
74+
declarations += `${formattedComment}\n${formattedExport}\n\n`
9775

98-
if (!exportStatement && !comment) {
99-
i++
76+
// Add types used in the export to usedTypes
77+
const typeRegex = /\b([A-Z]\w+)(?:<[^>]*>)?/g
78+
let typeMatch
79+
// eslint-disable-next-line no-cond-assign
80+
while ((typeMatch = typeRegex.exec(formattedExport)) !== null) {
81+
usedTypes.add(typeMatch[1])
10082
}
10183
}
10284

0 commit comments

Comments
 (0)