
Research
/Security News
Weaponizing Discord for Command and Control Across npm, PyPI, and RubyGems.org
Socket researchers uncover how threat actors weaponize Discord across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.
eslint-plugin-relations
Advanced tools
Controls relationships between folders and packages in a monorepo environment.
yarn add eslint-plugin-relations
// eslintrc.js
module.exports = {
plugins: [
'relations',
// other plugins
],
};
Because an autoimport
feature your IDE might provide is not always working. It might result with a:
correct
rule will restrict all imports to the explicitly defined ones, autocorrecting (trimming) anything else
eslintrc.js
module.exports = {
plugins: ['relations'],
rules: {
//...
'relations/correct-imports': [
'error',
{
// if you use another tool to derive package->path mapping for typescript
tsconfig: 'path-to-your-config',
// the one with `"compilerOptions": { "paths": [...] }
// OR
// explicit mapping to use
pathMapping: {
packageName: 'path',
},
// controls "suggestion" over "autofix" behavior
// you want this to be 'false' during development and 'true' in precommit
autofix: false,
},
],
},
};
Because of Rock paper scissors , Law of Demeter , Abstraction Layers and Hexagonal Architecture.
Examples:
This creates a controllable unidirectional flow and let you establish sound relationships between different domains.
Your packages and/or code has to be separated in zones/buckets you will be able to configure relationships in between. Having all packages in one folder will not work.
A good example of such separation can be found at Lerna:
It can be already a good idea to restrict core usage(nobody can), as well as put a boundary around helpers and utils - they should not use commands.
Can be configured in two ways:
eslint.rc
module.exports = {
plugins: ['relations'],
rules: {
//...
'relations/restrict': [
'error',
{
rules: [
// platform cannot use packages
{
// absolute folder
from: 'platform',
// absolute folder
to: 'packages',
type: 'restricted',
message: "Let's keep them separated",
},
// one page cannot use another
{
// glob support!
// note: 'pages/a' can assess 'pages/a', but not 'pages/b'
to: 'pages/*',
from: '{app,packages}/*.{js,ts}', // note only [ and { "braces" are supported
type: 'restricted',
message: 'pages are isolated',
},
// "allow" rules should precede "restrict" ones
{
// custom RegExp
from: /__tests__/,
to: /__tests__/,
// allow tests to access tests
type: 'allowed',
message: 'do not import from tests',
},
{
// anywhere
from: '*',
//relative folder
to: /__tests__/,
type: 'restricted',
message: 'do not import from tests',
},
],
},
],
},
};
ruleGenerator
A custom function to return rules to be used between locationFrom and locationTo
// eslintrc.js
module.exports = {
plugins: ['relations'],
rules: {
//...
'relations/restrict': [
'error',
{
ruleGenerator: (fromFile, toFile) => [rule1, rule2],
},
],
},
};
Paths(from
and to
) from rule generator are expected to be absolute (or regexp). You might need an exported helper to
handle this
import { adoptLocation } from 'eslint-plugin-relations';
const rule = {
to: adoptLocation(path /* or glob*/, cwd),
};
.relations
filesthis is a recommended way
One can put .relations
(js,ts,json) files with the rule definitions at various places to have "per-folder"
configuration.
All .relation
files in-and-above "source" and "destination" will be merged, with lower ones overriding the top
ones, and applied. This can create self-contained definition of "layers and fences" among your application.
//packages/core/.relations.js
module.exports = [
// allow internal access (from/to the same location)
{
from: '.',
to: '.',
type: 'allowed',
},
// prevent access to this folder (from the outside)
{
to: '.',
type: 'restricted',
},
];
It's important to test relations in order to keep boundaries active. Just think about it - if the rule is triggered only when you break it, and you do not breaking it - how one can know it's actually working?
There are two ways:
--report-unused-disable-directives
,
then "not violation" will generate an errorimport { resolveRelation } from 'eslint-plugin-relations';
resolveRelation(from, to, options); // => Rule | undefined
// match given rules
resolveRelation(from, to, { rules: [{}] }); // => Rule | undefined
// autodiscover from .relation files
resolveRelation(from, to); // => Rule | undefined
resolveRelation(from, to, { cwd: baseDir }); // => Rule | undefined
depcheck
to keep your package
relations up-to-date.All rules are highly optimized:
relations/correct-imports
uses trie
structure, and is not even visible in eslint timing reportrelations/restrict
takes roughly 3% of whole linting time. Using .relation
files or ruleGenerator
can greatly
reduce the time (via reducing the number of rules to apply)MIT
FAQs
Controls the way packages can import each other
We found that eslint-plugin-relations 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.
Research
/Security News
Socket researchers uncover how threat actors weaponize Discord across the npm, PyPI, and RubyGems ecosystems to exfiltrate sensitive data.
Security News
Socket now integrates with Bun 1.3’s Security Scanner API to block risky packages at install time and enforce your organization’s policies in local dev and CI.
Research
The Socket Threat Research Team is tracking weekly intrusions into the npm registry that follow a repeatable adversarial playbook used by North Korean state-sponsored actors.