@@ -15,6 +15,38 @@ import { sprintf } from 'sprintf-js';
15
15
import { AdblockSyntaxError } from '../../errors/adblock-syntax-error' ;
16
16
import { END_OF_INPUT , ERROR_MESSAGES } from './constants' ;
17
17
18
+ /**
19
+ * Utility type to get the last element from a tuple, handling optional last elements correctly.
20
+ *
21
+ * @param T - The tuple to extract the last element from.
22
+ * @returns The last element of the tuple if present; `L | undefined` if the last element is optional.
23
+ */
24
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
25
+ type Last < T extends unknown [ ] > = T extends [ ...infer _I , infer L ]
26
+ ? L
27
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
28
+ : T extends [ ...infer _I , ( infer L ) ?] ? L | undefined : never ;
29
+
30
+ /**
31
+ * Utility type to remove the last element from a tuple, handling optional last elements correctly.
32
+ *
33
+ * @param T - The tuple to remove the last element from.
34
+ * @returns A tuple without the last element. If the last element is optional, it is also removed.
35
+ */
36
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
37
+ type OmitLast < T extends unknown [ ] > = T extends [ ...infer Rest , infer _Last ]
38
+ ? Rest
39
+ // Handles cases where the last element is optional
40
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
41
+ : T extends [ ...infer Rest , ( infer _Last ) ?]
42
+ ? Rest
43
+ : never ;
44
+
45
+ /**
46
+ * Extracts the parameters of `OnTokenCallback` as a tuple.
47
+ */
48
+ type OnTokenCallbackParameters = Parameters < OnTokenCallback > ;
49
+
18
50
/**
19
51
* Extended version of `OnTokenCallback` which also receives a `balance` parameter.
20
52
*
@@ -23,11 +55,12 @@ import { END_OF_INPUT, ERROR_MESSAGES } from './constants';
23
55
* @param end End index in the source string.
24
56
* @param props Additional properties of the token (if any - can be `undefined`, depending on the token type).
25
57
* @param balance Calculated balance level of the token.
58
+ * @param stop Function to halt tokenization.
26
59
* @note This function is keeping the same signature as the original `OnTokenCallback` to avoid breaking changes,
27
60
* just adding the `balance` parameter at the end.
28
61
*/
29
62
export type OnBalancedTokenCallback = (
30
- ...args : [ ...Parameters < OnTokenCallback > , ... [ balance : number ] ]
63
+ ...args : [ ...OmitLast < OnTokenCallbackParameters > , balance : number , Last < OnTokenCallbackParameters > ]
31
64
) => ReturnType < OnTokenCallback > ;
32
65
33
66
/**
@@ -72,7 +105,7 @@ const tokenizeWithBalancedPairs = (
72
105
73
106
tokenizeExtended (
74
107
raw ,
75
- ( type : TokenType , start , end , props ) => {
108
+ ( type : TokenType , start , end , props , stop ) => {
76
109
if ( tokenPairs . has ( type ) ) {
77
110
// If the token is an opening token, push its corresponding closing token to the stack.
78
111
// It is safe to use non-null assertion here, because we have checked that the token exists in the map.
@@ -95,7 +128,7 @@ const tokenizeWithBalancedPairs = (
95
128
}
96
129
}
97
130
98
- onToken ( type , start , end , props , stack . length ) ;
131
+ onToken ( type , start , end , props , stack . length , stop ) ;
99
132
} ,
100
133
onError ,
101
134
functionHandlers ,
0 commit comments