Socket
Socket
Sign inDemoInstall

fs-jetpack

Package Overview
Dependencies
Maintainers
1
Versions
61
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fs-jetpack - npm Package Compare versions

Comparing version 0.10.3 to 0.10.4

4

CHANGELOG.md

@@ -0,1 +1,5 @@

0.10.4 (2016-12-06)
-------------------
* Fixed matcher edge cases, improved matcher tests (affects `find()` and `copy()` methods).
0.10.3 (2016-11-23)

@@ -2,0 +6,0 @@ -------------------

2

lib/copy.js

@@ -21,3 +21,3 @@ 'use strict';

if (opts.matching) {
parsedOptions.allowedToCopy = matcher.create(opts.matching, from);
parsedOptions.allowedToCopy = matcher.create(from, opts.matching);
} else {

@@ -24,0 +24,0 @@ parsedOptions.allowedToCopy = function () {

@@ -48,3 +48,3 @@ 'use strict';

var foundInspectObjects = [];
var matchesAnyOfGlobs = matcher.create(options.matching, path);
var matchesAnyOfGlobs = matcher.create(path, options.matching);

@@ -86,3 +86,3 @@ treeWalker.sync(path, {

var foundInspectObjects = [];
var matchesAnyOfGlobs = matcher.create(options.matching, path);
var matchesAnyOfGlobs = matcher.create(path, options.matching);

@@ -89,0 +89,0 @@ var walker = treeWalker.stream(path, {

@@ -1,3 +0,1 @@

// Matcher for glob patterns (e.g. *.txt, /a/b/**/z)
'use strict';

@@ -7,35 +5,24 @@

var convertPatternToAbsolutePath = function (passedPattern, basePath) {
var convertPatternToAbsolutePath = function (basePath, pattern) {
// All patterns without slash are left as they are, if pattern contain
// any slash we need to turn it into absolute path.
var pattern = passedPattern;
var hasSlash = (pattern.indexOf('/') !== -1);
var isAbsolute;
var isNegated;
var isAbsolute = /^!?\//.test(pattern);
var isNegated = /^!/.test(pattern);
var separator;
if (hasSlash) {
// Maybe already is in the format we wanted
isAbsolute = /^!?\//.test(pattern); // Starts with '/' or '!/'
if (!isAbsolute) {
isNegated = (pattern[0] === '!');
if (!isAbsolute && hasSlash) {
// Throw out meaningful characters from the beginning ("!", "./").
pattern = pattern.replace(/^!/, '').replace(/^\.\//, '');
// Remove starting characters which have meaning '!' and '.'
// and first slash to normalize the path.
if (isNegated) {
pattern = pattern.substring(1);
}
if (pattern[0] === '.') {
pattern = pattern.substring(1);
}
if (pattern[0] === '/') {
pattern = pattern.substring(1);
}
if (/\/$/.test(basePath)) {
separator = '';
} else {
separator = '/';
}
// Finally construct ready pattern
if (isNegated) {
pattern = '!' + basePath + '/' + pattern;
} else {
pattern = basePath + '/' + pattern;
}
if (isNegated) {
return '!' + basePath + separator + pattern;
}
return basePath + separator + pattern;
}

@@ -46,20 +33,13 @@

var normalizePatterns = function (passedPatterns, basePath) {
var patterns;
if (typeof passedPatterns === 'string') {
// Patterns must be an Array
patterns = [passedPatterns];
} else {
patterns = passedPatterns;
exports.create = function (basePath, patterns) {
var matchers;
if (typeof patterns === 'string') {
patterns = [patterns];
}
return patterns.map(function (pattern) {
return convertPatternToAbsolutePath(pattern, basePath);
});
};
exports.create = function (passedPatterns, basePath) {
var patterns = normalizePatterns(passedPatterns, basePath);
var matchers = patterns.map(function (pattern) {
matchers = patterns.map(function (pattern) {
return convertPatternToAbsolutePath(basePath, pattern);
})
.map(function (pattern) {
return new Minimatch(pattern, {

@@ -72,3 +52,3 @@ matchBase: true,

return function performMatch(path) {
return function performMatch(absolutePath) {
var mode = 'matching';

@@ -86,3 +66,3 @@ var weHaveMatch = false;

// There are only negated patterns in the set,
// so make everything match by default and
// so make everything matching by default and
// start to reject stuff.

@@ -93,3 +73,3 @@ weHaveMatch = true;

if (mode === 'negation' && weHaveMatch && !currentMatcher.match(path)) {
if (mode === 'negation' && weHaveMatch && !currentMatcher.match(absolutePath)) {
// One negation match is enought to know we can reject this one.

@@ -100,3 +80,3 @@ return false;

if (mode === 'matching' && !weHaveMatch) {
weHaveMatch = currentMatcher.match(path);
weHaveMatch = currentMatcher.match(absolutePath);
}

@@ -103,0 +83,0 @@ }

{
"name": "fs-jetpack",
"description": "Better file system API",
"version": "0.10.3",
"version": "0.10.4",
"author": "Jakub Szwacz <jakub@szwacz.com>",

@@ -6,0 +6,0 @@ "dependencies": {

@@ -85,3 +85,3 @@ fs-jetpack [![Build Status](https://travis-ci.org/szwacz/fs-jetpack.svg?branch=master)](https://travis-ci.org/szwacz/fs-jetpack) [![Build status](https://ci.appveyor.com/api/projects/status/er206e91fpuuqf58?svg=true)](https://ci.appveyor.com/project/szwacz/fs-jetpack) [![codecov](https://codecov.io/gh/szwacz/fs-jetpack/branch/master/graph/badge.svg)](https://codecov.io/gh/szwacz/fs-jetpack)

* `overwrite` (default: `false`) Whether to overwrite destination path if arready exists. For directories, source directory is merged with destination directory, so files in destination which are not present in the source, will remain intact.
* `matching` if defined will actually copy **only** items matching any of specified glob patterns and omit everything else (see examples below).
* `matching` if defined will actually copy **only** items matching any of specified glob patterns and omit everything else ([all possible globs are described further in this readme](#matching-patterns)).

@@ -93,14 +93,18 @@ **returns:**

```javascript
// Copies a file (and replaces it if one already exists in 'copied' directory)
jetpack.copy('file.txt', 'copied/file.txt', { overwrite: true });
// Copies a file (and replaces it if one already exists in 'foo' directory)
jetpack.copy('file.txt', 'foo/file.txt', { overwrite: true });
// Copies only .md files inside 'dir' to 'copied-dir'
jetpack.copy('dir', 'copied-dir', { matching: '*.md' });
// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'.
jetpack.copy('foo', 'bar', { matching: '*.md' });
// Copies only '.md' and '.txt' files from 'foo' (and subdirectories of 'foo') to 'bar'.
jetpack.copy('foo', 'bar', { matching: ['*.md', '*.txt'] });
// Can add many globs as an array
jetpack.copy('dir', 'copied-dir', { matching: ['*.md', '*.txt'] });
// You can filter previous matches by defining negated pattern further in the order:
// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'
// but will skip file '!top-secret.md'.
jetpack.copy('foo', 'bar', { matching: ['*.md', '!top-secret.md'] });
// Copies only '.md' files from 'foo' (and subdirectories of 'foo') to 'bar'
// but will skip all files in 'foo/top-secret' directory.
jetpack.copy('foo', 'bar', { matching: ['*.md', '!top-secret/**/*'] });
// Supports negation patterns as well
jetpack.copy('dir', 'copied-dir', { matching: ['*.md', '!top-secret.md'] });
// All patterns are anchored to directory you want to copy, not to CWD.

@@ -236,3 +240,3 @@ // So in this example directory 'dir1/dir2/images' will be copied

`searchOptions` is an `Object` with possible fields:
* `matching` glob patterns of files you want to find.
* `matching` glob patterns of files you want to find ([all possible globs are described further in this readme](#matching-patterns)).
* `files` (default `true`) whether or not should search for files.

@@ -250,3 +254,8 @@ * `directories` (default `false`) whether or not should search for directories.

// Finds all .js files inside 'my-project' but excluding those in 'vendor' subtree.
// Finds all '.txt' files inside 'foo/bar' directory and its subdirectories
jetpack.find('foo', { matching: 'bar/**/*.txt' });
// Finds all '.txt' files inside 'foo/bar' directory WITHOUT subdirectories
jetpack.find('foo', { matching: 'bar/*.txt' });
// Finds all '.js' files inside 'my-project' but excluding those in 'vendor' subtree.
jetpack.find('my-project', { matching: ['*.js', '!vendor/**/*'] });

@@ -257,2 +266,8 @@

// Finds all '.txt' files inside 'foo' directory WITHOUT subdirectories
jetpack.find('foo', { matching: './*.txt' });
// This line does the same as the above, but has better performance
// (skips looking in subdirectories)
jetpack.find('foo', { matching: '*.txt', recursive: false });
// Path parameter might be omitted and CWD is used as path in that case.

@@ -472,1 +487,18 @@ var myStuffDir = jetpack.cwd('my-stuff');

Nothing.
# Matching patterns
API methods [copy](#copyfrom-to-options) and [find](#findpath-searchoptions) have `matching` option. Those are all the possible tokens to use there:
- `*` - Matches 0 or more characters in a single path portion.
- `?` - Matches 1 character.
- `!` - Used as the first character in pattern will invert the matching logic (match everything what **is not** matched by tokens further in this pattern).
- `[...]` - Matches a range of characters, similar to a RegExp range. If the first character of the range is `!` or `^` then it matches any character not in the range.
- `@(pattern|pat*|pat?ern)` - Matches exactly one of the patterns provided.
- `+(pattern|pat*|pat?ern)` - Matches one or more occurrences of the patterns provided.
- `?(pattern|pat*|pat?ern)` - Matches zero or one occurrence of the patterns provided.
- `*(pattern|pat*|pat?ern)` - Matches zero or more occurrences of the patterns provided.
- `!(pattern|pat*|pat?ern)` - Matches anything that does not match any of the patterns provided.
- `**` - If a "globstar" is alone in a path portion, then it matches zero or more directories and subdirectories.
*(explanation borrowed from [glob](https://github.com/isaacs/node-glob) which is using [the same matching library](https://github.com/isaacs/minimatch) as this project)*

@@ -447,2 +447,38 @@ var fse = require('fs-extra');

});
describe('finds dot-dirs and dot-files', function () {
var preparations = function () {
fse.outputFileSync('.dir/file', 'a');
fse.outputFileSync('.dir/.file', 'b');
fse.outputFileSync('.foo/.file', 'c');
};
var expectations = function (found) {
var normalizedPaths = helper.osSep([
'.dir',
'.dir/.file'
]);
expect(found).to.eql(normalizedPaths);
};
it('sync', function () {
preparations();
expectations(jetpack.find({
matching: ['.dir', '.file', '!.foo/**'],
directories: true
}));
});
it('async', function (done) {
preparations();
jetpack.findAsync({
matching: ['.dir', '.file', '!.foo/**'],
directories: true
})
.then(function (found) {
expectations(found);
done();
});
});
});
});

@@ -6,3 +6,3 @@ var expect = require('chai').expect;

it('can test against one pattern passed as a string', function () {
var test = matcher.create('a');
var test = matcher.create('/', 'a');
expect(test('/a')).to.equal(true);

@@ -13,3 +13,3 @@ expect(test('/b')).to.equal(false);

it('can test against many patterns passed as an array', function () {
var test = matcher.create(['a', 'b']);
var test = matcher.create('/', ['a', 'b']);
expect(test('/a')).to.equal(true);

@@ -20,9 +20,38 @@ expect(test('/b')).to.equal(true);

describe('possible mask tokens', function () {
describe('pattern types', function () {
it('only basename', function () {
var test = matcher.create('/', 'a');
expect(test('/a')).to.equal(true);
expect(test('/b/a')).to.equal(true);
expect(test('/a/b')).to.equal(false);
});
it('absolute', function () {
var test = matcher.create('/', ['/b']);
expect(test('/b')).to.equal(true);
expect(test('/a/b')).to.equal(false);
test = matcher.create('/a', ['/b']);
expect(test('/a/b')).to.equal(false);
});
it('relative with ./', function () {
var test = matcher.create('/a', ['./b']);
expect(test('/a/b')).to.equal(true);
expect(test('/b')).to.equal(false);
});
it('relative (because has slash inside)', function () {
var test = matcher.create('/a', ['b/c']);
expect(test('/a/b/c')).to.equal(true);
expect(test('/b/c')).to.equal(false);
});
});
describe('possible tokens', function () {
it('*', function () {
var test = matcher.create(['*']);
var test = matcher.create('/', ['*']);
expect(test('/a')).to.equal(true);
expect(test('/a/b.txt')).to.equal(true);
test = matcher.create(['a*b']);
test = matcher.create('/', ['a*b']);
expect(test('/ab')).to.equal(true);

@@ -33,14 +62,8 @@ expect(test('/a_b')).to.equal(true);

it('/*', function () {
var test = matcher.create(['/*']);
expect(test('/a')).to.equal(true);
expect(test('/a/b')).to.equal(false);
});
it('**', function () {
var test = matcher.create(['**']);
var test = matcher.create('/', ['**']);
expect(test('/a')).to.equal(true);
expect(test('/a/b')).to.equal(true);
test = matcher.create(['/a/**/d']);
test = matcher.create('/', ['a/**/d']);
expect(test('/a/d')).to.equal(true);

@@ -53,4 +76,4 @@ expect(test('/a/b/d')).to.equal(true);

it('/**/something', function () {
var test = matcher.create(['/**/a']);
it('**/something', function () {
var test = matcher.create('/', ['**/a']);
expect(test('/a')).to.equal(true);

@@ -62,11 +85,37 @@ expect(test('/x/a')).to.equal(true);

it('+(option1|option2)', function () {
var test = matcher.create(['*.+(txt|md)']);
expect(test('/a.txt')).to.equal(true);
expect(test('/b.md')).to.equal(true);
expect(test('/c.rtf')).to.equal(false);
it('@(pattern|pattern) - exactly one of patterns', function () {
var test = matcher.create('/', ['@(foo|bar)']);
expect(test('/foo')).to.equal(true);
expect(test('/bar')).to.equal(true);
expect(test('/foobar')).to.equal(false);
});
it('+(pattern|pattern) - one or more of patterns', function () {
var test = matcher.create('/', ['+(foo|bar)']);
expect(test('/foo')).to.equal(true);
expect(test('/bar')).to.equal(true);
expect(test('/foobar')).to.equal(true);
expect(test('/foobarbaz')).to.equal(false);
});
it('?(pattern|pattern) - zero or one of patterns', function () {
var test = matcher.create('/', ['?(foo|bar)1']);
expect(test('/1')).to.equal(true);
expect(test('/foo1')).to.equal(true);
expect(test('/bar1')).to.equal(true);
expect(test('/foobar1')).to.equal(false);
});
it('*(pattern|pattern) - zero or more of patterns', function () {
var test = matcher.create('/', ['*(foo|bar)1']);
expect(test('/1')).to.equal(true);
expect(test('/foo1')).to.equal(true);
expect(test('/bar1')).to.equal(true);
expect(test('/foobar1')).to.equal(true);
expect(test('/barfoo1')).to.equal(true);
expect(test('/foofoo1')).to.equal(true);
});
it('{a,b}', function () {
var test = matcher.create(['*.{jpg,png}']);
var test = matcher.create('/', ['*.{jpg,png}']);
expect(test('a.jpg')).to.equal(true);

@@ -78,3 +127,3 @@ expect(test('b.png')).to.equal(true);

it('?', function () {
var test = matcher.create(['a?c']);
var test = matcher.create('/', ['a?c']);
expect(test('/abc')).to.equal(true);

@@ -85,4 +134,20 @@ expect(test('/ac')).to.equal(false);

it('comment character # havs no special meaning', function () {
var test = matcher.create(['#a']);
it('[...] - characters range', function () {
var test = matcher.create('/', ['[0-9][0-9]']);
expect(test('/78')).to.equal(true);
expect(test('/a78')).to.equal(false);
});
it('combining different tokens together', function () {
var test = matcher.create('/', ['+(f?o|bar*)']);
expect(test('/f0o')).to.equal(true);
expect(test('/f_o')).to.equal(true);
expect(test('/bar')).to.equal(true);
expect(test('/bar_')).to.equal(true);
expect(test('/f_obar123')).to.equal(true);
expect(test('/f__obar123')).to.equal(false);
});
it('comment character # has no special meaning', function () {
var test = matcher.create('/', ['#a']);
expect(test('/#a')).to.equal(true);

@@ -93,4 +158,4 @@ });

describe('negation', function () {
it('selects everything except negated for one defined pattern', function () {
var test = matcher.create('!abc');
it('selects everything except negated', function () {
var test = matcher.create('/', '!abc');
expect(test('/abc')).to.equal(false);

@@ -100,4 +165,4 @@ expect(test('/xyz')).to.equal(true);

it('selects everything except negated for multiple patterns', function () {
var test = matcher.create(['!abc', '!xyz']);
it('selects everything except negated (multiple patterns)', function () {
var test = matcher.create('/', ['!abc', '!xyz']);
expect(test('/abc')).to.equal(false);

@@ -109,3 +174,3 @@ expect(test('/xyz')).to.equal(false);

it('filters previous match if negation is farther in order', function () {
var test = matcher.create(['abc', '123', '!/xyz/**', '!/789/**']);
var test = matcher.create('/', ['abc', '123', '!/xyz/**', '!789/**']);
expect(test('/abc')).to.equal(true);

@@ -118,2 +183,17 @@ expect(test('/456/123')).to.equal(true);

});
describe('dotfiles', function () {
it('has no problem with matching dotfile', function () {
var test = matcher.create('/', '.foo');
expect(test('/.foo')).to.equal(true);
expect(test('/foo')).to.equal(false);
});
it('dotfile negation', function () {
var test = matcher.create('/', ['abc', '!.foo/**']);
expect(test('/.foo/abc')).to.equal(false);
test = matcher.create('/', ['abc', '!.foo/**']);
expect(test('/foo/abc')).to.equal(true);
});
});
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc