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.
grunt-collection-helper
Advanced tools
Helper function to be used with Grunt, for defining resource collections in packages.
grunt-collection-helper is designed to aid the construction of
resource collections from description files. It aims to separate
the description of the list of resources, from their way of usage
from the Gruntfile.js
.
Simple usage:
uglify: {
default: {
dest: 'dist/full.min.js',
src: collect.select('full.js')
)
}
}
provided collection.js
defines a list of resources for full.js
:
{
'full.js': {
'src/module1.js',
'src/module2.js',
'src/sub/module09.js'
}
}
The collection.json
can be provided locally, or originated from
a package installed by a supported packaging / installation method.
provides a way to describe a named collection of resource lists in a JSON description file
provides a simple API usable from a Gruntfile.js
script,
to select the list of resources from the above files by their name.
The resulting resource lists can be used:
with any grunt task and file mapping format
in a flexible way, as the collection helper does not support or dictate their way of usage, it merely provides the lists themselves
can support multiple packaging / installation methods via its 'locators'
local()
and bower()
are implementedThe package can be installed with npm.
$ npm install grunt-collection-helper
You may want to automate the installation of this package from the same
way you have installed grunt packages from. Normally, put something like
the following into the package.json
next to the Gruntfile.js
where you
want to use the collection helper from:
"devDependencies": {
"grunt": ">=0.4",
...
"grunt-collection-helper": "*"
}
With npm:
$ npm install git://github.com/reebalazs/grunt-collection-helper.git
Import the package first. (Assumed in all of the following examples.)
var collect = require('grunt-collection-helper');
Following this you can access the API through the collect
variable
from an expression.
The API is designed to be very simple: you need to apply a locator first
to specify the root of a package, and then select a collection of resources
(select(...)
), or
refer to a specific resource relative from within that package
(path(...)
).
collect.<LOCATOR>(...).select(str)
collect.<LOCATOR>(...).path(str)
As an example, let us create a collection.json
file in the
same directory where our
Gruntfile.js
resides. For example, it could have the following
simple content:
{
"flower.js": ["js/rose.js", "js/bluebell.js"],
"fruit.css": ["css/apple.css", "css/orange.css"]
}
This describes the construction order for flower.js
and fruit.css
resources.
The resource paths are specified relative from the collection.json
file.
The file must contain a dictionary in valid JSON format. This dictionary
contains named lists of resource paths. A script then can query for flower.js
,
and receive the list of the files associated with this name. After this,
the script will process this list according to the way it needs to.
The resources are always selected relatively to their 'package root', depending the installation method. The collection helper provides 'locators' to find the root of a given package.
The following expressions will select the construction order for the specified resource:
collect.local().select('flower.js')
//=> ['js/rose.js', 'js/bluebell.js']
collect.local().select('fruit.css')
//=> ['css/apple.css', 'css/orange.css']
A path parameter can be specified to local
, where a collection.json
file
will be read from. For example, src/scrumptious/collection.json
could contain:
{
"cakes.js": ["js/dobos.js", "js/tiramisu.js"],
"nuts.css": ["css/almond.css", "css/chestnut.css"]
}
This would make the following expressions work:
collect.local('src/scrumptious').select('cakes.js')
//=> ['js/dobos.js', 'js/tiramisu.js']
collect.local('src/scrumptious').select('nuts.css')
//=> ['css/almond.css', 'chestnut.css']
local()
locator is the default locatorIn case the local locator stands without parameters, it can be omitted.
collect.select('flower.js')
is equivalent to:
collect.local().select('flower.js')
and the followings resolve as:
collect.select('flower.js')
//=> ['js/rose.js', 'js/bluebell.js']
collect.select('fruit.css')
//=> ['css/apple.css', 'css/orange.css']
The following expression finds the source for a given package (in
our example the boo
package), that has been
installed with bower
:
collect.bower('boo').select('boolib.js')
This also assumes that the 'boo' package has a collection.json
that defines a list for the key boolib.js
. In other words, selection
works the same way with each locator, only the initial package
directory is different.
Using of the 'path' method makes it possible to refer to a resource
relative to the bower package root, independently from a
collection.json
in that package. path(...)
will always return
a string.
collect.bower('coo').path('fun/entertainment/discoo.js')
//=> './components/coo/fun/entertainment/discoo.js'
collect.bower('coo').path('agriculture/food/coocumber.css')
//=> './components/coo/agriculture/food/coocumber.css'
The locator will find the 'components' package each time by walking
up to the parent folders, in the above example it was found in the
same directory where Gruntfile.js
resides.
In addition to a composition order given in component.json
,
the main
property of Bower's component.json
can also be used.
It will add main.<EXT>
keys which group the files from main
by file extension.
collect.bower('jquery').select('main.js')
// component.json: generates into collection.js:
//
// main: 'single.js', => {'main.js': ['single.js']}
//
// main: ['apple.js', => {'main.js': ['apple.js', 'tree/orange.js']}
// 'tree/orange.js']
//
// main: ['apple.js', => {'main.js': ['apple.js', 'tree/orange.js'],
// 'tree/orange.js', 'main.css': ['cucumber.css']}
// 'cucumber.css']
The keys in collection.json
will take precedent: if it already defines
a main.js
, it will win over the main
value from component.json
.
It is extendable. We can easily create a jamjs
, ... locator.
A locator can accept any number of parameters.
.bowerrc
provides a way to specify a different components
directory
for bower to use. We currently ignore this and always use components
.
At some time later in the future, a more flexible way of parametrizing the selection could also be supported:
collect.bower('foo').select({'features': ['drag', 'drop']})
// uses a function from collection.js
Let us extend our collection.json
as follows:
{
"flower.js": ["js/rose.js", "js/bluebell.js"],
"fruit.css": ["css/apple.css", "css/orange.css"],
"dist.js": [
["bower", "jquery", "jquery.js"],
["bower", "bootstrap", "docs/assets/js/bootstrap.js"]
]
}
If the resource is represented by an array instead of a string, then the first parameter will select a locator, which will receice the rest of the parameter except the last one. The last parameter will be used to select the path of the resource relative inside the package.
For example, ["bower", "jquery", "jquery.js"]
will be translated to bower('jquery').path('jquery.js')
.
collect.select('dist.js')
//=> ['./components/jquery/jquery.js',
// './components/bootstrap/docs/assets/js/bootstrap.js']
As the select function returns just normal arrays, it can be used with any
grunt plugin, and in various combinations, from Gruntfile.js
. Consider the
following examples:
concat: {
'default': {
files: {
'dist/flower.js':
collect.select('flower.js'),
'src/scrumptious/dist/nuts.css':
collect.local('src/scrumptious').select('nuts.css')
}
}
},
or (a watch rule where adding the lists is demonstrated. Note that
we used [].concat(...)
, because lists are not addable with the plus
operator in JavaScript):
watch: {
'default': {
files: [].concat(
collect.select('flower.js'),
collect.local('src/scrumptious').select('nuts.css'),
),
tasks: ['concat:default']
},
},
or (when we also add files to the collections manually):
watch: {
'default': {
files: [].concat(
collect.select('flower.js'),
collect.local('src/scrumptious').select('nuts.css'),
[
collect.bower('jquery').path('jquery.js')
]
),
tasks: ['concat:default']
},
},
or (an uglify rule, where we use a different src - dest mapping format than previously):
uglify: {
default: {
dest: 'dist/full.min.js',
src: [].concat(
collect.select('flower.js'),
collect.local('src/scrumptious').select('cakes.js'),
collect.bower('jquery').select('main.js')
)
}
}
or (to see composition of lists at work, with our extended collection.json
):
uglify: {
default: {
dest: 'dist/full.min.js',
src: collect.select('dist.js')
}
},
watch: {
'default': {
files: collect.select('dist.js'),
tasks: ['uglify:default']
},
}
FAQs
Helper function to be used with Grunt, for defining resource collections in packages.
The npm package grunt-collection-helper receives a total of 1 weekly downloads. As such, grunt-collection-helper popularity was classified as not popular.
We found that grunt-collection-helper 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’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.