@@ -121,31 +121,20 @@ export interface PropertyInfo {
121
121
*/
122
122
interface ProcessingState {
123
123
dtsLines : string [ ]
124
- /** Import statements */
125
124
imports : string [ ]
126
- /** Set of types used in declarations */
127
125
usedTypes : Set < string >
128
- /** Map of type names to their source modules */
129
126
typeSources : Map < string , string >
130
- /** Default export declaration */
131
127
defaultExport : string
132
- /** Current declaration being processed */
133
128
currentDeclaration : string
134
- /** Last processed JSDoc comment block */
135
129
lastCommentBlock : string
136
- /** Bracket nesting level counter */
137
130
bracketCount : number
138
- /** Flag for multi-line declarations */
139
131
isMultiLineDeclaration : boolean
140
- /** Map of module imports with metadata */
141
132
moduleImports : Map < string , ImportInfo >
142
- /** Map of available type names */
143
133
availableTypes : Map < string , string >
144
- /** Map of available value names */
145
134
availableValues : Map < string , string >
146
135
currentIndentation : string
147
136
declarationBuffer : {
148
- type : 'interface' | 'type' | 'const' | 'function'
137
+ type : 'interface' | 'type' | 'const' | 'function' | 'import' | 'export'
149
138
indent : string
150
139
lines : string [ ]
151
140
comments : string [ ]
@@ -499,9 +488,20 @@ function processDeclarationBuffer(
499
488
state : ProcessingState ,
500
489
isExported : boolean ,
501
490
) : string {
502
- const declaration = buffer . lines . join ( '\n' )
503
- const cleaned = cleanDeclaration ( declaration )
491
+ const content = buffer . lines . join ( '\n' )
504
492
493
+ // Skip processing for export * statements
494
+ if ( content . trim ( ) . startsWith ( 'export *' ) ) {
495
+ return content
496
+ }
497
+
498
+ // Skip processing for export type {} statements
499
+ if ( content . trim ( ) . startsWith ( 'export type {' ) ) {
500
+ return content
501
+ }
502
+
503
+ // Process regular declarations
504
+ const cleaned = cleanDeclaration ( content )
505
505
switch ( buffer . type ) {
506
506
case 'interface' :
507
507
return processInterfaceDeclaration ( cleaned , isExported )
@@ -512,8 +512,72 @@ function processDeclarationBuffer(
512
512
case 'function' :
513
513
return processFunctionDeclaration ( cleaned , state . usedTypes , isExported )
514
514
default :
515
- return declaration
515
+ return content
516
+ }
517
+ }
518
+
519
+ function processDeclarationBlock ( lines : string [ ] , comments : string [ ] , state : ProcessingState ) : void {
520
+ const declaration = lines . join ( '\n' )
521
+ const trimmed = declaration . trim ( )
522
+
523
+ if ( ! trimmed || trimmed . startsWith ( '//' ) )
524
+ return
525
+
526
+ // Keep original indentation
527
+ const indentMatch = lines [ 0 ] . match ( / ^ ( \s * ) / )
528
+ const baseIndent = indentMatch ? indentMatch [ 1 ] : ''
529
+
530
+ if ( comments . length > 0 ) {
531
+ state . dtsLines . push ( ...comments )
532
+ }
533
+
534
+ if ( trimmed . startsWith ( 'import' ) ) {
535
+ // Imports are handled separately in the first pass
536
+ return
537
+ }
538
+
539
+ if ( trimmed . startsWith ( 'export * from' ) ) {
540
+ state . dtsLines . push ( declaration )
541
+ return
542
+ }
543
+
544
+ if ( trimmed . startsWith ( 'export type {' ) ) {
545
+ state . dtsLines . push ( declaration )
546
+ return
547
+ }
548
+
549
+ if ( trimmed . startsWith ( 'export {' ) ) {
550
+ state . dtsLines . push ( declaration )
551
+ return
552
+ }
553
+
554
+ if ( trimmed . startsWith ( 'interface' ) || trimmed . startsWith ( 'export interface' ) ) {
555
+ const processed = processInterfaceDeclaration ( declaration , trimmed . startsWith ( 'export' ) )
556
+ state . dtsLines . push ( processed )
557
+ return
558
+ }
559
+
560
+ if ( trimmed . startsWith ( 'type' ) || trimmed . startsWith ( 'export type' ) ) {
561
+ const processed = processTypeDeclaration ( declaration , trimmed . startsWith ( 'export' ) )
562
+ state . dtsLines . push ( processed )
563
+ return
564
+ }
565
+
566
+ if ( trimmed . startsWith ( 'const' ) || trimmed . startsWith ( 'export const' ) ) {
567
+ const processed = processConstDeclaration ( declaration , trimmed . startsWith ( 'export' ) )
568
+ state . dtsLines . push ( processed )
569
+ return
570
+ }
571
+
572
+ if ( trimmed . startsWith ( 'function' ) || trimmed . startsWith ( 'export function' )
573
+ || trimmed . startsWith ( 'async function' ) || trimmed . startsWith ( 'export async function' ) ) {
574
+ const processed = processFunctionDeclaration ( declaration , state . usedTypes , trimmed . startsWith ( 'export' ) )
575
+ state . dtsLines . push ( processed )
576
+ return
516
577
}
578
+
579
+ // Default case: preserve the declaration as-is
580
+ state . dtsLines . push ( declaration )
517
581
}
518
582
519
583
/**
@@ -530,8 +594,7 @@ function processConstDeclaration(declaration: string, isExported = true): string
530
594
const typeMatch = firstLine . match ( / c o n s t \s + ( [ ^ : ] + ) : \s * ( [ ^ = ] + ) \s * = / )
531
595
if ( typeMatch ) {
532
596
const [ , name , type ] = typeMatch
533
- // When there's an explicit type annotation, only use the type
534
- return `${ indent } declare const ${ name . trim ( ) } : ${ type . trim ( ) } ;`
597
+ return `${ isExported ? 'export ' : '' } declare const ${ name . trim ( ) } : ${ type . trim ( ) } ;`
535
598
}
536
599
537
600
// No type annotation, extract name and infer type
@@ -551,9 +614,33 @@ function processConstDeclaration(declaration: string, isExported = true): string
551
614
return `${ isExported ? 'export ' : '' } declare const ${ name } : {\n${ propertyStrings } \n};`
552
615
}
553
616
617
+ // Handle simple value assignments
618
+ const valueMatch = firstLine . match ( / = \s * ( .+ ) $ / )
619
+ if ( valueMatch ) {
620
+ const value = valueMatch [ 1 ] . trim ( )
621
+ const inferredType = inferValueType ( value )
622
+ return `${ isExported ? 'export ' : '' } declare const ${ name } : ${ inferredType } ;`
623
+ }
624
+
554
625
return declaration
555
626
}
556
627
628
+ function inferValueType ( value : string ) : string {
629
+ if ( value . startsWith ( '{' ) )
630
+ return 'Record<string, unknown>'
631
+ if ( value . startsWith ( '[' ) )
632
+ return 'unknown[]'
633
+ if ( value . startsWith ( '\'' ) || value . startsWith ( '"' ) )
634
+ return 'string'
635
+ if ( ! Number . isNaN ( Number ( value ) ) )
636
+ return 'number'
637
+ if ( value === 'true' || value === 'false' )
638
+ return 'boolean'
639
+ if ( value . includes ( '=>' ) )
640
+ return '(...args: any[]) => unknown'
641
+ return 'unknown'
642
+ }
643
+
557
644
/**
558
645
* Format nested properties with proper indentation
559
646
*/
@@ -802,15 +889,33 @@ function isDeclarationStart(line: string): boolean {
802
889
803
890
function isDeclarationComplete ( lines : string [ ] ) : boolean {
804
891
let bracketCount = 0
892
+ let inString = false
893
+ let stringChar = ''
894
+
805
895
for ( const line of lines ) {
806
896
for ( const char of line ) {
807
- if ( char === '{' )
808
- bracketCount ++
809
- if ( char === '}' )
810
- bracketCount --
897
+ // Handle string content
898
+ if ( ( char === '"' || char === '\'' ) && ! inString ) {
899
+ inString = true
900
+ stringChar = char
901
+ }
902
+ else if ( inString && char === stringChar ) {
903
+ inString = false
904
+ continue
905
+ }
906
+
907
+ if ( ! inString ) {
908
+ if ( char === '{' || char === '(' )
909
+ bracketCount ++
910
+ if ( char === '}' || char === ')' )
911
+ bracketCount --
912
+ }
811
913
}
812
914
}
813
- return bracketCount === 0
915
+
916
+ // Also check for single-line declarations
917
+ const lastLine = lines [ lines . length - 1 ] . trim ( )
918
+ return bracketCount === 0 && ( lastLine . endsWith ( ';' ) || lastLine . endsWith ( '}' ) )
814
919
}
815
920
816
921
/**
@@ -1066,17 +1171,25 @@ function processInterfaceDeclaration(declaration: string, isExported = true): st
1066
1171
]
1067
1172
1068
1173
// Add members with preserved indentation
1174
+ let seenContent = false
1069
1175
for ( let i = 1 ; i < lines . length - 1 ; i ++ ) {
1070
1176
const line = lines [ i ]
1071
1177
const content = line . trim ( )
1072
1178
if ( content ) {
1179
+ seenContent = true
1073
1180
processedLines . push ( `${ memberIndent } ${ content } ` )
1074
1181
}
1075
1182
}
1076
1183
1184
+ // If no content was found, add a newline for better formatting
1185
+ if ( ! seenContent ) {
1186
+ processedLines . push ( '' )
1187
+ }
1188
+
1077
1189
processedLines . push ( `${ baseIndent } }` )
1078
1190
return processedLines . join ( '\n' )
1079
1191
}
1192
+
1080
1193
/**
1081
1194
* Process type declarations
1082
1195
*/
@@ -1118,30 +1231,76 @@ function processTypeDeclaration(declaration: string, isExported = true): string
1118
1231
}
1119
1232
1120
1233
function processSourceFile ( content : string , state : ProcessingState ) : void {
1121
- console . log ( 'Processing source file...' )
1122
-
1123
1234
const lines = content . split ( '\n' )
1124
- let lineNumber = 0
1235
+
1236
+ // First pass: collect imports
1237
+ const imports = lines . filter ( line => line . trim ( ) . startsWith ( 'import' ) ) . join ( '\n' )
1238
+ if ( imports ) {
1239
+ state . imports = processImports ( imports . split ( '\n' ) , state . usedTypes )
1240
+ }
1241
+
1242
+ // Second pass: process everything else
1243
+ let currentBlock : string [ ] = [ ]
1244
+ let currentComments : string [ ] = [ ]
1245
+ let isInMultilineDeclaration = false
1125
1246
1126
1247
for ( const line of lines ) {
1127
- lineNumber ++
1128
- try {
1129
- // Clean the line before processing
1130
- const cleaned = cleanDeclaration ( line )
1131
-
1132
- // Check if line needs export
1133
- if ( needsExport ( cleaned ) ) {
1134
- console . log ( `Line ${ lineNumber } : Processing exportable declaration:` , cleaned )
1248
+ const trimmedLine = line . trim ( )
1249
+
1250
+ // Skip empty lines between declarations
1251
+ if ( ! trimmedLine && ! isInMultilineDeclaration ) {
1252
+ if ( currentBlock . length > 0 ) {
1253
+ processDeclarationBlock ( currentBlock , currentComments , state )
1254
+ currentBlock = [ ]
1255
+ currentComments = [ ]
1256
+ }
1257
+ continue
1258
+ }
1259
+
1260
+ // Handle comments
1261
+ if ( isCommentLine ( trimmedLine ) ) {
1262
+ if ( ! isInMultilineDeclaration ) {
1263
+ if ( trimmedLine . startsWith ( '/**' ) ) {
1264
+ currentComments = [ ]
1265
+ }
1266
+ currentComments . push ( line )
1135
1267
}
1268
+ else {
1269
+ currentBlock . push ( line )
1270
+ }
1271
+ continue
1272
+ }
1273
+
1274
+ // Track multiline declarations
1275
+ if ( ! isInMultilineDeclaration && ( trimmedLine . includes ( '{' ) || trimmedLine . includes ( '(' ) ) ) {
1276
+ isInMultilineDeclaration = true
1277
+ }
1278
+
1279
+ currentBlock . push ( line )
1280
+
1281
+ if ( isInMultilineDeclaration ) {
1282
+ const openCount = ( line . match ( / [ { ( ] / g) || [ ] ) . length
1283
+ const closeCount = ( line . match ( / [ } ) ] / g) || [ ] ) . length
1284
+ state . bracketCount += openCount - closeCount
1136
1285
1137
- processDeclarationLine ( line , state )
1286
+ if ( state . bracketCount === 0 ) {
1287
+ isInMultilineDeclaration = false
1288
+ processDeclarationBlock ( currentBlock , currentComments , state )
1289
+ currentBlock = [ ]
1290
+ currentComments = [ ]
1291
+ }
1138
1292
}
1139
- catch ( error ) {
1140
- console . error ( `Error processing line ${ lineNumber } :` , { line, error } )
1293
+ else if ( ! trimmedLine . endsWith ( ',' ) ) {
1294
+ processDeclarationBlock ( currentBlock , currentComments , state )
1295
+ currentBlock = [ ]
1296
+ currentComments = [ ]
1141
1297
}
1142
1298
}
1143
1299
1144
- console . log ( 'Finished processing source file' )
1300
+ // Process any remaining block
1301
+ if ( currentBlock . length > 0 ) {
1302
+ processDeclarationBlock ( currentBlock , currentComments , state )
1303
+ }
1145
1304
}
1146
1305
1147
1306
/**
0 commit comments