1
- import { getGlobalObject } from './compat' ;
1
+ import { getMainCarrier } from './compat' ;
2
2
import { SentryError } from './error' ;
3
3
import { isRegExp , isString } from './is' ;
4
4
@@ -112,42 +112,24 @@ export function isMatchingPattern(value: string, pattern: RegExp | string): bool
112
112
* @returns A base64-encoded version of the string
113
113
*/
114
114
export function unicodeToBase64 ( plaintext : string ) : string {
115
- const global = getGlobalObject ( ) ;
115
+ const platformSpecificBase64Convertor = getMainCarrier ( ) . __SENTRY__ ?. extensions ?. unsafeToBase64 ;
116
116
117
- // Cast to a string just in case we're given something else
118
- const stringifiedInput = String ( plaintext ) ;
119
- const errMsg = `Unable to convert to base64: ${
120
- stringifiedInput . length > 256 ? `${ stringifiedInput . slice ( 0 , 256 ) } ...` : stringifiedInput
121
- } `;
117
+ if ( ! platformSpecificBase64Convertor ) {
118
+ throw new SentryError ( '`unsafeToBase64` not found. Cannot convert string from base64.' ) ;
119
+ }
122
120
123
121
// To account for the fact that different platforms use different character encodings natively, our `tracestate`
124
122
// spec calls for all jsonified data to be encoded in UTF-8 bytes before being passed to the base64 encoder.
125
123
try {
126
- // browser
127
- if ( 'btoa' in global ) {
128
- // encode using UTF-8
129
- const bytes = new TextEncoder ( ) . encode ( plaintext ) ;
130
-
131
- // decode using UTF-16 (JS's native encoding) since `btoa` requires string input
132
- const bytesAsString = String . fromCharCode ( ...bytes ) ;
133
-
134
- return btoa ( bytesAsString ) ;
135
- }
136
-
137
- // Node
138
- if ( 'Buffer' in global ) {
139
- // encode using UTF-8
140
- const bytes = Buffer . from ( plaintext , 'utf-8' ) ;
141
-
142
- // unlike the browser, Node can go straight from bytes to base64
143
- return bytes . toString ( 'base64' ) ;
144
- }
124
+ return platformSpecificBase64Convertor ( plaintext ) ;
145
125
} catch ( err ) {
126
+ // Cast to a string just in case we're given something else
127
+ const stringifiedInput = String ( plaintext ) ;
128
+ const errMsg = `Unable to convert to base64: ${
129
+ stringifiedInput . length > 256 ? `${ stringifiedInput . slice ( 0 , 256 ) } ...` : stringifiedInput
130
+ } `;
146
131
throw new SentryError ( `${ errMsg } \nGot error: ${ err } ` ) ;
147
132
}
148
-
149
- // we shouldn't ever get here, because one of `btoa` and `Buffer` should exist, but just in case...
150
- throw new SentryError ( errMsg ) ;
151
133
}
152
134
153
135
/**
@@ -158,40 +140,23 @@ export function unicodeToBase64(plaintext: string): string {
158
140
* @returns A Unicode string
159
141
*/
160
142
export function base64ToUnicode ( base64String : string ) : string {
161
- const globalObject = getGlobalObject ( ) ;
143
+ const platformSpecificBase64Convertor = getMainCarrier ( ) . __SENTRY__ ?. extensions ?. unsafeFromBase64 ;
162
144
163
- // we cast to a string just in case we're given something else
164
- const stringifiedInput = String ( base64String ) ;
165
- const errMsg = `Unable to convert from base64: ${
166
- stringifiedInput . length > 256 ? `${ stringifiedInput . slice ( 0 , 256 ) } ...` : stringifiedInput
167
- } `;
145
+ if ( ! platformSpecificBase64Convertor ) {
146
+ throw new SentryError ( '`unsafeFromBase64` not found. Cannot convert string from base64.' ) ;
147
+ }
168
148
169
149
// To account for the fact that different platforms use different character encodings natively, our `tracestate` spec
170
150
// calls for all jsonified data to be encoded in UTF-8 bytes before being passed to the base64 encoder. So to reverse
171
151
// the process, decode from base64 to bytes, then feed those bytes to a UTF-8 decoder.
172
152
try {
173
- // browser
174
- if ( 'atob' in globalObject ) {
175
- // `atob` returns a string rather than bytes, so we first need to encode using the native encoding (UTF-16)
176
- const bytesAsString = atob ( base64String ) ;
177
- const bytes = [ ...bytesAsString ] . map ( char => char . charCodeAt ( 0 ) ) ;
178
-
179
- // decode using UTF-8 (cast the `bytes` arry to a Uint8Array just because that's the format `decode()` expects)
180
- return new TextDecoder ( ) . decode ( Uint8Array . from ( bytes ) ) ;
181
- }
182
-
183
- // Node
184
- if ( 'Buffer' in globalObject ) {
185
- // unlike the browser, Node can go straight from base64 to bytes
186
- const bytes = Buffer . from ( base64String , 'base64' ) ;
187
-
188
- // decode using UTF-8
189
- return bytes . toString ( 'utf-8' ) ;
190
- }
153
+ return platformSpecificBase64Convertor ( base64String ) ;
191
154
} catch ( err ) {
155
+ // we cast to a string just in case we're given something else
156
+ const stringifiedInput = String ( base64String ) ;
157
+ const errMsg = `Unable to convert from base64: ${
158
+ stringifiedInput . length > 256 ? `${ stringifiedInput . slice ( 0 , 256 ) } ...` : stringifiedInput
159
+ } `;
192
160
throw new SentryError ( `${ errMsg } \nGot error: ${ err } ` ) ;
193
161
}
194
-
195
- // we shouldn't ever get here, because one of `atob` and `Buffer` should exist, but just in case...
196
- throw new SentryError ( errMsg ) ;
197
162
}
0 commit comments