19
19
/* eslint-disable no-console */
20
20
21
21
import * as fs from "fs" ;
22
+ import { getRandomValues } from 'node:crypto' ;
22
23
import * as path from "path" ;
23
24
24
25
import * as ts from "typescript" ;
@@ -44,7 +45,7 @@ interface CallSiteInfo {
44
45
character : number ;
45
46
argumentsText : string [ ] ; // Added to store argument text
46
47
errorMessage : string | undefined ;
47
- assertionId : number ;
48
+ assertionId : string ;
48
49
}
49
50
50
51
/**
@@ -127,7 +128,7 @@ function findFunctionCalls(filePaths: string[]): CallSiteInfo[] {
127
128
// --- Extract Arguments ---
128
129
const argsText : string [ ] = [ ] ;
129
130
let errorMessage : string | undefined ;
130
- let assertionId : number | undefined ;
131
+ let assertionId : string | undefined ;
131
132
if ( node . arguments && node . arguments . length > 0 ) {
132
133
node . arguments . forEach ( ( arg : ts . Expression ) => {
133
134
// Get the source text of the argument node
@@ -137,7 +138,7 @@ function findFunctionCalls(filePaths: string[]): CallSiteInfo[] {
137
138
errorMessage = arg . getText ( sourceFile ) ;
138
139
}
139
140
else if ( ts . isNumericLiteral ( arg ) ) {
140
- assertionId = parseInt ( arg . getText ( sourceFile ) , 10 ) ;
141
+ assertionId = arg . getText ( sourceFile ) ;
141
142
}
142
143
} ) ;
143
144
}
@@ -151,7 +152,7 @@ function findFunctionCalls(filePaths: string[]): CallSiteInfo[] {
151
152
character : character + 1 ,
152
153
argumentsText : argsText , // Store the extracted arguments,
153
154
errorMessage,
154
- assertionId : assertionId ?? - 1
155
+ assertionId : assertionId ?? "INVALID" ,
155
156
} ) ;
156
157
}
157
158
}
@@ -180,19 +181,20 @@ function handleList(occurrences: CallSiteInfo[]): void {
180
181
return ;
181
182
}
182
183
183
- occurrences . sort ( ( a , b ) => a . assertionId - b . assertionId ) . forEach ( ( call ) => {
184
+ occurrences . sort ( ( a , b ) => a . assertionId . localeCompare ( b . assertionId ) ) . forEach ( ( call ) => {
184
185
console . log (
185
186
`ID: ${ call . assertionId } ; MESSAGE: ${ call . errorMessage } ; SOURCE: '${ call . functionName } ' call at ${ path . relative ( process . cwd ( ) , call . fileName ) } :${ call . line } :${ call . character } `
186
187
) ;
187
188
} ) ;
189
+ }
188
190
191
+ function find ( occurrences : CallSiteInfo [ ] , targetId : string | number ) : CallSiteInfo [ ] {
192
+ const target = typeof targetId === 'number' ? targetId . toString ( 16 ) : targetId ;
193
+ return occurrences . filter ( o => String ( o . assertionId ) === String ( target ) ) ;
189
194
}
190
195
191
196
function handleFind ( occurrences : CallSiteInfo [ ] , targetId : string | number ) : void {
192
- // Normalize target code for comparison if necessary (e.g., string vs number)
193
- const target = typeof targetId === 'number' ? targetId : targetId . toString ( ) ;
194
-
195
- const foundLocations = occurrences . filter ( o => String ( o . assertionId ) === String ( target ) ) ; // Compare as strings
197
+ const foundLocations = find ( occurrences , targetId ) ;
196
198
197
199
if ( foundLocations . length === 0 ) {
198
200
log ( `Assertion id "${ targetId } " not found.` ) ;
@@ -210,11 +212,20 @@ function handleCheck(occurrences: CallSiteInfo[]): void {
210
212
const idCounts : { [ id : string ] : CallSiteInfo [ ] } = { } ;
211
213
212
214
occurrences . forEach ( occ => {
215
+ // Count ID occurrences
213
216
const codeStr = String ( occ . assertionId ) ; // Use string representation as key
214
217
if ( ! idCounts [ codeStr ] ) {
215
218
idCounts [ codeStr ] = [ ] ;
216
219
}
217
220
idCounts [ codeStr ] . push ( occ ) ;
221
+
222
+ // validate formats
223
+ if ( ! / ^ 0 x [ 0 - 9 a - f ] { 4 } $ / . test ( occ . assertionId ) ) {
224
+ console . error ( `Invalid assertion ID '${ occ . assertionId } '. Must match /^0x[0-9a-f]{4}$/` ) ;
225
+
226
+ const relativePath = path . relative ( process . cwd ( ) , occ . fileName ) ;
227
+ console . error ( `- at '${ relativePath } :${ occ . line } :${ occ . character } ` ) ;
228
+ }
218
229
} ) ;
219
230
220
231
let duplicatesFound = false ;
@@ -238,22 +249,23 @@ function handleCheck(occurrences: CallSiteInfo[]): void {
238
249
}
239
250
}
240
251
241
- function handleNew ( occurrences : CallSiteInfo [ ] ) : void {
242
- // --- Simple Numeric Scheme: Find max numeric code and add 1 ---
243
- let maxCode = 0 ;
252
+ function randomId ( ) : string {
253
+ const randomBytes = new Uint8Array ( 2 ) ;
254
+ getRandomValues ( randomBytes ) ;
244
255
245
- occurrences . forEach ( occ => {
246
- if ( occ . assertionId > maxCode ) {
247
- maxCode = occ . assertionId ;
248
- }
249
- } ) ;
256
+ return '0x' + Array . from ( randomBytes )
257
+ . map ( byte => byte . toString ( 16 ) . padStart ( 2 , '0' ) )
258
+ . join ( '' ) ;
259
+ }
250
260
251
- if ( occurrences . length === 0 ) {
252
- log ( "0" ) ;
253
- return ;
261
+ function handleNew ( occurrences : CallSiteInfo [ ] ) : void {
262
+ let newCode : string = randomId ( ) ;
263
+
264
+ // If we find this code already is used, regenerate it.
265
+ while ( find ( occurrences , newCode ) . length > 0 ) {
266
+ newCode = randomId ( ) ;
254
267
}
255
268
256
- const newCode = maxCode + 1 ;
257
269
console . log ( newCode ) ;
258
270
}
259
271
0 commit comments