├── .babelrc ├── .eslintrc ├── .flowconfig ├── .gitignore ├── .travis.yml ├── README.md ├── example ├── .eslintrc ├── foo.scss ├── index.js └── tester.js ├── flow-typed └── npm │ ├── babel-cli_vx.x.x.js │ ├── babel-eslint_vx.x.x.js │ ├── babel-plugin-syntax-flow_vx.x.x.js │ ├── babel-plugin-transform-flow-strip-types_vx.x.x.js │ ├── babel-preset-es2015_vx.x.x.js │ ├── babel-preset-stage-1_vx.x.x.js │ ├── babel-watch_vx.x.x.js │ ├── eslint-config-standard_vx.x.x.js │ ├── eslint-plugin-flowtype_vx.x.x.js │ ├── eslint-plugin-import_vx.x.x.js │ ├── eslint-plugin-promise_vx.x.x.js │ ├── eslint-plugin-standard_vx.x.x.js │ ├── eslint_vx.x.x.js │ ├── flow-bin_v0.x.x.js │ ├── gonzales-pe_vx.x.x.js │ ├── lodash_v4.x.x.js │ ├── mocha_v3.1.x.js │ └── nodemon_vx.x.x.js ├── lib ├── core │ ├── index.js │ └── traversalUtils.js ├── index.js ├── rules │ ├── index.js │ ├── no-undef-class.js │ └── no-unused-class.js └── types │ └── index.js ├── package.json ├── screenshots └── screenshot3.png ├── test ├── files │ ├── composes1.scss │ ├── composesMultiple1.scss │ ├── export1.scss │ ├── export2.scss │ ├── extend1.scss │ ├── foo.js │ ├── global1.scss │ ├── noUndefClass1.less │ ├── noUndefClass1.scss │ ├── noUndefClass3.scss │ ├── noUnusedClass1.less │ ├── noUnusedClass1.scss │ ├── noUnusedClass2.scss │ ├── noUnusedClass3.scss │ ├── parentSelector1.scss │ ├── parentSelector2.scss │ ├── parentSelector3.scss │ ├── parentSelector4.scss │ ├── parentSelector5.scss │ ├── parentSelector6.scss │ ├── parentSelector7.scss │ ├── parentSelector8.scss │ ├── root1.scss │ └── unparsable.scss ├── lib │ ├── core │ │ └── traversalUtils.test.js │ └── rules │ │ ├── no-undef-class.test.js │ │ └── no-unused-class.test.js └── utils.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["@babel/preset-env"], 3 | "plugins": [ 4 | "@babel/plugin-syntax-flow", 5 | "@babel/transform-flow-strip-types", 6 | "@babel/plugin-proposal-export-default-from" 7 | ], 8 | "sourceMaps": "inline" 9 | } 10 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "parser": "@babel/eslint-parser", 3 | "extends": [ 4 | "standard", 5 | "plugin:import/errors", 6 | "plugin:import/warnings", 7 | "plugin:mocha/recommended" 8 | ], 9 | "env": { 10 | "es6": true, 11 | "node": true 12 | }, 13 | "rules": { 14 | "semi": [1, "always"], 15 | "camelcase": 0, 16 | "comma-dangle": 0 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | build/ 3 | 4 | [include] 5 | lib/ 6 | 7 | [version] 8 | ^0.36.0 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | 4 | build 5 | npm-debug.log 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4 4 | - 6 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eslint-plugin-css-modules 2 | 3 | [![Build Status](https://travis-ci.org/atfzl/eslint-plugin-css-modules.svg?branch=master)](https://travis-ci.org/atfzl/eslint-plugin-css-modules) 4 | 5 | This plugin intends to help you in tracking down problems when you are using css-modules. It tells if you are using a non-existent css/scss/less class in js or if you forgot to use some classes which you declared in css/scss/less. 6 | 7 | ## Rules 8 | 9 | * `css-modules/no-unused-class`: You must use all the classes defined in css/scss/less file. 10 | 11 | >If you still want to mark a class as used, then use this comment on top of your file 12 | ```js 13 | /* eslint css-modules/no-unused-class: [2, { markAsUsed: ['container'] }] */ 14 | ``` 15 | where container is the css class that you want to mark as used. 16 | Add all such classes in the array. 17 | 18 | >If you use the `camelCase` option of `css-loader`, you must also enabled it for this plugin 19 | ```js 20 | /* eslint css-modules/no-unused-class: [2, { camelCase: true }] */ 21 | ``` 22 | 23 | * `css-modules/no-undef-class`: You must not use a non existing class, or a property that hasn't been exported using the [:export keyword](https://github.com/css-modules/icss#export). 24 | 25 | >If you use the `camelCase` option of `css-loader`, you must also enabled it for this plugin 26 | ```js 27 | /* eslint css-modules/no-undef-class: [2, { camelCase: true }] */ 28 | ``` 29 | 30 | ## Installation 31 | 32 | ``` 33 | npm i --save-dev eslint-plugin-css-modules 34 | ``` 35 | 36 | ## Usage: 37 | 38 | .eslintrc 39 | ```json 40 | { 41 | "plugins": [ 42 | "css-modules" 43 | ], 44 | "extends": [ 45 | "plugin:css-modules/recommended" 46 | ] 47 | } 48 | ``` 49 | 50 | You may also tweak the rules individually. For instance, if you use the [camelCase](https://github.com/webpack-contrib/css-loader#camelcase) option of webpack's css-loader: 51 | 52 | ```json 53 | { 54 | "plugins": [ 55 | "css-modules" 56 | ], 57 | "extends": [ 58 | "plugin:css-modules/recommended" 59 | ], 60 | "rules": { 61 | "css-modules/no-unused-class": [2, { "camelCase": true }], 62 | "css-modules/no-undef-class": [2, { "camelCase": true }] 63 | } 64 | } 65 | ``` 66 | 67 | The camelCase option has 4 possible values, see [css-loader#camelCase](https://github.com/webpack-contrib/css-loader#camelcase) for description: 68 | ```js 69 | true | "dashes" | "only" | "dashes-only" 70 | ``` 71 | 72 | ## Specifying base path 73 | 74 | You can specify path for the base directory via plugin settings in .eslintrc. This is used by the plugin to resolve absolute (S)CSS paths: 75 | 76 | ```json 77 | { 78 | "settings": { 79 | "css-modules": { 80 | "basePath": "app/scripts/..." 81 | } 82 | } 83 | } 84 | ``` 85 | 86 | ## Screen Shot 87 | 88 | ![ScreenShot](https://raw.githubusercontent.com/atfzl/eslint-plugin-css-modules/master/screenshots/screenshot3.png) 89 | 90 | ``` 91 | 1:8 error Unused classes found: container css-modules/no-unused-class 92 | 5:17 error Class 'containr' not found css-modules/no-undef-class 93 | 10:26 error Class 'foo' not found css-modules/no-undef-class 94 | ``` 95 | 96 | scss: 97 | 98 | ```scss 99 | /* .head is global, will not be used in js */ 100 | :global(.head) { 101 | color: green; 102 | } 103 | 104 | .container { 105 | width: 116px; 106 | 107 | i { 108 | font-size: 2.2rem; 109 | } 110 | 111 | .button { 112 | padding: 7px 0 0 5px; 113 | } 114 | } 115 | 116 | .footer { 117 | color: cyan; 118 | } 119 | ``` 120 | -------------------------------------------------------------------------------- /example/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "plugins": [ 3 | "css-modules" 4 | ], 5 | "extends": [ 6 | "plugin:css-modules/recommended" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /example/foo.scss: -------------------------------------------------------------------------------- 1 | /* .head is global, will not be used in js */ 2 | :global(.head) { 3 | color: green; 4 | } 5 | 6 | .container { 7 | width: 116px; 8 | 9 | i { 10 | font-size: 2.2rem; 11 | } 12 | 13 | .button { 14 | padding: 7px 0 0 5px; 15 | } 16 | } 17 | 18 | .footer { 19 | color: cyan; 20 | } 21 | -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | /* eslint css-modules/no-unused-class: [2, { markAsUsed: ['container'] }] */ 2 | 3 | import s from './foo.scss'; 4 | 5 | const component = () => { 6 | const cls = s['containr']; 7 | 8 | s[cls]; 9 | 10 | s._getCss(); 11 | 12 | return ( 13 |
14 | text 15 |
16 |
17 |
18 | Footer 19 |
20 |
21 | ); 22 | }; 23 | 24 | export default component; 25 | -------------------------------------------------------------------------------- /example/tester.js: -------------------------------------------------------------------------------- 1 | /* 2 | ignore this file. This just for checking logs 3 | */ 4 | 5 | import { RuleTester } from 'eslint'; 6 | 7 | import rule from '../lib/rules/no-undef-class'; 8 | 9 | import { test } from '../test/utils'; 10 | 11 | const ruleTester = new RuleTester(); 12 | 13 | ruleTester.run('no-undef-class', rule, { 14 | valid: [ 15 | { code: '' }, 16 | ], 17 | invalid: [ 18 | test({ 19 | code: ` 20 | import s from './gonzalesFail1.css'; 21 | 22 | export default Foo = () => ( 23 |
24 | ); 25 | `, 26 | errors: ['foo'], 27 | }), 28 | ] 29 | }); 30 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-cli_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 670228b673fbf5d953585356d4345691 2 | // flow-typed version: <>/babel-cli_v^6.18.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-cli' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-cli' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-cli/bin/babel-doctor' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'babel-cli/bin/babel-external-helpers' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'babel-cli/bin/babel-node' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'babel-cli/bin/babel' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'babel-cli/lib/_babel-node' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'babel-cli/lib/babel-external-helpers' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'babel-cli/lib/babel-node' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'babel-cli/lib/babel/dir' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'babel-cli/lib/babel/file' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'babel-cli/lib/babel/index' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'babel-cli/lib/babel/util' { 66 | declare module.exports: any; 67 | } 68 | 69 | // Filename aliases 70 | declare module 'babel-cli/bin/babel-doctor.js' { 71 | declare module.exports: $Exports<'babel-cli/bin/babel-doctor'>; 72 | } 73 | declare module 'babel-cli/bin/babel-external-helpers.js' { 74 | declare module.exports: $Exports<'babel-cli/bin/babel-external-helpers'>; 75 | } 76 | declare module 'babel-cli/bin/babel-node.js' { 77 | declare module.exports: $Exports<'babel-cli/bin/babel-node'>; 78 | } 79 | declare module 'babel-cli/bin/babel.js' { 80 | declare module.exports: $Exports<'babel-cli/bin/babel'>; 81 | } 82 | declare module 'babel-cli/index' { 83 | declare module.exports: $Exports<'babel-cli'>; 84 | } 85 | declare module 'babel-cli/index.js' { 86 | declare module.exports: $Exports<'babel-cli'>; 87 | } 88 | declare module 'babel-cli/lib/_babel-node.js' { 89 | declare module.exports: $Exports<'babel-cli/lib/_babel-node'>; 90 | } 91 | declare module 'babel-cli/lib/babel-external-helpers.js' { 92 | declare module.exports: $Exports<'babel-cli/lib/babel-external-helpers'>; 93 | } 94 | declare module 'babel-cli/lib/babel-node.js' { 95 | declare module.exports: $Exports<'babel-cli/lib/babel-node'>; 96 | } 97 | declare module 'babel-cli/lib/babel/dir.js' { 98 | declare module.exports: $Exports<'babel-cli/lib/babel/dir'>; 99 | } 100 | declare module 'babel-cli/lib/babel/file.js' { 101 | declare module.exports: $Exports<'babel-cli/lib/babel/file'>; 102 | } 103 | declare module 'babel-cli/lib/babel/index.js' { 104 | declare module.exports: $Exports<'babel-cli/lib/babel/index'>; 105 | } 106 | declare module 'babel-cli/lib/babel/util.js' { 107 | declare module.exports: $Exports<'babel-cli/lib/babel/util'>; 108 | } 109 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-eslint_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: c629444c86e11ef6fd2f3f7bc4c49632 2 | // flow-typed version: <>/babel-eslint_v^7.1.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-eslint' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-eslint' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-eslint/babylon-to-espree/attachComments' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'babel-eslint/babylon-to-espree/convertTemplateType' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'babel-eslint/babylon-to-espree/index' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'babel-eslint/babylon-to-espree/toAST' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'babel-eslint/babylon-to-espree/toToken' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'babel-eslint/babylon-to-espree/toTokens' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module 'babel-eslint/babylon-to-espree/attachComments.js' { 51 | declare module.exports: $Exports<'babel-eslint/babylon-to-espree/attachComments'>; 52 | } 53 | declare module 'babel-eslint/babylon-to-espree/convertTemplateType.js' { 54 | declare module.exports: $Exports<'babel-eslint/babylon-to-espree/convertTemplateType'>; 55 | } 56 | declare module 'babel-eslint/babylon-to-espree/index.js' { 57 | declare module.exports: $Exports<'babel-eslint/babylon-to-espree/index'>; 58 | } 59 | declare module 'babel-eslint/babylon-to-espree/toAST.js' { 60 | declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toAST'>; 61 | } 62 | declare module 'babel-eslint/babylon-to-espree/toToken.js' { 63 | declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toToken'>; 64 | } 65 | declare module 'babel-eslint/babylon-to-espree/toTokens.js' { 66 | declare module.exports: $Exports<'babel-eslint/babylon-to-espree/toTokens'>; 67 | } 68 | declare module 'babel-eslint/index' { 69 | declare module.exports: $Exports<'babel-eslint'>; 70 | } 71 | declare module 'babel-eslint/index.js' { 72 | declare module.exports: $Exports<'babel-eslint'>; 73 | } 74 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-plugin-syntax-flow_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 5d7c2096f6bc30ca468313001f450834 2 | // flow-typed version: <>/babel-plugin-syntax-flow_v^6.18.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-plugin-syntax-flow' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-plugin-syntax-flow' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-plugin-syntax-flow/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-plugin-syntax-flow/lib/index.js' { 31 | declare module.exports: $Exports<'babel-plugin-syntax-flow/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-plugin-transform-flow-strip-types_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 855ea31ab2c7db08a247b6cee0c102cd 2 | // flow-typed version: <>/babel-plugin-transform-flow-strip-types_v^6.18.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-plugin-transform-flow-strip-types' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-plugin-transform-flow-strip-types' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-plugin-transform-flow-strip-types/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-plugin-transform-flow-strip-types/lib/index.js' { 31 | declare module.exports: $Exports<'babel-plugin-transform-flow-strip-types/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-preset-es2015_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: bf7573d40f6e30c6231567a9e265e245 2 | // flow-typed version: <>/babel-preset-es2015_v^6.18.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-preset-es2015' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-preset-es2015' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-preset-es2015/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-preset-es2015/lib/index.js' { 31 | declare module.exports: $Exports<'babel-preset-es2015/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-preset-stage-1_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1e58255aa40e674d103a1075688c9846 2 | // flow-typed version: <>/babel-preset-stage-1_v^6.16.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-preset-stage-1' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-preset-stage-1' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-preset-stage-1/lib/index' { 26 | declare module.exports: any; 27 | } 28 | 29 | // Filename aliases 30 | declare module 'babel-preset-stage-1/lib/index.js' { 31 | declare module.exports: $Exports<'babel-preset-stage-1/lib/index'>; 32 | } 33 | -------------------------------------------------------------------------------- /flow-typed/npm/babel-watch_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 1a65215b23bad8b23f7a002ddcac8dd9 2 | // flow-typed version: <>/babel-watch_v^2.0.6/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'babel-watch' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'babel-watch' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'babel-watch/babel-watch' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'babel-watch/runner' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'babel-watch/babel-watch.js' { 35 | declare module.exports: $Exports<'babel-watch/babel-watch'>; 36 | } 37 | declare module 'babel-watch/runner.js' { 38 | declare module.exports: $Exports<'babel-watch/runner'>; 39 | } 40 | -------------------------------------------------------------------------------- /flow-typed/npm/eslint-config-standard_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ca8fe33f0bf67720fe5e0b904410b0ae 2 | // flow-typed version: <>/eslint-config-standard_v^6.2.1/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'eslint-config-standard' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'eslint-config-standard' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'eslint-config-standard/test/basic' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'eslint-config-standard/test/validate-config' { 30 | declare module.exports: any; 31 | } 32 | 33 | // Filename aliases 34 | declare module 'eslint-config-standard/index' { 35 | declare module.exports: $Exports<'eslint-config-standard'>; 36 | } 37 | declare module 'eslint-config-standard/index.js' { 38 | declare module.exports: $Exports<'eslint-config-standard'>; 39 | } 40 | declare module 'eslint-config-standard/test/basic.js' { 41 | declare module.exports: $Exports<'eslint-config-standard/test/basic'>; 42 | } 43 | declare module 'eslint-config-standard/test/validate-config.js' { 44 | declare module.exports: $Exports<'eslint-config-standard/test/validate-config'>; 45 | } 46 | -------------------------------------------------------------------------------- /flow-typed/npm/eslint-plugin-flowtype_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 4cafa5d0a40ca126758232e98e85e341 2 | // flow-typed version: <>/eslint-plugin-flowtype_v^2.25.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'eslint-plugin-flowtype' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'eslint-plugin-flowtype' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'eslint-plugin-flowtype/bin/readmeAssertions' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'eslint-plugin-flowtype/dist/index' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'eslint-plugin-flowtype/dist/rules/booleanStyle' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'eslint-plugin-flowtype/dist/rules/defineFlowType' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'eslint-plugin-flowtype/dist/rules/genericSpacing' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'eslint-plugin-flowtype/dist/rules/requireParameterType' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'eslint-plugin-flowtype/dist/rules/requireReturnType' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'eslint-plugin-flowtype/dist/rules/requireVariableType' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'eslint-plugin-flowtype/dist/rules/semi' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'eslint-plugin-flowtype/dist/rules/sortKeys' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter' { 130 | declare module.exports: any; 131 | } 132 | 133 | declare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch' { 134 | declare module.exports: any; 135 | } 136 | 137 | declare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing' { 138 | declare module.exports: any; 139 | } 140 | 141 | declare module 'eslint-plugin-flowtype/dist/rules/useFlowType' { 142 | declare module.exports: any; 143 | } 144 | 145 | declare module 'eslint-plugin-flowtype/dist/rules/validSyntax' { 146 | declare module.exports: any; 147 | } 148 | 149 | declare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation' { 150 | declare module.exports: any; 151 | } 152 | 153 | declare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch' { 154 | declare module.exports: any; 155 | } 156 | 157 | declare module 'eslint-plugin-flowtype/dist/utilities/getParameterName' { 158 | declare module.exports: any; 159 | } 160 | 161 | declare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens' { 162 | declare module.exports: any; 163 | } 164 | 165 | declare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens' { 166 | declare module.exports: any; 167 | } 168 | 169 | declare module 'eslint-plugin-flowtype/dist/utilities/index' { 170 | declare module.exports: any; 171 | } 172 | 173 | declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile' { 174 | declare module.exports: any; 175 | } 176 | 177 | declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation' { 178 | declare module.exports: any; 179 | } 180 | 181 | declare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes' { 182 | declare module.exports: any; 183 | } 184 | 185 | declare module 'eslint-plugin-flowtype/dist/utilities/quoteName' { 186 | declare module.exports: any; 187 | } 188 | 189 | declare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers' { 190 | declare module.exports: any; 191 | } 192 | 193 | // Filename aliases 194 | declare module 'eslint-plugin-flowtype/bin/readmeAssertions.js' { 195 | declare module.exports: $Exports<'eslint-plugin-flowtype/bin/readmeAssertions'>; 196 | } 197 | declare module 'eslint-plugin-flowtype/dist/index.js' { 198 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/index'>; 199 | } 200 | declare module 'eslint-plugin-flowtype/dist/rules/booleanStyle.js' { 201 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/booleanStyle'>; 202 | } 203 | declare module 'eslint-plugin-flowtype/dist/rules/defineFlowType.js' { 204 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/defineFlowType'>; 205 | } 206 | declare module 'eslint-plugin-flowtype/dist/rules/delimiterDangle.js' { 207 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/delimiterDangle'>; 208 | } 209 | declare module 'eslint-plugin-flowtype/dist/rules/genericSpacing.js' { 210 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/genericSpacing'>; 211 | } 212 | declare module 'eslint-plugin-flowtype/dist/rules/noDupeKeys.js' { 213 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noDupeKeys'>; 214 | } 215 | declare module 'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes.js' { 216 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noPrimitiveConstructorTypes'>; 217 | } 218 | declare module 'eslint-plugin-flowtype/dist/rules/noWeakTypes.js' { 219 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/noWeakTypes'>; 220 | } 221 | declare module 'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter.js' { 222 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/objectTypeDelimiter'>; 223 | } 224 | declare module 'eslint-plugin-flowtype/dist/rules/requireParameterType.js' { 225 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireParameterType'>; 226 | } 227 | declare module 'eslint-plugin-flowtype/dist/rules/requireReturnType.js' { 228 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireReturnType'>; 229 | } 230 | declare module 'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation.js' { 231 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireValidFileAnnotation'>; 232 | } 233 | declare module 'eslint-plugin-flowtype/dist/rules/requireVariableType.js' { 234 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/requireVariableType'>; 235 | } 236 | declare module 'eslint-plugin-flowtype/dist/rules/semi.js' { 237 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/semi'>; 238 | } 239 | declare module 'eslint-plugin-flowtype/dist/rules/sortKeys.js' { 240 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/sortKeys'>; 241 | } 242 | declare module 'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon.js' { 243 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceAfterTypeColon'>; 244 | } 245 | declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket.js' { 246 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeGenericBracket'>; 247 | } 248 | declare module 'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon.js' { 249 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/spaceBeforeTypeColon'>; 250 | } 251 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions.js' { 252 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateFunctions'>; 253 | } 254 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer.js' { 255 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeIndexer'>; 256 | } 257 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty.js' { 258 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateObjectTypeProperty'>; 259 | } 260 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType.js' { 261 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateReturnType'>; 262 | } 263 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression.js' { 264 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypeCastExpression'>; 265 | } 266 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical.js' { 267 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/evaluateTypical'>; 268 | } 269 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index.js' { 270 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/index'>; 271 | } 272 | declare module 'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter.js' { 273 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeColonSpacing/reporter'>; 274 | } 275 | declare module 'eslint-plugin-flowtype/dist/rules/typeIdMatch.js' { 276 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/typeIdMatch'>; 277 | } 278 | declare module 'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing.js' { 279 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/unionIntersectionSpacing'>; 280 | } 281 | declare module 'eslint-plugin-flowtype/dist/rules/useFlowType.js' { 282 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/useFlowType'>; 283 | } 284 | declare module 'eslint-plugin-flowtype/dist/rules/validSyntax.js' { 285 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/rules/validSyntax'>; 286 | } 287 | declare module 'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation.js' { 288 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/checkFlowFileAnnotation'>; 289 | } 290 | declare module 'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch.js' { 291 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/fuzzyStringMatch'>; 292 | } 293 | declare module 'eslint-plugin-flowtype/dist/utilities/getParameterName.js' { 294 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getParameterName'>; 295 | } 296 | declare module 'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens.js' { 297 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenAfterParens'>; 298 | } 299 | declare module 'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens.js' { 300 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/getTokenBeforeParens'>; 301 | } 302 | declare module 'eslint-plugin-flowtype/dist/utilities/index.js' { 303 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/index'>; 304 | } 305 | declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFile.js' { 306 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFile'>; 307 | } 308 | declare module 'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation.js' { 309 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/isFlowFileAnnotation'>; 310 | } 311 | declare module 'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes.js' { 312 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/iterateFunctionNodes'>; 313 | } 314 | declare module 'eslint-plugin-flowtype/dist/utilities/quoteName.js' { 315 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/quoteName'>; 316 | } 317 | declare module 'eslint-plugin-flowtype/dist/utilities/spacingFixers.js' { 318 | declare module.exports: $Exports<'eslint-plugin-flowtype/dist/utilities/spacingFixers'>; 319 | } 320 | -------------------------------------------------------------------------------- /flow-typed/npm/eslint-plugin-import_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ed95a0dbf4ede73fb2995e80197fc3e2 2 | // flow-typed version: <>/eslint-plugin-import_v^2.0.1/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'eslint-plugin-import' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'eslint-plugin-import' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'eslint-plugin-import/config/electron' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'eslint-plugin-import/config/errors' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'eslint-plugin-import/config/react-native' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'eslint-plugin-import/config/react' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'eslint-plugin-import/config/recommended' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'eslint-plugin-import/config/stage-0' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'eslint-plugin-import/config/warnings' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'eslint-plugin-import/lib/core/importType' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'eslint-plugin-import/lib/core/staticRequire' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'eslint-plugin-import/lib/ExportMap' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'eslint-plugin-import/lib/importDeclaration' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'eslint-plugin-import/lib/index' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'eslint-plugin-import/lib/rules/default' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'eslint-plugin-import/lib/rules/export' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'eslint-plugin-import/lib/rules/extensions' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'eslint-plugin-import/lib/rules/first' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'eslint-plugin-import/lib/rules/imports-first' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'eslint-plugin-import/lib/rules/max-dependencies' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'eslint-plugin-import/lib/rules/named' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'eslint-plugin-import/lib/rules/namespace' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'eslint-plugin-import/lib/rules/newline-after-import' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'eslint-plugin-import/lib/rules/no-absolute-path' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'eslint-plugin-import/lib/rules/no-amd' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'eslint-plugin-import/lib/rules/no-commonjs' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'eslint-plugin-import/lib/rules/no-deprecated' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'eslint-plugin-import/lib/rules/no-duplicates' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'eslint-plugin-import/lib/rules/no-dynamic-require' { 130 | declare module.exports: any; 131 | } 132 | 133 | declare module 'eslint-plugin-import/lib/rules/no-extraneous-dependencies' { 134 | declare module.exports: any; 135 | } 136 | 137 | declare module 'eslint-plugin-import/lib/rules/no-internal-modules' { 138 | declare module.exports: any; 139 | } 140 | 141 | declare module 'eslint-plugin-import/lib/rules/no-mutable-exports' { 142 | declare module.exports: any; 143 | } 144 | 145 | declare module 'eslint-plugin-import/lib/rules/no-named-as-default-member' { 146 | declare module.exports: any; 147 | } 148 | 149 | declare module 'eslint-plugin-import/lib/rules/no-named-as-default' { 150 | declare module.exports: any; 151 | } 152 | 153 | declare module 'eslint-plugin-import/lib/rules/no-named-default' { 154 | declare module.exports: any; 155 | } 156 | 157 | declare module 'eslint-plugin-import/lib/rules/no-namespace' { 158 | declare module.exports: any; 159 | } 160 | 161 | declare module 'eslint-plugin-import/lib/rules/no-nodejs-modules' { 162 | declare module.exports: any; 163 | } 164 | 165 | declare module 'eslint-plugin-import/lib/rules/no-restricted-paths' { 166 | declare module.exports: any; 167 | } 168 | 169 | declare module 'eslint-plugin-import/lib/rules/no-unassigned-import' { 170 | declare module.exports: any; 171 | } 172 | 173 | declare module 'eslint-plugin-import/lib/rules/no-unresolved' { 174 | declare module.exports: any; 175 | } 176 | 177 | declare module 'eslint-plugin-import/lib/rules/no-webpack-loader-syntax' { 178 | declare module.exports: any; 179 | } 180 | 181 | declare module 'eslint-plugin-import/lib/rules/order' { 182 | declare module.exports: any; 183 | } 184 | 185 | declare module 'eslint-plugin-import/lib/rules/prefer-default-export' { 186 | declare module.exports: any; 187 | } 188 | 189 | declare module 'eslint-plugin-import/lib/rules/unambiguous' { 190 | declare module.exports: any; 191 | } 192 | 193 | declare module 'eslint-plugin-import/memo-parser/index' { 194 | declare module.exports: any; 195 | } 196 | 197 | // Filename aliases 198 | declare module 'eslint-plugin-import/config/electron.js' { 199 | declare module.exports: $Exports<'eslint-plugin-import/config/electron'>; 200 | } 201 | declare module 'eslint-plugin-import/config/errors.js' { 202 | declare module.exports: $Exports<'eslint-plugin-import/config/errors'>; 203 | } 204 | declare module 'eslint-plugin-import/config/react-native.js' { 205 | declare module.exports: $Exports<'eslint-plugin-import/config/react-native'>; 206 | } 207 | declare module 'eslint-plugin-import/config/react.js' { 208 | declare module.exports: $Exports<'eslint-plugin-import/config/react'>; 209 | } 210 | declare module 'eslint-plugin-import/config/recommended.js' { 211 | declare module.exports: $Exports<'eslint-plugin-import/config/recommended'>; 212 | } 213 | declare module 'eslint-plugin-import/config/stage-0.js' { 214 | declare module.exports: $Exports<'eslint-plugin-import/config/stage-0'>; 215 | } 216 | declare module 'eslint-plugin-import/config/warnings.js' { 217 | declare module.exports: $Exports<'eslint-plugin-import/config/warnings'>; 218 | } 219 | declare module 'eslint-plugin-import/lib/core/importType.js' { 220 | declare module.exports: $Exports<'eslint-plugin-import/lib/core/importType'>; 221 | } 222 | declare module 'eslint-plugin-import/lib/core/staticRequire.js' { 223 | declare module.exports: $Exports<'eslint-plugin-import/lib/core/staticRequire'>; 224 | } 225 | declare module 'eslint-plugin-import/lib/ExportMap.js' { 226 | declare module.exports: $Exports<'eslint-plugin-import/lib/ExportMap'>; 227 | } 228 | declare module 'eslint-plugin-import/lib/importDeclaration.js' { 229 | declare module.exports: $Exports<'eslint-plugin-import/lib/importDeclaration'>; 230 | } 231 | declare module 'eslint-plugin-import/lib/index.js' { 232 | declare module.exports: $Exports<'eslint-plugin-import/lib/index'>; 233 | } 234 | declare module 'eslint-plugin-import/lib/rules/default.js' { 235 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/default'>; 236 | } 237 | declare module 'eslint-plugin-import/lib/rules/export.js' { 238 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/export'>; 239 | } 240 | declare module 'eslint-plugin-import/lib/rules/extensions.js' { 241 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/extensions'>; 242 | } 243 | declare module 'eslint-plugin-import/lib/rules/first.js' { 244 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/first'>; 245 | } 246 | declare module 'eslint-plugin-import/lib/rules/imports-first.js' { 247 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/imports-first'>; 248 | } 249 | declare module 'eslint-plugin-import/lib/rules/max-dependencies.js' { 250 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/max-dependencies'>; 251 | } 252 | declare module 'eslint-plugin-import/lib/rules/named.js' { 253 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/named'>; 254 | } 255 | declare module 'eslint-plugin-import/lib/rules/namespace.js' { 256 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/namespace'>; 257 | } 258 | declare module 'eslint-plugin-import/lib/rules/newline-after-import.js' { 259 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/newline-after-import'>; 260 | } 261 | declare module 'eslint-plugin-import/lib/rules/no-absolute-path.js' { 262 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-absolute-path'>; 263 | } 264 | declare module 'eslint-plugin-import/lib/rules/no-amd.js' { 265 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-amd'>; 266 | } 267 | declare module 'eslint-plugin-import/lib/rules/no-commonjs.js' { 268 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-commonjs'>; 269 | } 270 | declare module 'eslint-plugin-import/lib/rules/no-deprecated.js' { 271 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-deprecated'>; 272 | } 273 | declare module 'eslint-plugin-import/lib/rules/no-duplicates.js' { 274 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-duplicates'>; 275 | } 276 | declare module 'eslint-plugin-import/lib/rules/no-dynamic-require.js' { 277 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-dynamic-require'>; 278 | } 279 | declare module 'eslint-plugin-import/lib/rules/no-extraneous-dependencies.js' { 280 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-extraneous-dependencies'>; 281 | } 282 | declare module 'eslint-plugin-import/lib/rules/no-internal-modules.js' { 283 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-internal-modules'>; 284 | } 285 | declare module 'eslint-plugin-import/lib/rules/no-mutable-exports.js' { 286 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-mutable-exports'>; 287 | } 288 | declare module 'eslint-plugin-import/lib/rules/no-named-as-default-member.js' { 289 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-as-default-member'>; 290 | } 291 | declare module 'eslint-plugin-import/lib/rules/no-named-as-default.js' { 292 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-as-default'>; 293 | } 294 | declare module 'eslint-plugin-import/lib/rules/no-named-default.js' { 295 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-named-default'>; 296 | } 297 | declare module 'eslint-plugin-import/lib/rules/no-namespace.js' { 298 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-namespace'>; 299 | } 300 | declare module 'eslint-plugin-import/lib/rules/no-nodejs-modules.js' { 301 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-nodejs-modules'>; 302 | } 303 | declare module 'eslint-plugin-import/lib/rules/no-restricted-paths.js' { 304 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-restricted-paths'>; 305 | } 306 | declare module 'eslint-plugin-import/lib/rules/no-unassigned-import.js' { 307 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unassigned-import'>; 308 | } 309 | declare module 'eslint-plugin-import/lib/rules/no-unresolved.js' { 310 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-unresolved'>; 311 | } 312 | declare module 'eslint-plugin-import/lib/rules/no-webpack-loader-syntax.js' { 313 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/no-webpack-loader-syntax'>; 314 | } 315 | declare module 'eslint-plugin-import/lib/rules/order.js' { 316 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/order'>; 317 | } 318 | declare module 'eslint-plugin-import/lib/rules/prefer-default-export.js' { 319 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/prefer-default-export'>; 320 | } 321 | declare module 'eslint-plugin-import/lib/rules/unambiguous.js' { 322 | declare module.exports: $Exports<'eslint-plugin-import/lib/rules/unambiguous'>; 323 | } 324 | declare module 'eslint-plugin-import/memo-parser/index.js' { 325 | declare module.exports: $Exports<'eslint-plugin-import/memo-parser/index'>; 326 | } 327 | -------------------------------------------------------------------------------- /flow-typed/npm/eslint-plugin-promise_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 5fd6942ecac535ed44e1bdbc2d708b19 2 | // flow-typed version: <>/eslint-plugin-promise_v^3.3.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'eslint-plugin-promise' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'eslint-plugin-promise' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'eslint-plugin-promise/rules/always-return' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'eslint-plugin-promise/rules/avoid-new' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'eslint-plugin-promise/rules/catch-or-return' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'eslint-plugin-promise/rules/lib/has-promise-callback' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'eslint-plugin-promise/rules/lib/is-callback' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'eslint-plugin-promise/rules/lib/is-inside-callback' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'eslint-plugin-promise/rules/lib/is-inside-promise' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'eslint-plugin-promise/rules/lib/is-named-callback' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'eslint-plugin-promise/rules/lib/is-promise' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'eslint-plugin-promise/rules/no-callback-in-promise' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'eslint-plugin-promise/rules/no-native' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'eslint-plugin-promise/rules/no-nesting' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'eslint-plugin-promise/rules/no-promise-in-callback' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'eslint-plugin-promise/rules/no-return-wrap' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'eslint-plugin-promise/rules/param-names' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'eslint-plugin-promise/rules/prefer-await-to-callbacks' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'eslint-plugin-promise/rules/prefer-await-to-then' { 90 | declare module.exports: any; 91 | } 92 | 93 | // Filename aliases 94 | declare module 'eslint-plugin-promise/index' { 95 | declare module.exports: $Exports<'eslint-plugin-promise'>; 96 | } 97 | declare module 'eslint-plugin-promise/index.js' { 98 | declare module.exports: $Exports<'eslint-plugin-promise'>; 99 | } 100 | declare module 'eslint-plugin-promise/rules/always-return.js' { 101 | declare module.exports: $Exports<'eslint-plugin-promise/rules/always-return'>; 102 | } 103 | declare module 'eslint-plugin-promise/rules/avoid-new.js' { 104 | declare module.exports: $Exports<'eslint-plugin-promise/rules/avoid-new'>; 105 | } 106 | declare module 'eslint-plugin-promise/rules/catch-or-return.js' { 107 | declare module.exports: $Exports<'eslint-plugin-promise/rules/catch-or-return'>; 108 | } 109 | declare module 'eslint-plugin-promise/rules/lib/has-promise-callback.js' { 110 | declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/has-promise-callback'>; 111 | } 112 | declare module 'eslint-plugin-promise/rules/lib/is-callback.js' { 113 | declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-callback'>; 114 | } 115 | declare module 'eslint-plugin-promise/rules/lib/is-inside-callback.js' { 116 | declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-inside-callback'>; 117 | } 118 | declare module 'eslint-plugin-promise/rules/lib/is-inside-promise.js' { 119 | declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-inside-promise'>; 120 | } 121 | declare module 'eslint-plugin-promise/rules/lib/is-named-callback.js' { 122 | declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-named-callback'>; 123 | } 124 | declare module 'eslint-plugin-promise/rules/lib/is-promise.js' { 125 | declare module.exports: $Exports<'eslint-plugin-promise/rules/lib/is-promise'>; 126 | } 127 | declare module 'eslint-plugin-promise/rules/no-callback-in-promise.js' { 128 | declare module.exports: $Exports<'eslint-plugin-promise/rules/no-callback-in-promise'>; 129 | } 130 | declare module 'eslint-plugin-promise/rules/no-native.js' { 131 | declare module.exports: $Exports<'eslint-plugin-promise/rules/no-native'>; 132 | } 133 | declare module 'eslint-plugin-promise/rules/no-nesting.js' { 134 | declare module.exports: $Exports<'eslint-plugin-promise/rules/no-nesting'>; 135 | } 136 | declare module 'eslint-plugin-promise/rules/no-promise-in-callback.js' { 137 | declare module.exports: $Exports<'eslint-plugin-promise/rules/no-promise-in-callback'>; 138 | } 139 | declare module 'eslint-plugin-promise/rules/no-return-wrap.js' { 140 | declare module.exports: $Exports<'eslint-plugin-promise/rules/no-return-wrap'>; 141 | } 142 | declare module 'eslint-plugin-promise/rules/param-names.js' { 143 | declare module.exports: $Exports<'eslint-plugin-promise/rules/param-names'>; 144 | } 145 | declare module 'eslint-plugin-promise/rules/prefer-await-to-callbacks.js' { 146 | declare module.exports: $Exports<'eslint-plugin-promise/rules/prefer-await-to-callbacks'>; 147 | } 148 | declare module 'eslint-plugin-promise/rules/prefer-await-to-then.js' { 149 | declare module.exports: $Exports<'eslint-plugin-promise/rules/prefer-await-to-then'>; 150 | } 151 | -------------------------------------------------------------------------------- /flow-typed/npm/eslint-plugin-standard_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6327ffe504a28c2a1c05f1c46aa1ec71 2 | // flow-typed version: <>/eslint-plugin-standard_v^2.0.1/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'eslint-plugin-standard' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'eslint-plugin-standard' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'eslint-plugin-standard/rules/array-bracket-even-spacing' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'eslint-plugin-standard/rules/computed-property-even-spacing' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'eslint-plugin-standard/rules/object-curly-even-spacing' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'eslint-plugin-standard/tests/array-bracket-even-spacing' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'eslint-plugin-standard/tests/computed-property-even-spacing' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'eslint-plugin-standard/tests/object-curly-even-spacing' { 46 | declare module.exports: any; 47 | } 48 | 49 | // Filename aliases 50 | declare module 'eslint-plugin-standard/index' { 51 | declare module.exports: $Exports<'eslint-plugin-standard'>; 52 | } 53 | declare module 'eslint-plugin-standard/index.js' { 54 | declare module.exports: $Exports<'eslint-plugin-standard'>; 55 | } 56 | declare module 'eslint-plugin-standard/rules/array-bracket-even-spacing.js' { 57 | declare module.exports: $Exports<'eslint-plugin-standard/rules/array-bracket-even-spacing'>; 58 | } 59 | declare module 'eslint-plugin-standard/rules/computed-property-even-spacing.js' { 60 | declare module.exports: $Exports<'eslint-plugin-standard/rules/computed-property-even-spacing'>; 61 | } 62 | declare module 'eslint-plugin-standard/rules/object-curly-even-spacing.js' { 63 | declare module.exports: $Exports<'eslint-plugin-standard/rules/object-curly-even-spacing'>; 64 | } 65 | declare module 'eslint-plugin-standard/tests/array-bracket-even-spacing.js' { 66 | declare module.exports: $Exports<'eslint-plugin-standard/tests/array-bracket-even-spacing'>; 67 | } 68 | declare module 'eslint-plugin-standard/tests/computed-property-even-spacing.js' { 69 | declare module.exports: $Exports<'eslint-plugin-standard/tests/computed-property-even-spacing'>; 70 | } 71 | declare module 'eslint-plugin-standard/tests/object-curly-even-spacing.js' { 72 | declare module.exports: $Exports<'eslint-plugin-standard/tests/object-curly-even-spacing'>; 73 | } 74 | -------------------------------------------------------------------------------- /flow-typed/npm/flow-bin_v0.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6a5610678d4b01e13bbfbbc62bdaf583 2 | // flow-typed version: 3817bc6980/flow-bin_v0.x.x/flow_>=v0.25.x 3 | 4 | declare module "flow-bin" { 5 | declare module.exports: string; 6 | } 7 | -------------------------------------------------------------------------------- /flow-typed/npm/gonzales-pe_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 750b2d64f194658ee7d5900e8c71c6dd 2 | // flow-typed version: <>/gonzales-pe_v^4.0.3/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'gonzales-pe' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'gonzales-pe' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'gonzales-pe/bin/gonzales' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'gonzales-pe/lib/gonzales' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'gonzales-pe/webpack.config' { 34 | declare module.exports: any; 35 | } 36 | 37 | // Filename aliases 38 | declare module 'gonzales-pe/bin/gonzales.js' { 39 | declare module.exports: $Exports<'gonzales-pe/bin/gonzales'>; 40 | } 41 | declare module 'gonzales-pe/lib/gonzales.js' { 42 | declare module.exports: $Exports<'gonzales-pe/lib/gonzales'>; 43 | } 44 | declare module 'gonzales-pe/webpack.config.js' { 45 | declare module.exports: $Exports<'gonzales-pe/webpack.config'>; 46 | } 47 | -------------------------------------------------------------------------------- /flow-typed/npm/lodash_v4.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: f0ca92a5557e6def26ab8132bc2ae10f 2 | // flow-typed version: 12af8270f6/lodash_v4.x.x/flow_>=v0.28.x_<=v0.37.x 3 | 4 | declare module 'lodash' { 5 | declare type TemplateSettings = { 6 | escape?: RegExp, 7 | evaluate?: RegExp, 8 | imports?: Object, 9 | interpolate?: RegExp, 10 | variable?: string, 11 | }; 12 | 13 | declare type TruncateOptions = { 14 | length?: number, 15 | omission?: string, 16 | separator?: RegExp|string, 17 | }; 18 | 19 | declare type DebounceOptions = { 20 | leading?: bool, 21 | maxWait?: number, 22 | trailing?: bool, 23 | }; 24 | 25 | declare type ThrottleOptions = { 26 | leading?: bool, 27 | trailing?: bool, 28 | }; 29 | 30 | declare type NestedArray = Array>; 31 | 32 | declare type matchesIterateeShorthand = Object; 33 | declare type matchesPropertyIterateeShorthand = [string, any]; 34 | declare type propertyIterateeShorthand = string; 35 | 36 | declare type OPredicate = 37 | | ((value: A, key: string, object: O) => any) 38 | | matchesIterateeShorthand 39 | | matchesPropertyIterateeShorthand 40 | | propertyIterateeShorthand; 41 | 42 | declare type OIterateeWithResult = Object|string|((value: V, key: string, object: O) => R); 43 | declare type OIteratee = OIterateeWithResult; 44 | declare type OFlatMapIteratee = OIterateeWithResult>; 45 | 46 | declare type Predicate = 47 | | ((value: T, index: number, array: Array) => any) 48 | | matchesIterateeShorthand 49 | | matchesPropertyIterateeShorthand 50 | | propertyIterateeShorthand; 51 | 52 | declare type _Iteratee = (item: T, index: number, array: ?Array) => mixed; 53 | declare type Iteratee = _Iteratee|Object|string; 54 | declare type Iteratee2 = ((item: T, index: number, array: ?Array) => U)|Object|string; 55 | declare type FlatMapIteratee = ((item: T, index: number, array: ?Array) => Array)|Object|string; 56 | declare type Comparator = (item: T, item2: T) => bool; 57 | 58 | declare type MapIterator = 59 | | ((item: T, index: number, array: Array) => U) 60 | | propertyIterateeShorthand; 61 | 62 | declare type OMapIterator = 63 | | ((item: T, key: string, object: O) => U) 64 | | propertyIterateeShorthand; 65 | 66 | declare class Lodash { 67 | // Array 68 | chunk(array: ?Array, size?: number): Array>; 69 | compact(array: Array): Array; 70 | concat(base: Array, ...elements: Array): Array; 71 | difference(array: ?Array, values?: Array): Array; 72 | differenceBy(array: ?Array, values: Array, iteratee: Iteratee): T[]; 73 | differenceWith(array: T[], values: T[], comparator?: Comparator): T[]; 74 | drop(array: ?Array, n?: number): Array; 75 | dropRight(array: ?Array, n?: number): Array; 76 | dropRightWhile(array: ?Array, predicate?: Predicate): Array; 77 | dropWhile(array: ?Array, predicate?: Predicate): Array; 78 | fill(array: ?Array, value: U, start?: number, end?: number): Array; 79 | findIndex(array: ?Array, predicate?: Predicate): number; 80 | findLastIndex(array: ?Array, predicate?: Predicate): number; 81 | // alias of _.head 82 | first(array: ?Array): T; 83 | flatten(array: Array|X>): Array; 84 | flattenDeep(array: any[]): Array; 85 | flattenDepth(array: any[], depth?: number): any[]; 86 | fromPairs(pairs: Array): Object; 87 | head(array: ?Array): T; 88 | indexOf(array: ?Array, value: T, fromIndex?: number): number; 89 | initial(array: ?Array): Array; 90 | intersection(...arrays: Array>): Array; 91 | //Workaround until (...parameter: T, parameter2: U) works 92 | intersectionBy(a1: Array, iteratee?: Iteratee): Array; 93 | intersectionBy(a1: Array, a2: Array, iteratee?: Iteratee): Array; 94 | intersectionBy(a1: Array, a2: Array, a3: Array, iteratee?: Iteratee): Array; 95 | intersectionBy(a1: Array, a2: Array, a3: Array, a4: Array, iteratee?: Iteratee): Array; 96 | //Workaround until (...parameter: T, parameter2: U) works 97 | intersectionWith(a1: Array, comparator: Comparator): Array; 98 | intersectionWith(a1: Array, a2: Array, comparator: Comparator): Array; 99 | intersectionWith(a1: Array, a2: Array, a3: Array, comparator: Comparator): Array; 100 | intersectionWith(a1: Array, a2: Array, a3: Array, a4: Array, comparator: Comparator): Array; 101 | join(array: ?Array, separator?: string): string; 102 | last(array: ?Array): T; 103 | lastIndexOf(array: ?Array, value: T, fromIndex?: number): number; 104 | nth(array: T[], n?: number): T; 105 | pull(array: ?Array, ...values?: Array): Array; 106 | pullAll(array: ?Array, values: Array): Array; 107 | pullAllBy(array: ?Array, values: Array, iteratee?: Iteratee): Array; 108 | pullAllWith(array?: T[], values: T[], comparator?: Function): T[]; 109 | pullAt(array: ?Array, ...indexed?: Array): Array; 110 | pullAt(array: ?Array, indexed?: Array): Array; 111 | remove(array: ?Array, predicate?: Predicate): Array; 112 | reverse(array: ?Array): Array; 113 | slice(array: ?Array, start?: number, end?: number): Array; 114 | sortedIndex(array: ?Array, value: T): number; 115 | sortedIndexBy(array: ?Array, value: T, iteratee?: Iteratee): number; 116 | sortedIndexOf(array: ?Array, value: T): number; 117 | sortedLastIndex(array: ?Array, value: T): number; 118 | sortedLastIndexBy(array: ?Array, value: T, iteratee?: Iteratee): number; 119 | sortedLastIndexOf(array: ?Array, value: T): number; 120 | sortedUniq(array: ?Array): Array; 121 | sortedUniqBy(array: ?Array, iteratee?: (value: T) => mixed): Array; 122 | tail(array: ?Array): Array; 123 | take(array: ?Array, n?: number): Array; 124 | takeRight(array: ?Array, n?: number): Array; 125 | takeRightWhile(array: ?Array, predicate?: Predicate): Array; 126 | takeWhile(array: ?Array, predicate?: Predicate): Array; 127 | union(...arrays?: Array>): Array; 128 | //Workaround until (...parameter: T, parameter2: U) works 129 | unionBy(a1: Array, iteratee?: Iteratee): Array; 130 | unionBy(a1: Array, a2: Array, iteratee?: Iteratee): Array; 131 | unionBy(a1: Array, a2: Array, a3: Array, iteratee?: Iteratee): Array; 132 | unionBy(a1: Array, a2: Array, a3: Array, a4: Array, iteratee?: Iteratee): Array; 133 | //Workaround until (...parameter: T, parameter2: U) works 134 | unionWith(a1: Array, comparator?: Comparator): Array; 135 | unionWith(a1: Array, a2: Array, comparator?: Comparator): Array; 136 | unionWith(a1: Array, a2: Array, a3: Array, comparator?: Comparator): Array; 137 | unionWith(a1: Array, a2: Array, a3: Array, a4: Array, comparator?: Comparator): Array; 138 | uniq(array: ?Array): Array; 139 | uniqBy(array: ?Array, iteratee?: Iteratee): Array; 140 | uniqWith(array: ?Array, comparator?: Comparator): Array; 141 | unzip(array: ?Array): Array; 142 | unzipWith(array: ?Array, iteratee?: Iteratee): Array; 143 | without(array: ?Array, ...values?: Array): Array; 144 | xor(...array: Array>): Array; 145 | //Workaround until (...parameter: T, parameter2: U) works 146 | xorBy(a1: Array, iteratee?: Iteratee): Array; 147 | xorBy(a1: Array, a2: Array, iteratee?: Iteratee): Array; 148 | xorBy(a1: Array, a2: Array, a3: Array, iteratee?: Iteratee): Array; 149 | xorBy(a1: Array, a2: Array, a3: Array, a4: Array, iteratee?: Iteratee): Array; 150 | //Workaround until (...parameter: T, parameter2: U) works 151 | xorWith(a1: Array, comparator?: Comparator): Array; 152 | xorWith(a1: Array, a2: Array, comparator?: Comparator): Array; 153 | xorWith(a1: Array, a2: Array, a3: Array, comparator?: Comparator): Array; 154 | xorWith(a1: Array, a2: Array, a3: Array, a4: Array, comparator?: Comparator): Array; 155 | zip(a1: A[], a2: B[]): Array<[A, B]>; 156 | zip(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>; 157 | zip(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>; 158 | zip(a1: A[], a2: B[], a3: C[], a4: D[], a5: E[]): Array<[A, B, C, D, E]>; 159 | 160 | zipObject(props?: Array, values?: Array): Object; 161 | zipObjectDeep(props?: any[], values?: any): Object; 162 | //Workaround until (...parameter: T, parameter2: U) works 163 | zipWith(a1: NestedArray, iteratee?: Iteratee): Array; 164 | zipWith(a1: NestedArray, a2: NestedArray, iteratee?: Iteratee): Array; 165 | zipWith(a1: NestedArray, a2: NestedArray, a3: NestedArray, iteratee?: Iteratee): Array; 166 | zipWith(a1: NestedArray, a2: NestedArray, a3: NestedArray, a4: NestedArray, iteratee?: Iteratee): Array; 167 | 168 | // Collection 169 | countBy(array: ?Array, iteratee?: Iteratee): Object; 170 | countBy(object: T, iteratee?: OIteratee): Object; 171 | // alias of _.forEach 172 | each(array: ?Array, iteratee?: Iteratee): Array; 173 | each(object: T, iteratee?: OIteratee): T; 174 | // alias of _.forEachRight 175 | eachRight(array: ?Array, iteratee?: Iteratee): Array; 176 | eachRight(object: T, iteratee?: OIteratee): T; 177 | every(array: ?Array, iteratee?: Iteratee): bool; 178 | every(object: T, iteratee?: OIteratee): bool; 179 | filter(array: ?Array, predicate?: Predicate): Array; 180 | filter(object: T, predicate?: OPredicate): Array; 181 | find(array: ?Array, predicate?: Predicate): T; 182 | find(object: T, predicate?: OPredicate): V; 183 | findLast(array: ?Array, predicate?: Predicate): T; 184 | findLast(object: T, predicate?: OPredicate): V; 185 | flatMap(array: ?Array, iteratee?: FlatMapIteratee): Array; 186 | flatMap(object: T, iteratee?: OFlatMapIteratee): Array; 187 | flatMapDeep(array: ?Array, iteratee?: FlatMapIteratee): Array; 188 | flatMapDeep(object: T, iteratee?: OFlatMapIteratee): Array; 189 | flatMapDepth(array: ?Array, iteratee?: FlatMapIteratee, depth?: number): Array; 190 | flatMapDepth(object: T, iteratee?: OFlatMapIteratee, depth?: number): Array; 191 | forEach(array: ?Array, iteratee?: Iteratee): Array; 192 | forEach(object: T, iteratee?: OIteratee): T; 193 | forEachRight(array: ?Array, iteratee?: Iteratee): Array; 194 | forEachRight(object: T, iteratee?: OIteratee): T; 195 | groupBy(array: ?Array, iteratee?: Iteratee): Object; 196 | groupBy(object: T, iteratee?: OIteratee): Object; 197 | includes(array: ?Array, value: T, fromIndex?: number): bool; 198 | includes(object: T, value: any, fromIndex?: number): bool; 199 | includes(str: string, value: string, fromIndex?: number): bool; 200 | invokeMap(array: ?Array, path: ((value: T) => Array|string)|Array|string, ...args?: Array): Array; 201 | invokeMap(object: T, path: ((value: any) => Array|string)|Array|string, ...args?: Array): Array; 202 | keyBy(array: ?Array, iteratee?: Iteratee2): {[key: V]: T}; 203 | keyBy(object: T, iteratee?: OIteratee): Object; 204 | map(array: ?Array, iteratee?: MapIterator): Array; 205 | map(object: ?T, iteratee?: OMapIterator): Array; 206 | map(str: ?string, iteratee?: (char: string, index: number, str: string) => any): string; 207 | orderBy(array: ?Array, iteratees?: Array>|string, orders?: Array<'asc'|'desc'>|string): Array; 208 | orderBy(object: T, iteratees?: Array>|string, orders?: Array<'asc'|'desc'>|string): Array; 209 | partition(array: ?Array, predicate?: Predicate): NestedArray; 210 | partition(object: T, predicate?: OPredicate): NestedArray; 211 | reduce(array: ?Array, iteratee?: (accumulator: U, value: T, index: number, array: ?Array) => U, accumulator?: U): U; 212 | reduce(object: T, iteratee?: (accumulator: U, value: any, key: string, object: T) => U, accumulator?: U): U; 213 | reduceRight(array: ?Array, iteratee?: (accumulator: U, value: T, index: number, array: ?Array) => U, accumulator?: U): U; 214 | reduceRight(object: T, iteratee?: (accumulator: U, value: any, key: string, object: T) => U, accumulator?: U): U; 215 | reject(array: ?Array, predicate?: Predicate): Array; 216 | reject(object: T, predicate?: OPredicate): Array; 217 | sample(array: ?Array): T; 218 | sample(object: T): V; 219 | sampleSize(array: ?Array, n?: number): Array; 220 | sampleSize(object: T, n?: number): Array; 221 | shuffle(array: ?Array): Array; 222 | shuffle(object: T): Array; 223 | size(collection: Array|Object): number; 224 | some(array: ?Array, predicate?: Predicate): bool; 225 | some(object?: ?T, predicate?: OPredicate): bool; 226 | sortBy(array: ?Array, ...iteratees?: Array>): Array; 227 | sortBy(array: ?Array, iteratees?: Array>): Array; 228 | sortBy(object: T, ...iteratees?: Array>): Array; 229 | sortBy(object: T, iteratees?: Array>): Array; 230 | 231 | // Date 232 | now(): number; 233 | 234 | // Function 235 | after(n: number, fn: Function): Function; 236 | ary(func: Function, n?: number): Function; 237 | before(n: number, fn: Function): Function; 238 | bind(func: Function, thisArg: any, ...partials: Array): Function; 239 | bindKey(obj: Object, key: string, ...partials: Array): Function; 240 | curry(func: Function, arity?: number): Function; 241 | curryRight(func: Function, arity?: number): Function; 242 | debounce(func: Function, wait?: number, options?: DebounceOptions): Function; 243 | defer(func: Function, ...args?: Array): number; 244 | delay(func: Function, wait: number, ...args?: Array): number; 245 | flip(func: Function): Function; 246 | memoize(func: Function, resolver?: Function): Function; 247 | negate(predicate: Function): Function; 248 | once(func: Function): Function; 249 | overArgs(func: Function, ...transforms: Array): Function; 250 | overArgs(func: Function, transforms: Array): Function; 251 | partial(func: Function, ...partials: any[]): Function; 252 | partialRight(func: Function, ...partials: Array): Function; 253 | partialRight(func: Function, partials: Array): Function; 254 | rearg(func: Function, ...indexes: Array): Function; 255 | rearg(func: Function, indexes: Array): Function; 256 | rest(func: Function, start?: number): Function; 257 | spread(func: Function): Function; 258 | throttle(func: Function, wait?: number, options?: ThrottleOptions): Function; 259 | unary(func: Function): Function; 260 | wrap(value: any, wrapper: Function): Function; 261 | 262 | // Lang 263 | castArray(value: *): any[]; 264 | clone(value: T): T; 265 | cloneDeep(value: T): T; 266 | cloneDeepWith(value: T, customizer?: ?(value: T, key: number|string, object: T, stack: any) => U): U; 267 | cloneWith(value: T, customizer?: ?(value: T, key: number|string, object: T, stack: any) => U): U; 268 | conformsTo(source: T, predicates: T&{[key:string]:(x:any)=>boolean}): boolean; 269 | eq(value: any, other: any): bool; 270 | gt(value: any, other: any): bool; 271 | gte(value: any, other: any): bool; 272 | isArguments(value: any): bool; 273 | isArray(value: any): bool; 274 | isArrayBuffer(value: any): bool; 275 | isArrayLike(value: any): bool; 276 | isArrayLikeObject(value: any): bool; 277 | isBoolean(value: any): bool; 278 | isBuffer(value: any): bool; 279 | isDate(value: any): bool; 280 | isElement(value: any): bool; 281 | isEmpty(value: any): bool; 282 | isEqual(value: any, other: any): bool; 283 | isEqualWith(value: T, other: U, customizer?: (objValue: any, otherValue: any, key: number|string, object: T, other: U, stack: any) => bool|void): bool; 284 | isError(value: any): bool; 285 | isFinite(value: any): bool; 286 | isFunction(value: Function): true; 287 | isFunction(value: number|string|void|null|Object): false; 288 | isInteger(value: any): bool; 289 | isLength(value: any): bool; 290 | isMap(value: any): bool; 291 | isMatch(object?: ?Object, source: Object): bool; 292 | isMatchWith(object: T, source: U, customizer?: (objValue: any, srcValue: any, key: number|string, object: T, source: U) => bool|void): bool; 293 | isNaN(value: any): bool; 294 | isNative(value: any): bool; 295 | isNil(value: any): bool; 296 | isNull(value: any): bool; 297 | isNumber(value: any): bool; 298 | isObject(value: any): bool; 299 | isObjectLike(value: any): bool; 300 | isPlainObject(value: any): bool; 301 | isRegExp(value: any): bool; 302 | isSafeInteger(value: any): bool; 303 | isSet(value: any): bool; 304 | isString(value: string): true; 305 | isString(value: number|Function|void|null|Object|Array): false; 306 | isSymbol(value: any): bool; 307 | isTypedArray(value: any): bool; 308 | isUndefined(value: any): bool; 309 | isWeakMap(value: any): bool; 310 | isWeakSet(value: any): bool; 311 | lt(value: any, other: any): bool; 312 | lte(value: any, other: any): bool; 313 | toArray(value: any): Array; 314 | toFinite(value: any): number; 315 | toInteger(value: any): number; 316 | toLength(value: any): number; 317 | toNumber(value: any): number; 318 | toPlainObject(value: any): Object; 319 | toSafeInteger(value: any): number; 320 | toString(value: any): string; 321 | 322 | // Math 323 | add(augend: number, addend: number): number; 324 | ceil(number: number, precision?: number): number; 325 | divide(dividend: number, divisor: number): number; 326 | floor(number: number, precision?: number): number; 327 | max(array: ?Array): T; 328 | maxBy(array: ?Array, iteratee?: Iteratee): T; 329 | mean(array: Array<*>): number; 330 | meanBy(array: Array, iteratee?: Iteratee): number; 331 | min(array: ?Array): T; 332 | minBy(array: ?Array, iteratee?: Iteratee): T; 333 | multiply(multiplier: number, multiplicand: number): number; 334 | round(number: number, precision?: number): number; 335 | subtract(minuend: number, subtrahend: number): number; 336 | sum(array: Array<*>): number; 337 | sumBy(array: Array, iteratee?: Iteratee): number; 338 | 339 | // number 340 | clamp(number: number, lower?: number, upper: number): number; 341 | inRange(number: number, start?: number, end: number): bool; 342 | random(lower?: number, upper?: number, floating?: bool): number; 343 | 344 | // Object 345 | assign(object?: ?Object, ...sources?: Array): Object; 346 | assignIn(a: A, b: B): A & B; 347 | assignIn(a: A, b: B, c: C): A & B & C; 348 | assignIn(a: A, b: B, c: C, d: D): A & B & C & D; 349 | assignIn(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E; 350 | assignInWith(object: T, s1: A, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object; 351 | assignInWith(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object; 352 | assignInWith(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object; 353 | assignInWith(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object; 354 | assignWith(object: T, s1: A, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object; 355 | assignWith(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object; 356 | assignWith(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object; 357 | assignWith(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object; 358 | at(object?: ?Object, ...paths: Array): Array; 359 | at(object?: ?Object, paths: Array): Array; 360 | create(prototype: T, properties?: Object): $Supertype; 361 | defaults(object?: ?Object, ...sources?: Array): Object; 362 | defaultsDeep(object?: ?Object, ...sources?: Array): Object; 363 | // alias for _.toPairs 364 | entries(object?: ?Object): NestedArray; 365 | // alias for _.toPairsIn 366 | entriesIn(object?: ?Object): NestedArray; 367 | // alias for _.assignIn 368 | extend(a: A, b: B): A & B; 369 | extend(a: A, b: B, c: C): A & B & C; 370 | extend(a: A, b: B, c: C, d: D): A & B & C & D; 371 | extend(a: A, b: B, c: C, d: D, e: E): A & B & C & D & E; 372 | // alias for _.assignInWith 373 | extendWith(object: T, s1: A, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object; 374 | extendWith(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object; 375 | extendWith(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object; 376 | extendWith(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object; 377 | findKey(object?: ?T, predicate?: OPredicate): string|void; 378 | findLastKey(object?: ?T, predicate?: OPredicate): string|void; 379 | forIn(object?: ?Object, iteratee?: OIteratee<*>): Object; 380 | forInRight(object?: ?Object, iteratee?: OIteratee<*>): Object; 381 | forOwn(object?: ?Object, iteratee?: OIteratee<*>): Object; 382 | forOwnRight(object?: ?Object, iteratee?: OIteratee<*>): Object; 383 | functions(object?: ?Object): Array; 384 | functionsIn(object?: ?Object): Array; 385 | get(object?: ?Object, path?: ?Array|string, defaultValue?: any): any; 386 | has(object?: ?Object, path?: ?Array|string): bool; 387 | hasIn(object?: ?Object, path?: ?Array|string): bool; 388 | invert(object?: ?Object, multiVal?: bool): Object; 389 | invertBy(object: ?Object, iteratee?: Function): Object; 390 | invoke(object?: ?Object, path?: ?Array|string, ...args?: Array): any; 391 | keys(object?: ?Object): Array; 392 | keysIn(object?: ?Object): Array; 393 | mapKeys(object?: ?Object, iteratee?: OIteratee<*>): Object; 394 | mapValues(object?: ?Object, iteratee?: OIteratee<*>): Object; 395 | merge(object?: ?Object, ...sources?: Array): Object; 396 | mergeWith(object: T, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A) => any|void): Object; 397 | mergeWith(object: T, s1: A, s2: B, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B) => any|void): Object; 398 | mergeWith(object: T, s1: A, s2: B, s3: C, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C) => any|void): Object; 399 | mergeWith(object: T, s1: A, s2: B, s3: C, s4: D, customizer?: (objValue: any, srcValue: any, key: string, object: T, source: A|B|C|D) => any|void): Object; 400 | omit(object?: ?Object, ...props: Array): Object; 401 | omit(object?: ?Object, props: Array): Object; 402 | omitBy(object?: ?T, predicate?: OPredicate): Object; 403 | pick(object?: ?Object, ...props: Array): Object; 404 | pick(object?: ?Object, props: Array): Object; 405 | pickBy(object?: ?T, predicate?: OPredicate): Object; 406 | result(object?: ?Object, path?: ?Array|string, defaultValue?: any): any; 407 | set(object?: ?Object, path?: ?Array|string, value: any): Object; 408 | setWith(object: T, path?: ?Array|string, value: any, customizer?: (nsValue: any, key: string, nsObject: T) => any): Object; 409 | toPairs(object?: ?Object|Array<*>): NestedArray; 410 | toPairsIn(object?: ?Object): NestedArray; 411 | transform(collection: Object|Array, iteratee?: OIteratee<*>, accumulator?: any): any; 412 | unset(object?: ?Object, path?: ?Array|string): bool; 413 | update(object: Object, path: string[]|string, updater: Function): Object; 414 | updateWith(object: Object, path: string[]|string, updater: Function, customizer?: Function): Object; 415 | values(object?: ?Object): Array; 416 | valuesIn(object?: ?Object): Array; 417 | 418 | // Seq 419 | // harder to read, but this is _() 420 | (value: any): any; 421 | chain(value: T): any; 422 | tap(value: T, interceptor: (value:T)=>any): T; 423 | thru(value: T1, interceptor: (value:T1)=>T2): T2; 424 | // TODO: _.prototype.* 425 | 426 | // String 427 | camelCase(string?: ?string): string; 428 | capitalize(string?: string): string; 429 | deburr(string?: string): string; 430 | endsWith(string?: string, target?: string, position?: number): bool; 431 | escape(string?: string): string; 432 | escapeRegExp(string?: string): string; 433 | kebabCase(string?: string): string; 434 | lowerCase(string?: string): string; 435 | lowerFirst(string?: string): string; 436 | pad(string?: string, length?: number, chars?: string): string; 437 | padEnd(string?: string, length?: number, chars?: string): string; 438 | padStart(string?: string, length?: number, chars?: string): string; 439 | parseInt(string: string, radix?: number): number; 440 | repeat(string?: string, n?: number): string; 441 | replace(string?: string, pattern: RegExp|string, replacement: ((string: string) => string)|string): string; 442 | snakeCase(string?: string): string; 443 | split(string?: string, separator: RegExp|string, limit?: number): Array; 444 | startCase(string?: string): string; 445 | startsWith(string?: string, target?: string, position?: number): bool; 446 | template(string?: string, options?: TemplateSettings): Function; 447 | toLower(string?: string): string; 448 | toUpper(string?: string): string; 449 | trim(string?: string, chars?: string): string; 450 | trimEnd(string?: string, chars?: string): string; 451 | trimStart(string?: string, chars?: string): string; 452 | truncate(string?: string, options?: TruncateOptions): string; 453 | unescape(string?: string): string; 454 | upperCase(string?: string): string; 455 | upperFirst(string?: string): string; 456 | words(string?: string, pattern?: RegExp|string): Array; 457 | 458 | // Util 459 | attempt(func: Function): any; 460 | bindAll(object?: ?Object, methodNames: Array): Object; 461 | bindAll(object?: ?Object, ...methodNames: Array): Object; 462 | cond(pairs: NestedArray): Function; 463 | conforms(source: Object): Function; 464 | constant(value: T): () => T; 465 | defaultTo(value: T1, default: T2): T1; 466 | // NaN is a number instead of its own type, otherwise it would behave like null/void 467 | defaultTo(value: T1, default: T2): T1|T2; 468 | defaultTo(value: T1, default: T2): T2; 469 | flow(...funcs?: Array): Function; 470 | flow(funcs?: Array): Function; 471 | flowRight(...funcs?: Array): Function; 472 | flowRight(funcs?: Array): Function; 473 | identity(value: T): T; 474 | iteratee(func?: any): Function; 475 | matches(source: Object): Function; 476 | matchesProperty(path?: ?Array|string, srcValue: any): Function; 477 | method(path?: ?Array|string, ...args?: Array): Function; 478 | methodOf(object?: ?Object, ...args?: Array): Function; 479 | mixin(object?: T, source: Object, options?: { chain: bool }): T; 480 | noConflict(): Lodash; 481 | noop(): void; 482 | nthArg(n?: number): Function; 483 | over(...iteratees: Array): Function; 484 | over(iteratees: Array): Function; 485 | overEvery(...predicates: Array): Function; 486 | overEvery(predicates: Array): Function; 487 | overSome(...predicates: Array): Function; 488 | overSome(predicates: Array): Function; 489 | property(path?: ?Array|string): Function; 490 | propertyOf(object?: ?Object): Function; 491 | range(start: number, end: number, step?: number): Array; 492 | range(end: number, step?: number): Array; 493 | rangeRight(start: number, end: number, step?: number): Array; 494 | rangeRight(end: number, step?: number): Array; 495 | runInContext(context?: Object): Function; 496 | 497 | stubArray(): Array<*>; 498 | stubFalse(): false; 499 | stubObject(): {}; 500 | stubString(): ''; 501 | stubTrue(): true; 502 | times(n: number, ...rest: Array): Array; 503 | times(n: number, iteratee: ((i: number) => T)): Array; 504 | toPath(value: any): Array; 505 | uniqueId(prefix?: string): string; 506 | 507 | // Properties 508 | VERSION: string; 509 | templateSettings: TemplateSettings; 510 | } 511 | 512 | declare var exports: Lodash; 513 | } 514 | -------------------------------------------------------------------------------- /flow-typed/npm/mocha_v3.1.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: 6b82cf8c1da27b4f0fa7a58e5ed5babf 2 | // flow-typed version: edf70dde46/mocha_v3.1.x/flow_>=v0.22.x 3 | 4 | type TestFunction = ((done: () => void) => void | Promise); 5 | 6 | declare var describe : { 7 | (name:string, spec:() => void): void; 8 | only(description:string, spec:() => void): void; 9 | skip(description:string, spec:() => void): void; 10 | timeout(ms:number): void; 11 | }; 12 | 13 | declare var context : typeof describe; 14 | 15 | declare var it : { 16 | (name:string, spec?:TestFunction): void; 17 | only(description:string, spec:TestFunction): void; 18 | skip(description:string, spec:TestFunction): void; 19 | timeout(ms:number): void; 20 | }; 21 | 22 | declare function before(method : TestFunction):void; 23 | declare function beforeEach(method : TestFunction):void; 24 | declare function after(method : TestFunction):void; 25 | declare function afterEach(method : TestFunction):void; 26 | -------------------------------------------------------------------------------- /flow-typed/npm/nodemon_vx.x.x.js: -------------------------------------------------------------------------------- 1 | // flow-typed signature: ecc82da093280a7b0eef229e40c481bc 2 | // flow-typed version: <>/nodemon_v^1.11.0/flow_v0.36.0 3 | 4 | /** 5 | * This is an autogenerated libdef stub for: 6 | * 7 | * 'nodemon' 8 | * 9 | * Fill this stub out by replacing all the `any` types. 10 | * 11 | * Once filled out, we encourage you to share your work with the 12 | * community by sending a pull request to: 13 | * https://github.com/flowtype/flow-typed 14 | */ 15 | 16 | declare module 'nodemon' { 17 | declare module.exports: any; 18 | } 19 | 20 | /** 21 | * We include stubs for each file inside this npm package in case you need to 22 | * require those files directly. Feel free to delete any files that aren't 23 | * needed. 24 | */ 25 | declare module 'nodemon/bin/nodemon' { 26 | declare module.exports: any; 27 | } 28 | 29 | declare module 'nodemon/lib/cli/index' { 30 | declare module.exports: any; 31 | } 32 | 33 | declare module 'nodemon/lib/cli/parse' { 34 | declare module.exports: any; 35 | } 36 | 37 | declare module 'nodemon/lib/config/command' { 38 | declare module.exports: any; 39 | } 40 | 41 | declare module 'nodemon/lib/config/defaults' { 42 | declare module.exports: any; 43 | } 44 | 45 | declare module 'nodemon/lib/config/exec' { 46 | declare module.exports: any; 47 | } 48 | 49 | declare module 'nodemon/lib/config/index' { 50 | declare module.exports: any; 51 | } 52 | 53 | declare module 'nodemon/lib/config/load' { 54 | declare module.exports: any; 55 | } 56 | 57 | declare module 'nodemon/lib/help/index' { 58 | declare module.exports: any; 59 | } 60 | 61 | declare module 'nodemon/lib/index' { 62 | declare module.exports: any; 63 | } 64 | 65 | declare module 'nodemon/lib/monitor/index' { 66 | declare module.exports: any; 67 | } 68 | 69 | declare module 'nodemon/lib/monitor/match' { 70 | declare module.exports: any; 71 | } 72 | 73 | declare module 'nodemon/lib/monitor/run' { 74 | declare module.exports: any; 75 | } 76 | 77 | declare module 'nodemon/lib/monitor/watch' { 78 | declare module.exports: any; 79 | } 80 | 81 | declare module 'nodemon/lib/nodemon' { 82 | declare module.exports: any; 83 | } 84 | 85 | declare module 'nodemon/lib/rules/add' { 86 | declare module.exports: any; 87 | } 88 | 89 | declare module 'nodemon/lib/rules/index' { 90 | declare module.exports: any; 91 | } 92 | 93 | declare module 'nodemon/lib/rules/parse' { 94 | declare module.exports: any; 95 | } 96 | 97 | declare module 'nodemon/lib/spawn' { 98 | declare module.exports: any; 99 | } 100 | 101 | declare module 'nodemon/lib/utils/bus' { 102 | declare module.exports: any; 103 | } 104 | 105 | declare module 'nodemon/lib/utils/clone' { 106 | declare module.exports: any; 107 | } 108 | 109 | declare module 'nodemon/lib/utils/colour' { 110 | declare module.exports: any; 111 | } 112 | 113 | declare module 'nodemon/lib/utils/index' { 114 | declare module.exports: any; 115 | } 116 | 117 | declare module 'nodemon/lib/utils/log' { 118 | declare module.exports: any; 119 | } 120 | 121 | declare module 'nodemon/lib/utils/merge' { 122 | declare module.exports: any; 123 | } 124 | 125 | declare module 'nodemon/lib/version' { 126 | declare module.exports: any; 127 | } 128 | 129 | declare module 'nodemon/web/index' { 130 | declare module.exports: any; 131 | } 132 | 133 | // Filename aliases 134 | declare module 'nodemon/bin/nodemon.js' { 135 | declare module.exports: $Exports<'nodemon/bin/nodemon'>; 136 | } 137 | declare module 'nodemon/lib/cli/index.js' { 138 | declare module.exports: $Exports<'nodemon/lib/cli/index'>; 139 | } 140 | declare module 'nodemon/lib/cli/parse.js' { 141 | declare module.exports: $Exports<'nodemon/lib/cli/parse'>; 142 | } 143 | declare module 'nodemon/lib/config/command.js' { 144 | declare module.exports: $Exports<'nodemon/lib/config/command'>; 145 | } 146 | declare module 'nodemon/lib/config/defaults.js' { 147 | declare module.exports: $Exports<'nodemon/lib/config/defaults'>; 148 | } 149 | declare module 'nodemon/lib/config/exec.js' { 150 | declare module.exports: $Exports<'nodemon/lib/config/exec'>; 151 | } 152 | declare module 'nodemon/lib/config/index.js' { 153 | declare module.exports: $Exports<'nodemon/lib/config/index'>; 154 | } 155 | declare module 'nodemon/lib/config/load.js' { 156 | declare module.exports: $Exports<'nodemon/lib/config/load'>; 157 | } 158 | declare module 'nodemon/lib/help/index.js' { 159 | declare module.exports: $Exports<'nodemon/lib/help/index'>; 160 | } 161 | declare module 'nodemon/lib/index.js' { 162 | declare module.exports: $Exports<'nodemon/lib/index'>; 163 | } 164 | declare module 'nodemon/lib/monitor/index.js' { 165 | declare module.exports: $Exports<'nodemon/lib/monitor/index'>; 166 | } 167 | declare module 'nodemon/lib/monitor/match.js' { 168 | declare module.exports: $Exports<'nodemon/lib/monitor/match'>; 169 | } 170 | declare module 'nodemon/lib/monitor/run.js' { 171 | declare module.exports: $Exports<'nodemon/lib/monitor/run'>; 172 | } 173 | declare module 'nodemon/lib/monitor/watch.js' { 174 | declare module.exports: $Exports<'nodemon/lib/monitor/watch'>; 175 | } 176 | declare module 'nodemon/lib/nodemon.js' { 177 | declare module.exports: $Exports<'nodemon/lib/nodemon'>; 178 | } 179 | declare module 'nodemon/lib/rules/add.js' { 180 | declare module.exports: $Exports<'nodemon/lib/rules/add'>; 181 | } 182 | declare module 'nodemon/lib/rules/index.js' { 183 | declare module.exports: $Exports<'nodemon/lib/rules/index'>; 184 | } 185 | declare module 'nodemon/lib/rules/parse.js' { 186 | declare module.exports: $Exports<'nodemon/lib/rules/parse'>; 187 | } 188 | declare module 'nodemon/lib/spawn.js' { 189 | declare module.exports: $Exports<'nodemon/lib/spawn'>; 190 | } 191 | declare module 'nodemon/lib/utils/bus.js' { 192 | declare module.exports: $Exports<'nodemon/lib/utils/bus'>; 193 | } 194 | declare module 'nodemon/lib/utils/clone.js' { 195 | declare module.exports: $Exports<'nodemon/lib/utils/clone'>; 196 | } 197 | declare module 'nodemon/lib/utils/colour.js' { 198 | declare module.exports: $Exports<'nodemon/lib/utils/colour'>; 199 | } 200 | declare module 'nodemon/lib/utils/index.js' { 201 | declare module.exports: $Exports<'nodemon/lib/utils/index'>; 202 | } 203 | declare module 'nodemon/lib/utils/log.js' { 204 | declare module.exports: $Exports<'nodemon/lib/utils/log'>; 205 | } 206 | declare module 'nodemon/lib/utils/merge.js' { 207 | declare module.exports: $Exports<'nodemon/lib/utils/merge'>; 208 | } 209 | declare module 'nodemon/lib/version.js' { 210 | declare module.exports: $Exports<'nodemon/lib/version'>; 211 | } 212 | declare module 'nodemon/web/index.js' { 213 | declare module.exports: $Exports<'nodemon/web/index'>; 214 | } 215 | -------------------------------------------------------------------------------- /lib/core/index.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | import fp from 'lodash/fp'; 6 | import _ from 'lodash'; 7 | import gonzales from 'gonzales-pe'; 8 | 9 | import type { JsNode, gASTNode } from '../types'; 10 | 11 | import { 12 | getRegularClassesMap, 13 | getComposesClassesMap, 14 | getExtendClassesMap, 15 | getParentSelectorClassesMap, 16 | getICSSExportPropsMap, 17 | eliminateGlobals, 18 | } from './traversalUtils'; 19 | 20 | const styleExtensionRegex = /\.(s?css|less)$/; 21 | 22 | function dashesCamelCase (str: string) { 23 | return str.replace(/-+(\w)/g, function (match, firstLetter) { 24 | return firstLetter.toUpperCase(); 25 | }); 26 | } 27 | 28 | export const getFilePath = (context, styleFilePath) => { 29 | const settings = context.settings['css-modules']; 30 | 31 | const dirName = path.dirname(context.getFilename()); 32 | const basePath = (settings && settings.basePath) ? settings.basePath : ''; 33 | 34 | return styleFilePath.startsWith('.') 35 | ? path.resolve(dirName, styleFilePath) 36 | : path.resolve(basePath, styleFilePath); 37 | }; 38 | 39 | export const getPropertyName = (node: JsNode): ?string => { 40 | const propertyName = node.computed 41 | /* 42 | square braces eg s['header'] 43 | we won't use node.property.name because it is for cases like 44 | s[abc] where abc is a variable 45 | */ 46 | ? node.property.value 47 | /* dot notation, eg s.header */ 48 | : node.property.name; 49 | 50 | /* 51 | skip property names starting with _ 52 | eg. special functions provided 53 | by css modules like _getCss() 54 | 55 | Tried to just skip function calls, but the parser 56 | thinks of normal property access like s._getCss and 57 | function calls like s._getCss() as same. 58 | */ 59 | if (!propertyName || _.startsWith(propertyName, '_')) { 60 | return null; 61 | } 62 | 63 | return propertyName; 64 | }; 65 | 66 | export const getClassesMap = (classes: Object, camelCase: string|boolean): Object => { 67 | const classesMap = {}; 68 | 69 | // Unroll the loop because of performance! 70 | // Remember that this function will run on every lint (e.g.: on file save) 71 | switch (camelCase) { 72 | case true: 73 | _.forIn(classes, (value, className) => { 74 | classesMap[className] = className; 75 | classesMap[_.camelCase(className)] = className; 76 | }); 77 | break; 78 | case 'dashes': 79 | _.forIn(classes, (value, className) => { 80 | classesMap[className] = className; 81 | classesMap[dashesCamelCase(className)] = className; 82 | }); 83 | break; 84 | case 'only': 85 | _.forIn(classes, (value, className) => { 86 | classesMap[_.camelCase(className)] = className; 87 | }); 88 | break; 89 | case 'dashes-only': 90 | _.forIn(classes, (value, className) => { 91 | classesMap[dashesCamelCase(className)] = className; 92 | }); 93 | break; 94 | default: 95 | _.forIn(classes, (value, className) => { 96 | classesMap[className] = className; 97 | }); 98 | } 99 | 100 | return classesMap; 101 | }; 102 | 103 | export const getStyleImportNodeData = (node: JsNode): ?Object => { 104 | // path from which it was imported 105 | const styleFilePath = fp.get('source.value')(node); 106 | 107 | if (styleFilePath && styleExtensionRegex.test(styleFilePath)) { 108 | const importNode = fp.compose( 109 | fp.find({ type: 'ImportDefaultSpecifier' }), 110 | fp.get('specifiers'), 111 | )(node); 112 | 113 | // the default imported name 114 | const importName = fp.get('local.name')(importNode); 115 | 116 | if (importName) { // it had a default import 117 | return { importName, styleFilePath, importNode }; 118 | } 119 | } 120 | }; 121 | 122 | export const fileExists = (filePath: string): boolean => { 123 | try { 124 | // check if file exists 125 | fs.statSync(filePath); 126 | return true; 127 | } catch (e) { 128 | return false; 129 | } 130 | }; 131 | 132 | /** 133 | * @returns AST of the parsed file or null if parse failed 134 | */ 135 | export const getAST = (filePath: string): gASTNode | null => { 136 | const fileContent = fs.readFileSync(filePath); 137 | 138 | const syntax = path.extname(filePath).slice(1); // remove leading . 139 | 140 | try { 141 | return gonzales.parse(fileContent.toString(), { syntax }); 142 | } catch (e) { 143 | return null; 144 | } 145 | }; 146 | 147 | export const getStyleClasses = (ast: gASTNode): ?Object => { 148 | /* 149 | mutates ast by removing :global scopes 150 | */ 151 | eliminateGlobals(ast); 152 | 153 | const classesMap = getRegularClassesMap(ast); 154 | const composedClassesMap = getComposesClassesMap(ast); 155 | const extendClassesMap = getExtendClassesMap(ast); 156 | const parentSelectorClassesMap = getParentSelectorClassesMap(ast); 157 | 158 | return { 159 | ...classesMap, 160 | ...composedClassesMap, 161 | ...extendClassesMap, 162 | ...parentSelectorClassesMap 163 | }; 164 | }; 165 | 166 | export const getExportPropsMap = (ast: gASTNode): ?Object => { 167 | const exportPropsMap = getICSSExportPropsMap(ast); 168 | return { 169 | ...exportPropsMap 170 | }; 171 | }; 172 | -------------------------------------------------------------------------------- /lib/core/traversalUtils.js: -------------------------------------------------------------------------------- 1 | // @flow 2 | /* eslint-disable no-param-reassign */ 3 | import fp from 'lodash/fp'; 4 | 5 | import type { gASTNode } from '../types'; 6 | 7 | type classMapType = { 8 | [key: string]: boolean, 9 | } 10 | 11 | export const getICSSExportPropsMap = (ast: gASTNode): classMapType => { 12 | const ruleSets: Array = []; 13 | ast.traverseByType('ruleset', node => ruleSets.push(node)); 14 | 15 | return fp.compose( 16 | fp.reduce((result, key) => { 17 | const prop = fp.compose(fp.nth(0), fp.map('content'))(key); 18 | result[prop] = prop; // e.g. { myProp: 'myProp' } 19 | return result; 20 | }, {}), 21 | fp.map('content'), 22 | fp.filter({ type: 'property' }), 23 | fp.flatMap('content'), 24 | fp.filter({ type: 'declaration' }), 25 | fp.flatMap('content'), 26 | fp.filter({ type: 'block' }), 27 | fp.flatMap('content'), 28 | fp.filter({ 29 | content: [{ 30 | type: 'selector', 31 | content: [{ 32 | type: 'pseudoClass', 33 | content: [{ 34 | type: 'ident', content: 'export' 35 | }] 36 | }] 37 | }] 38 | }) 39 | )(ruleSets); 40 | }; 41 | 42 | export const getRegularClassesMap = (ast: gASTNode): classMapType => { 43 | const ruleSets: Array = []; 44 | ast.traverseByType('ruleset', node => ruleSets.push(node)); 45 | 46 | return fp.compose( 47 | fp.reduce((result, key) => { 48 | result[key] = false; // classes haven't been used 49 | return result; 50 | }, {}), 51 | fp.map('content'), 52 | fp.filter({ type: 'ident' }), 53 | fp.flatMap('content'), 54 | fp.filter({ type: 'class' }), 55 | fp.flatMap('content'), 56 | fp.filter({ type: 'selector' }), 57 | fp.flatMap('content'), 58 | )(ruleSets); 59 | }; 60 | 61 | export const getComposesClassesMap = (ast: gASTNode): classMapType => { 62 | const declarations = []; 63 | ast.traverseByType('declaration', node => declarations.push(node)); 64 | 65 | return fp.compose( 66 | fp.reduce((result, key) => { 67 | result[key] = true; // mark composed classes as true 68 | return result; 69 | }, {}), 70 | fp.flatMap(fp.compose( 71 | fp.map(fp.get('content')), 72 | fp.filter({ type: 'ident' }), 73 | fp.get('content'), 74 | fp.find({ type: 'value' }), 75 | fp.get('content'), 76 | )), 77 | /* 78 | reject classes composing from other files 79 | eg. 80 | .foo { 81 | composes: .bar from './otherFile'; 82 | } 83 | */ 84 | fp.reject(fp.compose( 85 | fp.find({ type: 'ident', content: 'from' }), 86 | fp.get('content'), 87 | fp.find({ type: 'value' }), 88 | fp.get('content'), 89 | )), 90 | fp.filter(fp.compose( 91 | fp.find({ type: 'ident', content: 'composes' }), 92 | fp.get('content'), 93 | fp.find({ type: 'property' }), 94 | fp.get('content'), 95 | )), 96 | )(declarations); 97 | }; 98 | 99 | export const getExtendClassesMap = (ast: gASTNode): classMapType => { 100 | const extendNodes = []; 101 | ast.traverseByType('extend', node => extendNodes.push(node)); 102 | 103 | return fp.compose( 104 | fp.reduce((result, key) => { 105 | result[key] = true; // mark extend classes as true 106 | return result; 107 | }, {}), 108 | fp.map(fp.compose( 109 | fp.get('content'), 110 | fp.find({ type: 'ident' }), 111 | fp.get('content'), 112 | fp.find({ type: 'class' }), 113 | fp.get('content'), 114 | fp.find({ type: 'selector' }), 115 | fp.get('content'), 116 | )), 117 | )(extendNodes); 118 | }; 119 | 120 | /** 121 | * Resolves parent selectors to their full class names. 122 | * 123 | * E.g. `.foo { &_bar {color: blue } }` to `.foo_bar`. 124 | */ 125 | export const getParentSelectorClassesMap = (ast: gASTNode): classMapType => { 126 | const classesMap: classMapType = {}; 127 | 128 | // Recursively traverses down the tree looking for parent selector 129 | // extensions. Recursion is necessary as these selectors can be nested. 130 | const getExtensions = nodeContent => { 131 | const blockContent = fp.compose( 132 | fp.flatMap('content'), 133 | fp.filter({ type: 'block' }) 134 | )(nodeContent); 135 | 136 | const rulesetsContent = fp.flatMap('content', fp.concat( 137 | // `ruleset` children 138 | fp.filter({ type: 'ruleset' }, blockContent), 139 | 140 | // `ruleset` descendants nested in `include` nodes 141 | fp.compose( 142 | fp.filter({ type: 'ruleset' }), 143 | fp.flatMap('content'), 144 | fp.filter({ type: 'block' }), 145 | fp.flatMap('content'), 146 | fp.filter({ type: 'include' }) 147 | )(blockContent) 148 | )); 149 | 150 | const extensions = fp.compose( 151 | fp.map('content'), 152 | fp.filter({ type: 'ident' }), 153 | fp.flatMap('content'), 154 | fp.filter({ type: 'parentSelectorExtension' }), 155 | fp.flatMap('content'), 156 | fp.filter({ type: 'selector' }) 157 | )(rulesetsContent); 158 | 159 | if (!extensions.length) return []; 160 | 161 | const nestedExtensions = getExtensions(rulesetsContent); 162 | const result = extensions; 163 | if (nestedExtensions.length) { 164 | nestedExtensions.forEach(nestedExt => { 165 | extensions.forEach(ext => { 166 | result.push(ext + nestedExt); 167 | }); 168 | }); 169 | } 170 | 171 | return result; 172 | }; 173 | 174 | ast.traverseByType('ruleset', node => { 175 | const classNames = fp.compose( 176 | fp.map('content'), 177 | fp.filter({ type: 'ident' }), 178 | fp.flatMap('content'), 179 | fp.filter({ type: 'class' }), 180 | fp.flatMap('content'), 181 | fp.filter({ type: 'selector' }) 182 | )(node.content); 183 | 184 | if (!classNames.length) return; 185 | 186 | const extensions = getExtensions(node.content); 187 | if (!extensions.length) return; 188 | 189 | classNames.forEach(className => { 190 | extensions.forEach(ext => { 191 | classesMap[className + ext] = false; 192 | }); 193 | 194 | // Ignore the base class if it only exists for nesting parent selectors 195 | const hasDeclarations = fp.compose( 196 | fp.filter({ type: 'declaration' }), 197 | fp.flatMap('content'), 198 | fp.filter({ type: 'block' }) 199 | )(node.content).length > 0; 200 | if (!hasDeclarations) classesMap[className] = true; 201 | }); 202 | }); 203 | 204 | return classesMap; 205 | }; 206 | 207 | /** 208 | * Mutates the AST by removing `:global` instances. 209 | * 210 | * For the AST structure: 211 | * @see https://github.com/css/gonzales/blob/master/doc/AST.CSSP.en.md 212 | */ 213 | export const eliminateGlobals = (ast: gASTNode) => { 214 | // Remove all :global/:global(...) in selectors 215 | ast.traverseByType('selector', (selectorNode) => { 216 | const selectorContent = selectorNode.content; 217 | let hasGlobalWithNoArgs = false; 218 | let i = 0; 219 | let currNode = selectorContent[i]; 220 | while (currNode) { 221 | if (currNode.is('pseudoClass')) { 222 | // Remove all :global/:global(...) and trailing space 223 | const identifierNode = currNode.content[0]; 224 | if (identifierNode && identifierNode.content === 'global') { 225 | if (currNode.content.length === 1) hasGlobalWithNoArgs = true; 226 | selectorNode.removeChild(i); 227 | if (selectorContent[i] && selectorContent[i].is('space')) { 228 | selectorNode.removeChild(i); 229 | } 230 | } else { 231 | i++; 232 | } 233 | } else if (currNode.is('class') && hasGlobalWithNoArgs) { 234 | // Remove all class after :global and their trailing space 235 | selectorNode.removeChild(i); 236 | if (selectorContent[i] && selectorContent[i].is('space')) { 237 | selectorNode.removeChild(i); 238 | } 239 | } else { 240 | i++; 241 | } 242 | 243 | currNode = selectorContent[i]; 244 | } 245 | }); 246 | 247 | // Remove all ruleset with no selectors 248 | ast.traverseByType('ruleset', (node, index, parent) => { 249 | const rulesetContent = node.content; 250 | 251 | // Remove empty selectors and trailing deliminator and space 252 | let i = 0; 253 | let currNode = rulesetContent[i]; 254 | while (currNode) { 255 | if (currNode.is('selector') && currNode.content.length === 0) { 256 | node.removeChild(i); 257 | if (rulesetContent[i].is('delimiter')) node.removeChild(i); 258 | if (rulesetContent[i].is('space')) node.removeChild(i); 259 | } else { 260 | i++; 261 | } 262 | currNode = rulesetContent[i]; 263 | } 264 | 265 | // Remove the ruleset if no selectors 266 | if (rulesetContent.filter((node) => node.is('selector')).length === 0) { 267 | parent.removeChild(index); 268 | } 269 | }); 270 | }; 271 | -------------------------------------------------------------------------------- /lib/index.js: -------------------------------------------------------------------------------- 1 | export rules from './rules'; 2 | 3 | export const configs = { 4 | recommended: { 5 | rules: { 6 | 'css-modules/no-unused-class': 2, // error 7 | 'css-modules/no-undef-class': 2, // error 8 | } 9 | } 10 | }; 11 | -------------------------------------------------------------------------------- /lib/rules/index.js: -------------------------------------------------------------------------------- 1 | import noUnusedClass from './no-unused-class'; 2 | import noUndefClass from './no-undef-class'; 3 | 4 | export default { 5 | 'no-unused-class': noUnusedClass, 6 | 'no-undef-class': noUndefClass, 7 | }; 8 | -------------------------------------------------------------------------------- /lib/rules/no-undef-class.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import _ from 'lodash'; 3 | 4 | import { 5 | getStyleImportNodeData, 6 | getAST, 7 | fileExists, 8 | getStyleClasses, 9 | getPropertyName, 10 | getClassesMap, 11 | getExportPropsMap, 12 | getFilePath, 13 | } from '../core'; 14 | 15 | import type { JsNode } from '../types'; 16 | 17 | export default { 18 | meta: { 19 | docs: { 20 | description: 'Checks that you are using the existent css/scss/less classes', 21 | recommended: true, 22 | }, 23 | schema: [ 24 | { 25 | type: 'object', 26 | properties: { 27 | camelCase: { enum: [true, 'dashes', 'only', 'dashes-only'] } 28 | }, 29 | } 30 | ], 31 | }, 32 | create (context: Object) { 33 | const camelCase = _.get(context, 'options[0].camelCase'); 34 | 35 | /* 36 | maps variable name to property Object 37 | map = { 38 | [variableName]: { 39 | classesMap: { foo: 'foo', fooBar: 'foo-bar', 'foo-bar': 'foo-bar' }, 40 | node: {...} 41 | } 42 | } 43 | 44 | example: 45 | import s from './foo.scss'; 46 | s is variable name 47 | 48 | property Object has two keys 49 | 1. classesMap: an object with propertyName as key and its className as value 50 | 2. node: node that correspond to s (see example above) 51 | */ 52 | const map = {}; 53 | 54 | return { 55 | ImportDeclaration (node: JsNode) { 56 | const styleImportNodeData = getStyleImportNodeData(node); 57 | 58 | if (!styleImportNodeData) { 59 | return; 60 | } 61 | 62 | const { 63 | importName, 64 | styleFilePath, 65 | importNode, 66 | } = styleImportNodeData; 67 | 68 | const styleFileAbsolutePath = getFilePath(context, styleFilePath); 69 | let classesMap = {}; 70 | let exportPropsMap = {}; 71 | 72 | if (fileExists(styleFileAbsolutePath)) { 73 | const ast = getAST(styleFileAbsolutePath); 74 | const classes = ast && getStyleClasses(ast); 75 | 76 | classesMap = classes && getClassesMap(classes, camelCase); 77 | exportPropsMap = ast && getExportPropsMap(ast); 78 | } 79 | 80 | // this will be used to check if classes are defined 81 | _.set(map, `${importName}.classesMap`, classesMap); 82 | 83 | // this will be used to check if :export properties are defined 84 | _.set(map, `${importName}.exportPropsMap`, exportPropsMap); 85 | 86 | // save node for reporting unused styles 87 | _.set(map, `${importName}.node`, importNode); 88 | }, 89 | MemberExpression: (node: JsNode) => { 90 | /* 91 | Check if property exists in css/scss file as class 92 | */ 93 | 94 | const objectName = node.object.name; 95 | 96 | const propertyName = getPropertyName(node, camelCase); 97 | 98 | if (!propertyName) { 99 | return; 100 | } 101 | 102 | const classesMap = _.get(map, `${objectName}.classesMap`); 103 | const exportPropsMap = _.get(map, `${objectName}.exportPropsMap`); 104 | 105 | if (classesMap && classesMap[propertyName] == null && 106 | exportPropsMap && exportPropsMap[propertyName] == null) { 107 | context.report(node.property, `Class or exported property '${propertyName}' not found`); 108 | } 109 | } 110 | }; 111 | } 112 | }; 113 | -------------------------------------------------------------------------------- /lib/rules/no-unused-class.js: -------------------------------------------------------------------------------- 1 | /* @flow */ 2 | import fp from 'lodash/fp'; 3 | import _ from 'lodash'; 4 | import path from 'path'; 5 | 6 | import { 7 | getStyleImportNodeData, 8 | getStyleClasses, 9 | getPropertyName, 10 | getClassesMap, 11 | getFilePath, 12 | getAST, 13 | fileExists, 14 | } from '../core'; 15 | 16 | import type { JsNode } from '../types'; 17 | 18 | export default { 19 | meta: { 20 | docs: { 21 | description: 'Checks that you are using all css/scss/less classes', 22 | recommended: true, 23 | }, 24 | schema: [ 25 | { 26 | type: 'object', 27 | properties: { 28 | camelCase: { enum: [true, 'dashes', 'only', 'dashes-only'] }, 29 | markAsUsed: { type: 'array' }, 30 | }, 31 | } 32 | ], 33 | }, 34 | create (context: Object) { 35 | const markAsUsed = _.get(context, 'options[0].markAsUsed'); 36 | const camelCase = _.get(context, 'options[0].camelCase'); 37 | 38 | /* 39 | maps variable name to property Object 40 | map = { 41 | [variableName]: { 42 | classes: { foo: false, 'foo-bar': false }, 43 | classesMap: { foo: 'foo', fooBar: 'foo-bar', 'foo-bar': 'foo-bar' }, 44 | node: {...} 45 | } 46 | } 47 | 48 | example: 49 | import s from './foo.scss'; 50 | s is variable name 51 | 52 | property Object has two keys 53 | 1. classes: an object with className as key and a boolean as value. The boolean is marked if it is used in file 54 | 2. classesMap: an object with propertyName as key and its className as value 55 | 3. node: node that correspond to s (see example above) 56 | */ 57 | const map = {}; 58 | 59 | return { 60 | ImportDeclaration (node: JsNode) { 61 | const styleImportNodeData = getStyleImportNodeData(node); 62 | 63 | if (!styleImportNodeData) { 64 | return; 65 | } 66 | 67 | const { 68 | importName, 69 | styleFilePath, 70 | importNode, 71 | } = styleImportNodeData; 72 | 73 | const styleFileAbsolutePath = getFilePath(context, styleFilePath); 74 | 75 | let classes = {}; 76 | let classesMap = {}; 77 | 78 | if (fileExists(styleFileAbsolutePath)) { 79 | // this will be used to mark s.foo as used in MemberExpression 80 | const ast = getAST(styleFileAbsolutePath); 81 | classes = ast && getStyleClasses(ast); 82 | classesMap = classes && getClassesMap(classes, camelCase); 83 | } 84 | 85 | _.set(map, `${importName}.classes`, classes); 86 | _.set(map, `${importName}.classesMap`, classesMap); 87 | 88 | // save node for reporting unused styles 89 | _.set(map, `${importName}.node`, importNode); 90 | 91 | // save file path for reporting unused styles 92 | _.set(map, `${importName}.filePath`, styleFilePath); 93 | }, 94 | MemberExpression: (node: JsNode) => { 95 | /* 96 | Check if property exists in css/scss file as class 97 | */ 98 | 99 | const objectName = node.object.name; 100 | const propertyName = getPropertyName(node, camelCase); 101 | 102 | if (!propertyName) { 103 | return; 104 | } 105 | 106 | const className = _.get(map, `${objectName}.classesMap.${propertyName}`); 107 | 108 | if (className == null) { 109 | return; 110 | } 111 | 112 | // mark this property has used 113 | _.set(map, `${objectName}.classes.${className}`, true); 114 | }, 115 | 'Program:exit' () { 116 | /* 117 | Check if all classes defined in css/scss file are used 118 | */ 119 | 120 | /* 121 | we are looping over each import style node in program 122 | example: 123 | ``` 124 | import s from './foo.css'; 125 | import x from './bar.scss'; 126 | ``` 127 | then the loop will be run 2 times 128 | */ 129 | _.forIn(map, (o) => { 130 | const { classes, node, filePath } = o; 131 | 132 | /* 133 | if option is passed to mark a class as used, example: 134 | eslint css-modules/no-unused-class: [2, { markAsUsed: ['container'] }] 135 | */ 136 | _.forEach(markAsUsed, (usedClass) => { 137 | classes[usedClass] = true; 138 | }); 139 | 140 | // classNames not marked as true are unused 141 | const unusedClasses = fp.compose( 142 | fp.keys, 143 | fp.omitBy(fp.identity), // omit truthy values 144 | )(classes); 145 | 146 | if (!_.isEmpty(unusedClasses)) { 147 | context.report(node, `Unused classes found in ${path.basename(filePath)}: ${unusedClasses.join(', ')}`); 148 | } 149 | }); 150 | } 151 | }; 152 | } 153 | }; 154 | -------------------------------------------------------------------------------- /lib/types/index.js: -------------------------------------------------------------------------------- 1 | // js Node 2 | export type Position = { 3 | line: number, // 1 indexed 4 | column: number, // 0 indexed 5 | }; 6 | 7 | export type SourceLocation = { 8 | start: Position, 9 | end: Position, 10 | identifierName?: string, 11 | }; 12 | 13 | export type JsNode = { 14 | type: 'ImportDeclaration' | 'ImportDefaultSpecifier', 15 | start: number, 16 | end: number, 17 | loc: JsNode, 18 | local?: JsNode, 19 | name?: string, 20 | value?: string, 21 | specifiers?: Array, 22 | importKind?: 'value', 23 | extra?: { 24 | rawValue: string, 25 | raw: string, 26 | }, 27 | source: JsNode, 28 | range: Array, // most probably array of 2 numbers ?, 29 | _babelType: string, 30 | parent: JsNode, 31 | }; 32 | 33 | // gonzales AST Node Type 34 | export type gASTNode = { 35 | traverseByType: Function, 36 | 37 | type: 'stylesheet' 38 | | 'ident' 39 | | 'class' 40 | | 'selector' 41 | | 'value' 42 | | 'property' 43 | | 'ruleset' 44 | | 'extend' 45 | | 'declaration', 46 | content: string | Array, 47 | syntax: 'css' | 'scss' | 'less', 48 | }; 49 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-plugin-css-modules", 3 | "version": "2.12.0", 4 | "description": "Checks that you are using the existent css/scss/less classes, no more no less", 5 | "main": "build/index.js", 6 | "files": [ 7 | "build", 8 | "packages" 9 | ], 10 | "scripts": { 11 | "watch": "babel lib -d build --watch", 12 | "build": "rm -rf build && babel lib -d build", 13 | "lint": "eslint lib test", 14 | "test": "mocha 'test/**/*.test.js' --compilers js:@babel/register", 15 | "my-pre-publish": "npm run test && npm run build", 16 | "my-publish": "npm run my-pre-publish && yarn publish" 17 | }, 18 | "engines": { 19 | "node": ">=4.0.0" 20 | }, 21 | "keywords": [ 22 | "eslint", 23 | "eslintplugin", 24 | "eslint-plugin", 25 | "css-modules" 26 | ], 27 | "author": { 28 | "name": "Atif Afzal", 29 | "email": "atif5801@gmail.com", 30 | "url": "http://atfzl.me" 31 | }, 32 | "repository": { 33 | "type": "git", 34 | "url": "git://github.com/atfzl/eslint-plugin-css-modules.git" 35 | }, 36 | "license": "MIT", 37 | "peerDependencies": { 38 | "eslint": ">=2.0.0" 39 | }, 40 | "devDependencies": { 41 | "@babel/cli": "^7.23.0", 42 | "@babel/core": "^7.23.0", 43 | "@babel/eslint-parser": "^7.22.15", 44 | "@babel/plugin-proposal-export-default-from": "^7.22.17", 45 | "@babel/plugin-syntax-flow": "^7.22.5", 46 | "@babel/plugin-transform-flow-strip-types": "^7.22.5", 47 | "@babel/preset-env": "^7.22.20", 48 | "@babel/register": "^7.22.15", 49 | "chai": "^4.3.9", 50 | "eslint": "^8.50.0", 51 | "eslint-config-standard": "^17.1.0", 52 | "eslint-plugin-import": "^2.28.1", 53 | "eslint-plugin-mocha": "^10.2.0", 54 | "eslint-plugin-n": "^16.1.0", 55 | "eslint-plugin-promise": "^6.1.1", 56 | "flow-bin": "^0.36.0", 57 | "mocha": "^3.2.0", 58 | "nodemon": "^3.0.1" 59 | }, 60 | "dependencies": { 61 | "gonzales-pe": "^4.3.0", 62 | "lodash": "^4.17.2" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /screenshots/screenshot3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/atfzl/eslint-plugin-css-modules/e8ad744480547809f5cbcdf415b8cf8379920305/screenshots/screenshot3.png -------------------------------------------------------------------------------- /test/files/composes1.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | } 4 | 5 | .bar { 6 | color: red; 7 | composes: foo; 8 | } 9 | 10 | .baz { 11 | composes: other from './otherfile'; 12 | color: blue; 13 | } 14 | -------------------------------------------------------------------------------- /test/files/composesMultiple1.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | } 4 | 5 | .tar { 6 | color: black; 7 | } 8 | 9 | .bar { 10 | color: red; 11 | composes: foo tar; 12 | } 13 | 14 | .baz { 15 | composes: other from './otherfile'; 16 | color: blue; 17 | } 18 | -------------------------------------------------------------------------------- /test/files/export1.scss: -------------------------------------------------------------------------------- 1 | .bar { 2 | color: blue; 3 | } 4 | 5 | :export { 6 | myProp: something; 7 | } 8 | -------------------------------------------------------------------------------- /test/files/export2.scss: -------------------------------------------------------------------------------- 1 | .bar { 2 | color: blue; 3 | } 4 | 5 | :export { 6 | otherProp: something; 7 | } 8 | -------------------------------------------------------------------------------- /test/files/extend1.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | } 4 | 5 | .bar { 6 | @extend .foo; 7 | color: red; 8 | } 9 | 10 | .baz { 11 | width: 100px; 12 | } 13 | -------------------------------------------------------------------------------- /test/files/foo.js: -------------------------------------------------------------------------------- 1 | /* 2 | nothing to see here 3 | this file will be provided as filename parameter for RuleTester. 4 | This file is referred in utils.js 5 | */ 6 | -------------------------------------------------------------------------------- /test/files/global1.scss: -------------------------------------------------------------------------------- 1 | .local1 {} 2 | 3 | .local2 { 4 | :global(.global1) {} 5 | } 6 | 7 | :global .global1 {} 8 | 9 | :global(.global2) {} 10 | 11 | :global { 12 | .global1 { 13 | 14 | } 15 | } 16 | 17 | .local3 { 18 | :global { 19 | .global2 {} 20 | } 21 | } 22 | 23 | .local4 :global .global1 .global2 {} 24 | 25 | .local5 :global(.global1, .global2) .local6 {} -------------------------------------------------------------------------------- /test/files/noUndefClass1.less: -------------------------------------------------------------------------------- 1 | :global(.bold) { 2 | font-weight: bold; 3 | } 4 | -------------------------------------------------------------------------------- /test/files/noUndefClass1.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | min-width: 1024px; 3 | } 4 | -------------------------------------------------------------------------------- /test/files/noUndefClass3.scss: -------------------------------------------------------------------------------- 1 | .foo-bar { 2 | display: flex; 3 | } 4 | 5 | .bar-foo { 6 | display: flex; 7 | } 8 | 9 | .alreadyCamelCased { 10 | display: flex; 11 | } 12 | 13 | .snake_cased { 14 | display: flex; 15 | } 16 | 17 | :global(.bar) { 18 | font-weight: bold; 19 | } 20 | -------------------------------------------------------------------------------- /test/files/noUnusedClass1.less: -------------------------------------------------------------------------------- 1 | .foo { 2 | display: flex; 3 | } 4 | 5 | :global(.bar) { 6 | font-weight: bold; 7 | } 8 | -------------------------------------------------------------------------------- /test/files/noUnusedClass1.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | width: 100px; 3 | } 4 | 5 | .bar { 6 | height: 100%; 7 | 8 | .bold { 9 | font-weight: bold; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/files/noUnusedClass2.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | display: flex; 3 | } 4 | 5 | :global(.bar) { 6 | font-weight: bold; 7 | } 8 | -------------------------------------------------------------------------------- /test/files/noUnusedClass3.scss: -------------------------------------------------------------------------------- 1 | .foo-bar { 2 | display: flex; 3 | } 4 | 5 | .bar-foo { 6 | display: flex; 7 | } 8 | 9 | .alreadyCamelCased { 10 | display: flex; 11 | } 12 | 13 | .snake_cased { 14 | display: flex; 15 | } 16 | 17 | :global(.bar) { 18 | font-weight: bold; 19 | } 20 | -------------------------------------------------------------------------------- /test/files/parentSelector1.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | 4 | &_bar { 5 | width: 100px; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/files/parentSelector2.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | 4 | .bar { 5 | &_baz { 6 | width: 100px; 7 | } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/files/parentSelector3.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | 4 | &_baz { 5 | width: 100px; 6 | } 7 | 8 | &_bar { 9 | width: 100px; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/files/parentSelector4.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | 4 | &_baz, &_bar { 5 | width: 100px; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/files/parentSelector5.scss: -------------------------------------------------------------------------------- 1 | .foo, .bar { 2 | font-weight: 300; 3 | 4 | &_baz { 5 | font-weight: 300; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/files/parentSelector6.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | font-weight: 300; 3 | 4 | &_bar { 5 | font-weight: 300; 6 | 7 | &_baz { 8 | font-weight: 300; 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /test/files/parentSelector7.scss: -------------------------------------------------------------------------------- 1 | .foo { 2 | &_bar { 3 | font-weight: 300; 4 | } 5 | 6 | &_baz { 7 | font-weight: 300; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/files/parentSelector8.scss: -------------------------------------------------------------------------------- 1 | @import "~styles/media-queries"; 2 | 3 | .foo { 4 | @include match-medium { 5 | &_bar { 6 | font-weight: 300; 7 | } 8 | }; 9 | } 10 | -------------------------------------------------------------------------------- /test/files/root1.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --color: red; 3 | } 4 | 5 | .foo {} 6 | -------------------------------------------------------------------------------- /test/files/unparsable.scss: -------------------------------------------------------------------------------- 1 | safslf f sf 2 | -------------------------------------------------------------------------------- /test/lib/core/traversalUtils.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-env mocha */ 2 | 3 | import { expect } from 'chai'; 4 | import gonzales from 'gonzales-pe'; 5 | 6 | import { eliminateGlobals } from '../../../lib/core/traversalUtils'; 7 | 8 | describe('eliminateGlobals()', function () { 9 | describe('resolving :global pseudo class', function () { 10 | it('should remove :global operator and the global class', function () { 11 | const content = ` 12 | :global .global {} 13 | `; 14 | 15 | const ast = gonzales.parse(content, { syntax: 'scss' }); 16 | 17 | eliminateGlobals(ast); 18 | 19 | expect(ast.toString().trim()).to.be.equal(''); 20 | }); 21 | 22 | it('should remove :global operator and the global classes', function () { 23 | const content = ` 24 | :global .global1 .global2 .global3.global4 {} 25 | `; 26 | 27 | const ast = gonzales.parse(content, { syntax: 'scss' }); 28 | 29 | eliminateGlobals(ast); 30 | 31 | expect(ast.toString().trim()).to.be.equal(''); 32 | }); 33 | 34 | it('should only remove :global operator and the global classes', function () { 35 | const content = ` 36 | .local1 :global .global1 :local(.local2) .global2 :local(.local3), .local4 {} 37 | `; 38 | 39 | const ast = gonzales.parse(content, { syntax: 'scss' }); 40 | 41 | eliminateGlobals(ast); 42 | 43 | expect(ast.toString().trim()).to.be.equal( 44 | '.local1 :local(.local2) :local(.local3), .local4 {}' 45 | ); 46 | }); 47 | }); 48 | 49 | describe('resolving :global() pseudo class', function () { 50 | it('should remove :global() pseudo class and its argument class', function () { 51 | const content = ` 52 | :global(.global1) {} 53 | `; 54 | 55 | const ast = gonzales.parse(content, { syntax: 'scss' }); 56 | 57 | eliminateGlobals(ast); 58 | 59 | expect(ast.toString().trim()).to.be.equal(''); 60 | }); 61 | 62 | it('should remove :global() pseudo class and its argument classes', function () { 63 | const content = ` 64 | :global(.global1) :global(.global2, .global3), :global(.global4.global5) {} 65 | `; 66 | 67 | const ast = gonzales.parse(content, { syntax: 'scss' }); 68 | 69 | eliminateGlobals(ast); 70 | 71 | expect(ast.toString().trim()).to.be.equal(''); 72 | }); 73 | 74 | it('should only remove :global() pseudo class and its argument classes', function () { 75 | const content = ` 76 | .local1 :global(.global1) .local2, .local3 :global(.global2, .global3) :local(.local4) {} 77 | `; 78 | 79 | const ast = gonzales.parse(content, { syntax: 'scss' }); 80 | 81 | eliminateGlobals(ast); 82 | 83 | expect(ast.toString().trim()).to.be.equal( 84 | '.local1 .local2, .local3 :local(.local4) {}' 85 | ); 86 | }); 87 | }); 88 | }); 89 | -------------------------------------------------------------------------------- /test/lib/rules/no-undef-class.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable mocha/no-setup-in-describe */ 2 | import rule from '../../../lib/rules/no-undef-class'; 3 | import { RuleTester, addFilenameOption } from '../../utils'; 4 | 5 | const ruleTester = new RuleTester(); 6 | 7 | /** 8 | * ESLint ruleTester uses its own `describe` and `it` functions. This Mocha 9 | * `describe` is used merely for test output formatting. Disabling the 10 | * `mocha/no-setup-in-describe` rule to allow running rule tester in it. 11 | */ 12 | describe('no-undef-class', function () { 13 | ruleTester.run('no-undef-class', rule, { 14 | valid: [ 15 | { 16 | name: "absolute import eg: 'foo/bar.scss'", 17 | code: ` 18 | import s from 'test/files/noUndefClass1.scss'; 19 | 20 | export default Foo = () => ( 21 |
22 | ); 23 | `, 24 | }, 25 | { 26 | name: 'dot notation eg: s.container', 27 | code: ` 28 | import s from './noUndefClass1.scss'; 29 | 30 | export default Foo = () => ( 31 |
32 | ); 33 | `, 34 | }, 35 | { 36 | name: "square bracket string key eg: s['container']", 37 | code: ` 38 | import s from './noUndefClass1.scss'; 39 | 40 | export default Foo = () => ( 41 |
42 | ); 43 | `, 44 | }, 45 | { 46 | name: 'does not check for dynamic properties eg: s[dynamicValue]', 47 | code: ` 48 | import s from './noUndefClass1.scss'; 49 | 50 | export default Foo = (props) => ( 51 |
52 | ); 53 | `, 54 | }, 55 | { 56 | name: 'names starting with _ will be ignored', 57 | code: ` 58 | import s from './noUndefClass1.scss'; 59 | 60 | export default Foo = () => ( 61 |
62 | {s._getCss()} 63 |
64 | ); 65 | `, 66 | }, 67 | { 68 | name: 'using composes', 69 | code: ` 70 | import s from './composes1.scss'; 71 | 72 | export default Foo = () => ( 73 |
74 |
75 |
76 | ); 77 | `, 78 | }, 79 | { 80 | name: 'composing with multiple classes', 81 | code: ` 82 | import s from './composesMultiple1.scss'; 83 | 84 | export default Foo = () => ( 85 |
86 |
87 |
88 | ); 89 | `, 90 | }, 91 | { 92 | name: 'using @extend', 93 | code: ` 94 | import s from './extend1.scss'; 95 | 96 | export default Foo = () => ( 97 |
98 |
99 |
100 | ); 101 | `, 102 | }, 103 | { 104 | name: 'using parent selector (`&`)', 105 | code: ` 106 | import s from './parentSelector1.scss'; 107 | 108 | export default Foo = () => ( 109 |
110 |
111 |
112 | ); 113 | `, 114 | }, 115 | { 116 | name: 'Add support for parent selectors (&).', 117 | code: ` 118 | import s from './parentSelector2.scss'; 119 | 120 | export default Foo = () => ( 121 |
122 |
123 |
124 |
125 | ); 126 | `, 127 | }, 128 | { 129 | name: 'Add support for parent selectors (&).', 130 | code: ` 131 | import s from './parentSelector3.scss'; 132 | 133 | export default Foo = () => ( 134 |
135 |
136 |
137 |
138 | ); 139 | `, 140 | }, 141 | { 142 | name: 'Add support for parent selectors (&).', 143 | code: ` 144 | import s from './parentSelector4.scss'; 145 | 146 | export default Foo = () => ( 147 |
148 |
149 |
150 |
151 | ); 152 | `, 153 | }, 154 | { 155 | name: 'Add support for parent selectors (&).', 156 | code: ` 157 | import s from './parentSelector5.scss'; 158 | 159 | export default Foo = () => ( 160 |
161 |
162 |
163 |
164 | ); 165 | `, 166 | }, 167 | { 168 | name: 'Add support for parent selectors (&).', 169 | code: ` 170 | import s from './parentSelector6.scss'; 171 | 172 | export default Foo = () => ( 173 |
174 |
175 |
176 |
177 | ); 178 | `, 179 | }, 180 | { 181 | name: 'Support parent selectors in include blocks (aka mixins).', 182 | code: ` 183 | import s from './parentSelector8.scss'; 184 | 185 | export default Foo = () => ( 186 |
187 |
188 |
189 | ); 190 | `, 191 | }, 192 | { 193 | name: "file that can't be parsed should not give any error", 194 | code: ` 195 | import s from './unparsable.scss'; 196 | 197 | export default Foo = () => ( 198 |
199 |
200 |
201 | ); 202 | `, 203 | }, 204 | { 205 | name: 'global is ignored', 206 | code: ` 207 | import s from './global1.scss'; 208 | 209 | export default Foo = () => ( 210 |
211 |
212 | ); 213 | `, 214 | }, 215 | { 216 | name: 'ICSS :export pseudo-selector with a correct prop name should not give error', 217 | code: ` 218 | import s from './export1.scss'; 219 | 220 | export default Foo = () => ( 221 |
222 |
223 |
224 |
225 | ); 226 | `, 227 | }, 228 | { 229 | name: 'check if camelCase=true classes work as expected', 230 | code: ` 231 | import s from './noUndefClass3.scss'; 232 | 233 | export default Foo = () => ( 234 |
235 |
236 |
237 |
238 |
239 | ); 240 | `, 241 | options: [{ camelCase: true }], 242 | }, 243 | { 244 | name: 'Add support for all variants of the camelCase options.', 245 | code: ` 246 | import s from './noUndefClass3.scss'; 247 | 248 | export default Foo = () => ( 249 |
250 |
251 |
252 |
253 |
254 | ); 255 | `, 256 | options: [{ camelCase: true }], 257 | }, 258 | { 259 | name: 'check if camelCase=dashes classes work as expected', 260 | code: ` 261 | import s from './noUndefClass3.scss'; 262 | 263 | export default Foo = () => ( 264 |
265 |
266 |
267 |
268 |
269 | ); 270 | `, 271 | options: [{ camelCase: 'dashes' }], 272 | }, 273 | { 274 | name: 'Add camelCase option', 275 | code: ` 276 | import s from './noUndefClass3.scss'; 277 | 278 | export default Foo = () => ( 279 |
280 |
281 |
282 |
283 |
284 | ); 285 | `, 286 | options: [{ camelCase: 'dashes' }], 287 | }, 288 | { 289 | name: 'check if camelCase=only classes work as expected', 290 | code: ` 291 | import s from './noUndefClass3.scss'; 292 | 293 | export default Foo = () => ( 294 |
295 |
296 |
297 |
298 |
299 | ); 300 | `, 301 | options: [{ camelCase: 'only' }], 302 | }, 303 | { 304 | name: 'check if camelCase=dashes-only classes work as expected', 305 | code: ` 306 | import s from './noUndefClass3.scss'; 307 | 308 | export default Foo = () => ( 309 |
310 |
311 |
312 |
313 |
314 | ); 315 | `, 316 | options: [{ camelCase: 'dashes-only' }], 317 | }, 318 | ].map((testCase) => addFilenameOption(testCase)), 319 | invalid: [ 320 | { 321 | name: 'dot notation', 322 | code: ` 323 | import s from './noUndefClass1.scss'; 324 | 325 | export default Foo = () => ( 326 |
327 | ); 328 | `, 329 | errors: ["Class or exported property 'containr' not found"], 330 | }, 331 | { 332 | name: 'square bracket', 333 | code: ` 334 | import s from './noUndefClass1.scss'; 335 | 336 | export default Foo = () => ( 337 |
338 | ); 339 | `, 340 | errors: ["Class or exported property 'containr' not found"], 341 | }, 342 | { 343 | name: 'classes with global scope for selector are ignored eg. :global(.bold) { font-weight: bold; }', 344 | code: ` 345 | import s from './global1.scss'; 346 | 347 | export default Foo = () => ( 348 |
349 | ); 350 | `, 351 | errors: [ 352 | "Class or exported property 'global1' not found", 353 | "Class or exported property 'global2' not found", 354 | "Class or exported property 'global3' not found", 355 | ], 356 | }, 357 | { 358 | name: 'ICSS :export pseudo-selector with wrong prop name https://github.com/css-modules/icss#export', 359 | code: ` 360 | import s from './export2.scss'; 361 | 362 | export default Foo = () => ( 363 |
364 |
365 |
366 |
367 | ); 368 | `, 369 | errors: ["Class or exported property 'myProp' not found"], 370 | }, 371 | { 372 | name: 'check less support', 373 | code: ` 374 | import s from './noUndefClass1.less'; 375 | 376 | export default Foo = () => ( 377 |
378 | ); 379 | `, 380 | errors: ["Class or exported property 'bold' not found"], 381 | }, 382 | { 383 | name: 'using composes', 384 | code: ` 385 | import s from './composes1.scss'; 386 | 387 | export default Foo = () => ( 388 |
389 |
390 |
391 | ); 392 | `, 393 | errors: ["Class or exported property 'bazz' not found"], 394 | }, 395 | { 396 | name: 'composing multiple classes', 397 | code: ` 398 | import s from './composesMultiple1.scss'; 399 | 400 | export default Foo = () => ( 401 |
402 |
403 |
404 |
405 | ); 406 | `, 407 | errors: ["Class or exported property 'bazz' not found"], 408 | }, 409 | { 410 | name: 'using @extend', 411 | code: ` 412 | import s from './extend1.scss'; 413 | 414 | export default Foo = () => ( 415 |
416 |
417 |
418 | ); 419 | `, 420 | errors: ["Class or exported property 'bazz' not found"], 421 | }, 422 | { 423 | name: 'using parent selector (`&`)', 424 | code: ` 425 | import s from './parentSelector1.scss'; 426 | 427 | export default Foo = () => ( 428 |
429 |
430 |
431 |
432 | ); 433 | `, 434 | errors: ["Class or exported property 'foo_baz' not found"], 435 | }, 436 | { 437 | name: 'should show errors for file that does not exist', 438 | code: ` 439 | import s from './fileThatDoesNotExist.scss'; 440 | 441 | export default Foo = () => ( 442 |
443 |
444 |
445 | ); 446 | `, 447 | errors: [ 448 | "Class or exported property 'bar' not found", 449 | "Class or exported property 'baz' not found", 450 | ], 451 | }, 452 | { 453 | name: 'should detect if camel case properties are NOT defined when camelCase=true', 454 | code: ` 455 | import s from './noUndefClass3.scss'; 456 | 457 | export default Foo = () => ( 458 |
459 |
460 |
461 |
462 |
463 | ); 464 | `, 465 | options: [{ camelCase: true }], 466 | errors: ["Class or exported property 'fooBaz' not found"], 467 | }, 468 | { 469 | name: 'Add support for all variants of the camelCase options.', 470 | code: ` 471 | import s from './noUndefClass3.scss'; 472 | 473 | export default Foo = () => ( 474 |
475 |
476 |
477 |
478 |
479 | ); 480 | `, 481 | options: [{ camelCase: true }], 482 | errors: ["Class or exported property 'foo-baz' not found"], 483 | }, 484 | { 485 | name: 'should detect if camel case properties are NOT defined when camelCase=dashes', 486 | code: ` 487 | import s from './noUndefClass3.scss'; 488 | 489 | export default Foo = () => ( 490 |
491 |
492 |
493 |
494 |
495 | 496 |
497 |
498 |
499 |
500 |
501 | ); 502 | `, 503 | options: [{ camelCase: 'dashes' }], 504 | errors: [ 505 | "Class or exported property 'snakeCased' not found", 506 | "Class or exported property 'fooBaz' not found", 507 | "Class or exported property 'already-camel-cased' not found", 508 | "Class or exported property 'foo-baz' not found", 509 | ], 510 | }, 511 | { 512 | name: 'should detect if camel case properties are NOT defined when camelCase=only', 513 | code: ` 514 | import s from './noUndefClass3.scss'; 515 | 516 | export default Foo = () => ( 517 |
518 |
519 |
520 |
521 |
522 | 523 |
524 |
525 |
526 |
527 |
528 | ); 529 | `, 530 | options: [{ camelCase: 'only' }], 531 | errors: [ 532 | "Class or exported property 'fooBaz' not found", 533 | "Class or exported property 'foo-bar' not found", 534 | "Class or exported property 'already-camel-cased' not found", 535 | "Class or exported property 'snake_cased' not found", 536 | "Class or exported property 'foo-baz' not found", 537 | ], 538 | }, 539 | { 540 | name: 'should detect if camel case properties are NOT defined when camelCase=dashes-only', 541 | code: ` 542 | import s from './noUndefClass3.scss'; 543 | 544 | export default Foo = () => ( 545 |
546 |
547 |
548 |
549 |
550 | 551 |
552 |
553 |
554 |
555 |
556 | ); 557 | `, 558 | options: [{ camelCase: 'dashes-only' }], 559 | errors: [ 560 | "Class or exported property 'snakeCased' not found", 561 | "Class or exported property 'fooBaz' not found", 562 | "Class or exported property 'foo-bar' not found", 563 | "Class or exported property 'already-camel-cased' not found", 564 | "Class or exported property 'foo-baz' not found", 565 | ], 566 | }, 567 | ].map((testCase) => addFilenameOption(testCase)), 568 | }); 569 | }); 570 | -------------------------------------------------------------------------------- /test/lib/rules/no-unused-class.test.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable mocha/no-setup-in-describe */ 2 | import rule from '../../../lib/rules/no-unused-class'; 3 | import { RuleTester, addFilenameOption } from '../../utils'; 4 | 5 | const ruleTester = new RuleTester(); 6 | 7 | /** 8 | * ESLint ruleTester uses its own `describe` and `it` functions. This Mocha 9 | * `describe` is used merely for test output formatting. Disabling the 10 | * `mocha/no-setup-in-describe` rule to allow running rule tester in it. 11 | */ 12 | describe('no-unused-class', function () { 13 | ruleTester.run('no-unused-class', rule, { 14 | valid: [ 15 | { 16 | name: "absolute import eg: 'foo/bar.scss'", 17 | code: ` 18 | import s from 'test/files/noUndefClass1.scss'; 19 | 20 | export default Foo = () => ( 21 |
22 | ); 23 | `, 24 | }, 25 | { 26 | name: "dot notation and square brackets eg: s.foo and s['bar']", 27 | code: ` 28 | import s from './noUnusedClass1.scss'; 29 | 30 | export default Foo = () => ( 31 |
32 |
33 | 34 |
35 |
36 | ); 37 | `, 38 | }, 39 | { 40 | name: 'ignore global scope selector', 41 | code: ` 42 | import s from './noUnusedClass2.scss'; 43 | 44 | export default Foo = () => ( 45 |
46 | 47 |
48 | ); 49 | `, 50 | }, 51 | { 52 | name: 'ignore props exported by ICSS :export pseudo-selector https://github.com/css-modules/icss#export', 53 | code: ` 54 | import s from './export1.scss'; 55 | 56 | export default Foo = () => ( 57 |
58 | ); 59 | `, 60 | }, 61 | { 62 | name: 'check if composes classes are ignored', 63 | code: ` 64 | import s from './composes1.scss'; 65 | 66 | export default Foo = () => ( 67 |
68 | 69 |
70 | ); 71 | `, 72 | }, 73 | { 74 | name: 'composes with multiple classes', 75 | code: ` 76 | import s from './composesMultiple1.scss'; 77 | 78 | export default Foo = () => ( 79 |
80 | 81 |
82 | ); 83 | `, 84 | }, 85 | { 86 | name: 'check if @extend classes are ignored', 87 | code: ` 88 | import s from './extend1.scss'; 89 | 90 | export default Foo = () => ( 91 |
92 | 93 |
94 | ); 95 | `, 96 | }, 97 | { 98 | name: 'check if classes are ignored if they only exist for nesting parent selectors (`&`)', 99 | code: ` 100 | import s from './parentSelector7.scss'; 101 | 102 | export default Foo = () => ( 103 |
104 | 105 | 106 |
107 | ); 108 | `, 109 | }, 110 | { 111 | name: 'check if camelCase=true classes work as expected', 112 | code: ` 113 | import s from './noUnusedClass3.scss'; 114 | 115 | export default Foo = () => ( 116 |
117 |
118 |
119 |
120 |
121 | ); 122 | `, 123 | options: [{ camelCase: true }], 124 | }, 125 | { 126 | name: 'Add camelCase option', 127 | code: ` 128 | import s from './noUnusedClass3.scss'; 129 | 130 | export default Foo = () => ( 131 |
132 |
133 |
134 |
135 |
136 | ); 137 | `, 138 | options: [{ camelCase: true }], 139 | }, 140 | { 141 | name: 'check if camelCase=dashes classes work as expected', 142 | code: ` 143 | import s from './noUnusedClass3.scss'; 144 | 145 | export default Foo = () => ( 146 |
147 |
148 |
149 |
150 |
151 | ); 152 | `, 153 | options: [{ camelCase: 'dashes' }], 154 | }, 155 | { 156 | name: 'Add support for all variants of the camelCase options', 157 | code: ` 158 | import s from './noUnusedClass3.scss'; 159 | 160 | export default Foo = () => ( 161 |
162 |
163 |
164 |
165 |
166 | ); 167 | `, 168 | options: [{ camelCase: 'dashes' }], 169 | }, 170 | { 171 | name: 'check if camelCase=only classes work as expected', 172 | code: ` 173 | import s from './noUnusedClass3.scss'; 174 | 175 | export default Foo = () => ( 176 |
177 |
178 |
179 |
180 |
181 | ); 182 | `, 183 | options: [{ camelCase: 'only' }], 184 | }, 185 | { 186 | name: 'check if camelCase=dashes-only classes work as expected', 187 | code: ` 188 | import s from './noUnusedClass3.scss'; 189 | 190 | export default Foo = () => ( 191 |
192 |
193 |
194 |
195 |
196 | ); 197 | `, 198 | options: [{ camelCase: 'dashes-only' }], 199 | }, 200 | ].map((testCase) => addFilenameOption(testCase)), 201 | invalid: [ 202 | { 203 | name: 'Unused class error', 204 | code: ` 205 | import s from './noUnusedClass1.scss'; 206 | 207 | export default Foo = () => ( 208 |
209 | ); 210 | `, 211 | errors: ['Unused classes found in noUnusedClass1.scss: foo, bold'], 212 | }, 213 | { 214 | name: 'ignored global scope selector class', 215 | code: ` 216 | import s from './noUnusedClass2.scss'; 217 | 218 | export default Foo = () => ( 219 |
220 |
221 | ); 222 | `, 223 | errors: ['Unused classes found in noUnusedClass2.scss: foo'], 224 | }, 225 | { 226 | name: 'check less support', 227 | code: ` 228 | import s from './noUnusedClass1.less'; 229 | 230 | export default Foo = () => ( 231 |
232 |
233 | ); 234 | `, 235 | errors: ['Unused classes found in noUnusedClass1.less: foo'], 236 | }, 237 | { 238 | name: 'check composes support', 239 | code: ` 240 | import s from './composes1.scss'; 241 | 242 | export default Foo = () => ( 243 |
244 | ); 245 | `, 246 | errors: ['Unused classes found in composes1.scss: baz'], 247 | }, 248 | { 249 | name: 'check multiple composes support', 250 | code: ` 251 | import s from './composesMultiple1.scss'; 252 | 253 | export default Foo = () => ( 254 |
255 | ); 256 | `, 257 | errors: ['Unused classes found in composesMultiple1.scss: baz'], 258 | }, 259 | { 260 | name: 'check @extend support', 261 | code: ` 262 | import s from './extend1.scss'; 263 | 264 | export default Foo = () => ( 265 |
266 | ); 267 | `, 268 | errors: ['Unused classes found in extend1.scss: baz'], 269 | }, 270 | { 271 | name: 'using parent selector (`&`)', 272 | code: ` 273 | import s from './parentSelector4.scss'; 274 | 275 | export default Foo = () => ( 276 |
277 |
278 |
279 | ); 280 | `, 281 | errors: ['Unused classes found in parentSelector4.scss: foo_bar'], 282 | }, 283 | { 284 | name: 'snake_case', 285 | code: ` 286 | import s from './parentSelector8.scss'; 287 | 288 | export default Foo = () => ( 289 |
290 | ); 291 | `, 292 | errors: ['Unused classes found in parentSelector8.scss: foo_bar'], 293 | }, 294 | { 295 | name: 'should detect if camel case properties are NOT used when camelCase=true', 296 | code: ` 297 | import s from './noUnusedClass3.scss'; 298 | 299 | export default Foo = () => ( 300 |
301 | ); 302 | `, 303 | options: [{ camelCase: true }], 304 | errors: [ 305 | 'Unused classes found in noUnusedClass3.scss: bar-foo, alreadyCamelCased, snake_cased', 306 | ], 307 | }, 308 | { 309 | name: 'should detect if camel case properties are NOT used when camelCase=dashes', 310 | code: ` 311 | import s from './noUnusedClass3.scss'; 312 | 313 | export default Foo = () => ( 314 |
315 |
316 |
317 | ); 318 | `, 319 | options: [{ camelCase: 'dashes' }], 320 | errors: [ 321 | 'Unused classes found in noUnusedClass3.scss: bar-foo, alreadyCamelCased, snake_cased', 322 | ], 323 | }, 324 | { 325 | name: 'should detect if camel case properties are NOT used when camelCase=only', 326 | code: ` 327 | import s from './noUnusedClass3.scss'; 328 | 329 | export default Foo = () => ( 330 |
331 |
332 |
333 |
334 |
335 | ); 336 | `, 337 | options: [{ camelCase: 'only' }], 338 | errors: [ 339 | 'Unused classes found in noUnusedClass3.scss: foo-bar, alreadyCamelCased', 340 | ], 341 | }, 342 | { 343 | name: 'should detect if camel case properties are NOT used when camelCase=dashes-only', 344 | code: ` 345 | import s from './noUnusedClass3.scss'; 346 | 347 | export default Foo = () => ( 348 |
349 |
350 |
351 |
352 |
353 | ); 354 | `, 355 | options: [{ camelCase: 'dashes-only' }], 356 | errors: [ 357 | 'Unused classes found in noUnusedClass3.scss: foo-bar, alreadyCamelCased, snake_cased', 358 | ], 359 | }, 360 | ].map((testCase) => addFilenameOption(testCase)), 361 | }); 362 | }); 363 | -------------------------------------------------------------------------------- /test/utils.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import { RuleTester as EslintRuleTester } from 'eslint'; 3 | import { test } from 'mocha'; 4 | 5 | /* pattern taken from eslint-plugin-import */ 6 | export function addFilenameOption (testCase) { 7 | return { 8 | ...testCase, 9 | // TODO: Find a way to remove this. 10 | filename: path.resolve(__dirname, './files/foo.js'), 11 | }; 12 | } 13 | 14 | /** 15 | * Customizing ESLint rule tester to be run by Mocha. 16 | * @see https://eslint.org/docs/latest/integrate/nodejs-api#customizing-ruletester 17 | */ 18 | EslintRuleTester.describe = (text, method) => { 19 | EslintRuleTester.it.title = text; 20 | return method.call(this); 21 | }; 22 | 23 | EslintRuleTester.it = (text, method) => { 24 | test(EslintRuleTester.it.title + ': ' + text, method); 25 | }; 26 | 27 | export const RuleTester = () => { 28 | return new EslintRuleTester({ 29 | parserOptions: { 30 | sourceType: 'module', 31 | ecmaVersion: 6, 32 | ecmaFeatures: { jsx: true }, 33 | }, 34 | }); 35 | }; 36 | --------------------------------------------------------------------------------