This repository was archived by the owner on May 22, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 35
/
Copy pathnested.js
90 lines (78 loc) · 3.61 KB
/
nested.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
const { valid: validVersion, validRange, satisfies, gte: greaterThanEqual, ltr: lessThanRange } = require('semver')
// Apply the Node.js module logic recursively on its own dependencies, using
// the `package.json` `dependencies`, `peerDependencies` and
// `optionalDependencies` keys
const getNestedDependencies = function ({ dependencies = {}, peerDependencies = {}, optionalDependencies = {} }) {
return [
...Object.keys(dependencies),
...Object.keys(peerDependencies).filter(shouldIncludePeerDependency),
...Object.keys(optionalDependencies),
]
}
// Workaround for https://github.com/netlify/zip-it-and-ship-it/issues/73
// TODO: remove this after adding proper modules exclusion as outlined in
// https://github.com/netlify/zip-it-and-ship-it/issues/68
const shouldIncludePeerDependency = function (name) {
return !EXCLUDED_PEER_DEPENDENCIES.has(name)
}
const EXCLUDED_PEER_DEPENDENCIES = new Set(['@prisma/cli', 'prisma2'])
// Modules can be required conditionally (inside an `if` or `try`/`catch` block).
// When a `require()` statement is found but the module is not found, it is
// possible that that block either always evaluates to:
// - `false`: in which case, we should not bundle the dependency
// - `true`: in which case, we should report the dependency as missing
// Those conditional modules might be:
// - present in the `package.json` `dependencies`
// - present in the `package.json` `optionalDependencies`
// - present in the `package.json` `peerDependencies`
// - not present in the `package.json`, if the module author wants its users
// to explicitly install it as an optional dependency.
// The current implementation:
// - when parsing `require()` statements inside function files, always consider
// conditional modules to be included, i.e. report them if not found.
// This is because our current parsing logic does not know whether a
// `require()` is conditional or not.
// - when parsing module dependencies, ignore `require()` statements if not
// present in the `package.json` `*dependencies`. I.e. user must manually
// install them if the module is used.
// `optionalDependencies`:
// - are not reported when missing
// - are included in module dependencies
const handleModuleNotFound = function ({ error, moduleName, packageJson }) {
if (
error.code === 'MODULE_NOT_FOUND' &&
(isOptionalModule(moduleName, packageJson) || isExternalCrittersModule(moduleName, packageJson))
) {
return []
}
throw error
}
const isOptionalModule = function (
moduleName,
{ optionalDependencies = {}, peerDependenciesMeta = {}, peerDependencies = {} },
) {
return (
optionalDependencies[moduleName] !== undefined ||
(peerDependenciesMeta[moduleName] &&
peerDependenciesMeta[moduleName].optional &&
peerDependencies[moduleName] !== undefined)
)
}
const MIN_NEXT_VERSION = '10.0.4'
const satisfiesRange = (range) =>
validRange(range) && (satisfies(MIN_NEXT_VERSION, range) || lessThanRange(MIN_NEXT_VERSION, range))
// 'critters' is used only in Next.js >= 10.0.4 when enabling an experimental option and has to be installed manually
// we ignore it if it's missing
const isExternalCrittersModule = function (moduleName, { dependencies = {}, devDependencies = {} }) {
if (moduleName !== 'critters') {
return false
}
const nextVersion = dependencies.next || devDependencies.next
// can the declared Next.js version resolve to >=10.0.4 ?
// test exact versions
if (validVersion(nextVersion)) {
return greaterThanEqual(nextVersion, MIN_NEXT_VERSION)
}
return satisfiesRange(nextVersion)
}
module.exports = { getNestedDependencies, handleModuleNotFound }