Skip to content

Commit 21139e2

Browse files
committed
Don't copy overrides from pnpm.overrides or resolutions field to the npm overrides field.
1 parent 59e734b commit 21139e2

File tree

5 files changed

+123
-117
lines changed

5 files changed

+123
-117
lines changed

.dep-stats.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"@npmcli/promise-spawn": "^8.0.1",
88
"@socketregistry/hyrious__bun.lockb": "1.0.0",
99
"@socketsecurity/config": "^2.1.3",
10-
"@socketsecurity/registry": "^1.0.4",
10+
"@socketsecurity/registry": "^1.0.8",
1111
"@socketsecurity/sdk": "^1.3.0",
1212
"blessed": "^0.1.81",
1313
"blessed-contrib": "^4.11.0",
@@ -86,7 +86,7 @@
8686
"@npmcli/promise-spawn": "^8.0.1",
8787
"@socketregistry/hyrious__bun.lockb": "1.0.0",
8888
"@socketsecurity/config": "^2.1.3",
89-
"@socketsecurity/registry": "^1.0.4",
89+
"@socketsecurity/registry": "^1.0.8",
9090
"@socketsecurity/sdk": "^1.3.0",
9191
"ansi-align": "^3.0.1",
9292
"blessed": "^0.1.81",

package-lock.json

Lines changed: 5 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
"@npmcli/promise-spawn": "^8.0.1",
4848
"@socketregistry/hyrious__bun.lockb": "1.0.0",
4949
"@socketsecurity/config": "^2.1.3",
50-
"@socketsecurity/registry": "^1.0.4",
50+
"@socketsecurity/registry": "^1.0.8",
5151
"@socketsecurity/sdk": "^1.3.0",
5252
"ansi-align": "^3.0.1",
5353
"blessed": "^0.1.81",

src/commands/optimize.ts

Lines changed: 108 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -5,53 +5,55 @@ import EditablePackageJson from '@npmcli/package-json'
55
import { getManifestData } from '@socketsecurity/registry'
66
import meow from 'meow'
77
import ora from 'ora'
8+
import semver from 'semver'
89

910
import { printFlagList } from '../utils/formatting'
10-
import { hasOwn, isObjectObject } from '../utils/objects'
11+
import { hasOwn } from '../utils/objects'
1112
import { detect } from '../utils/package-manager-detector'
1213
import { escapeRegExp } from '../utils/regexps'
1314
import { toSortedObject } from '../utils/sorts'
1415

15-
import type { Content as PackageJsonContentType } from '@npmcli/package-json'
16+
import type { Content as PackageJsonContent } from '@npmcli/package-json'
1617
import type { CliSubcommand } from '../utils/meow-with-subcommands'
1718
import type {
1819
Agent,
19-
PackageJSONObject,
2020
StringKeyValueObject
2121
} from '../utils/package-manager-detector'
2222

2323
const distPath = __dirname
2424

2525
const OVERRIDES_FIELD_NAME = 'overrides'
26-
2726
const RESOLUTIONS_FIELD_NAME = 'resolutions'
2827

29-
const SOCKET_REGISTRY_NAME = '@socketregistry'
30-
31-
const SOCKET_REGISTRY_MAJOR_VERSION = '^1'
32-
33-
const allPackages = getManifestData('npm')!
34-
.filter(({ 1: d }) => d.engines?.node?.startsWith('>=18'))
35-
.map(({ 1: d }) => d.package)
28+
const availableOverrides = getManifestData('npm')!.filter(({ 1: d }) =>
29+
d.engines?.node?.startsWith('>=18')
30+
)
3631

3732
type NpmOverrides = { [key: string]: string | StringKeyValueObject }
3833
type PnpmOrYarnOverrides = { [key: string]: string }
3934
type Overrides = NpmOverrides | PnpmOrYarnOverrides
35+
type GetOverrides = (pkg: PackageJsonContent) => GetOverridesResult | undefined
36+
type GetOverridesResult = { type: Agent; overrides: Overrides }
4037

41-
type GetManifestOverrides = (pkg: PackageJSONObject) => Overrides | undefined
42-
43-
const getManifestOverridesByAgent: Record<Agent, GetManifestOverrides> = {
38+
const getOverridesDataByAgent: Record<Agent, GetOverrides> = {
4439
// npm overrides documentation:
4540
// https://docs.npmjs.com/cli/v10/configuring-npm/package-json#overrides
46-
npm: (pkgJson: PackageJSONObject) => (pkgJson as any)?.overrides ?? undefined,
41+
npm: (pkgJson: PackageJsonContent) => {
42+
const overrides = (pkgJson as any)?.overrides ?? {}
43+
return { type: 'npm', overrides }
44+
},
4745
// pnpm overrides documentation:
4846
// https://pnpm.io/package_json#pnpmoverrides
49-
pnpm: (pkgJson: PackageJSONObject) =>
50-
(pkgJson as any)?.pnpm?.overrides ?? undefined,
47+
pnpm: (pkgJson: PackageJsonContent) => {
48+
const overrides = (pkgJson as any)?.pnpm?.overrides ?? undefined
49+
return overrides ? { type: 'pnpm', overrides } : undefined
50+
},
5151
// Yarn resolutions documentation:
5252
// https://yarnpkg.com/configuration/manifest#resolutions
53-
yarn: (pkgJson: PackageJSONObject) =>
54-
(pkgJson as any)?.resolutions ?? undefined
53+
yarn: (pkgJson: PackageJsonContent) => {
54+
const overrides = (pkgJson as any)?.resolutions ?? {}
55+
return { type: 'yarn', overrides }
56+
}
5557
}
5658

5759
type LockIncludes = (lockSrc: string, name: string) => boolean
@@ -96,16 +98,22 @@ const updateManifestByAgent: Record<Agent, ModifyManifest> = (<any>{
9698
__proto__: null,
9799
npm(editablePkgJson: EditablePackageJson, overrides: Overrides) {
98100
editablePkgJson.update({
101+
__proto__: null,
99102
[OVERRIDES_FIELD_NAME]: overrides
100103
})
101104
},
102105
pnpm(editablePkgJson: EditablePackageJson, overrides: Overrides) {
103106
editablePkgJson.update({
104-
[OVERRIDES_FIELD_NAME]: overrides
107+
pnpm: {
108+
__proto__: null,
109+
...(<object>editablePkgJson.content['pnpm']),
110+
[OVERRIDES_FIELD_NAME]: overrides
111+
}
105112
})
106113
},
107114
yarn(editablePkgJson: EditablePackageJson, overrides: PnpmOrYarnOverrides) {
108115
editablePkgJson.update({
116+
__proto__: null,
109117
[RESOLUTIONS_FIELD_NAME]: overrides
110118
})
111119
}
@@ -119,7 +127,7 @@ type AddOverridesConfig = {
119127
lockIncludes: LockIncludes
120128
pkgJsonPath: string
121129
pkgJsonStr: string
122-
pkgJson: PackageJSONObject
130+
pkgJson: PackageJsonContent
123131
overrides?: Overrides | undefined
124132
}
125133

@@ -135,55 +143,77 @@ async function addOverrides(
135143
isWorkspace,
136144
lockSrc,
137145
lockIncludes,
138-
pkgJsonPath,
139-
overrides
146+
pkgJsonPath
140147
}: AddOverridesConfig,
141148
aoState: AddOverridesState
142149
): Promise<AddOverridesState> {
143150
const { packageNames } = aoState
144-
let addedCount = 0
145-
let clonedOverrides: Overrides | undefined
146-
for (const name of allPackages) {
147-
if (!hasOwn(overrides, name) && lockIncludes(lockSrc, name)) {
148-
if (clonedOverrides === undefined) {
149-
clonedOverrides = (<unknown>{
150-
__proto__: null,
151-
...overrides
152-
}) as Overrides
151+
const editablePkgJson = await EditablePackageJson.load(
152+
path.dirname(pkgJsonPath)
153+
)
154+
const {
155+
dependencies,
156+
devDependencies,
157+
peerDependencies,
158+
optionalDependencies
159+
} = editablePkgJson.content
160+
const depEntries = <[string, NonNullable<typeof dependencies>][]>[
161+
[
162+
'dependencies',
163+
dependencies ? { __proto__: null, ...dependencies } : undefined
164+
],
165+
[
166+
'devDependencies',
167+
devDependencies ? { __proto__: null, ...devDependencies } : undefined
168+
],
169+
[
170+
'peerDependencies',
171+
peerDependencies ? { __proto__: null, ...peerDependencies } : undefined
172+
],
173+
[
174+
'optionalDependencies',
175+
optionalDependencies
176+
? { __proto__: null, ...optionalDependencies }
177+
: undefined
178+
]
179+
].filter(({ 1: o }) => o)
180+
const overridesDataObjects = <GetOverridesResult[]>[
181+
getOverridesDataByAgent['npm'](editablePkgJson.content)
182+
]
183+
const isApp = isPrivate || isWorkspace
184+
const overridesData =
185+
!isApp || agent !== 'npm'
186+
? getOverridesDataByAgent[isApp ? agent : 'yarn'](editablePkgJson.content)
187+
: undefined
188+
if (overridesData) {
189+
overridesDataObjects.push(overridesData)
190+
}
191+
for (const { 1: data } of availableOverrides) {
192+
const { name: regPkgName, package: origPkgName, version } = data
193+
for (const { 1: depObj } of depEntries) {
194+
const pkgSpec = depObj[origPkgName]
195+
if (pkgSpec) {
196+
if (!pkgSpec.startsWith(`npm:${regPkgName}@`)) {
197+
packageNames.add(regPkgName)
198+
depObj[origPkgName] = `npm:${regPkgName}@^${version}`
199+
}
153200
}
154-
addedCount += 1
155-
packageNames.add(name)
156-
clonedOverrides[name] =
157-
`npm:${SOCKET_REGISTRY_NAME}/${name}@${SOCKET_REGISTRY_MAJOR_VERSION}`
158201
}
159-
}
160-
if (addedCount) {
161-
const editablePkgJson = await EditablePackageJson.load(
162-
path.dirname(pkgJsonPath)
163-
)
164-
const sortedOverrides = toSortedObject(clonedOverrides!)
165-
updateManifestByAgent[agent](editablePkgJson, sortedOverrides)
166-
if (!isPrivate && !isWorkspace) {
202+
for (const { overrides } of overridesDataObjects) {
167203
if (
168-
hasOwn(editablePkgJson.content, 'pnpm') &&
169-
isObjectObject(editablePkgJson.content['pnpm'])
204+
overrides &&
205+
!hasOwn(overrides, origPkgName) &&
206+
lockIncludes(lockSrc, origPkgName)
170207
) {
171-
const pnpmKeys = Object.keys(editablePkgJson.content['pnpm'])
172-
editablePkgJson.update(
173-
(<unknown>(pnpmKeys.length === 1 && pnpmKeys[0] === 'overrides'
174-
? // Properties with undefined values are omitted when saved as JSON.
175-
{ pnpm: undefined }
176-
: {
177-
pnpm: {
178-
__proto__: null,
179-
...(<object>editablePkgJson.content['pnpm']),
180-
overrides: undefined
181-
}
182-
})) as PackageJsonContentType
183-
)
208+
packageNames.add(regPkgName)
209+
overrides[origPkgName] = `npm:${regPkgName}@^${semver.major(version)}`
184210
}
185-
updateManifestByAgent.npm(editablePkgJson, sortedOverrides)
186-
updateManifestByAgent.yarn(editablePkgJson, sortedOverrides)
211+
}
212+
}
213+
if (packageNames.size) {
214+
editablePkgJson.update(<PackageJsonContent>Object.fromEntries(depEntries))
215+
for (const { type, overrides } of overridesDataObjects) {
216+
updateManifestByAgent[type](editablePkgJson, toSortedObject(overrides))
187217
}
188218
await editablePkgJson.save()
189219
}
@@ -232,47 +262,24 @@ export const optimize: CliSubcommand = {
232262
packageNames: new Set()
233263
}
234264
if (lockSrc) {
235-
const configs: {
236-
agent: Agent
237-
lockIncludes: LockIncludes
238-
overrides: Overrides | undefined
239-
}[] =
265+
const lockIncludes =
240266
agent === 'bun'
241-
? [
242-
{
243-
agent: 'npm',
244-
lockIncludes: lockIncludesByAgent.yarn,
245-
overrides: getManifestOverridesByAgent.npm(pkgJson)
246-
},
247-
{
248-
agent: 'yarn',
249-
lockIncludes: lockIncludesByAgent.yarn,
250-
overrides: getManifestOverridesByAgent.yarn(pkgJson)
251-
}
252-
]
253-
: [
254-
{
255-
agent,
256-
lockIncludes: lockIncludesByAgent[agent],
257-
overrides: getManifestOverridesByAgent[agent](pkgJson)
258-
}
259-
]
260-
261-
for (const config of configs) {
262-
await addOverrides(
263-
<AddOverridesConfig>{
264-
__proto__: null,
265-
isPrivate,
266-
isWorkspace,
267-
lockSrc,
268-
pkgJsonPath,
269-
pkgJsonStr,
270-
pkgJson,
271-
...config
272-
},
273-
aoState
274-
)
275-
}
267+
? lockIncludesByAgent.yarn
268+
: lockIncludesByAgent[agent]
269+
await addOverrides(
270+
<AddOverridesConfig>{
271+
__proto__: null,
272+
agent: agent === 'bun' ? 'yarn' : agent,
273+
isPrivate,
274+
isWorkspace,
275+
lockIncludes,
276+
lockSrc,
277+
pkgJsonPath,
278+
pkgJsonStr,
279+
pkgJson
280+
},
281+
aoState
282+
)
276283
}
277284
const { size: count } = aoState.packageNames
278285
if (count) {

src/utils/package-manager-detector.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,16 @@ import { parseJSONObject } from './json'
1111
import { getOwn, isObjectObject } from './objects'
1212
import { isNonEmptyString } from './strings'
1313

14+
import type { Content as PackageJsonContent } from '@npmcli/package-json'
15+
16+
const PNPM_WORKSPACE = 'pnpm-workspace'
17+
1418
export const AGENTS = ['bun', 'npm', 'pnpm', 'yarn'] as const
1519

1620
export type AgentPlusBun = (typeof AGENTS)[number]
17-
1821
export type Agent = Exclude<AgentPlusBun, 'bun'>
19-
2022
export type StringKeyValueObject = { [key: string]: string }
2123

22-
export type PackageJSONObject = {
23-
[key: string]: string | StringKeyValueObject | StringKeyValueObject[]
24-
}
25-
2624
export const LOCKS: Record<string, string> = {
2725
'bun.lockb': 'bun',
2826
'pnpm-lock.yaml': 'pnpm',
@@ -59,7 +57,7 @@ export type DetectResult = Readonly<{
5957
isWorkspace: boolean
6058
lockPath: string | undefined
6159
lockSrc: string | undefined
62-
pkgJson: PackageJSONObject | undefined
60+
pkgJson: PackageJsonContent | undefined
6361
pkgJsonPath: string | undefined
6462
pkgJsonStr: string | undefined
6563
supported: boolean
@@ -176,8 +174,8 @@ export async function detect({
176174
isPrivate = !!pkgJson['private']
177175
isWorkspace =
178176
!!pkgJson['workspaces'] ||
179-
(agent === 'pnpm' &&
180-
existsSync(path.join(pkgPath, 'pnpm-workspace.yaml')))
177+
existsSync(path.join(pkgPath, `${PNPM_WORKSPACE}.yaml`)) ||
178+
existsSync(path.join(pkgPath, `${PNPM_WORKSPACE}.yml`))
181179
let browser: boolean | undefined
182180
let node: boolean | undefined
183181
const browserField = getOwn(pkgJson, 'browser')

0 commit comments

Comments
 (0)