@@ -4,109 +4,82 @@ import npa from 'npm-package-arg'
44import semver from 'semver'
55import { glob as tinyGlob } from 'tinyglobby'
66
7- import { type ManifestEntry } from '@socketsecurity/registry'
7+ import { getManifestData } from '@socketsecurity/registry'
88import { hasOwn , toSortedObject } from '@socketsecurity/registry/lib/objects'
99import {
1010 fetchPackageManifest ,
1111 readPackageJson
1212} from '@socketsecurity/registry/lib/packages'
13- import { type EditablePackageJson } from '@socketsecurity/registry/lib/packages'
1413import { pEach } from '@socketsecurity/registry/lib/promises'
1514import { Spinner } from '@socketsecurity/registry/lib/spinner'
1615import { pluralize } from '@socketsecurity/registry/lib/words'
1716
1817import { depsIncludesByAgent } from './deps-includes-by-agent'
19- import { detectAndValidatePackageManager } from './detect-and-validate-package-manager '
18+ import { detectAndValidatePackageEnvironment } from './detect-and-validate-package-environment '
2019import { getDependencyEntries } from './get-dependency-entries'
21- import { getOverridesDataByAgent } from './get-overrides-by-agent'
20+ import { overridesDataByAgent } from './get-overrides-by-agent'
2221import { getWorkspaceGlobs } from './get-workspace-globs'
23- import {
24- AgentLockIncludesFn ,
25- lockIncludesByAgent
26- } from './lock-includes-by-agent'
22+ import { lockIncludesByAgent } from './lock-includes-by-agent'
2723import { lsByAgent } from './ls-by-agent'
2824import { updateManifestByAgent } from './update-manifest-by-agent'
2925import { updatePackageLockJson } from './update-package-lock-json'
3026import constants from '../../constants'
3127
28+ import type { AgentLockIncludesFn } from './lock-includes-by-agent'
3229import type {
3330 Agent ,
31+ PackageEnvironmentDetails ,
3432 StringKeyValueObject
35- } from '../../utils/package-manager-detector'
36-
37- type PackageJson = Awaited < ReturnType < typeof readPackageJson > >
33+ } from '../../utils/package-environment-detector'
3834
39- type AddOverridesConfig = {
40- agent : Agent
41- agentExecPath : string
42- lockBasename : string
43- lockSrc : string
44- manifestEntries : ManifestEntry [ ]
45- npmExecPath : string
46- pkgJson ?: EditablePackageJson | undefined
47- pkgPath : string
35+ type AddOverridesOptions = {
36+ logger ?: Console | undefined
4837 pin ?: boolean | undefined
4938 prod ?: boolean | undefined
50- rootPath : string
39+ spinner ?: Spinner | undefined
40+ state ?: AddOverridesState | undefined
5141}
52-
5342type AddOverridesState = {
5443 added : Set < string >
5544 addedInWorkspaces : Set < string >
56- spinner : Spinner
5745 updated : Set < string >
5846 updatedInWorkspaces : Set < string >
5947 warnedPnpmWorkspaceRequiresNpm : boolean
6048}
61-
49+ type GetOverridesResult = { type : Agent ; overrides : Overrides }
6250type NpmOverrides = { [ key : string ] : string | StringKeyValueObject }
51+ type PackageJson = Awaited < ReturnType < typeof readPackageJson > >
6352type PnpmOrYarnOverrides = { [ key : string ] : string }
6453type Overrides = NpmOverrides | PnpmOrYarnOverrides
65- type GetOverridesResult = { type : Agent ; overrides : Overrides }
6654
6755const { NPM , PNPM , YARN_CLASSIC } = constants
6856
6957const COMMAND_TITLE = 'Socket Optimize'
7058
59+ const manifestNpmOverrides = getManifestData ( NPM )
60+
7161export async function applyOptimization (
7262 cwd : string ,
7363 pin : boolean ,
7464 prod : boolean
7565) {
76- const pkgMgrData = await detectAndValidatePackageManager ( cwd , prod )
77- if ( ! pkgMgrData ) return
78-
79- const {
80- agent,
81- agentExecPath,
82- lockBasename,
83- lockName,
84- lockSrc,
85- manifestEntries,
86- npmExecPath,
87- pkgJson,
88- pkgPath
89- } = pkgMgrData
90-
66+ const logger = console
67+ const pkgEnvDetails = await detectAndValidatePackageEnvironment ( cwd , {
68+ logger,
69+ prod
70+ } )
71+ if ( ! pkgEnvDetails ) {
72+ return
73+ }
9174 const spinner = new Spinner ( { text : 'Socket optimizing...' } )
9275 spinner . start ( )
9376
94- const state = await addOverrides (
95- {
96- agent,
97- agentExecPath,
98- lockBasename,
99- lockSrc,
100- manifestEntries,
101- npmExecPath,
102- pin,
103- pkgJson,
104- pkgPath,
105- prod,
106- rootPath : pkgPath
107- } ,
108- createAddOverridesState ( spinner )
109- )
77+ const state = await addOverrides ( pkgEnvDetails . pkgPath , pkgEnvDetails , {
78+ logger,
79+ pin,
80+ prod,
81+ spinner
82+ } )
11083
11184 spinner . stop ( )
11285
@@ -115,23 +88,23 @@ export async function applyOptimization(
11588 const pkgJsonChanged = addedCount > 0 || updatedCount > 0
11689 if ( pkgJsonChanged ) {
11790 if ( updatedCount > 0 ) {
118- console . log (
91+ logger ? .log (
11992 `${ createActionMessage ( 'Updated' , updatedCount , state . updatedInWorkspaces . size ) } ${ addedCount ? '.' : '🚀' } `
12093 )
12194 }
12295 if ( addedCount > 0 ) {
123- console . log (
96+ logger ? .log (
12497 `${ createActionMessage ( 'Added' , addedCount , state . addedInWorkspaces . size ) } 🚀`
12598 )
12699 }
127100 } else {
128- console . log ( 'Congratulations! Already Socket.dev optimized 🎉' )
101+ logger ? .log ( 'Congratulations! Already Socket.dev optimized 🎉' )
129102 }
130103
131- if ( agent === NPM || pkgJsonChanged ) {
104+ if ( pkgEnvDetails . agent === NPM || pkgJsonChanged ) {
132105 // Always update package-lock.json until the npm overrides PR lands:
133106 // https://github.com/npm/cli/pull/8089
134- await updatePackageLockJson ( lockName , agentExecPath , agent , spinner )
107+ await updatePackageLockJson ( pkgEnvDetails , { logger , spinner } )
135108 }
136109}
137110
@@ -143,37 +116,36 @@ function createActionMessage(
143116 return `${ verb } ${ overrideCount } Socket.dev optimized ${ pluralize ( 'override' , overrideCount ) } ${ workspaceCount ? ` in ${ workspaceCount } ${ pluralize ( 'workspace' , workspaceCount ) } ` : '' } `
144117}
145118
146- function createAddOverridesState ( spinner : Spinner ) : AddOverridesState {
147- return {
148- added : new Set ( ) ,
149- addedInWorkspaces : new Set ( ) ,
150- spinner,
151- updated : new Set ( ) ,
152- updatedInWorkspaces : new Set ( ) ,
153- warnedPnpmWorkspaceRequiresNpm : false
154- }
155- }
156-
157119async function addOverrides (
158- {
120+ pkgPath : string ,
121+ pkgEnvDetails : PackageEnvironmentDetails ,
122+ options ?: AddOverridesOptions | undefined
123+ ) : Promise < AddOverridesState > {
124+ const {
159125 agent,
160126 agentExecPath,
161- lockBasename ,
127+ lockName ,
162128 lockSrc,
163- manifestEntries,
164129 npmExecPath,
130+ pkgPath : rootPath
131+ } = pkgEnvDetails
132+ const {
133+ logger,
165134 pin,
166- pkgJson : editablePkgJson ,
167- pkgPath,
168135 prod,
169- rootPath
170- } : AddOverridesConfig ,
171- state : AddOverridesState
172- ) : Promise < AddOverridesState > {
136+ spinner,
137+ state = {
138+ added : new Set ( ) ,
139+ addedInWorkspaces : new Set ( ) ,
140+ updated : new Set ( ) ,
141+ updatedInWorkspaces : new Set ( ) ,
142+ warnedPnpmWorkspaceRequiresNpm : false
143+ }
144+ } = < AddOverridesOptions > { __proto__ : null , ...options }
145+ let { pkgJson : editablePkgJson } = pkgEnvDetails
173146 if ( editablePkgJson === undefined ) {
174147 editablePkgJson = await readPackageJson ( pkgPath , { editable : true } )
175148 }
176- const { spinner } = state
177149 const { content : pkgJson } = editablePkgJson
178150 const isRoot = pkgPath === rootPath
179151 const isLockScanned = isRoot && ! prod
@@ -187,35 +159,42 @@ async function addOverrides(
187159 ! state . warnedPnpmWorkspaceRequiresNpm
188160 ) {
189161 state . warnedPnpmWorkspaceRequiresNpm = true
190- console . warn (
162+ logger ? .warn (
191163 `⚠️ ${ COMMAND_TITLE } : pnpm workspace support requires \`npm ls\`, falling back to \`pnpm list\``
192164 )
193165 }
194166 const thingToScan = isLockScanned
195167 ? lockSrc
196- : await lsByAgent [ agent ] ( agentExecPath , pkgPath , { npmExecPath } )
168+ : await lsByAgent [ agent ] ! ( agentExecPath , pkgPath , { npmExecPath } )
197169 // The AgentDepsIncludesFn and AgentLockIncludesFn types overlap in their
198170 // first two parameters. AgentLockIncludesFn accepts an optional third
199171 // parameter which AgentDepsIncludesFn will ignore so we cast thingScanner
200172 // as an AgentLockIncludesFn type.
201173 const thingScanner = < AgentLockIncludesFn > (
202- ( isLockScanned ? lockIncludesByAgent [ agent ] : depsIncludesByAgent [ agent ] )
174+ ( isLockScanned
175+ ? lockIncludesByAgent . get ( agent )
176+ : depsIncludesByAgent . get ( agent ) )
203177 )
204178 const depEntries = getDependencyEntries ( pkgJson )
205179
206180 const overridesDataObjects = < GetOverridesResult [ ] > [ ]
207181 if ( pkgJson [ 'private' ] || isWorkspace ) {
208- overridesDataObjects . push ( getOverridesDataByAgent [ agent ] ( pkgJson ) )
182+ overridesDataObjects . push ( overridesDataByAgent . get ( agent ) ! ( pkgJson ) )
209183 } else {
210184 overridesDataObjects . push (
211- getOverridesDataByAgent [ NPM ] ( pkgJson ) ,
212- getOverridesDataByAgent [ YARN_CLASSIC ] ( pkgJson )
185+ overridesDataByAgent . get ( NPM ) ! ( pkgJson ) ,
186+ overridesDataByAgent . get ( YARN_CLASSIC ) ! ( pkgJson )
213187 )
214188 }
215189 if ( spinner ) {
216190 spinner . text = `Adding overrides${ workspaceName ? ` to ${ workspaceName } ` : '' } ...`
217191 }
218192 const depAliasMap = new Map < string , string > ( )
193+
194+ const nodeRange = `>=${ pkgEnvDetails . minimumNodeVersion } `
195+ const manifestEntries = manifestNpmOverrides . filter ( ( { 1 : data } ) =>
196+ semver . satisfies ( semver . coerce ( data . engines . node ) ! , nodeRange )
197+ )
219198 // Chunk package names to process them in parallel 3 at a time.
220199 await pEach ( manifestEntries , 3 , async ( { 1 : data } ) => {
221200 const { name : sockRegPkgName , package : origPkgName , version } = data
@@ -258,7 +237,7 @@ async function addOverrides(
258237 const overrideExists = hasOwn ( overrides , origPkgName )
259238 if (
260239 overrideExists ||
261- thingScanner ( thingToScan , origPkgName , lockBasename )
240+ thingScanner ( thingToScan , origPkgName , lockName )
262241 ) {
263242 const oldSpec = overrideExists ? overrides [ origPkgName ] ! : undefined
264243 const origDepAlias = depAliasMap . get ( origPkgName )
@@ -313,19 +292,14 @@ async function addOverrides(
313292 // Chunk package names to process them in parallel 3 at a time.
314293 await pEach ( workspacePkgJsonPaths , 3 , async workspacePkgJsonPath => {
315294 const otherState = await addOverrides (
295+ path . dirname ( workspacePkgJsonPath ) ,
296+ pkgEnvDetails ,
316297 {
317- agent,
318- agentExecPath,
319- lockBasename,
320- lockSrc,
321- manifestEntries,
322- npmExecPath,
298+ logger,
323299 pin,
324- pkgPath : path . dirname ( workspacePkgJsonPath ) ,
325300 prod,
326- rootPath
327- } ,
328- createAddOverridesState ( spinner )
301+ spinner
302+ }
329303 )
330304 for ( const key of [
331305 'added' ,
@@ -351,7 +325,10 @@ async function addOverrides(
351325 if ( state . added . size > 0 || state . updated . size > 0 ) {
352326 editablePkgJson . update ( < PackageJson > Object . fromEntries ( depEntries ) )
353327 for ( const { overrides, type } of overridesDataObjects ) {
354- updateManifestByAgent [ type ] ( editablePkgJson , toSortedObject ( overrides ) )
328+ updateManifestByAgent . get ( type ) ! (
329+ editablePkgJson ,
330+ toSortedObject ( overrides )
331+ )
355332 }
356333 await editablePkgJson . save ( )
357334 }
0 commit comments