import cssColors from './css-colors-list' ; type NodeName = 'ident' | 'selector' | 'call' | 'function' | 'media' | 'keyframes' | 'atrule' | 'import' | 'require' | 'supports' | 'literal' | 'group' | 'root' | 'block' | 'expression' | 'rgba' | 'property' | 'object' ; type NodeSegment = { string : string ; lineno : number ; nodes : Array < { name : string ; } > ; } ; export interface StylusValue { nodeName : NodeName ; lineno : number ; nodes ? : StylusNode [ ] ; } export interface StylusNode { nodeName : NodeName ; name : NodeName ; segments : NodeSegment [ ] ; expr ? : StylusValue ; lineno : number ; column : number ; val : StylusValue ; nodes ? : StylusNode [ ] ; vals ? : StylusNode [ ] ; } const stylus = require ( 'stylus' ) ; param { StylusNode } node return { Boolean } export function isVariableNode ( node ) { return node . nodeName === 'ident' && node . val && node . val . nodeName === 'expression' ; } param { StylusNode } node return { Boolean } export function isFunctionNode ( node ) { return node . nodeName === 'ident' && node . val && node . val . nodeName === 'function' ; } param { StylusNode } node return { Boolean } export function isSelectorNode ( node ) { return node . nodeName === 'selector' ; } param { StylusNode } node return { Boolean } export function isSelectorCallNode ( node ) { return node . nodeName === 'call' && node . name === 'selector' ; } param { StylusNode } node return { Boolean } export function isAtRuleNode ( node ) { return [ 'media' , 'keyframes' , 'atrule' , 'import' , 'require' , 'supports' , 'literal' ] . indexOf ( node . nodeName ) !== - 1 ; } param { StylusNode } node return { Boolean } export function isColor ( node ) { if ( node . nodeName === 'ident' && cssColors . indexOf ( node . name ) >= 0 ) return true ; if ( node . nodeName === 'rgba' ) return true ; if ( node . nodeName === 'call' && [ 'rgb' , 'rgba' , 'hsl' , 'hsla' ] . indexOf ( node . name ) >= 0 ) return true ; return false ; } param { string } text return { Object } export function buildAst ( text ) { try { return new stylus . Parser ( text ) . parse ( ) ; } catch ( error ) { return [ ] ; } } param { Object | Array } node return { Array } export function flattenAndFilterAst ( node ) { if ( Array . isArray ( node ) ) { return node . reduce ( ( acc , item ) => { return acc . concat ( flattenAndFilterAst ( item ) ) ; } , [ ] ) ; } if ( ! node . nodeName ) return ; if ( node . nodeName === 'keyframes' ) return node ; let nested = [ ] ; if ( node . nodes ) { nested = nested . concat ( flattenAndFilterAst ( node . nodes ) ) ; } if ( node . block ) { nested = nested . concat ( flattenAndFilterAst ( node . block ) ) ; } if ( node . nodeName === 'group' || node . nodeName === 'root' || node . nodeName === 'block' ) { return nested . length ? nested : node ; } node . nodes = null ; node . block = null ; return nested . length ? [ node ] . concat ( nested ) : node ; }