Skip to content

Commit de619a4

Browse files
committed
deps: npm-pick-manifest@11.0.3
1 parent 0e042ec commit de619a4

File tree

12 files changed

+569
-11
lines changed

12 files changed

+569
-11
lines changed

node_modules/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,10 @@
170170
/npm-packlist/node_modules/*
171171
!/npm-packlist/node_modules/proc-log
172172
!/npm-pick-manifest
173+
!/npm-pick-manifest/node_modules/
174+
/npm-pick-manifest/node_modules/*
175+
!/npm-pick-manifest/node_modules/npm-install-checks
176+
!/npm-pick-manifest/node_modules/npm-normalize-package-bin
173177
!/npm-profile
174178
!/npm-registry-fetch
175179
!/npm-user-validate
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
Copyright (c) Robert Kowalski and Isaac Z. Schlueter ("Authors")
2+
All rights reserved.
3+
4+
The BSD License
5+
6+
Redistribution and use in source and binary forms, with or without
7+
modification, are permitted provided that the following conditions
8+
are met:
9+
10+
1. Redistributions of source code must retain the above copyright
11+
notice, this list of conditions and the following disclaimer.
12+
13+
2. Redistributions in binary form must reproduce the above copyright
14+
notice, this list of conditions and the following disclaimer in the
15+
documentation and/or other materials provided with the distribution.
16+
17+
THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20+
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS
21+
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27+
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
const process = require('node:process')
2+
const nodeOs = require('node:os')
3+
const fs = require('node:fs')
4+
5+
function isMusl (file) {
6+
return file.includes('libc.musl-') || file.includes('ld-musl-')
7+
}
8+
9+
function os () {
10+
return process.platform
11+
}
12+
13+
function cpu () {
14+
return process.arch
15+
}
16+
17+
const LDD_PATH = '/usr/bin/ldd'
18+
function getFamilyFromFilesystem () {
19+
try {
20+
const content = fs.readFileSync(LDD_PATH, 'utf-8')
21+
if (content.includes('musl')) {
22+
return 'musl'
23+
}
24+
if (content.includes('GNU C Library')) {
25+
return 'glibc'
26+
}
27+
return null
28+
} catch {
29+
return undefined
30+
}
31+
}
32+
33+
function getFamilyFromReport () {
34+
const originalExclude = process.report.excludeNetwork
35+
process.report.excludeNetwork = true
36+
const report = process.report.getReport()
37+
process.report.excludeNetwork = originalExclude
38+
if (report.header?.glibcVersionRuntime) {
39+
family = 'glibc'
40+
} else if (Array.isArray(report.sharedObjects) && report.sharedObjects.some(isMusl)) {
41+
family = 'musl'
42+
} else {
43+
family = null
44+
}
45+
return family
46+
}
47+
48+
let family
49+
function libc (osName) {
50+
if (osName !== 'linux') {
51+
return undefined
52+
}
53+
if (family === undefined) {
54+
family = getFamilyFromFilesystem()
55+
if (family === undefined) {
56+
family = getFamilyFromReport()
57+
}
58+
}
59+
return family
60+
}
61+
62+
function devEngines (env = {}) {
63+
const osName = env.os || os()
64+
return {
65+
cpu: {
66+
name: env.cpu || cpu(),
67+
},
68+
libc: {
69+
name: env.libc || libc(osName),
70+
},
71+
os: {
72+
name: osName,
73+
version: env.osVersion || nodeOs.release(),
74+
},
75+
packageManager: {
76+
name: 'npm',
77+
version: env.npmVersion,
78+
},
79+
runtime: {
80+
name: 'node',
81+
version: env.nodeVersion || process.version,
82+
},
83+
}
84+
}
85+
86+
module.exports = {
87+
cpu,
88+
libc,
89+
os,
90+
devEngines,
91+
}
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
const satisfies = require('semver/functions/satisfies')
2+
const validRange = require('semver/ranges/valid')
3+
4+
const recognizedOnFail = [
5+
'ignore',
6+
'warn',
7+
'error',
8+
'download',
9+
]
10+
11+
const recognizedProperties = [
12+
'name',
13+
'version',
14+
'onFail',
15+
]
16+
17+
const recognizedEngines = [
18+
'packageManager',
19+
'runtime',
20+
'cpu',
21+
'libc',
22+
'os',
23+
]
24+
25+
/** checks a devEngine dependency */
26+
function checkDependency (wanted, current, opts) {
27+
const { engine } = opts
28+
29+
if ((typeof wanted !== 'object' || wanted === null) || Array.isArray(wanted)) {
30+
throw new Error(`Invalid non-object value for "${engine}"`)
31+
}
32+
33+
const properties = Object.keys(wanted)
34+
35+
for (const prop of properties) {
36+
if (!recognizedProperties.includes(prop)) {
37+
throw new Error(`Invalid property "${prop}" for "${engine}"`)
38+
}
39+
}
40+
41+
if (!properties.includes('name')) {
42+
throw new Error(`Missing "name" property for "${engine}"`)
43+
}
44+
45+
if (typeof wanted.name !== 'string') {
46+
throw new Error(`Invalid non-string value for "name" within "${engine}"`)
47+
}
48+
49+
if (typeof current.name !== 'string' || current.name === '') {
50+
throw new Error(`Unable to determine "name" for "${engine}"`)
51+
}
52+
53+
if (properties.includes('onFail')) {
54+
if (typeof wanted.onFail !== 'string') {
55+
throw new Error(`Invalid non-string value for "onFail" within "${engine}"`)
56+
}
57+
if (!recognizedOnFail.includes(wanted.onFail)) {
58+
throw new Error(`Invalid onFail value "${wanted.onFail}" for "${engine}"`)
59+
}
60+
}
61+
62+
if (wanted.name !== current.name) {
63+
return new Error(
64+
`Invalid name "${wanted.name}" does not match "${current.name}" for "${engine}"`
65+
)
66+
}
67+
68+
if (properties.includes('version')) {
69+
if (typeof wanted.version !== 'string') {
70+
throw new Error(`Invalid non-string value for "version" within "${engine}"`)
71+
}
72+
if (typeof current.version !== 'string' || current.version === '') {
73+
throw new Error(`Unable to determine "version" for "${engine}" "${wanted.name}"`)
74+
}
75+
if (validRange(wanted.version)) {
76+
if (!satisfies(current.version, wanted.version, opts.semver)) {
77+
return new Error(
78+
// eslint-disable-next-line max-len
79+
`Invalid semver version "${wanted.version}" does not match "${current.version}" for "${engine}"`
80+
)
81+
}
82+
} else if (wanted.version !== current.version) {
83+
return new Error(
84+
`Invalid version "${wanted.version}" does not match "${current.version}" for "${engine}"`
85+
)
86+
}
87+
}
88+
}
89+
90+
/** checks devEngines package property and returns array of warnings / errors */
91+
function checkDevEngines (wanted, current = {}, opts = {}) {
92+
if ((typeof wanted !== 'object' || wanted === null) || Array.isArray(wanted)) {
93+
throw new Error(`Invalid non-object value for "devEngines"`)
94+
}
95+
96+
const errors = []
97+
98+
for (const engine of Object.keys(wanted)) {
99+
if (!recognizedEngines.includes(engine)) {
100+
throw new Error(`Invalid property "devEngines.${engine}"`)
101+
}
102+
const dependencyAsAuthored = wanted[engine]
103+
const dependencies = [dependencyAsAuthored].flat()
104+
const currentEngine = current[engine] || {}
105+
106+
// this accounts for empty array eg { runtime: [] } and ignores it
107+
if (dependencies.length === 0) {
108+
continue
109+
}
110+
111+
const depErrors = []
112+
for (const dep of dependencies) {
113+
const result = checkDependency(dep, currentEngine, { ...opts, engine })
114+
if (result) {
115+
depErrors.push(result)
116+
}
117+
}
118+
119+
const invalid = depErrors.length === dependencies.length
120+
121+
if (invalid) {
122+
const lastDependency = dependencies[dependencies.length - 1]
123+
let onFail = lastDependency.onFail || 'error'
124+
if (onFail === 'download') {
125+
onFail = 'error'
126+
}
127+
128+
const err = Object.assign(new Error(`Invalid devEngines.${engine}`), {
129+
errors: depErrors,
130+
engine,
131+
isWarn: onFail === 'warn',
132+
isError: onFail === 'error',
133+
current: currentEngine,
134+
required: dependencyAsAuthored,
135+
})
136+
137+
errors.push(err)
138+
}
139+
}
140+
return errors
141+
}
142+
143+
module.exports = {
144+
checkDevEngines,
145+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
const semver = require('semver')
2+
const currentEnv = require('./current-env')
3+
const { checkDevEngines } = require('./dev-engines')
4+
5+
const checkEngine = (target, npmVer, nodeVer, force = false) => {
6+
const nodev = force ? null : nodeVer
7+
const eng = target.engines
8+
const opt = { includePrerelease: true }
9+
if (!eng) {
10+
return
11+
}
12+
13+
const nodeFail = nodev && eng.node && !semver.satisfies(nodev, eng.node, opt)
14+
const npmFail = npmVer && eng.npm && !semver.satisfies(npmVer, eng.npm, opt)
15+
if (nodeFail || npmFail) {
16+
throw Object.assign(new Error('Unsupported engine'), {
17+
pkgid: target._id,
18+
current: { node: nodeVer, npm: npmVer },
19+
required: eng,
20+
code: 'EBADENGINE',
21+
})
22+
}
23+
}
24+
25+
const checkPlatform = (target, force = false, environment = {}) => {
26+
if (force) {
27+
return
28+
}
29+
30+
const os = environment.os || currentEnv.os()
31+
const cpu = environment.cpu || currentEnv.cpu()
32+
const libc = environment.libc || currentEnv.libc(os)
33+
34+
const osOk = target.os ? checkList(os, target.os) : true
35+
const cpuOk = target.cpu ? checkList(cpu, target.cpu) : true
36+
let libcOk = target.libc ? checkList(libc, target.libc) : true
37+
if (target.libc && !libc) {
38+
libcOk = false
39+
}
40+
41+
if (!osOk || !cpuOk || !libcOk) {
42+
throw Object.assign(new Error('Unsupported platform'), {
43+
pkgid: target._id,
44+
current: {
45+
os,
46+
cpu,
47+
libc,
48+
},
49+
required: {
50+
os: target.os,
51+
cpu: target.cpu,
52+
libc: target.libc,
53+
},
54+
code: 'EBADPLATFORM',
55+
})
56+
}
57+
}
58+
59+
const checkList = (value, list) => {
60+
if (typeof list === 'string') {
61+
list = [list]
62+
}
63+
if (list.length === 1 && list[0] === 'any') {
64+
return true
65+
}
66+
// match none of the negated values, and at least one of the
67+
// non-negated values, if any are present.
68+
let negated = 0
69+
let match = false
70+
for (const entry of list) {
71+
const negate = entry.charAt(0) === '!'
72+
const test = negate ? entry.slice(1) : entry
73+
if (negate) {
74+
negated++
75+
if (value === test) {
76+
return false
77+
}
78+
} else {
79+
match = match || value === test
80+
}
81+
}
82+
return match || negated === list.length
83+
}
84+
85+
module.exports = {
86+
checkEngine,
87+
checkPlatform,
88+
checkDevEngines,
89+
currentEnv,
90+
}

0 commit comments

Comments
 (0)