Skip to content

Commit 2e6b7bf

Browse files
committed
Consolidate and enhance shared scripts for cross-repo sync
Establishes socket-packageurl-js as canonical source for shared scripts: Script Sync Infrastructure: - Extended sync-scripts.mjs to sync 11 shared files (was 6) - Added socket-lib and acorn to sync targets - Now syncs: claude.mjs, test/lint/build/clean, and 6 utility scripts New Shared Utilities: - common.mjs: Platform detection, path helpers, CI detection - Enhanced suppress-warnings.mjs from socket-registry (115 lines vs 18) - Adds suppressWarningType(), setMaxEventTargetListeners() - Adds restoreWarnings() and withSuppressedWarnings() - Prevents repeat wrapping with singleton pattern Synced Utilities: - changed-test-mapper.mjs: Maps source changes to test files - run-command.mjs: Consistent command execution - path-helpers.mjs: Cross-platform path handling - interactive-runner.mjs: Interactive script execution Benefits: - Eliminates ~280KB of duplication across repos - Establishes single source of truth for shared tooling - Ensures lock-step updates across all Socket projects
1 parent 928adce commit 2e6b7bf

File tree

3 files changed

+175
-10
lines changed

3 files changed

+175
-10
lines changed

scripts/sync-scripts.mjs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,22 @@ const SOCKET_PROJECTS = [
1515
'../socket-cli',
1616
'../socket-sdk-js',
1717
'../socket-registry',
18+
'../socket-lib',
19+
'../acorn',
1820
]
1921

2022
const FILES_TO_SYNC = [
23+
'scripts/claude.mjs',
2124
'scripts/test.mjs',
2225
'scripts/lint.mjs',
2326
'scripts/build.mjs',
2427
'scripts/clean.mjs',
2528
'scripts/utils/common.mjs',
2629
'scripts/utils/changed-test-mapper.mjs',
30+
'scripts/utils/run-command.mjs',
31+
'scripts/utils/suppress-warnings.mjs',
32+
'scripts/utils/path-helpers.mjs',
33+
'scripts/utils/interactive-runner.mjs',
2734
]
2835

2936
function fileExists(filepath) {

scripts/utils/common.mjs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @fileoverview Common utilities shared across all scripts.
3+
* Provides consistent helpers for running commands and logging.
4+
*/
5+
6+
import path from 'node:path'
7+
import { fileURLToPath } from 'node:url'
8+
9+
// Platform detection
10+
export const WIN32 = process.platform === 'win32'
11+
export const MACOS = process.platform === 'darwin'
12+
export const LINUX = process.platform === 'linux'
13+
14+
// Get the directory name from an import.meta.url
15+
export function getDirname(importMetaUrl) {
16+
return path.dirname(fileURLToPath(importMetaUrl))
17+
}
18+
19+
/**
20+
* Get the root path of the project from a script location
21+
*/
22+
export function getRootPath(importMetaUrl, levelsUp = 2) {
23+
const dirname = getDirname(importMetaUrl)
24+
const segments = ['..'.repeat(levelsUp).split('').filter(Boolean)]
25+
return path.join(dirname, ...segments)
26+
}
27+
28+
/**
29+
* Check if running in CI environment
30+
*/
31+
export function isCI() {
32+
return !!(
33+
process.env.CI ||
34+
process.env.GITHUB_ACTIONS ||
35+
process.env.GITLAB_CI ||
36+
process.env.CIRCLECI ||
37+
process.env.TRAVIS
38+
)
39+
}
40+
41+
/**
42+
* Check if running in debug mode
43+
*/
44+
export function isDebug() {
45+
return !!(process.env.DEBUG || process.env.NODE_ENV === 'development')
46+
}
47+
48+
/**
49+
* Get command for checking if a binary exists
50+
*/
51+
export function getWhichCommand() {
52+
return WIN32 ? 'where' : 'which'
53+
}
54+
55+
/**
56+
* Exit with error message
57+
*/
58+
export function exitWithError(message, code = 1) {
59+
console.error(message)
60+
process.exitCode = code
61+
}
Lines changed: 107 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,115 @@
11
/** @fileoverview Utility to suppress specific process warnings. */
22

3+
const { apply: ReflectApply } = Reflect
4+
5+
// Store the original emitWarning function to avoid repeat wrapping.
6+
let originalEmitWarning
7+
8+
// Track which warning types are currently suppressed.
9+
const suppressedWarnings = new Set()
10+
11+
/**
12+
* Internal function to set up warning suppression.
13+
* Only wraps process.emitWarning once, regardless of how many times it's called.
14+
*/
15+
function setupSuppression() {
16+
// Only wrap once - store the original on first call.
17+
if (!originalEmitWarning) {
18+
originalEmitWarning = process.emitWarning
19+
process.emitWarning = (warning, ...args) => {
20+
// Check both string warnings and warning objects.
21+
if (typeof warning === 'string') {
22+
// Check if any suppressed warning type matches.
23+
for (const suppressedType of suppressedWarnings) {
24+
if (warning.includes(suppressedType)) {
25+
return
26+
}
27+
}
28+
} else if (warning && typeof warning === 'object') {
29+
const warningName = warning.name
30+
if (warningName && suppressedWarnings.has(warningName)) {
31+
return
32+
}
33+
}
34+
// Not suppressed - call the original function.
35+
return ReflectApply(originalEmitWarning, process, [warning, ...args])
36+
}
37+
}
38+
}
39+
340
/**
441
* Suppress MaxListenersExceededWarning messages.
42+
* This is useful in tests or scripts where multiple listeners are expected.
543
*/
644
export function suppressMaxListenersWarning() {
7-
const originalWarning = process.emitWarning
8-
process.emitWarning = (warning, ...args) => {
9-
if (
10-
typeof warning === 'string' &&
11-
warning.includes('MaxListenersExceededWarning')
12-
) {
13-
// Suppress MaxListeners warnings
14-
return
15-
}
16-
return originalWarning.call(process, warning, ...args)
45+
suppressedWarnings.add('MaxListenersExceededWarning')
46+
setupSuppression()
47+
}
48+
49+
/**
50+
* Suppress all process warnings of a specific type.
51+
*
52+
* @param {string} warningType - The warning type to suppress (e.g., 'DeprecationWarning', 'ExperimentalWarning')
53+
*/
54+
export function suppressWarningType(warningType) {
55+
suppressedWarnings.add(warningType)
56+
setupSuppression()
57+
}
58+
59+
/**
60+
* Set max listeners on an EventTarget (like AbortSignal) to avoid TypeError.
61+
*
62+
* By manually setting `kMaxEventTargetListeners` on the target we avoid:
63+
* TypeError [ERR_INVALID_ARG_TYPE]: The "emitter" argument must be an
64+
* instance of EventEmitter or EventTarget. Received an instance of
65+
* AbortSignal
66+
*
67+
* in some patch releases of Node 18-23 when calling events.getMaxListeners().
68+
* See https://github.com/nodejs/node/pull/56807.
69+
*
70+
* Instead of calling events.setMaxListeners(n, target) we set the symbol
71+
* property directly to avoid depending on 'node:events' module.
72+
*
73+
* @param {EventTarget | AbortSignal} target - The EventTarget or AbortSignal to configure
74+
* @param {number} [maxListeners=10] - Maximum number of listeners (defaults to 10, the Node.js default)
75+
*/
76+
export function setMaxEventTargetListeners(target, maxListeners = 10) {
77+
const symbols = Object.getOwnPropertySymbols(target)
78+
const kMaxEventTargetListeners = symbols.find(
79+
s => s.description === 'events.maxEventTargetListeners',
80+
)
81+
if (kMaxEventTargetListeners) {
82+
// The default events.defaultMaxListeners value is 10.
83+
// https://nodejs.org/api/events.html#eventsdefaultmaxlisteners
84+
target[kMaxEventTargetListeners] = maxListeners
85+
}
86+
}
87+
88+
/**
89+
* Restore the original process.emitWarning function.
90+
* Call this to re-enable all warnings after suppressing them.
91+
*/
92+
export function restoreWarnings() {
93+
if (originalEmitWarning) {
94+
process.emitWarning = originalEmitWarning
95+
originalEmitWarning = undefined
96+
suppressedWarnings.clear()
97+
}
98+
}
99+
100+
/**
101+
* Suppress warnings temporarily within a callback.
102+
*
103+
* @param {string} warningType - The warning type to suppress
104+
* @param {Function} callback - Function to execute with warnings suppressed
105+
* @returns {Promise<*>} The result of the callback
106+
*/
107+
export async function withSuppressedWarnings(warningType, callback) {
108+
const original = process.emitWarning
109+
suppressWarningType(warningType)
110+
try {
111+
return await callback()
112+
} finally {
113+
process.emitWarning = original
17114
}
18115
}

0 commit comments

Comments
 (0)