detective-postcss
Advanced tools
Comparing version 2.0.0 to 2.1.0
@@ -1,2 +0,8 @@ | ||
declare const _default: (src: any) => any[]; | ||
export = _default; | ||
declare function detective(src: any, options?: detective.Options): any[]; | ||
declare namespace detective { | ||
interface Options { | ||
url: boolean; | ||
} | ||
function MalformedCssError(): void; | ||
} | ||
export = detective; |
@@ -7,2 +7,40 @@ "use strict"; | ||
var debug = d('detective-postcss'); | ||
function detective(src, options) { | ||
if (options === void 0) { options = { url: false }; } | ||
var references = []; | ||
var root; | ||
try { | ||
root = postcss_1.parse(src); | ||
} | ||
catch (e) { | ||
throw new detective.MalformedCssError(); | ||
} | ||
root.walkAtRules(function (rule) { | ||
var file = null; | ||
if (isImportRule(rule)) { | ||
var firstNode = parseValue(rule.params).first; | ||
file = getValueOrUrl(firstNode); | ||
if (file) { | ||
debug("found %s of %s", '@import', file); | ||
} | ||
} | ||
if (isValueRule(rule)) { | ||
var lastNode = parseValue(rule.params).last; | ||
if (isFrom(lastNode.prev())) { | ||
file = getValueOrUrl(lastNode); | ||
if (file) { | ||
debug("found %s of %s", '@value with import', file); | ||
} | ||
} | ||
} | ||
file && references.push(file); | ||
}); | ||
if (options.url) { | ||
root.walkDecls(function (decl) { | ||
var nodes = parseValue(decl.value).nodes; | ||
references = references.concat(nodes.filter(isUrlNode).map(getValueOrUrl)); | ||
}); | ||
} | ||
return references; | ||
} | ||
function parseValue(value) { | ||
@@ -31,24 +69,10 @@ return postCssValuesParser(value).parse().first; | ||
} | ||
module.exports = function (src) { | ||
var references = []; | ||
var root = postcss_1.parse(src); | ||
root.walkAtRules(function (rule) { | ||
var file = null; | ||
if (isImportRule(rule)) { | ||
var firstNode = parseValue(rule.params).first; | ||
file = getValueOrUrl(firstNode); | ||
if (file) { | ||
debug("found %s of %s", '@import', file); | ||
} | ||
} | ||
if (isValueRule(rule)) { | ||
var lastNode = parseValue(rule.params).last; | ||
file = getValueOrUrl(lastNode); | ||
if (file) { | ||
debug("found %s of %s", '@value with import', file); | ||
} | ||
} | ||
file && references.push(file); | ||
}); | ||
return references; | ||
}; | ||
function isFrom(node) { | ||
return node.type == 'word' && node.value === 'from'; | ||
} | ||
(function (detective) { | ||
function MalformedCssError() { } | ||
detective.MalformedCssError = MalformedCssError; | ||
MalformedCssError.prototype = Object.create(Error.prototype); | ||
})(detective || (detective = {})); | ||
module.exports = detective; |
{ | ||
"name": "detective-postcss", | ||
"version": "2.0.0", | ||
"version": "2.1.0", | ||
"description": "Detective to find dependents of CSS (PostCSS dialect)", | ||
@@ -30,3 +30,3 @@ "main": "dist/index.js", | ||
"test": "jest --ci", | ||
"test:watch": "jest --watch", | ||
"test:watch": "jest --watch --notify", | ||
"precommit": "lint-staged" | ||
@@ -33,0 +33,0 @@ }, |
@@ -1,2 +0,2 @@ | ||
# node-detective-postcss | ||
# node-detective-postcss [![Build Status](https://travis-ci.org/joscha/node-detective-postcss.svg?branch=master)](https://travis-ci.org/joscha/node-detective-postcss) | ||
@@ -9,3 +9,3 @@ > Find the dependencies of a CSS file (postCSS dialects) | ||
It's the CSS (PostCSS dialect) counterpart to [detective](https://github.com/substack/node-detective), [detective-amd](https://github.com/mrjoelkemp/node-detective-amd), [detective-es6](https://github.com/mrjoelkemp/node-detective-es6), [detective-sass](https://github.com/mrjoelkemp/node-detective-sass), [detective-scsss](https://github.com/mrjoelkemp/node-detective-scss). | ||
It's the CSS (PostCSS dialect) counterpart to [detective](https://github.com/substack/node-detective), [detective-amd](https://github.com/mrjoelkemp/node-detective-amd), [detective-es6](https://github.com/mrjoelkemp/node-detective-es6), [detective-sass](https://github.com/mrjoelkemp/node-detective-sass), [detective-scss](https://github.com/mrjoelkemp/node-detective-scss). | ||
@@ -12,0 +12,0 @@ * The AST is generated using [postcss](https://github.com/postcss/postcss) and [postcss-values-parser](https://github.com/shellscape/postcss-values-parser). |
@@ -8,5 +8,10 @@ import * as d from 'debug'; | ||
export = function(src) { | ||
const references = []; | ||
const root = parse(src); | ||
function detective(src, options: detective.Options = { url: false }) { | ||
let references = []; | ||
let root; | ||
try { | ||
root = parse(src); | ||
} catch (e) { | ||
throw new detective.MalformedCssError(); | ||
} | ||
root.walkAtRules(rule => { | ||
@@ -23,5 +28,7 @@ let file = null; | ||
const lastNode = parseValue(rule.params).last; | ||
file = getValueOrUrl(lastNode); | ||
if (file) { | ||
debug(`found %s of %s`, '@value with import', file); | ||
if (isFrom(lastNode.prev())) { | ||
file = getValueOrUrl(lastNode); | ||
if (file) { | ||
debug(`found %s of %s`, '@value with import', file); | ||
} | ||
} | ||
@@ -31,4 +38,12 @@ } | ||
}); | ||
if (options.url) { | ||
root.walkDecls(decl => { | ||
const { nodes } = parseValue(decl.value); | ||
references = references.concat( | ||
nodes.filter(isUrlNode).map(getValueOrUrl) | ||
); | ||
}); | ||
} | ||
return references; | ||
}; | ||
} | ||
@@ -61,1 +76,16 @@ function parseValue(value: string) { | ||
} | ||
function isFrom(node: postCssValuesParser.Node) { | ||
return node.type == 'word' && node.value === 'from'; | ||
} | ||
namespace detective { | ||
export interface Options { | ||
url: boolean; | ||
} | ||
export function MalformedCssError() {} | ||
MalformedCssError.prototype = Object.create(Error.prototype); | ||
} | ||
export = detective; |
@@ -7,2 +7,3 @@ // incomplete declarations for the postcss-values-parser | ||
last?: parser.Node; | ||
prev?(): parser.Node; | ||
type: | ||
@@ -9,0 +10,0 @@ | 'atword' |
import detective = require('../src'); | ||
function assert(source: string, deps: string[]) { | ||
expect(detective(source)).toEqual(deps); | ||
function assert(source: string, deps: string[], options?: detective.Options) { | ||
expect(detective(source, options)).toEqual(deps); | ||
} | ||
@@ -83,2 +83,3 @@ | ||
}); | ||
it('works with grouped aliases', () => { | ||
@@ -90,3 +91,53 @@ assert( | ||
}); | ||
it('leaves simple definitions alone', () => { | ||
assert('@value mine: #fff;', []); | ||
}); | ||
it('leaves calculated definitions alone', () => { | ||
assert('@value mine: calc(1px + 4px)', []); | ||
}); | ||
}); | ||
describe('declarations', () => { | ||
it('ignores url() by default', () => { | ||
assert('.x { background: url(bla.png) }', []); | ||
}); | ||
it('filters out url() for direct usages', () => { | ||
assert('.x { background: url(bla.png) }', ['bla.png'], { | ||
url: true, | ||
}); | ||
}); | ||
it('filters out url() for deeper nested ones', () => { | ||
assert( | ||
".x { list-style: lower-roman url('../img/shape.png') outside; }", | ||
['../img/shape.png'], | ||
{ url: true } | ||
); | ||
}); | ||
it('finds url() in cursor definitions', () => { | ||
assert( | ||
'.x { cursor: url(cursor1.png) 4 12, auto; }', | ||
['cursor1.png'], | ||
{ url: true } | ||
); | ||
}); | ||
it('finds url() in @font-face', () => { | ||
assert( | ||
'@font-face { font-family: myFirstFont; src: url(sansation_light.woff); }', | ||
['sansation_light.woff'], | ||
{ url: true } | ||
); | ||
}); | ||
}); | ||
describe('error handling', () => { | ||
it('works for broken CSS', () => { | ||
expect(() => detective('--')).toThrow(detective.MalformedCssError); | ||
}); | ||
}); | ||
}); |
144151
11
306