@@ -104,11 +104,11 @@ export function isMatchingPattern(value: string, pattern: RegExp | string): bool
104104 return false ;
105105}
106106
107- type GlobalWithBase64Helpers = {
108- // browser
107+ export type GlobalBase64Helpers = {
108+ // browser and Node 16+
109109 atob ?: ( base64String : string ) => string ;
110110 btoa ?: ( utf8String : string ) => string ;
111- // Node
111+ // all versions of Node
112112 Buffer ?: { from : ( input : string , encoding : string ) => { toString : ( encoding : string ) => string } } ;
113113} ;
114114
@@ -120,7 +120,7 @@ type GlobalWithBase64Helpers = {
120120 * @returns A base64-encoded version of the string
121121 */
122122export function unicodeToBase64 ( plaintext : string ) : string {
123- const globalObject = getGlobalObject < GlobalWithBase64Helpers > ( ) ;
123+ const globalObject = getGlobalObject < GlobalBase64Helpers > ( ) ;
124124
125125 // To account for the fact that different platforms use different character encodings natively, our `tracestate`
126126 // spec calls for all jsonified data to be encoded in UTF-8 bytes before being passed to the base64 encoder.
@@ -129,7 +129,7 @@ export function unicodeToBase64(plaintext: string): string {
129129 throw new Error ( `Input must be a string. Received input of type '${ typeof plaintext } '.` ) ;
130130 }
131131
132- // browser
132+ // browser and Node 16+
133133 if ( 'btoa' in globalObject ) {
134134 // encode using UTF-8
135135 const bytes = new TextEncoder ( ) . encode ( plaintext ) ;
@@ -142,7 +142,7 @@ export function unicodeToBase64(plaintext: string): string {
142142 return globalObject . btoa ! ( bytesAsString ) ;
143143 }
144144
145- // Node
145+ // fallback for Node <= 14
146146 if ( 'Buffer' in globalObject ) {
147147 // encode using UTF-8
148148 // TODO: if TS ever learns about "in", we can get rid of the non-null assertion
@@ -173,7 +173,7 @@ export function unicodeToBase64(plaintext: string): string {
173173 * @returns A Unicode string
174174 */
175175export function base64ToUnicode ( base64String : string ) : string {
176- const globalObject = getGlobalObject < GlobalWithBase64Helpers > ( ) ;
176+ const globalObject = getGlobalObject < GlobalBase64Helpers > ( ) ;
177177
178178 // To account for the fact that different platforms use different character encodings natively, our `tracestate` spec
179179 // calls for all jsonified data to be encoded in UTF-8 bytes before being passed to the base64 encoder. So to reverse
@@ -183,7 +183,7 @@ export function base64ToUnicode(base64String: string): string {
183183 throw new Error ( `Input must be a string. Received input of type '${ typeof base64String } '.` ) ;
184184 }
185185
186- // browser
186+ // browser and Node 16+
187187 if ( 'atob' in globalObject ) {
188188 // `atob` returns a string rather than bytes, so we first need to encode using the native encoding (UTF-16)
189189 // TODO: if TS ever learns about "in", we can get rid of the non-null assertion
@@ -195,7 +195,7 @@ export function base64ToUnicode(base64String: string): string {
195195 return new TextDecoder ( ) . decode ( Uint8Array . from ( bytes ) ) ;
196196 }
197197
198- // Node
198+ // fallback for Node <= 14
199199 if ( 'Buffer' in globalObject ) {
200200 // unlike the browser, Node can go straight from base64 to bytes
201201 // TODO: if TS ever learns about "in", we can get rid of the non-null assertion
0 commit comments