11import { Buffer } from "node:buffer" ;
22
3+ const PHONE_CHARS = [
4+ "0" ,
5+ "1" ,
6+ "2" ,
7+ "3" ,
8+ "4" ,
9+ "5" ,
10+ "6" ,
11+ "7" ,
12+ "8" ,
13+ "9" ,
14+ "*" ,
15+ "#" ,
16+ ] as const ;
17+
18+ export type DTMFChar = ( typeof PHONE_CHARS ) [ number ] ;
19+
20+ const VALID_DTMF_SET = new Set < string > ( PHONE_CHARS ) ;
21+
22+ export function isDTMFChar ( char : string ) : char is DTMFChar {
23+ return VALID_DTMF_SET . has ( char ) ;
24+ }
25+
326class DTMF {
4- public static readonly phoneChars = [
5- "0" ,
6- "1" ,
7- "2" ,
8- "3" ,
9- "4" ,
10- "5" ,
11- "6" ,
12- "7" ,
13- "8" ,
14- "9" ,
15- "*" ,
16- "#" ,
17- ] ;
27+ public static readonly phoneChars = PHONE_CHARS ;
28+
1829 private static readonly payloads = [
1930 0x00060000 ,
2031 0x000600a0 ,
@@ -24,11 +35,8 @@ class DTMF {
2435 0x00860320 ,
2536 ] ;
2637
27- public static charToPayloads = ( char : string ) => {
28- const index = DTMF . phoneChars . indexOf ( char [ 0 ] ) ;
29- if ( index === - 1 ) {
30- throw new Error ( "invalid phone char" ) ;
31- }
38+ public static charToPayloads = ( char : DTMFChar ) => {
39+ const index = DTMF . phoneChars . indexOf ( char ) ;
3240 return DTMF . payloads . map ( ( payload ) => {
3341 const temp = payload + index * 0x01000000 ;
3442 const buffer = Buffer . alloc ( 4 ) ;
@@ -37,9 +45,12 @@ class DTMF {
3745 } ) ;
3846 } ;
3947
40- public static payloadToChar = ( payload : Buffer ) => {
48+ public static payloadToChar = ( payload : Buffer ) : DTMFChar | undefined => {
4149 const intBE = payload . readIntBE ( 0 , 4 ) ;
42- const index = ( intBE - 0x00060000 ) / 0x01000000 ;
50+ const index = Math . floor ( ( intBE - 0x00060000 ) / 0x01000000 ) ;
51+ if ( index < 0 || index >= DTMF . phoneChars . length ) {
52+ return undefined ;
53+ }
4354 return DTMF . phoneChars [ index ] ;
4455 } ;
4556}
0 commit comments