11/* eslint-disable @typescript-eslint/no-explicit-any */
22import { Event , Integration , Options , StackFrame , WrappedFunction } from '@sentry/types' ;
33
4- import { isString } from './is' ;
5- import { normalize } from './object' ;
4+ import { dynamicRequire , isNodeEnv } from './node' ;
65import { snipLine } from './string' ;
76
87/** Internal */
@@ -22,26 +21,6 @@ interface SentryGlobal {
2221 } ;
2322}
2423
25- /**
26- * Requires a module which is protected against bundler minification.
27- *
28- * @param request The module path to resolve
29- */
30- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
31- export function dynamicRequire ( mod : any , request : string ) : any {
32- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
33- return mod . require ( request ) ;
34- }
35-
36- /**
37- * Checks whether we're in the Node.js or Browser environment
38- *
39- * @returns Answer to given question
40- */
41- export function isNodeEnv ( ) : boolean {
42- return Object . prototype . toString . call ( typeof process !== 'undefined' ? process : 0 ) === '[object process]' ;
43- }
44-
4524const fallbackGlobalObject = { } ;
4625
4726/**
@@ -253,103 +232,6 @@ export function getLocationHref(): string {
253232 }
254233}
255234
256- /**
257- * Given a child DOM element, returns a query-selector statement describing that
258- * and its ancestors
259- * e.g. [HTMLElement] => body > div > input#foo.btn[name=baz]
260- * @returns generated DOM path
261- */
262- export function htmlTreeAsString ( elem : unknown ) : string {
263- type SimpleNode = {
264- parentNode : SimpleNode ;
265- } | null ;
266-
267- // try/catch both:
268- // - accessing event.target (see getsentry/raven-js#838, #768)
269- // - `htmlTreeAsString` because it's complex, and just accessing the DOM incorrectly
270- // - can throw an exception in some circumstances.
271- try {
272- let currentElem = elem as SimpleNode ;
273- const MAX_TRAVERSE_HEIGHT = 5 ;
274- const MAX_OUTPUT_LEN = 80 ;
275- const out = [ ] ;
276- let height = 0 ;
277- let len = 0 ;
278- const separator = ' > ' ;
279- const sepLength = separator . length ;
280- let nextStr ;
281-
282- // eslint-disable-next-line no-plusplus
283- while ( currentElem && height ++ < MAX_TRAVERSE_HEIGHT ) {
284- nextStr = _htmlElementAsString ( currentElem ) ;
285- // bail out if
286- // - nextStr is the 'html' element
287- // - the length of the string that would be created exceeds MAX_OUTPUT_LEN
288- // (ignore this limit if we are on the first iteration)
289- if ( nextStr === 'html' || ( height > 1 && len + out . length * sepLength + nextStr . length >= MAX_OUTPUT_LEN ) ) {
290- break ;
291- }
292-
293- out . push ( nextStr ) ;
294-
295- len += nextStr . length ;
296- currentElem = currentElem . parentNode ;
297- }
298-
299- return out . reverse ( ) . join ( separator ) ;
300- } catch ( _oO ) {
301- return '<unknown>' ;
302- }
303- }
304-
305- /**
306- * Returns a simple, query-selector representation of a DOM element
307- * e.g. [HTMLElement] => input#foo.btn[name=baz]
308- * @returns generated DOM path
309- */
310- function _htmlElementAsString ( el : unknown ) : string {
311- const elem = el as {
312- tagName ?: string ;
313- id ?: string ;
314- className ?: string ;
315- getAttribute ( key : string ) : string ;
316- } ;
317-
318- const out = [ ] ;
319- let className ;
320- let classes ;
321- let key ;
322- let attr ;
323- let i ;
324-
325- if ( ! elem || ! elem . tagName ) {
326- return '' ;
327- }
328-
329- out . push ( elem . tagName . toLowerCase ( ) ) ;
330- if ( elem . id ) {
331- out . push ( `#${ elem . id } ` ) ;
332- }
333-
334- // eslint-disable-next-line prefer-const
335- className = elem . className ;
336- if ( className && isString ( className ) ) {
337- classes = className . split ( / \s + / ) ;
338- for ( i = 0 ; i < classes . length ; i ++ ) {
339- out . push ( `.${ classes [ i ] } ` ) ;
340- }
341- }
342- const allowedAttrs = [ 'type' , 'name' , 'title' , 'alt' ] ;
343- for ( i = 0 ; i < allowedAttrs . length ; i ++ ) {
344- key = allowedAttrs [ i ] ;
345- attr = elem . getAttribute ( key ) ;
346- if ( attr ) {
347- out . push ( `[${ key } ="${ attr } "]` ) ;
348- }
349- }
350- return out . join ( '' ) ;
351- }
352-
353235const INITIAL_TIME = Date . now ( ) ;
354236let prevNow = 0 ;
355237
@@ -471,24 +353,6 @@ export function parseRetryAfterHeader(now: number, header?: string | number | nu
471353 return defaultRetryAfter ;
472354}
473355
474- const defaultFunctionName = '<anonymous>' ;
475-
476- /**
477- * Safely extract function name from itself
478- */
479- export function getFunctionName ( fn : unknown ) : string {
480- try {
481- if ( ! fn || typeof fn !== 'function' ) {
482- return defaultFunctionName ;
483- }
484- return fn . name || defaultFunctionName ;
485- } catch ( e ) {
486- // Just accessing custom props in some Selenium environments
487- // can cause a "Permission denied" exception (see raven-js#495).
488- return defaultFunctionName ;
489- }
490- }
491-
492356/**
493357 * This function adds context (pre/post/line) lines to the provided frame
494358 *
@@ -520,98 +384,3 @@ export function addContextToFrame(lines: string[], frame: StackFrame, linesOfCon
520384export function hasTracingEnabled ( options : Options ) : boolean {
521385 return ! ! options . tracesSampleRate || ! ! options . tracesSampler ;
522386}
523-
524- /** Default request keys that'll be used to extract data from the request */
525- const DEFAULT_REQUEST_KEYS = [ 'cookies' , 'data' , 'headers' , 'method' , 'query_string' , 'url' ] ;
526-
527- /**
528- * Normalizes data from the request object, accounting for framework differences.
529- *
530- * @param req The request object from which to extract data
531- * @param keys An optional array of keys to include in the normalized data. Defaults to DEFAULT_REQUEST_KEYS if not
532- * provided.
533- * @returns An object containing normalized request data
534- */
535- export function extractNodeRequestData (
536- req : { [ key : string ] : any } ,
537- keys : string [ ] = DEFAULT_REQUEST_KEYS ,
538- ) : { [ key : string ] : string } {
539- // make sure we can safely use dynamicRequire below
540- if ( ! isNodeEnv ( ) ) {
541- throw new Error ( "Can't get node request data outside of a node environment" ) ;
542- }
543-
544- const requestData : { [ key : string ] : any } = { } ;
545-
546- // headers:
547- // node, express: req.headers
548- // koa: req.header
549- const headers = ( req . headers || req . header || { } ) as {
550- host ?: string ;
551- cookie ?: string ;
552- } ;
553- // method:
554- // node, express, koa: req.method
555- const method = req . method ;
556- // host:
557- // express: req.hostname in > 4 and req.host in < 4
558- // koa: req.host
559- // node: req.headers.host
560- const host = req . hostname || req . host || headers . host || '<no host>' ;
561- // protocol:
562- // node: <n/a>
563- // express, koa: req.protocol
564- const protocol =
565- req . protocol === 'https' || req . secure || ( ( req . socket || { } ) as { encrypted ?: boolean } ) . encrypted
566- ? 'https'
567- : 'http' ;
568- // url (including path and query string):
569- // node, express: req.originalUrl
570- // koa: req.url
571- const originalUrl = ( req . originalUrl || req . url ) as string ;
572- // absolute url
573- const absoluteUrl = `${ protocol } ://${ host } ${ originalUrl } ` ;
574-
575- keys . forEach ( key => {
576- switch ( key ) {
577- case 'headers' :
578- requestData . headers = headers ;
579- break ;
580- case 'method' :
581- requestData . method = method ;
582- break ;
583- case 'url' :
584- requestData . url = absoluteUrl ;
585- break ;
586- case 'cookies' :
587- // cookies:
588- // node, express, koa: req.headers.cookie
589- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
590- requestData . cookies = dynamicRequire ( module , 'cookie' ) . parse ( headers . cookie || '' ) ;
591- break ;
592- case 'query_string' :
593- // query string:
594- // node: req.url (raw)
595- // express, koa: req.query
596- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
597- requestData . query_string = dynamicRequire ( module , 'url' ) . parse ( originalUrl || '' , false ) . query ;
598- break ;
599- case 'data' :
600- if ( method === 'GET' || method === 'HEAD' ) {
601- break ;
602- }
603- // body data:
604- // node, express, koa: req.body
605- if ( req . body !== undefined ) {
606- requestData . data = isString ( req . body ) ? req . body : JSON . stringify ( normalize ( req . body ) ) ;
607- }
608- break ;
609- default :
610- if ( { } . hasOwnProperty . call ( req , key ) ) {
611- requestData [ key ] = ( req as { [ key : string ] : any } ) [ key ] ;
612- }
613- }
614- } ) ;
615-
616- return requestData ;
617- }
0 commit comments