Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
conditional-install
Advanced tools
A utility to install npm packages based on certain conditions.
The original motivation for this package is to install the proper version of the jest unit testing library.
Some of the ilib packages supported node 10 through the current latest version and used jest as their unit testing library. The only problem is that the latest version of jest did not run on node 10 through 13 because it was rewritten with ES6 syntax in jest@27.0.0. The tests, which were not particularly fancy and did not use any advanced features, ran fine with jest@26.6.2 on older versions of node but would not work with the latest jest because it wasn't transpiled to support older versions of node.
What was needed was a way to install jest@26 for older versions of node and jest@29 for the newer ones. There was no easy, elegant way to do that.
Hence this conditional install package.
Usage is simple. Basically, modify your package.json to include conditional dependencies, and then run this package as a postinstall script.
Here is what the package.json would look like:
{
"name": "mypackage",
"scripts": {
"postinstall": "conditional-install"
},
"dependencies": {
"conditional-install": "^1.0.0"
},
"conditionalDependencies": {
"process.version >= 14.0.0": {
"example-package": "^29.0.0"
},
"process.version < 14.0.0": {
"example-package": "^26.0.0"
}
}
}
The postinstall script is run automatically by npm
or yarn
after the
regular installation is complete. If you are using npm-ci
, it does not, so
you will have to run npm-ci run postinstall
explicitly in order to
install the conditional dependencies.
The conditionalDependencies
object contains properties that are
expressions to test against the current version of node. Inside of the
value object is a list of dependencies to install if the value of that
expression is true. All dependencies inside of the value are installed.
The versions are specified with the same syntax as regular, dev, or peer
dependencies.
When the dependencies are installed, they are installed using the current package manner, but in such a way that the new dependencies are not saved to the package.json.
The expressions are built on the hard work of node-compat-table.
The core of an expression is a test. There are multiple things that can be tested:
RegExp.prototype.flags
. See the node.green web site to see all the
possible features and their pass/fail values for various versions of node.process
variable. There are various different
possible types of values:
process.config.variables.icu_ver_major
will give you the major
version of ICU that this version of node supports as a numberprocess.ENV.variableName
will return you the value of an environment
variable as a string. In this way, you can control conditional installation
with external means. Strings may have spaces and other characters in them
so that they can represent JS features.process.versions.node
will return a full version spec,
like "v14.4.2" or "18.0.0". This may or may not have the leading "v" in front
of it.process.config.variables.icu_small
return true if this
version of node uses the small ICU package, and false if this version has
full ICU.Individual tests can be combined into more complex expressions together using the following familiar operators. All operators return a boolean value as well.
!
is "not". A value can be negated using this unary operator, meaning that the current
version of node does NOT support that feature. Negation for numbers are similar to
Javascript's truthy and falsy. String literals that do not name a JS feature, an ES
version, or a setting inside of the process variable are considered to be false.&&
is "and". Both sides must be true||
is "or". At least one side must be true=
is "equals". Both sides must be equal!=
is "not equal". Both sides must not be equal each other>
is "greater than". Left side must be greater than the right side>=
is "greater than or equal to". Left side must be greater than or equal to the right side<
is "less than". Left side must be less than the right side<=
is "less than or equal to". Left side must be less than or equal to the right side.^
is "major compatibility". For versions, this is the same as carat compatibility in the
semver package. For strings and numbers, this operator returns false.~
is "minor compatibility". For versions, this is the same as tilde compatibility in the
semver package. For strings and numbers, this operator returns false.-
is "range". For versions, this is the range operator which forms ranges of versions. For
strings and numbers, this operator returns false.(
and )
group expressions together to enforce order of operationsWhen the two sides of a binary operator are versions, this package will use semver to compare them using all the normal, familiar semver rules. Examples:
"process.versions.node ^ 14.0.0" -> test whether or not the current version of node
is carat compatible with version 14.0.0
"process.versions.node < v14.0.0" -> test whether or not the current version of node
is less than version 14.0.0
If the two sides of an operator are different types, the right side will be co-ersed to the same type as the left side. - strings become numbers with parseInt() - numbers become boolean with 0 = false, any other number = true - numbers become versions by treating them as a major version number. 14 = v14.0.0 - strings become booleans by value. "true" is true, and everything else is false
Example of a conditional expression using more complex syntax:
"conditionalDependencies": {
"!ES6 || (process.config.variables.icu_ver_major < 67 && process.config.variables.icu_small)": {
"full-icu": "^1.5.0"
}
}
If you put "conditional-install" into the postinstall script, both npm and yarn will run the
conditional installation whether you are doing npm install
locally in your cloned git repo, or
including your package into another package from the npm repository.
In some cases, you only want to do conditional installation when running locally during development.
To do that, put "conditional-install" into the "prepare" script instead and include "conditional-install"
in your devDependencies
instead:
{
"name": "mypackage",
"scripts": {
"prepare": "conditional-install"
},
"devDependencies": {
"conditional-install": "^1.0.0"
},
"conditionalDependencies": {
"process.version >= 14.0.0": {
"jest": "^29.0.0"
},
"process.version < 14.0.0": {
"jest": "^26.0.0"
}
}
}
Copyright © 2023-2024, JEDLSoft
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and limitations under the License.
FAQs
Install conditional dependencies
We found that conditional-install demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.