-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsuppress.ts
More file actions
147 lines (138 loc) · 4.7 KB
/
Copy pathsuppress.ts
File metadata and controls
147 lines (138 loc) · 4.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/**
* @file `process.emitWarning` suppression. Single shared wrapper installed on
* first call, driven by a membership Set so repeated `suppressWarningType`
* calls are cheap.
*/
import process from 'node:process'
import { SetCtor } from '../../primordials/map-set'
import { ReflectApply } from '../../primordials/reflect'
// Store the original emitWarning function to avoid repeat wrapping.
let originalEmitWarning: typeof process.emitWarning | undefined
// Track which warning types are currently suppressed.
const suppressedWarnings = new SetCtor<string>()
/**
* Restore the original process.emitWarning function. Call this to re-enable all
* warnings after suppressing them.
*
* @example
* ;```typescript
* suppressMaxListenersWarning()
* // ... do work ...
* restoreWarnings() // Re-enable all warnings
* ```
*/
export function restoreWarnings(): void {
if (originalEmitWarning) {
process.emitWarning = originalEmitWarning
originalEmitWarning = undefined
suppressedWarnings.clear()
}
}
/**
* Internal function to set up warning suppression. Only wraps
* process.emitWarning once, regardless of how many times it's called.
*/
export function setupSuppression(): void {
// Only wrap once - store the original on first call.
// First-call init only fires once per process; subsequent calls
// hit the second-call no-op branch.
/* c8 ignore start */
if (!originalEmitWarning) {
originalEmitWarning = process.emitWarning
process.emitWarning = (warning: string | Error, ...args: unknown[]) => {
if (typeof warning === 'string') {
for (const suppressedType of suppressedWarnings) {
if (warning.includes(suppressedType)) {
return
}
}
} else if (warning && typeof warning === 'object') {
/* c8 ignore start - Object-shaped warning suppression
(Error / Warning instances). process.emitWarning rarely
passes object form in test runs; covered when consumers
pass real Warning subclasses. */
const warningObj = warning as { name?: string | undefined }
if (warningObj.name && suppressedWarnings.has(warningObj.name)) {
return
}
/* c8 ignore stop */
}
// Not suppressed - call the original function.
return ReflectApply(
originalEmitWarning as typeof process.emitWarning,
process,
[warning, ...args],
)
}
}
/* c8 ignore stop */
}
/**
* Silence `MaxListenersExceededWarning` messages from `process.emitWarning`.
* Installs a single shared wrapper around `process.emitWarning` on first call
* so repeat invocations are cheap.
*
* @example
* import { suppressMaxListenersWarning } from '@socketsecurity/lib/events/warning/suppress'
*
* suppressMaxListenersWarning()
*/
export function suppressMaxListenersWarning(): void {
suppressedWarnings.add('MaxListenersExceededWarning')
setupSuppression()
}
/**
* Suppress all process warnings of a specific type.
*
* @example
* import { suppressWarningType } from '@socketsecurity/lib/events/warning/suppress'
*
* suppressWarningType('ExperimentalWarning')
*
* @param warningType - The warning type to suppress (e.g.,
* 'DeprecationWarning', 'ExperimentalWarning')
*/
export function suppressWarningType(warningType: string): void {
suppressedWarnings.add(warningType)
setupSuppression()
}
/**
* Suppress warnings temporarily within a callback.
*
* @example
* import { withSuppressedWarnings } from '@socketsecurity/lib/events/warning/suppress'
*
* const result = await withSuppressedWarnings(
* 'ExperimentalWarning',
* async () => {
* // Code that triggers experimental warnings
* return someValue
* },
* )
*
* @param warningType - The warning type to suppress.
* @param callback - Function to execute with warnings suppressed.
*
* @returns The result of the callback
*/
export async function withSuppressedWarnings<T>(
warningType: string,
callback: () => T | Promise<T>,
): Promise<T> {
const wasAlreadySuppressed = suppressedWarnings.has(warningType)
suppressWarningType(warningType)
try {
return await callback()
} finally {
// The wrapper is driven by `suppressedWarnings` membership, so
// removing this type from the set is enough to stop suppressing it.
// Do NOT reassign `process.emitWarning` here: snapshotting the
// previous value at the top would either (a) capture the native
// function when the wrapper was already installed and then restore
// native — wiping every other active suppression — or (b) be the
// wrapper itself, in which case the restore is a no-op anyway.
if (!wasAlreadySuppressed) {
suppressedWarnings.delete(warningType)
}
}
}