@@ -72,7 +72,6 @@ import { c as tarCreate, x as tarExtract } from 'tar'
7272import { parseArgs } from '../registry/dist/lib/parse-args.js'
7373
7474import { cleanTestScript } from '../test/utils/script-cleaning.mjs'
75- import { testRunners } from '../test/utils/test-runners.mjs'
7675import { suppressMaxListenersWarning } from './utils/suppress-warnings.mjs'
7776import { safeRemove } from './utils/fs.mjs'
7877import { filterPackagesByChanges } from './utils/git.mjs'
@@ -83,13 +82,34 @@ import {
8382import constants from './constants.mjs'
8483import ENV from '../registry/dist/lib/constants/ENV.js'
8584import spinner from '../registry/dist/lib/constants/spinner.js'
85+ import NODE_MODULES from '../registry/dist/lib/constants/NODE_MODULES.js'
86+ import PACKAGE_JSON from '../registry/dist/lib/constants/PACKAGE_JSON.js'
8687import WIN32 from '../registry/dist/lib/constants/WIN32.js'
8788import { readPackageJson } from '../registry/dist/lib/packages.js'
8889import { pEach , pRetry } from '../registry/dist/lib/promises.js'
8990import { LOG_SYMBOLS , logger } from '../registry/dist/lib/logger.js'
9091import { spawn } from '../registry/dist/lib/spawn.js'
9192import { pluralize } from '../registry/dist/lib/words.js'
92- import { writeJson } from '../registry/dist/lib/fs.js'
93+ import { readFileUtf8 , readJson , writeJson } from '../registry/dist/lib/fs.js'
94+
95+ // Default concurrency values based on environment and platform.
96+ const DEFAULT_CI_CONCURRENCY_WIN32 = '5'
97+ const DEFAULT_CI_CONCURRENCY_POSIX = '10'
98+ const DEFAULT_DEV_CONCURRENCY = '15'
99+
100+ // Filesystem delay constants for tar extraction and JSON parsing.
101+ const FS_FLUSH_DELAY_MS = 100
102+ const JSON_PARSE_RETRY_BASE_DELAY_MS = 200
103+ const JSON_PARSE_MAX_RETRIES = 3
104+
105+ // Output truncation length for error messages.
106+ const ERROR_OUTPUT_TRUNCATE_LENGTH = 1_000
107+
108+ // Progress update intervals for CI vs. local environments.
109+ const PROGRESS_UPDATE_INTERVAL_CI = 10
110+ const PROGRESS_UPDATE_INTERVAL_DEV = 1
111+ const PROGRESS_TIMER_INTERVAL_CI_MS = 1_000
112+ const PROGRESS_TIMER_INTERVAL_DEV_MS = 100
93113
94114const { values : cliArgs } = parseArgs ( {
95115 options : {
@@ -99,7 +119,11 @@ const { values: cliArgs } = parseArgs({
99119 } ,
100120 concurrency : {
101121 type : 'string' ,
102- default : ENV . CI ? ( WIN32 ? '5' : '10' ) : '15' ,
122+ default : ENV . CI
123+ ? WIN32
124+ ? DEFAULT_CI_CONCURRENCY_WIN32
125+ : DEFAULT_CI_CONCURRENCY_POSIX
126+ : DEFAULT_DEV_CONCURRENCY ,
103127 } ,
104128 'temp-dir' : {
105129 type : 'string' ,
@@ -140,7 +164,7 @@ function completePackage() {
140164
141165async function computeOverrideHash ( overridePath ) {
142166 try {
143- const pkgJsonPath = path . join ( overridePath , 'package.json' )
167+ const pkgJsonPath = path . join ( overridePath , PACKAGE_JSON )
144168 const pkgJson = await readPackageJson ( pkgJsonPath )
145169 // Hash the dependencies to detect changes.
146170 const depsString = JSON . stringify ( {
@@ -217,7 +241,7 @@ async function generatePnpmOverrides(options) {
217241 }
218242
219243 const packagePath = path . join ( npmPackagesDir , packageName )
220- const pkgJsonPath = path . join ( packagePath , 'package.json' )
244+ const pkgJsonPath = path . join ( packagePath , PACKAGE_JSON )
221245
222246 try {
223247 // eslint-disable-next-line no-await-in-loop
@@ -322,7 +346,7 @@ async function applySocketOverrideIfExists(packageName, packagePath) {
322346 }
323347
324348 // Read the Socket override package.json.
325- const overridePkgJsonPath = path . join ( overridePath , 'package.json' )
349+ const overridePkgJsonPath = path . join ( overridePath , PACKAGE_JSON )
326350 let overridePkgJson
327351 try {
328352 overridePkgJson = await readPackageJson ( overridePkgJsonPath )
@@ -331,7 +355,7 @@ async function applySocketOverrideIfExists(packageName, packagePath) {
331355 }
332356
333357 // Read the existing package.json.
334- const packageJsonPath = path . join ( packagePath , 'package.json' )
358+ const packageJsonPath = path . join ( packagePath , PACKAGE_JSON )
335359 let existingPkgJson
336360 try {
337361 existingPkgJson = await readPackageJson ( packageJsonPath , {
@@ -352,9 +376,9 @@ async function applySocketOverrideIfExists(packageName, packagePath) {
352376 errorOnExist : false ,
353377 ...( WIN32 ? { retryDelay : 100 , maxRetries : 3 } : { } ) ,
354378 filter : src =>
355- ! src . includes ( 'node_modules' ) &&
379+ ! src . includes ( NODE_MODULES ) &&
356380 ! src . endsWith ( '.DS_Store' ) &&
357- ! src . endsWith ( 'package.json' ) ,
381+ ! src . endsWith ( PACKAGE_JSON ) ,
358382 } )
359383 } catch ( e ) {
360384 // Ignore errors about same paths - this happens when pnpm symlinks to our override.
@@ -421,8 +445,8 @@ async function installPackage(packageInfo) {
421445 const packageTempDir = path . join ( tempBaseDir , socketPkgName )
422446
423447 // Check if package is already installed and has a test script.
424- const installedPath = path . join ( packageTempDir , 'node_modules' , origPkgName )
425- const packageJsonPath = path . join ( installedPath , 'package.json' )
448+ const installedPath = path . join ( packageTempDir , NODE_MODULES , origPkgName )
449+ const packageJsonPath = path . join ( installedPath , PACKAGE_JSON )
426450 const installMarkerPath = path . join (
427451 packageTempDir ,
428452 '.socket-install-complete' ,
@@ -438,9 +462,7 @@ async function installPackage(packageInfo) {
438462 const existingPkgJson = await readPackageJson ( packageJsonPath , {
439463 editable : true ,
440464 } )
441- const markerData = JSON . parse (
442- await fs . readFile ( installMarkerPath , 'utf8' ) ,
443- )
465+ const markerData = await readJson ( installMarkerPath )
444466
445467 // Verify the installation matches the requested version and override hash.
446468 // Also check if the cached installation references GitHub extraction directories.
@@ -620,25 +642,29 @@ async function installPackage(packageInfo) {
620642
621643 // Wait briefly for filesystem to flush after tar extraction.
622644 // This prevents reading truncated files on slower CI systems.
623- await new Promise ( resolve => setTimeout ( resolve , 100 ) )
645+ await new Promise ( resolve => setTimeout ( resolve , FS_FLUSH_DELAY_MS ) )
624646
625647 // Find the extracted directory (GitHub archives extract to reponame-commitish/).
626648 const entries = await fs . readdir ( tempExtractDir , {
627649 withFileTypes : true ,
628650 } )
629651 const extractedDir = entries . find (
630- e => e . isDirectory ( ) && e . name !== 'node_modules' ,
652+ e => e . isDirectory ( ) && e . name !== NODE_MODULES ,
631653 )
632654
633655 if ( extractedDir ) {
634656 const extractedPath = path . join ( tempExtractDir , extractedDir . name )
635- const pkgJsonPath = path . join ( extractedPath , 'package.json' )
657+ const pkgJsonPath = path . join ( extractedPath , PACKAGE_JSON )
636658
637659 // Verify package.json exists and is not empty.
638- // Retry up to 3 times to handle filesystem flush delays on slow CI systems.
660+ // Retry up to JSON_PARSE_MAX_RETRIES times to handle filesystem flush delays on slow CI systems.
639661 let editablePkgJson
640662 let lastError
641- for ( let attempt = 1 ; attempt <= 3 ; attempt += 1 ) {
663+ for (
664+ let attempt = 1 ;
665+ attempt <= JSON_PARSE_MAX_RETRIES ;
666+ attempt += 1
667+ ) {
642668 try {
643669 // eslint-disable-next-line no-await-in-loop
644670 const pkgJsonStats = await fs . stat ( pkgJsonPath )
@@ -655,18 +681,20 @@ async function installPackage(packageInfo) {
655681 break
656682 } catch ( error ) {
657683 lastError = error
658- if ( attempt < 3 ) {
684+ if ( attempt < JSON_PARSE_MAX_RETRIES ) {
659685 // Wait longer on each retry (200ms, 400ms).
660686 // eslint-disable-next-line no-await-in-loop
661- await new Promise ( resolve => setTimeout ( resolve , attempt * 200 ) )
687+ await new Promise ( resolve =>
688+ setTimeout ( resolve , attempt * JSON_PARSE_RETRY_BASE_DELAY_MS ) ,
689+ )
662690 }
663691 }
664692 }
665693
666694 if ( ! editablePkgJson ) {
667695 // All retries failed, add diagnostic info.
668696 const pkgJsonStats = await fs . stat ( pkgJsonPath )
669- const fileContent = await fs . readFile ( pkgJsonPath , 'utf8' )
697+ const fileContent = await readFileUtf8 ( pkgJsonPath )
670698 throw new Error (
671699 `Invalid package.json after 3 retries: ${ lastError . message } . File size: ${ pkgJsonStats . size } , Content preview: ${ fileContent . slice ( 0 , 200 ) } ` ,
672700 )
@@ -901,11 +929,6 @@ async function installPackage(packageInfo) {
901929 ...( overridePkgJson . main ? { main : overridePkgJson . main } : { } ) ,
902930 ...( overridePkgJson . module ? { module : overridePkgJson . module } : { } ) ,
903931 ...( overridePkgJson . types ? { types : overridePkgJson . types } : { } ) ,
904- ...( overridePkgJson . files ? { files : overridePkgJson . files } : { } ) ,
905- ...( overridePkgJson . sideEffects !== undefined
906- ? { sideEffects : overridePkgJson . sideEffects }
907- : { } ) ,
908- ...( overridePkgJson . socket ? { socket : overridePkgJson . socket } : { } ) ,
909932 // Make the package private for testing.
910933 private : true ,
911934 } )
@@ -916,86 +939,18 @@ async function installPackage(packageInfo) {
916939 delete originalPkgJson . content . scripts . pretest
917940 delete originalPkgJson . content . scripts . posttest
918941
919- // Look for actual test runner in scripts.
920- const additionalTestRunners = [ ...testRunners , 'test:stock' , 'test:all' ]
921- let actualTestScript = additionalTestRunners . find (
922- runner => originalPkgJson . content . scripts [ runner ] ,
923- )
924-
925- if ( ! actualTestScript && originalPkgJson . content . scripts . test ) {
926- // Try to extract the test runner from the test script.
927- const testMatch =
928- originalPkgJson . content . scripts . test . match ( / n p m r u n ( [ - : \w ] + ) / )
929- if ( testMatch && originalPkgJson . content . scripts [ testMatch [ 1 ] ] ) {
930- actualTestScript = testMatch [ 1 ]
931- }
932- }
933-
934- // Helper to check if a script contains non-test patterns.
935- const nonTestPatterns = [ 'lint' , 'pretest' , 'build' , 'compile' , 'tsc' ]
936- const containsNonTestPattern = script =>
937- nonTestPatterns . some ( pattern => script ?. includes ( pattern ) )
938-
939- // Helper to find a real test runner that doesn't run non-test commands.
940- const findRealTestRunner = ( ) =>
941- testRunners . find (
942- runner =>
943- originalPkgJson . content . scripts [ runner ] &&
944- ! containsNonTestPattern ( originalPkgJson . content . scripts [ runner ] ) ,
945- )
946-
947942 // Build cleaned scripts object.
948943 const cleanedScripts = { __proto__ : null }
949944 for ( const { 0 : key , 1 : value } of Object . entries (
950945 originalPkgJson . content . scripts ,
951946 ) ) {
952- if ( key . startsWith ( 'test' ) || key === actualTestScript ) {
947+ if ( key . startsWith ( 'test' ) ) {
953948 cleanedScripts [ key ] = cleanTestScript ( value )
954949 } else {
955950 cleanedScripts [ key ] = value
956951 }
957952 }
958953
959- // Clean the test script first to extract just the test runner.
960- if ( cleanedScripts . test ) {
961- // If the test script just runs non-test commands after cleaning, find a real test runner.
962- if ( containsNonTestPattern ( cleanedScripts . test ) ) {
963- const realTestRunner = findRealTestRunner ( )
964- if ( realTestRunner ) {
965- cleanedScripts . test =
966- originalPkgJson . content . scripts [ realTestRunner ]
967- }
968- }
969-
970- // If test script just delegates to another script, resolve it.
971- const delegateMatch = cleanedScripts . test ?. match ( / ^ n p m r u n ( [ - : \w ] + ) $ / )
972- if ( delegateMatch ) {
973- const targetScript = delegateMatch [ 1 ]
974- const targetScriptContent =
975- originalPkgJson . content . scripts [ targetScript ]
976-
977- if (
978- targetScriptContent &&
979- ! containsNonTestPattern ( targetScriptContent )
980- ) {
981- // Resolve to the actual command, not the npm run wrapper.
982- cleanedScripts . test = targetScriptContent
983- // Also preserve the target script itself.
984- cleanedScripts [ targetScript ] = targetScriptContent
985- } else {
986- // Target script doesn't exist or is non-test, try to find a real test runner.
987- const realTestRunner = findRealTestRunner ( )
988- if ( realTestRunner ) {
989- cleanedScripts . test =
990- originalPkgJson . content . scripts [ realTestRunner ]
991- // Also preserve the real test runner script.
992- cleanedScripts [ realTestRunner ] =
993- originalPkgJson . content . scripts [ realTestRunner ]
994- }
995- }
996- }
997- }
998-
999954 // Update scripts using .update().
1000955 originalPkgJson . update ( {
1001956 scripts : cleanedScripts ,
@@ -1082,15 +1037,21 @@ async function installPackage(packageInfo) {
10821037 writeProgress ( LOG_SYMBOLS . fail )
10831038 completePackage ( )
10841039 const errorDetails = [ error . message ]
1085- // Show last 1000 chars of stderr (where actual errors appear)
1040+ // Show last ERROR_OUTPUT_TRUNCATE_LENGTH chars of stderr (where actual errors appear).
10861041 if ( error . stderr ) {
1087- const stderrText = error . stderr . slice ( - 1_000 )
1088- errorDetails . push ( 'STDERR (last 1000 chars):' , stderrText )
1042+ const stderrText = error . stderr . slice ( - ERROR_OUTPUT_TRUNCATE_LENGTH )
1043+ errorDetails . push (
1044+ `STDERR (last ${ ERROR_OUTPUT_TRUNCATE_LENGTH } chars):` ,
1045+ stderrText ,
1046+ )
10891047 }
1090- // Show last 1000 chars of stdout
1048+ // Show last ERROR_OUTPUT_TRUNCATE_LENGTH chars of stdout.
10911049 if ( error . stdout ) {
1092- const stdoutText = error . stdout . slice ( - 1_000 )
1093- errorDetails . push ( 'STDOUT (last 1000 chars):' , stdoutText )
1050+ const stdoutText = error . stdout . slice ( - ERROR_OUTPUT_TRUNCATE_LENGTH )
1051+ errorDetails . push (
1052+ `STDOUT (last ${ ERROR_OUTPUT_TRUNCATE_LENGTH } chars):` ,
1053+ stdoutText ,
1054+ )
10941055 }
10951056 return {
10961057 package : origPkgName ,
@@ -1194,7 +1155,9 @@ async function main() {
11941155
11951156 // Update spinner text when progress changes.
11961157 // In CI environments, batch updates to avoid excessive line output.
1197- const updateInterval = ENV . CI ? 10 : 1
1158+ const updateInterval = ENV . CI
1159+ ? PROGRESS_UPDATE_INTERVAL_CI
1160+ : PROGRESS_UPDATE_INTERVAL_DEV
11981161 let lastCompletedCount = 0
11991162 const progressInterval = setInterval (
12001163 ( ) => {
@@ -1209,7 +1172,7 @@ async function main() {
12091172 lastCompletedCount = completedPackages
12101173 }
12111174 } ,
1212- ENV . CI ? 1_000 : 100 ,
1175+ ENV . CI ? PROGRESS_TIMER_INTERVAL_CI_MS : PROGRESS_TIMER_INTERVAL_DEV_MS ,
12131176 )
12141177
12151178 // Ensure base temp directory exists.
0 commit comments