Security News
RubyGems.org Adds New Maintainer Role
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Automated pub/sub across project dependencies. Run code from any installed package based on declarative rules in package.json
Scan all explicitly declared package dependencies in the current project for Node modules that declare a particular purpose.
You want to detect which of a project's dependencies can do a particular task. No, that's too abstract.
You're throwing a potluck dinner party with NodeJS. You're listing your guests as dependencies, and inviting them over with npm install
.
{
"name": "@my-house/potluck",
"version": "1.0.0",
"description": "Come over Saturday!",
"dependencies": {
"aunt-cathy": "^1.2.3",
"@work/cornelius": "^4.3.1",
"grandma": "^23.0.1",
"philippe": "^0.5.0"
}
}
You have cleverly selected family and friends who can cook. But you don't know what each of them wants to bring. How do you set the dang table?
const cathy = require('aunt-cathy');
const cornelius = require('@work/cornelius');
const grandma = require('grandma');
const philippe = require('philippe');
let numSoups = 0;
numSoups += cathy.howManySoups();
numSoups += cornelius.howManySoups();
numSoups += grandma.howManySoups();
numSoups += philippe.howManySoups();
const shoppingList = [
`${numSoups} tureens`,
`${numSoups * 2} ladles`
];
That's a lot of manual work to build a whole shopping list. Plus, you get some updates from your guests:
npm remove aunt-cathy
prep.js
will throw an exception.cornelius.howManySoups()
will now throw a BlasphemyError
.npm install cousin-todd
prep.js
though!You could manually edit prep.js
, but it doesn't seem efficient, especially with more guests.
Like any good party planner, you ask all your guests to tell you what they're bringing.
Hey potluck pals! Could you each please add a
potluck
property to yourpackage.json
file? It should be the path of a module which exports an array of the dishes you'd like to make!
Some guests follow suit.
{
"name": "@work/cornelius",
"version": "4.4.0",
"potluck": "./potluck-dishes.js"
}
const favorites = [
'tomato soup',
'brownies',
'fondue'
];
// EDIT 20XX: SOUP IS EVIL
favorites = favorites.slice(1);
module.exports = favorites;
{
"name": "grandma",
"version": "23.0.2",
"potluck": "./recipes"
}
module.exports = [
'perfect enchiladas',
'amazing pie',
'awesome tortilla soup'
];
{
"name": "philippe",
"version": "0.5.1",
"potluck": "./scrapbook/food-ideas"
}
module.exports = [
'haricots verts',
'vichysoisse soup'
];
The next time you update your dependencies, three of your guests have declared that they know how to potluck
.
Each of those declarations lists a Node module exporting a list.
This is going to make shopping easier.
const pertain = require('pertain');
const dishBringers = pertain('./', 'potluck');
You call pertain
with the current directory to say "get the dependencies of whatever invoked this process".
(In this case, that's your own prep.js
script, but you always have to tell it.)
To the second argument of pertain
, you say 'potluck'
.
This is what pertain
returns:
[
{
"name": "@work/cornelius",
"path": "/home/potluck/node_modules/@work/cornelius/potluck-dishes.js",
"modulePath": "/home/potluck/node_modules/@work/cornelius",
"subject": "potluck"
},
{
"name": "grandma",
"path": "/home/potluck/node_modules/grandma/recipes/index.js",
"modulePath": "/home/potluck/node_modules/grandma",
"subject": "potluck"
},
{
"name": "philippe",
"path": "/home/potluck/node_modules/philippe/scrapbook/food-ideas.js",
"modulePath": "/home/potluck/node_modules/philippe",
"subject": "potluck"
}
]
Pertain has resolved each of those module paths to their actual location, so you can require()
them no matter what context you're in.
Let's map it into a list.
const allDishes = dishBringers.map((dishes, guest) => dishes.concat(require(guest.path)));
That code will run each named module in each package with potluck
. Then it concatenates all the lists together. Now allDishes
is:
[
'brownies',
'fondue',
'perfect enchiladas',
'amazing pie',
'awesome tortilla soup',
'haricots verts',
'vichysoisse soup'
]
And here's our new, simpler prep:
const pertain = require('pertain');
const dishBringers = pertain('./', 'potluck');
const allDishes = dishBringers.map((dishes, guest) => dishes.concat(require(guest.path)));
const soups = allDishes.filter(dish => dish.includes('soup'));
const shoppingList = [
`${soups.length} tureens`,
`${soups.length * 2} ladles`
];
That'll hold up better to changes.
This is an ultra-simple example. You can have multiple subjects in the same package, and subjects can be complex objects which you reference with dot-lookup. More TBD.
To make a package that pertain
can automatically call when it's a listed dependency, declare a custom property in your package.json
:
{
"name": "potluck-guest-grandma",
"description": "You're lucky she's coming",
"potluck": {
"desserts": "./potluck/desserts"
}
}
When potluck-guest-grandma
is installed in a project, and code in that project runs pertain("potluck.desserts")
, then Pertain will load potluck-guest-grandma/potluck/desserts.js
.
If potluck-guest-grandma
depends on another package that pertains to the same topic, it should list that package in peerDependencies
:
{
"name": "potluck-guest-grandma",
"description": "You're lucky she's coming",
"potluck": {
"desserts": "./potluck/desserts"
},
"peerDependencies": {
"pie-baking-aunt": "^1.2.0"
}
}
If this is declared, then Pertain will call potluck-guest-grandma
after pie-baking-aunt
by default.
To get all dependencies with potluck.desserts
labeled in package.json
:
const pertain = require('pertain');
const desserts = pertain(process.cwd(), 'potluck.desserts');
const dessertTable = {};
for (const dessertFile of desserts) {
// Require and execute the module.
const Dessert = require(dessertFile.path);
// Expect that a dessert will be a class. Provide it with the table
// everything else has set, so it can interact with other dependencies.
const dessert = new Dessert(dessertTable);
// Expect Dessert#serve() to run a side effect.
dessert.serve();
}
Supply a custom getDependencies(found, packageJson, rootDir, subject)
function to customize how pertain finds the list of dependency names.
Its first argument is a union of dependencies
and devDependencies
, and by default it simply returns that argument.
This is useful for when you are developing a pertinent package and linking it via npm link
to the consuming package.
const pertain = require('pertain');
const desserts = pertain(
process.cwd(),
'potluck.desserts',
deps => deps.concat(['neighbor-window-pie'])
);
const dessertTable = {};
for (const dessertFile of desserts) {
// Require and execute the module.
const Dessert = require(dessertFile.path);
// Expect that a dessert will be a class. Provide it with the table
// everything else has set, so it can interact with other dependencies.
const dessert = new Dessert(dessertTable);
// Expect Dessert#serve() to run a side effect.
dessert.serve();
}
pertain(workingDirectory, subject, getDependencies?)
Return an array of module info, sorted in peer dependency order, for all modules declared as direct dependencies of the package root of workingDirectory
. Filter those modules for only those which:
subject
in their package.json
filerequire()
Returned module info is an array of objects with the following properties:
name
: The name of the dependency package, e.g. left-pad
.path
: The real filesystem path of the module file mentioned in the subject
fieldmodulePath
: The real filesystem path of the found module base directorysubject
: The originally argued subject stringThe subject
can be a dot-lookup path, e.g. "foo.bar"
, which will then look for "foo": { "bar": "./path" }
in the package.
pertain.clearCache()
Pertain caches expensive operations on the same package for the same subject. Use this method to clear that cache.
FAQs
Automated pub/sub across project dependencies. Run code from any installed package based on declarative rules in package.json
The npm package pertain receives a total of 2,060 weekly downloads. As such, pertain popularity was classified as popular.
We found that pertain demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.
Security News
Research
Socket's threat research team has detected five malicious npm packages targeting Roblox developers, deploying malware to steal credentials and personal data.