@bhollis/eslint-plugin-css-modules 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +142 -0
- package/build/core/index.js +138 -0
- package/build/core/traversalUtils.js +186 -0
- package/build/index.js +27 -0
- package/build/rules/index.js +7 -0
- package/build/rules/no-undef-class.js +86 -0
- package/build/rules/no-unused-class.js +132 -0
- package/build/types/index.js +2 -0
- package/package.json +66 -0
package/README.md
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# @bhollis/eslint-plugin-css-modules
|
|
2
|
+
|
|
3
|
+
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.
|
|
4
|
+
|
|
5
|
+
This is a forked version of https://github.com/atfzl/eslint-plugin-css-modules with fixes to make it compatible with more recent versions of css-loader, especially with [`namedExports: true`](https://webpack.js.org/loaders/css-loader/#namedexport). It is also compatible with ESLint's flat config.
|
|
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 @bhollis/eslint-plugin-css-modules
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage:
|
|
37
|
+
|
|
38
|
+
```js
|
|
39
|
+
// eslint.config.js
|
|
40
|
+
import { defineConfig } from "eslint/config";
|
|
41
|
+
import cssModules from "@bhollis/eslint-plugin-css-modules";
|
|
42
|
+
|
|
43
|
+
export default defineConfig([
|
|
44
|
+
cssModules.configs.recommended
|
|
45
|
+
{
|
|
46
|
+
files: ["**/*.jsx"], // any patterns you want to apply the config to
|
|
47
|
+
plugins: {
|
|
48
|
+
'css-modules': cssModules,
|
|
49
|
+
},
|
|
50
|
+
extends: ["css-modules/recommended"],
|
|
51
|
+
},
|
|
52
|
+
]);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
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:
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
// eslint.config.js
|
|
59
|
+
import { defineConfig } from "eslint/config";
|
|
60
|
+
import cssModules from "@bhollis/eslint-plugin-css-modules";
|
|
61
|
+
|
|
62
|
+
export default defineConfig([
|
|
63
|
+
{
|
|
64
|
+
files: ["**/*.jsx"], // any patterns you want to apply the config to
|
|
65
|
+
plugins: {
|
|
66
|
+
'css-modules': cssModules,
|
|
67
|
+
},
|
|
68
|
+
rules: {
|
|
69
|
+
"css-modules/no-unused-class": [2, { "camelCase": true }],
|
|
70
|
+
"css-modules/no-undef-class": [2, { "camelCase": true }]
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
]);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
The camelCase option has 4 possible values, see [css-loader#camelCase](https://github.com/webpack-contrib/css-loader#camelcase) for description:
|
|
77
|
+
```js
|
|
78
|
+
true | "dashes" | "only" | "dashes-only"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Specifying base path
|
|
82
|
+
|
|
83
|
+
You can specify path for the base directory via plugin settings in eslint.config.js. This is used by the plugin to resolve absolute (S)CSS paths:
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
// eslint.config.js
|
|
87
|
+
import { defineConfig } from "eslint/config";
|
|
88
|
+
import cssModules from "@bhollis/eslint-plugin-css-modules";
|
|
89
|
+
|
|
90
|
+
export default defineConfig([
|
|
91
|
+
{
|
|
92
|
+
files: ["**/*.jsx"], // any patterns you want to apply the config to
|
|
93
|
+
plugins: {
|
|
94
|
+
'css-modules': cssModules,
|
|
95
|
+
},
|
|
96
|
+
settings: {
|
|
97
|
+
'css-modules': {
|
|
98
|
+
basePath: "app/scripts/..."
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
]);
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Screen Shot
|
|
106
|
+
|
|
107
|
+

|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
1:8 error Unused classes found: container css-modules/no-unused-class
|
|
111
|
+
5:17 error Class 'containr' not found css-modules/no-undef-class
|
|
112
|
+
10:26 error Class 'foo' not found css-modules/no-undef-class
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
scss:
|
|
116
|
+
|
|
117
|
+
```scss
|
|
118
|
+
/* .head is global, will not be used in js */
|
|
119
|
+
:global(.head) {
|
|
120
|
+
color: green;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.container {
|
|
124
|
+
width: 116px;
|
|
125
|
+
|
|
126
|
+
i {
|
|
127
|
+
font-size: 2.2rem;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.button {
|
|
131
|
+
padding: 7px 0 0 5px;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.footer {
|
|
136
|
+
color: cyan;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## With Thanks
|
|
141
|
+
|
|
142
|
+
* This is forked from [`eslint-plugin-css-modules`](https://github.com/atfzl/eslint-plugin-css-modules).
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { camelCase } from 'es-toolkit';
|
|
4
|
+
import gonzales from 'gonzales-pe';
|
|
5
|
+
import { getRegularClassesMap, getComposesClassesMap, getExtendClassesMap, getParentSelectorClassesMap, getICSSExportPropsMap, eliminateGlobals } from './traversalUtils.js';
|
|
6
|
+
const styleExtensionRegex = /\.(s?css|less)$/;
|
|
7
|
+
function dashesCamelCase(str) {
|
|
8
|
+
return str.replace(/-+(\w)/g, function (match, firstLetter) {
|
|
9
|
+
return firstLetter.toUpperCase();
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
export const getFilePath = (context, styleFilePath) => {
|
|
13
|
+
const settings = context.settings['css-modules'];
|
|
14
|
+
const dirName = path.dirname(context.getFilename());
|
|
15
|
+
const basePath = settings && settings.basePath ? settings.basePath : '';
|
|
16
|
+
return styleFilePath.startsWith('.') ? path.resolve(dirName, styleFilePath) : path.resolve(basePath, styleFilePath);
|
|
17
|
+
};
|
|
18
|
+
export const getPropertyName = node => {
|
|
19
|
+
const propertyName = node.computed
|
|
20
|
+
/*
|
|
21
|
+
square braces eg s['header']
|
|
22
|
+
we won't use node.property.name because it is for cases like
|
|
23
|
+
s[abc] where abc is a variable
|
|
24
|
+
*/ ? node.property.value
|
|
25
|
+
/* dot notation, eg s.header */ : node.property.name;
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
skip property names starting with _
|
|
29
|
+
eg. special functions provided
|
|
30
|
+
by css modules like _getCss()
|
|
31
|
+
Tried to just skip function calls, but the parser
|
|
32
|
+
thinks of normal property access like s._getCss and
|
|
33
|
+
function calls like s._getCss() as same.
|
|
34
|
+
*/
|
|
35
|
+
if (!propertyName || propertyName?.toString().startsWith('_')) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
return propertyName;
|
|
39
|
+
};
|
|
40
|
+
export const getClassesMap = (classes, camelCaseOption) => {
|
|
41
|
+
const classesMap = {};
|
|
42
|
+
|
|
43
|
+
// Unroll the loop because of performance!
|
|
44
|
+
// Remember that this function will run on every lint (e.g.: on file save)
|
|
45
|
+
switch (camelCaseOption) {
|
|
46
|
+
case true:
|
|
47
|
+
for (const className of Object.keys(classes)) {
|
|
48
|
+
classesMap[className] = className;
|
|
49
|
+
classesMap[camelCase(className)] = className;
|
|
50
|
+
}
|
|
51
|
+
break;
|
|
52
|
+
case 'dashes':
|
|
53
|
+
for (const className of Object.keys(classes)) {
|
|
54
|
+
classesMap[className] = className;
|
|
55
|
+
classesMap[dashesCamelCase(className)] = className;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case 'only':
|
|
59
|
+
for (const className of Object.keys(classes)) {
|
|
60
|
+
classesMap[camelCase(className)] = className;
|
|
61
|
+
}
|
|
62
|
+
break;
|
|
63
|
+
case 'dashes-only':
|
|
64
|
+
for (const className of Object.keys(classes)) {
|
|
65
|
+
classesMap[dashesCamelCase(className)] = className;
|
|
66
|
+
}
|
|
67
|
+
break;
|
|
68
|
+
default:
|
|
69
|
+
for (const className of Object.keys(classes)) {
|
|
70
|
+
classesMap[className] = className;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return classesMap;
|
|
74
|
+
};
|
|
75
|
+
export const getStyleImportNodeData = node => {
|
|
76
|
+
// path from which it was imported
|
|
77
|
+
const styleFilePath = node?.source?.value;
|
|
78
|
+
if (styleFilePath && styleExtensionRegex.test(styleFilePath)) {
|
|
79
|
+
const importNode = node.specifiers?.find(specifier => specifier.type === 'ImportDefaultSpecifier' || specifier.type === 'ImportNamespaceSpecifier');
|
|
80
|
+
const importName = importNode?.local?.name;
|
|
81
|
+
if (importName) {
|
|
82
|
+
// it had a default or namespace import
|
|
83
|
+
return {
|
|
84
|
+
importName,
|
|
85
|
+
styleFilePath,
|
|
86
|
+
importNode
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
export const fileExists = filePath => {
|
|
92
|
+
try {
|
|
93
|
+
// check if file exists
|
|
94
|
+
fs.statSync(filePath);
|
|
95
|
+
return true;
|
|
96
|
+
} catch (e) {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @returns AST of the parsed file or null if parse failed
|
|
103
|
+
*/
|
|
104
|
+
export const getAST = filePath => {
|
|
105
|
+
const fileContent = fs.readFileSync(filePath);
|
|
106
|
+
const syntax = path.extname(filePath).slice(1); // remove leading .
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
return gonzales.parse(fileContent.toString(), {
|
|
110
|
+
syntax
|
|
111
|
+
});
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
export const getStyleClasses = ast => {
|
|
117
|
+
/*
|
|
118
|
+
mutates ast by removing :global scopes
|
|
119
|
+
*/
|
|
120
|
+
eliminateGlobals(ast);
|
|
121
|
+
const classesMap = getRegularClassesMap(ast);
|
|
122
|
+
const composedClassesMap = getComposesClassesMap(ast);
|
|
123
|
+
const extendClassesMap = getExtendClassesMap(ast);
|
|
124
|
+
const parentSelectorClassesMap = getParentSelectorClassesMap(ast);
|
|
125
|
+
return {
|
|
126
|
+
...classesMap,
|
|
127
|
+
...composedClassesMap,
|
|
128
|
+
...extendClassesMap,
|
|
129
|
+
...parentSelectorClassesMap
|
|
130
|
+
};
|
|
131
|
+
};
|
|
132
|
+
export const getExportPropsMap = ast => {
|
|
133
|
+
const exportPropsMap = getICSSExportPropsMap(ast);
|
|
134
|
+
return {
|
|
135
|
+
...exportPropsMap
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmcyIsInBhdGgiLCJjYW1lbENhc2UiLCJnb256YWxlcyIsImdldFJlZ3VsYXJDbGFzc2VzTWFwIiwiZ2V0Q29tcG9zZXNDbGFzc2VzTWFwIiwiZ2V0RXh0ZW5kQ2xhc3Nlc01hcCIsImdldFBhcmVudFNlbGVjdG9yQ2xhc3Nlc01hcCIsImdldElDU1NFeHBvcnRQcm9wc01hcCIsImVsaW1pbmF0ZUdsb2JhbHMiLCJzdHlsZUV4dGVuc2lvblJlZ2V4IiwiZGFzaGVzQ2FtZWxDYXNlIiwic3RyIiwicmVwbGFjZSIsIm1hdGNoIiwiZmlyc3RMZXR0ZXIiLCJ0b1VwcGVyQ2FzZSIsImdldEZpbGVQYXRoIiwiY29udGV4dCIsInN0eWxlRmlsZVBhdGgiLCJzZXR0aW5ncyIsImRpck5hbWUiLCJkaXJuYW1lIiwiZ2V0RmlsZW5hbWUiLCJiYXNlUGF0aCIsInN0YXJ0c1dpdGgiLCJyZXNvbHZlIiwiZ2V0UHJvcGVydHlOYW1lIiwibm9kZSIsInByb3BlcnR5TmFtZSIsImNvbXB1dGVkIiwicHJvcGVydHkiLCJ2YWx1ZSIsIm5hbWUiLCJ0b1N0cmluZyIsImdldENsYXNzZXNNYXAiLCJjbGFzc2VzIiwiY2FtZWxDYXNlT3B0aW9uIiwiY2xhc3Nlc01hcCIsImNsYXNzTmFtZSIsIk9iamVjdCIsImtleXMiLCJnZXRTdHlsZUltcG9ydE5vZGVEYXRhIiwic291cmNlIiwidGVzdCIsImltcG9ydE5vZGUiLCJzcGVjaWZpZXJzIiwiZmluZCIsInNwZWNpZmllciIsInR5cGUiLCJpbXBvcnROYW1lIiwibG9jYWwiLCJmaWxlRXhpc3RzIiwiZmlsZVBhdGgiLCJzdGF0U3luYyIsImUiLCJnZXRBU1QiLCJmaWxlQ29udGVudCIsInJlYWRGaWxlU3luYyIsInN5bnRheCIsImV4dG5hbWUiLCJzbGljZSIsInBhcnNlIiwiZ2V0U3R5bGVDbGFzc2VzIiwiYXN0IiwiY29tcG9zZWRDbGFzc2VzTWFwIiwiZXh0ZW5kQ2xhc3Nlc01hcCIsInBhcmVudFNlbGVjdG9yQ2xhc3Nlc01hcCIsImdldEV4cG9ydFByb3BzTWFwIiwiZXhwb3J0UHJvcHNNYXAiXSwic291cmNlcyI6WyIuLi8uLi9saWIvY29yZS9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAZmxvd1xuXG5pbXBvcnQgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcGF0aCBmcm9tICdub2RlOnBhdGgnO1xuaW1wb3J0IHsgY2FtZWxDYXNlIH0gZnJvbSAnZXMtdG9vbGtpdCc7XG5pbXBvcnQgZ29uemFsZXMgZnJvbSAnZ29uemFsZXMtcGUnO1xuXG5pbXBvcnQgdHlwZSB7IEpzTm9kZSwgZ0FTVE5vZGUgfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5cbmltcG9ydCB7XG4gIGdldFJlZ3VsYXJDbGFzc2VzTWFwLFxuICBnZXRDb21wb3Nlc0NsYXNzZXNNYXAsXG4gIGdldEV4dGVuZENsYXNzZXNNYXAsXG4gIGdldFBhcmVudFNlbGVjdG9yQ2xhc3Nlc01hcCxcbiAgZ2V0SUNTU0V4cG9ydFByb3BzTWFwLFxuICBlbGltaW5hdGVHbG9iYWxzLFxufSBmcm9tICcuL3RyYXZlcnNhbFV0aWxzLmpzJztcblxuY29uc3Qgc3R5bGVFeHRlbnNpb25SZWdleCA9IC9cXC4ocz9jc3N8bGVzcykkLztcblxuZnVuY3Rpb24gZGFzaGVzQ2FtZWxDYXNlIChzdHI6IHN0cmluZykge1xuICByZXR1cm4gc3RyLnJlcGxhY2UoLy0rKFxcdykvZywgZnVuY3Rpb24gKG1hdGNoLCBmaXJzdExldHRlcikge1xuICAgIHJldHVybiBmaXJzdExldHRlci50b1VwcGVyQ2FzZSgpO1xuICB9KTtcbn1cblxuZXhwb3J0IGNvbnN0IGdldEZpbGVQYXRoID0gKGNvbnRleHQsIHN0eWxlRmlsZVBhdGgpID0+IHtcbiAgY29uc3Qgc2V0dGluZ3MgPSBjb250ZXh0LnNldHRpbmdzWydjc3MtbW9kdWxlcyddO1xuXG4gIGNvbnN0IGRpck5hbWUgPSBwYXRoLmRpcm5hbWUoY29udGV4dC5nZXRGaWxlbmFtZSgpKTtcbiAgY29uc3QgYmFzZVBhdGggPSAoc2V0dGluZ3MgJiYgc2V0dGluZ3MuYmFzZVBhdGgpID8gc2V0dGluZ3MuYmFzZVBhdGggOiAnJztcblxuICByZXR1cm4gc3R5bGVGaWxlUGF0aC5zdGFydHNXaXRoKCcuJylcbiAgICA/IHBhdGgucmVzb2x2ZShkaXJOYW1lLCBzdHlsZUZpbGVQYXRoKVxuICAgIDogcGF0aC5yZXNvbHZlKGJhc2VQYXRoLCBzdHlsZUZpbGVQYXRoKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRQcm9wZXJ0eU5hbWUgPSAobm9kZTogSnNOb2RlKTogP3N0cmluZyA9PiB7XG4gIGNvbnN0IHByb3BlcnR5TmFtZSA9IG5vZGUuY29tcHV0ZWRcbiAgICAvKlxuICAgICAgIHNxdWFyZSBicmFjZXMgZWcgc1snaGVhZGVyJ11cbiAgICAgICB3ZSB3b24ndCB1c2Ugbm9kZS5wcm9wZXJ0eS5uYW1lIGJlY2F1c2UgaXQgaXMgZm9yIGNhc2VzIGxpa2VcbiAgICAgICBzW2FiY10gd2hlcmUgYWJjIGlzIGEgdmFyaWFibGVcbiAgICAgKi9cbiAgICA/IG5vZGUucHJvcGVydHkudmFsdWVcbiAgICAvKiBkb3Qgbm90YXRpb24sIGVnIHMuaGVhZGVyICovXG4gICAgOiBub2RlLnByb3BlcnR5Lm5hbWU7XG5cbiAgLypcbiAgICAgc2tpcCBwcm9wZXJ0eSBuYW1lcyBzdGFydGluZyB3aXRoIF9cbiAgICAgZWcuIHNwZWNpYWwgZnVuY3Rpb25zIHByb3ZpZGVkXG4gICAgIGJ5IGNzcyBtb2R1bGVzIGxpa2UgX2dldENzcygpXG5cbiAgICAgVHJpZWQgdG8ganVzdCBza2lwIGZ1bmN0aW9uIGNhbGxzLCBidXQgdGhlIHBhcnNlclxuICAgICB0aGlua3Mgb2Ygbm9ybWFsIHByb3BlcnR5IGFjY2VzcyBsaWtlIHMuX2dldENzcyBhbmRcbiAgICAgZnVuY3Rpb24gY2FsbHMgbGlrZSBzLl9nZXRDc3MoKSBhcyBzYW1lLlxuICAgKi9cbiAgaWYgKCFwcm9wZXJ0eU5hbWUgfHwgcHJvcGVydHlOYW1lPy50b1N0cmluZygpLnN0YXJ0c1dpdGgoJ18nKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHByb3BlcnR5TmFtZTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRDbGFzc2VzTWFwID0gKGNsYXNzZXM6IE9iamVjdCwgY2FtZWxDYXNlT3B0aW9uOiBzdHJpbmd8Ym9vbGVhbik6IE9iamVjdCA9PiB7XG4gIGNvbnN0IGNsYXNzZXNNYXAgPSB7fTtcblxuICAvLyBVbnJvbGwgdGhlIGxvb3AgYmVjYXVzZSBvZiBwZXJmb3JtYW5jZSFcbiAgLy8gUmVtZW1iZXIgdGhhdCB0aGlzIGZ1bmN0aW9uIHdpbGwgcnVuIG9uIGV2ZXJ5IGxpbnQgKGUuZy46IG9uIGZpbGUgc2F2ZSlcbiAgc3dpdGNoIChjYW1lbENhc2VPcHRpb24pIHtcbiAgICBjYXNlIHRydWU6XG4gICAgICBmb3IgKGNvbnN0IGNsYXNzTmFtZSBvZiBPYmplY3Qua2V5cyhjbGFzc2VzKSkge1xuICAgICAgICBjbGFzc2VzTWFwW2NsYXNzTmFtZV0gPSBjbGFzc05hbWU7XG4gICAgICAgIGNsYXNzZXNNYXBbY2FtZWxDYXNlKGNsYXNzTmFtZSldID0gY2xhc3NOYW1lO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZGFzaGVzJzpcbiAgICAgIGZvciAoY29uc3QgY2xhc3NOYW1lIG9mIE9iamVjdC5rZXlzKGNsYXNzZXMpKSB7XG4gICAgICAgIGNsYXNzZXNNYXBbY2xhc3NOYW1lXSA9IGNsYXNzTmFtZTtcbiAgICAgICAgY2xhc3Nlc01hcFtkYXNoZXNDYW1lbENhc2UoY2xhc3NOYW1lKV0gPSBjbGFzc05hbWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBjYXNlICdvbmx5JzpcbiAgICAgIGZvciAoY29uc3QgY2xhc3NOYW1lIG9mIE9iamVjdC5rZXlzKGNsYXNzZXMpKSB7XG4gICAgICAgIGNsYXNzZXNNYXBbY2FtZWxDYXNlKGNsYXNzTmFtZSldID0gY2xhc3NOYW1lO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnZGFzaGVzLW9ubHknOlxuICAgICAgZm9yIChjb25zdCBjbGFzc05hbWUgb2YgT2JqZWN0LmtleXMoY2xhc3NlcykpIHtcbiAgICAgICAgY2xhc3Nlc01hcFtkYXNoZXNDYW1lbENhc2UoY2xhc3NOYW1lKV0gPSBjbGFzc05hbWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgZm9yIChjb25zdCBjbGFzc05hbWUgb2YgT2JqZWN0LmtleXMoY2xhc3NlcykpIHtcbiAgICAgICAgY2xhc3Nlc01hcFtjbGFzc05hbWVdID0gY2xhc3NOYW1lO1xuICAgICAgfVxuICB9XG5cbiAgcmV0dXJuIGNsYXNzZXNNYXA7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0U3R5bGVJbXBvcnROb2RlRGF0YSA9IChub2RlOiBKc05vZGUpOiA/T2JqZWN0ID0+IHtcbiAgLy8gcGF0aCBmcm9tIHdoaWNoIGl0IHdhcyBpbXBvcnRlZFxuICBjb25zdCBzdHlsZUZpbGVQYXRoID0gbm9kZT8uc291cmNlPy52YWx1ZTtcblxuICBpZiAoc3R5bGVGaWxlUGF0aCAmJiBzdHlsZUV4dGVuc2lvblJlZ2V4LnRlc3Qoc3R5bGVGaWxlUGF0aCkpIHtcbiAgICBjb25zdCBpbXBvcnROb2RlID0gbm9kZS5zcGVjaWZpZXJzPy5maW5kKFxuICAgICAgKHNwZWNpZmllcikgPT5cbiAgICAgICAgc3BlY2lmaWVyLnR5cGUgPT09ICdJbXBvcnREZWZhdWx0U3BlY2lmaWVyJyB8fCBzcGVjaWZpZXIudHlwZSA9PT0gJ0ltcG9ydE5hbWVzcGFjZVNwZWNpZmllcidcbiAgICApO1xuICAgIGNvbnN0IGltcG9ydE5hbWUgPSBpbXBvcnROb2RlPy5sb2NhbD8ubmFtZTtcbiAgICBpZiAoaW1wb3J0TmFtZSkge1xuICAgICAgLy8gaXQgaGFkIGEgZGVmYXVsdCBvciBuYW1lc3BhY2UgaW1wb3J0XG4gICAgICByZXR1cm4geyBpbXBvcnROYW1lLCBzdHlsZUZpbGVQYXRoLCBpbXBvcnROb2RlIH07XG4gICAgfVxuICB9XG59O1xuXG5leHBvcnQgY29uc3QgZmlsZUV4aXN0cyA9IChmaWxlUGF0aDogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIHRyeSB7XG4gICAgLy8gY2hlY2sgaWYgZmlsZSBleGlzdHNcbiAgICBmcy5zdGF0U3luYyhmaWxlUGF0aCk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbi8qKlxuICogQHJldHVybnMgQVNUIG9mIHRoZSBwYXJzZWQgZmlsZSBvciBudWxsIGlmIHBhcnNlIGZhaWxlZFxuICovXG5leHBvcnQgY29uc3QgZ2V0QVNUID0gKGZpbGVQYXRoOiBzdHJpbmcpOiBnQVNUTm9kZSB8IG51bGwgPT4ge1xuICBjb25zdCBmaWxlQ29udGVudCA9IGZzLnJlYWRGaWxlU3luYyhmaWxlUGF0aCk7XG5cbiAgY29uc3Qgc3ludGF4ID0gcGF0aC5leHRuYW1lKGZpbGVQYXRoKS5zbGljZSgxKTsgLy8gcmVtb3ZlIGxlYWRpbmcgLlxuXG4gIHRyeSB7XG4gICAgcmV0dXJuIGdvbnphbGVzLnBhcnNlKGZpbGVDb250ZW50LnRvU3RyaW5nKCksIHsgc3ludGF4IH0pO1xuICB9IGNhdGNoIChlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn07XG5cbmV4cG9ydCBjb25zdCBnZXRTdHlsZUNsYXNzZXMgPSAoYXN0OiBnQVNUTm9kZSk6ID9PYmplY3QgPT4ge1xuICAvKlxuICAgICBtdXRhdGVzIGFzdCBieSByZW1vdmluZyA6Z2xvYmFsIHNjb3Blc1xuICAgKi9cbiAgZWxpbWluYXRlR2xvYmFscyhhc3QpO1xuXG4gIGNvbnN0IGNsYXNzZXNNYXAgPSBnZXRSZWd1bGFyQ2xhc3Nlc01hcChhc3QpO1xuICBjb25zdCBjb21wb3NlZENsYXNzZXNNYXAgPSBnZXRDb21wb3Nlc0NsYXNzZXNNYXAoYXN0KTtcbiAgY29uc3QgZXh0ZW5kQ2xhc3Nlc01hcCA9IGdldEV4dGVuZENsYXNzZXNNYXAoYXN0KTtcbiAgY29uc3QgcGFyZW50U2VsZWN0b3JDbGFzc2VzTWFwID0gZ2V0UGFyZW50U2VsZWN0b3JDbGFzc2VzTWFwKGFzdCk7XG5cbiAgcmV0dXJuIHtcbiAgICAuLi5jbGFzc2VzTWFwLFxuICAgIC4uLmNvbXBvc2VkQ2xhc3Nlc01hcCxcbiAgICAuLi5leHRlbmRDbGFzc2VzTWFwLFxuICAgIC4uLnBhcmVudFNlbGVjdG9yQ2xhc3Nlc01hcFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEV4cG9ydFByb3BzTWFwID0gKGFzdDogZ0FTVE5vZGUpOiA/T2JqZWN0ID0+IHtcbiAgY29uc3QgZXhwb3J0UHJvcHNNYXAgPSBnZXRJQ1NTRXhwb3J0UHJvcHNNYXAoYXN0KTtcbiAgcmV0dXJuIHtcbiAgICAuLi5leHBvcnRQcm9wc01hcFxuICB9O1xufTtcbiJdLCJtYXBwaW5ncyI6IkFBRUEsT0FBT0EsRUFBRSxNQUFNLFNBQVM7QUFDeEIsT0FBT0MsSUFBSSxNQUFNLFdBQVc7QUFDNUIsU0FBU0MsU0FBUyxRQUFRLFlBQVk7QUFDdEMsT0FBT0MsUUFBUSxNQUFNLGFBQWE7QUFJbEMsU0FDRUMsb0JBQW9CLEVBQ3BCQyxxQkFBcUIsRUFDckJDLG1CQUFtQixFQUNuQkMsMkJBQTJCLEVBQzNCQyxxQkFBcUIsRUFDckJDLGdCQUFnQixRQUNYLHFCQUFxQjtBQUU1QixNQUFNQyxtQkFBbUIsR0FBRyxpQkFBaUI7QUFFN0MsU0FBU0MsZUFBZUEsQ0FBRUMsR0FBVyxFQUFFO0VBQ3JDLE9BQU9BLEdBQUcsQ0FBQ0MsT0FBTyxDQUFDLFNBQVMsRUFBRSxVQUFVQyxLQUFLLEVBQUVDLFdBQVcsRUFBRTtJQUMxRCxPQUFPQSxXQUFXLENBQUNDLFdBQVcsQ0FBQyxDQUFDO0VBQ2xDLENBQUMsQ0FBQztBQUNKO0FBRUEsT0FBTyxNQUFNQyxXQUFXLEdBQUdBLENBQUNDLE9BQU8sRUFBRUMsYUFBYSxLQUFLO0VBQ3JELE1BQU1DLFFBQVEsR0FBR0YsT0FBTyxDQUFDRSxRQUFRLENBQUMsYUFBYSxDQUFDO0VBRWhELE1BQU1DLE9BQU8sR0FBR3BCLElB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
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/* eslint-disable no-param-reassign */
|
|
2
|
+
export const getICSSExportPropsMap = ast => {
|
|
3
|
+
const ruleSets = [];
|
|
4
|
+
ast.traverseByType('ruleset', node => ruleSets.push(node));
|
|
5
|
+
return ruleSets.filter(ruleSet => {
|
|
6
|
+
const content = ruleSet.content || [];
|
|
7
|
+
return content.some(item => item.type === 'selector' && item.content?.some(selectorItem => selectorItem.type === 'pseudoClass' && selectorItem.content?.some(pseudoItem => pseudoItem.type === 'ident' && pseudoItem.content === 'export')));
|
|
8
|
+
}).reduce((result, ruleSet) => {
|
|
9
|
+
const declarations = (ruleSet.content || []).filter(item => item.type === 'block').flatMap(block => block.content || []).filter(item => item.type === 'declaration');
|
|
10
|
+
for (const declaration of declarations) {
|
|
11
|
+
const property = (declaration.content || []).find(item => item.type === 'property');
|
|
12
|
+
const propName = (property?.content || [])[0]?.content;
|
|
13
|
+
if (propName) {
|
|
14
|
+
result[propName] = propName;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return result;
|
|
18
|
+
}, {});
|
|
19
|
+
};
|
|
20
|
+
export const getRegularClassesMap = ast => {
|
|
21
|
+
const ruleSets = [];
|
|
22
|
+
ast.traverseByType('ruleset', node => ruleSets.push(node));
|
|
23
|
+
return ruleSets.reduce((result, ruleSet) => {
|
|
24
|
+
const selectors = ruleSet.content?.filter(item => item.type === 'selector') ?? [];
|
|
25
|
+
for (const selector of selectors) {
|
|
26
|
+
const classes = selector.content?.filter(item => item.type === 'class') ?? [];
|
|
27
|
+
for (const classNode of classes) {
|
|
28
|
+
const ident = classNode.content?.find(item => item.type === 'ident');
|
|
29
|
+
if (ident?.content) {
|
|
30
|
+
result[ident.content] = false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return result;
|
|
35
|
+
}, {});
|
|
36
|
+
};
|
|
37
|
+
export const getComposesClassesMap = ast => {
|
|
38
|
+
const declarations = [];
|
|
39
|
+
ast.traverseByType('declaration', node => declarations.push(node));
|
|
40
|
+
return declarations.reduce((result, declaration) => {
|
|
41
|
+
const content = declaration.content;
|
|
42
|
+
const property = content?.find(item => item.type === 'property');
|
|
43
|
+
const hasComposes = property?.content?.some(item => item.type === 'ident' && item.content === 'composes');
|
|
44
|
+
if (!hasComposes) return result;
|
|
45
|
+
const value = content?.find(item => item.type === 'value');
|
|
46
|
+
const valueContent = value?.content;
|
|
47
|
+
|
|
48
|
+
// Reject classes composing from other files, e.g. `composes: foo from './other.css'`
|
|
49
|
+
if (valueContent?.some(item => item.type === 'ident' && item.content === 'from')) {
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Extract and mark composed classes
|
|
54
|
+
const composedClasses = valueContent?.filter(item => item.type === 'ident' && item.content) ?? [];
|
|
55
|
+
for (const item of composedClasses) {
|
|
56
|
+
result[item.content] = true;
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
59
|
+
}, {});
|
|
60
|
+
};
|
|
61
|
+
export const getExtendClassesMap = ast => {
|
|
62
|
+
const extendNodes = [];
|
|
63
|
+
ast.traverseByType('extend', node => extendNodes.push(node));
|
|
64
|
+
return extendNodes.reduce((result, extendNode) => {
|
|
65
|
+
const selector = extendNode.content?.find(item => item.type === 'selector');
|
|
66
|
+
const classNode = selector?.content?.find(item => item.type === 'class');
|
|
67
|
+
const ident = classNode?.content?.find(item => item.type === 'ident');
|
|
68
|
+
const className = ident?.content;
|
|
69
|
+
if (className) {
|
|
70
|
+
result[className] = true; // mark extend classes as true
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return result;
|
|
74
|
+
}, {});
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Resolves parent selectors to their full class names.
|
|
79
|
+
*
|
|
80
|
+
* E.g. `.foo { &_bar {color: blue } }` to `.foo_bar`.
|
|
81
|
+
*/
|
|
82
|
+
export const getParentSelectorClassesMap = ast => {
|
|
83
|
+
const classesMap = {};
|
|
84
|
+
|
|
85
|
+
// Recursively traverses down the tree looking for parent selector
|
|
86
|
+
// extensions. Recursion is necessary as these selectors can be nested.
|
|
87
|
+
const getExtensions = nodeContent => {
|
|
88
|
+
const blockContent = nodeContent.filter(item => item.type === 'block').flatMap(item => item.content || []);
|
|
89
|
+
const rulesetChildren = blockContent.filter(item => item.type === 'ruleset');
|
|
90
|
+
const rulesetDescendants = blockContent.filter(item => item.type === 'include').flatMap(item => item.content || []).filter(subItem => subItem.type === 'block').flatMap(subItem => subItem.content || []).filter(subItem => subItem.type === 'ruleset');
|
|
91
|
+
const rulesetsContent = [...rulesetChildren, ...rulesetDescendants].flatMap(item => item.content || []);
|
|
92
|
+
const extensions = rulesetsContent.filter(item => item.type === 'selector').flatMap(item => item.content || []).filter(selectorItem => selectorItem.type === 'parentSelectorExtension').flatMap(selectorItem => selectorItem.content || []).filter(identItem => identItem.type === 'ident').map(identItem => identItem.content);
|
|
93
|
+
if (!extensions.length) return [];
|
|
94
|
+
const nestedExtensions = getExtensions(rulesetsContent);
|
|
95
|
+
const result = extensions;
|
|
96
|
+
if (nestedExtensions.length) {
|
|
97
|
+
for (const nestedExt of nestedExtensions) {
|
|
98
|
+
extensions.forEach(ext => {
|
|
99
|
+
result.push(ext + nestedExt);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return result;
|
|
104
|
+
};
|
|
105
|
+
ast.traverseByType('ruleset', node => {
|
|
106
|
+
const classNames = (node.content || []).filter(item => item.type === 'selector').flatMap(item => item.content || []).filter(item => item.type === 'class').flatMap(item => item.content || []).filter(item => item.type === 'ident' && item.content).map(item => item.content);
|
|
107
|
+
if (!classNames.length) return;
|
|
108
|
+
const extensions = getExtensions(node.content);
|
|
109
|
+
if (!extensions.length) return;
|
|
110
|
+
classNames.forEach(className => {
|
|
111
|
+
extensions.forEach(ext => {
|
|
112
|
+
classesMap[className + ext] = false;
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Ignore the base class if it only exists for nesting parent selectors
|
|
116
|
+
const hasDeclarations = node.content?.some(item => item.type === 'block' && item.content?.some(subItem => subItem.type === 'declaration'));
|
|
117
|
+
if (!hasDeclarations) classesMap[className] = true;
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
return classesMap;
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Mutates the AST by removing `:global` instances.
|
|
125
|
+
*
|
|
126
|
+
* For the AST structure:
|
|
127
|
+
* @see https://github.com/css/gonzales/blob/master/doc/AST.CSSP.en.md
|
|
128
|
+
*/
|
|
129
|
+
export const eliminateGlobals = ast => {
|
|
130
|
+
// Remove all :global/:global(...) in selectors
|
|
131
|
+
ast.traverseByType('selector', selectorNode => {
|
|
132
|
+
const selectorContent = selectorNode.content;
|
|
133
|
+
let hasGlobalWithNoArgs = false;
|
|
134
|
+
let i = 0;
|
|
135
|
+
let currNode = selectorContent[i];
|
|
136
|
+
while (currNode) {
|
|
137
|
+
if (currNode.is('pseudoClass')) {
|
|
138
|
+
// Remove all :global/:global(...) and trailing space
|
|
139
|
+
const identifierNode = currNode.content[0];
|
|
140
|
+
if (identifierNode && identifierNode.content === 'global') {
|
|
141
|
+
if (currNode.content.length === 1) hasGlobalWithNoArgs = true;
|
|
142
|
+
selectorNode.removeChild(i);
|
|
143
|
+
if (selectorContent[i] && selectorContent[i].is('space')) {
|
|
144
|
+
selectorNode.removeChild(i);
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
i++;
|
|
148
|
+
}
|
|
149
|
+
} else if (currNode.is('class') && hasGlobalWithNoArgs) {
|
|
150
|
+
// Remove all class after :global and their trailing space
|
|
151
|
+
selectorNode.removeChild(i);
|
|
152
|
+
if (selectorContent[i] && selectorContent[i].is('space')) {
|
|
153
|
+
selectorNode.removeChild(i);
|
|
154
|
+
}
|
|
155
|
+
} else {
|
|
156
|
+
i++;
|
|
157
|
+
}
|
|
158
|
+
currNode = selectorContent[i];
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
// Remove all ruleset with no selectors
|
|
163
|
+
ast.traverseByType('ruleset', (node, index, parent) => {
|
|
164
|
+
const rulesetContent = node.content;
|
|
165
|
+
|
|
166
|
+
// Remove empty selectors and trailing deliminator and space
|
|
167
|
+
let i = 0;
|
|
168
|
+
let currNode = rulesetContent[i];
|
|
169
|
+
while (currNode) {
|
|
170
|
+
if (currNode.is('selector') && currNode.content.length === 0) {
|
|
171
|
+
node.removeChild(i);
|
|
172
|
+
if (rulesetContent[i].is('delimiter')) node.removeChild(i);
|
|
173
|
+
if (rulesetContent[i].is('space')) node.removeChild(i);
|
|
174
|
+
} else {
|
|
175
|
+
i++;
|
|
176
|
+
}
|
|
177
|
+
currNode = rulesetContent[i];
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Remove the ruleset if no selectors
|
|
181
|
+
if (rulesetContent.filter(node => node.is('selector')).length === 0) {
|
|
182
|
+
parent.removeChild(index);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRJQ1NTRXhwb3J0UHJvcHNNYXAiLCJhc3QiLCJydWxlU2V0cyIsInRyYXZlcnNlQnlUeXBlIiwibm9kZSIsInB1c2giLCJmaWx0ZXIiLCJydWxlU2V0IiwiY29udGVudCIsInNvbWUiLCJpdGVtIiwidHlwZSIsInNlbGVjdG9ySXRlbSIsInBzZXVkb0l0ZW0iLCJyZWR1Y2UiLCJyZXN1bHQiLCJkZWNsYXJhdGlvbnMiLCJmbGF0TWFwIiwiYmxvY2siLCJkZWNsYXJhdGlvbiIsInByb3BlcnR5IiwiZmluZCIsInByb3BOYW1lIiwiZ2V0UmVndWxhckNsYXNzZXNNYXAiLCJzZWxlY3RvcnMiLCJzZWxlY3RvciIsImNsYXNzZXMiLCJjbGFzc05vZGUiLCJpZGVudCIsImdldENvbXBvc2VzQ2xhc3Nlc01hcCIsImhhc0NvbXBvc2VzIiwidmFsdWUiLCJ2YWx1ZUNvbnRlbnQiLCJjb21wb3NlZENsYXNzZXMiLCJnZXRFeHRlbmRDbGFzc2VzTWFwIiwiZXh0ZW5kTm9kZXMiLCJleHRlbmROb2RlIiwiY2xhc3NOYW1lIiwiZ2V0UGFyZW50U2VsZWN0b3JDbGFzc2VzTWFwIiwiY2xhc3Nlc01hcCIsImdldEV4dGVuc2lvbnMiLCJub2RlQ29udGVudCIsImJsb2NrQ29udGVudCIsInJ1bGVzZXRDaGlsZHJlbiIsInJ1bGVzZXREZXNjZW5kYW50cyIsInN1Ykl0ZW0iLCJydWxlc2V0c0NvbnRlbnQiLCJleHRlbnNpb25zIiwiaWRlbnRJdGVtIiwibWFwIiwibGVuZ3RoIiwibmVzdGVkRXh0ZW5zaW9ucyIsIm5lc3RlZEV4dCIsImZvckVhY2giLCJleHQiLCJjbGFzc05hbWVzIiwiaGFzRGVjbGFyYXRpb25zIiwiZWxpbWluYXRlR2xvYmFscyIsInNlbGVjdG9yTm9kZSIsInNlbGVjdG9yQ29udGVudCIsImhhc0dsb2JhbFdpdGhOb0FyZ3MiLCJpIiwiY3Vyck5vZGUiLCJpcyIsImlkZW50aWZpZXJOb2RlIiwicmVtb3ZlQ2hpbGQiLCJpbmRleCIsInBhcmVudCIsInJ1bGVzZXRDb250ZW50Il0sInNvdXJjZXMiOlsiLi4vLi4vbGliL2NvcmUvdHJhdmVyc2FsVXRpbHMuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbi8qIGVzbGludC1kaXNhYmxlIG5vLXBhcmFtLXJlYXNzaWduICovXG5cbmltcG9ydCB0eXBlIHsgZ0FTVE5vZGUgfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5cbnR5cGUgY2xhc3NNYXBUeXBlID0ge1xuICBba2V5OiBzdHJpbmddOiBib29sZWFuLFxufVxuXG5leHBvcnQgY29uc3QgZ2V0SUNTU0V4cG9ydFByb3BzTWFwID0gKGFzdDogZ0FTVE5vZGUpOiBjbGFzc01hcFR5cGUgPT4ge1xuICBjb25zdCBydWxlU2V0czogQXJyYXk8Z0FTVE5vZGU+ID0gW107XG4gIGFzdC50cmF2ZXJzZUJ5VHlwZSgncnVsZXNldCcsIG5vZGUgPT4gcnVsZVNldHMucHVzaChub2RlKSk7XG5cbiAgcmV0dXJuIHJ1bGVTZXRzXG4gICAgLmZpbHRlcihydWxlU2V0ID0+IHtcbiAgICAgIGNvbnN0IGNvbnRlbnQgPSBydWxlU2V0LmNvbnRlbnQgfHwgW107XG4gICAgICByZXR1cm4gY29udGVudC5zb21lKGl0ZW0gPT5cbiAgICAgICAgaXRlbS50eXBlID09PSAnc2VsZWN0b3InICYmXG4gICAgICAgIGl0ZW0uY29udGVudD8uc29tZShzZWxlY3Rvckl0ZW0gPT5cbiAgICAgICAgICBzZWxlY3Rvckl0ZW0udHlwZSA9PT0gJ3BzZXVkb0NsYXNzJyAmJlxuICAgICAgICAgIHNlbGVjdG9ySXRlbS5jb250ZW50Py5zb21lKHBzZXVkb0l0ZW0gPT5cbiAgICAgICAgICAgIHBzZXVkb0l0ZW0udHlwZSA9PT0gJ2lkZW50JyAmJiBwc2V1ZG9JdGVtLmNvbnRlbnQgPT09ICdleHBvcnQnXG4gICAgICAgICAgKVxuICAgICAgICApXG4gICAgICApO1xuICAgIH0pXG4gICAgLnJlZHVjZSgocmVzdWx0LCBydWxlU2V0KSA9PiB7XG4gICAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSAocnVsZVNldC5jb250ZW50IHx8IFtdKVxuICAgICAgICAuZmlsdGVyKGl0ZW0gPT4gaXRlbS50eXBlID09PSAnYmxvY2snKVxuICAgICAgICAuZmxhdE1hcChibG9jayA9PiAoYmxvY2suY29udGVudCB8fCBbXSkpXG4gICAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdkZWNsYXJhdGlvbicpO1xuXG4gICAgICBmb3IgKGNvbnN0IGRlY2xhcmF0aW9uIG9mIGRlY2xhcmF0aW9ucykge1xuICAgICAgICBjb25zdCBwcm9wZXJ0eSA9IChkZWNsYXJhdGlvbi5jb250ZW50IHx8IFtdKS5maW5kKGl0ZW0gPT4gaXRlbS50eXBlID09PSAncHJvcGVydHknKTtcbiAgICAgICAgY29uc3QgcHJvcE5hbWUgPSAocHJvcGVydHk/LmNvbnRlbnQgfHwgW10pWzBdPy5jb250ZW50O1xuICAgICAgICBpZiAocHJvcE5hbWUpIHtcbiAgICAgICAgICByZXN1bHRbcHJvcE5hbWVdID0gcHJvcE5hbWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9LCB7fSk7XG59O1xuXG5leHBvcnQgY29uc3QgZ2V0UmVndWxhckNsYXNzZXNNYXAgPSAoYXN0OiBnQVNUTm9kZSk6IGNsYXNzTWFwVHlwZSA9PiB7XG4gIGNvbnN0IHJ1bGVTZXRzOiBBcnJheTxnQVNUTm9kZT4gPSBbXTtcbiAgYXN0LnRyYXZlcnNlQnlUeXBlKCdydWxlc2V0Jywgbm9kZSA9PiBydWxlU2V0cy5wdXNoKG5vZGUpKTtcblxuICByZXR1cm4gcnVsZVNldHNcbiAgICAucmVkdWNlKChyZXN1bHQsIHJ1bGVTZXQpID0+IHtcbiAgICAgIGNvbnN0IHNlbGVjdG9ycyA9IHJ1bGVTZXQuY29udGVudD8uZmlsdGVyKGl0ZW0gPT4gaXRlbS50eXBlID09PSAnc2VsZWN0b3InKSA/PyBbXTtcbiAgICAgIGZvciAoY29uc3Qgc2VsZWN0b3Igb2Ygc2VsZWN0b3JzKSB7XG4gICAgICAgIGNvbnN0IGNsYXNzZXMgPSBzZWxlY3Rvci5jb250ZW50Py5maWx0ZXIoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdjbGFzcycpID8/IFtdO1xuICAgICAgICBmb3IgKGNvbnN0IGNsYXNzTm9kZSBvZiBjbGFzc2VzKSB7XG4gICAgICAgICAgY29uc3QgaWRlbnQgPSBjbGFzc05vZGUuY29udGVudD8uZmluZChpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ2lkZW50Jyk7XG4gICAgICAgICAgaWYgKGlkZW50Py5jb250ZW50KSB7XG4gICAgICAgICAgICByZXN1bHRbaWRlbnQuY29udGVudF0gPSBmYWxzZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSwge30pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldENvbXBvc2VzQ2xhc3Nlc01hcCA9IChhc3Q6IGdBU1ROb2RlKTogY2xhc3NNYXBUeXBlID0+IHtcbiAgY29uc3QgZGVjbGFyYXRpb25zID0gW107XG4gIGFzdC50cmF2ZXJzZUJ5VHlwZSgnZGVjbGFyYXRpb24nLCBub2RlID0+IGRlY2xhcmF0aW9ucy5wdXNoKG5vZGUpKTtcblxuICByZXR1cm4gZGVjbGFyYXRpb25zXG4gICAgLnJlZHVjZSgocmVzdWx0LCBkZWNsYXJhdGlvbikgPT4ge1xuICAgICAgY29uc3QgY29udGVudCA9IGRlY2xhcmF0aW9uLmNvbnRlbnQ7XG4gICAgICBjb25zdCBwcm9wZXJ0eSA9IGNvbnRlbnQ/LmZpbmQoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdwcm9wZXJ0eScpO1xuICAgICAgY29uc3QgaGFzQ29tcG9zZXMgPSBwcm9wZXJ0eT8uY29udGVudD8uc29tZShpdGVtID0+XG4gICAgICAgIGl0ZW0udHlwZSA9PT0gJ2lkZW50JyAmJiBpdGVtLmNvbnRlbnQgPT09ICdjb21wb3NlcydcbiAgICAgICk7XG5cbiAgICAgIGlmICghaGFzQ29tcG9zZXMpIHJldHVybiByZXN1bHQ7XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gY29udGVudD8uZmluZChpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3ZhbHVlJyk7XG4gICAgICBjb25zdCB2YWx1ZUNvbnRlbnQgPSB2YWx1ZT8uY29udGVudDtcblxuICAgICAgLy8gUmVqZWN0IGNsYXNzZXMgY29tcG9zaW5nIGZyb20gb3RoZXIgZmlsZXMsIGUuZy4gYGNvbXBvc2VzOiBmb28gZnJvbSAnLi9vdGhlci5jc3MnYFxuICAgICAgaWYgKHZhbHVlQ29udGVudD8uc29tZShpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ2lkZW50JyAmJiBpdGVtLmNvbnRlbnQgPT09ICdmcm9tJykpIHtcbiAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgLy8gRXh0cmFjdCBhbmQgbWFyayBjb21wb3NlZCBjbGFzc2VzXG4gICAgICBjb25zdCBjb21wb3NlZENsYXNzZXMgPSB2YWx1ZUNvbnRlbnQ/LmZpbHRlcihpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ2lkZW50JyAmJiBpdGVtLmNvbnRlbnQpID8/IFtdO1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGNvbXBvc2VkQ2xhc3Nlcykge1xuICAgICAgICByZXN1bHRbaXRlbS5jb250ZW50XSA9IHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfSwge30pO1xufTtcblxuZXhwb3J0IGNvbnN0IGdldEV4dGVuZENsYXNzZXNNYXAgPSAoYXN0OiBnQVNUTm9kZSk6IGNsYXNzTWFwVHlwZSA9PiB7XG4gIGNvbnN0IGV4dGVuZE5vZGVzID0gW107XG4gIGFzdC50cmF2ZXJzZUJ5VHlwZSgnZXh0ZW5kJywgbm9kZSA9PiBleHRlbmROb2Rlcy5wdXNoKG5vZGUpKTtcblxuICByZXR1cm4gZXh0ZW5kTm9kZXMucmVkdWNlKChyZXN1bHQsIGV4dGVuZE5vZGUpID0+IHtcbiAgICBjb25zdCBzZWxlY3RvciA9IGV4dGVuZE5vZGUuY29udGVudD8uZmluZChpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3NlbGVjdG9yJyk7XG4gICAgY29uc3QgY2xhc3NOb2RlID0gc2VsZWN0b3I/LmNvbnRlbnQ/LmZpbmQoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdjbGFzcycpO1xuICAgIGNvbnN0IGlkZW50ID0gY2xhc3NOb2RlPy5jb250ZW50Py5maW5kKGl0ZW0gPT4gaXRlbS50eXBlID09PSAnaWRlbnQnKTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBpZGVudD8uY29udGVudDtcblxuICAgIGlmIChjbGFzc05hbWUpIHtcbiAgICAgIHJlc3VsdFtjbGFzc05hbWVdID0gdHJ1ZTsgLy8gbWFyayBleHRlbmQgY2xhc3NlcyBhcyB0cnVlXG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSwge30pO1xufTtcblxuLyoqXG4gKiBSZXNvbHZlcyBwYXJlbnQgc2VsZWN0b3JzIHRvIHRoZWlyIGZ1bGwgY2xhc3MgbmFtZXMuXG4gKlxuICogRS5nLiBgLmZvbyB7ICZfYmFyIHtjb2xvcjogYmx1ZSB9IH1gIHRvIGAuZm9vX2JhcmAuXG4gKi9cbmV4cG9ydCBjb25zdCBnZXRQYXJlbnRTZWxlY3RvckNsYXNzZXNNYXAgPSAoYXN0OiBnQVNUTm9kZSk6IGNsYXNzTWFwVHlwZSA9PiB7XG4gIGNvbnN0IGNsYXNzZXNNYXA6IGNsYXNzTWFwVHlwZSA9IHt9O1xuXG4gIC8vIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlcyBkb3duIHRoZSB0cmVlIGxvb2tpbmcgZm9yIHBhcmVudCBzZWxlY3RvclxuICAvLyBleHRlbnNpb25zLiBSZWN1cnNpb24gaXMgbmVjZXNzYXJ5IGFzIHRoZXNlIHNlbGVjdG9ycyBjYW4gYmUgbmVzdGVkLlxuICBjb25zdCBnZXRFeHRlbnNpb25zID0gbm9kZUNvbnRlbnQgPT4ge1xuICAgIGNvbnN0IGJsb2NrQ29udGVudCA9IG5vZGVDb250ZW50XG4gICAgICAuZmlsdGVyKGl0ZW0gPT4gaXRlbS50eXBlID09PSAnYmxvY2snKVxuICAgICAgLmZsYXRNYXAoaXRlbSA9PiBpdGVtLmNvbnRlbnQgfHwgW10pO1xuXG4gICAgY29uc3QgcnVsZXNldENoaWxkcmVuID0gYmxvY2tDb250ZW50LmZpbHRlcihpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3J1bGVzZXQnKTtcblxuICAgIGNvbnN0IHJ1bGVzZXREZXNjZW5kYW50cyA9IGJsb2NrQ29udGVudFxuICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ2luY2x1ZGUnKVxuICAgICAgLmZsYXRNYXAoaXRlbSA9PiBpdGVtLmNvbnRlbnQgfHwgW10pXG4gICAgICAuZmlsdGVyKHN1Ykl0ZW0gPT4gc3ViSXRlbS50eXBlID09PSAnYmxvY2snKVxuICAgICAgLmZsYXRNYXAoc3ViSXRlbSA9PiBzdWJJdGVtLmNvbnRlbnQgfHwgW10pXG4gICAgICAuZmlsdGVyKHN1Ykl0ZW0gPT4gc3ViSXRlbS50eXBlID09PSAncnVsZXNldCcpO1xuXG4gICAgY29uc3QgcnVsZXNldHNDb250ZW50ID0gWy4uLnJ1bGVzZXRDaGlsZHJlbiwgLi4ucnVsZXNldERlc2NlbmRhbnRzXVxuICAgICAgLmZsYXRNYXAoaXRlbSA9PiBpdGVtLmNvbnRlbnQgfHwgW10pO1xuXG4gICAgY29uc3QgZXh0ZW5zaW9ucyA9IHJ1bGVzZXRzQ29udGVudFxuICAgICAgLmZpbHRlcihpdGVtID0+IGl0ZW0udHlwZSA9PT0gJ3NlbGVjdG9yJylcbiAgICAgIC5mbGF0TWFwKGl0ZW0gPT4gaXRlbS5jb250ZW50IHx8IFtdKVxuICAgICAgLmZpbHRlcihzZWxlY3Rvckl0ZW0gPT4gc2VsZWN0b3JJdGVtLnR5cGUgPT09ICdwYXJlbnRTZWxlY3RvckV4dGVuc2lvbicpXG4gICAgICAuZmxhdE1hcChzZWxlY3Rvckl0ZW0gPT4gc2VsZWN0b3JJdGVtLmNvbnRlbnQgfHwgW10pXG4gICAgICAuZmlsdGVyKGlkZW50SXRlbSA9PiBpZGVudEl0ZW0udHlwZSA9PT0gJ2lkZW50JylcbiAgICAgIC5tYXAoaWRlbnRJdGVtID0+IGlkZW50SXRlbS5jb250ZW50KTtcblxuICAgIGlmICghZXh0ZW5zaW9ucy5sZW5ndGgpIHJldHVybiBbXTtcblxuICAgIGNvbnN0IG5lc3RlZEV4dGVuc2lvbnMgPSBnZXRFeHRlbnNpb25zKHJ1bGVzZXRzQ29udGVudCk7XG4gICAgY29uc3QgcmVzdWx0ID0gZXh0ZW5zaW9ucztcbiAgICBpZiAobmVzdGVkRXh0ZW5zaW9ucy5sZW5ndGgpIHtcbiAgICAgIGZvciAoY29uc3QgbmVzdGVkRXh0IG9mIG5lc3RlZEV4dGVuc2lvbnMpIHtcbiAgICAgICAgZXh0ZW5zaW9ucy5mb3JFYWNoKGV4dCA9PiB7XG4gICAgICAgICAgcmVzdWx0LnB1c2goZXh0ICsgbmVzdGVkRXh0KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfTtcblxuICBhc3QudHJhdmVyc2VCeVR5cGUoJ3J1bGVzZXQnLCBub2RlID0+IHtcbiAgICBjb25zdCBjbGFzc05hbWVzID0gKG5vZGUuY29udGVudCB8fCBbXSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdzZWxlY3RvcicpXG4gICAgICAuZmxhdE1hcChpdGVtID0+IGl0ZW0uY29udGVudCB8fCBbXSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdjbGFzcycpXG4gICAgICAuZmxhdE1hcChpdGVtID0+IGl0ZW0uY29udGVudCB8fCBbXSlcbiAgICAgIC5maWx0ZXIoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdpZGVudCcgJiYgaXRlbS5jb250ZW50KVxuICAgICAgLm1hcChpdGVtID0+IGl0ZW0uY29udGVudCk7XG5cbiAgICBpZiAoIWNsYXNzTmFtZXMubGVuZ3RoKSByZXR1cm47XG5cbiAgICBjb25zdCBleHRlbnNpb25zID0gZ2V0RXh0ZW5zaW9ucyhub2RlLmNvbnRlbnQpO1xuICAgIGlmICghZXh0ZW5zaW9ucy5sZW5ndGgpIHJldHVybjtcblxuICAgIGNsYXNzTmFtZXMuZm9yRWFjaChjbGFzc05hbWUgPT4ge1xuICAgICAgZXh0ZW5zaW9ucy5mb3JFYWNoKGV4dCA9PiB7XG4gICAgICAgIGNsYXNzZXNNYXBbY2xhc3NOYW1lICsgZXh0XSA9IGZhbHNlO1xuICAgICAgfSk7XG5cbiAgICAgIC8vIElnbm9yZSB0aGUgYmFzZSBjbGFzcyBpZiBpdCBvbmx5IGV4aXN0cyBmb3IgbmVzdGluZyBwYXJlbnQgc2VsZWN0b3JzXG4gICAgICBjb25zdCBoYXNEZWNsYXJhdGlvbnMgPSBub2RlLmNvbnRlbnQ/LnNvbWUoaXRlbSA9PiBpdGVtLnR5cGUgPT09ICdibG9jaycgJiZcbiAgICAgICAgICBpdGVtLmNvbnRlbnQ/LnNvbWUoc3ViSXRlbSA9PiBzdWJJdGVtLnR5cGUgPT09ICdkZWNsYXJhdGlvbicpKTtcbiAgICAgIGlmICghaGFzRGVjbGFyYXRpb25zKSBjbGFzc2VzTWFwW2NsYXNzTmFtZV0gPSB0cnVlO1xuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gY2xhc3Nlc01hcDtcbn07XG5cbi8qKlxuICogTXV0YXRlcyB0aGUgQVNUIGJ5IHJlbW92aW5nIGA6Z2xvYmFsYCBpbnN0YW5jZXMuXG4gKlxuICogRm9yIHRoZSBBU1Qgc3RydWN0dXJlOlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vY3NzL2dvbnphbGVzL2Jsb2IvbWFzdGVyL2RvYy9BU1QuQ1NTUC5lbi5tZFxuICovXG5leHBvcnQgY29uc3QgZWxpbWluYXRlR2xvYmFscyA9IChhc3Q6IGdBU1ROb2RlKSA9PiB7XG4gIC8vIFJlbW92ZSBhbGwgOmdsb2JhbC86Z2xvYmFsKC4uLikgaW4gc2VsZWN0b3JzXG4gIGFzdC50cmF2ZXJzZUJ5VHlwZSgnc2VsZWN0b3InLCAoc2VsZWN0b3JOb2RlKSA9PiB7XG4gICAgY29uc3Qgc2VsZWN0b3JDb250ZW50ID0gc2VsZWN0b3JOb2RlLmNvbnRlbnQ7XG4gICAgbGV0IGhhc0dsb2JhbFdpdGhOb0FyZ3MgPSBmYWxzZTtcbiAgICBsZXQgaSA9IDA7XG4gICAgbGV0IGN1cnJOb2RlID0gc2VsZWN0b3JDb250ZW50W2ldO1xuICAgIHdoaWxlIChjdXJyTm9kZSkge1xuICAgICAgaWYgKGN1cnJOb2RlLmlzKCdwc2V1ZG9DbGFzcycpKSB7XG4gICAgICAgIC8vIFJlbW92ZSBhbGwgOmdsb2JhbC86Z2xvYmFsKC4uLikgYW5kIHRyYWlsaW5nIHNwYWNlXG4gICAgICAgIGNvbnN0IGlkZW50aWZpZXJOb2RlID0gY3Vyck5vZGUuY29udGVudFswXTtcbiAgICAgICAgaWYgKGlkZW50aWZpZXJOb2RlICYmIGlkZW50aWZpZXJOb2RlLmNvbnRlbnQgPT09ICdnbG9iYWwnKSB7XG4gICAgICAgICAgaWYgKGN1cnJOb2RlLmNvbnRlbnQubGVuZ3RoID09PSAxKSBoYXNHbG9iYWxXaXRoTm9BcmdzID0gdHJ1ZTtcbiAgICAgICAgICBzZWxlY3Rvck5vZGUucmVtb3ZlQ2hpbGQoaSk7XG4gICAgICAgICAgaWYgKHNlbGVjdG9yQ29udGVudFtpXSAmJiBzZWxlY3RvckNvbnRlbnRbaV0uaXMoJ3NwYWNlJykpIHtcbiAgICAgICAgICAgIHNlbGVjdG9yTm9kZS5yZW1vdmVDaGlsZChpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaSsrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJOb2RlLmlzKCdjbGFzcycpICYmIGhhc0dsb2JhbFdpdGhOb0FyZ3MpIHtcbiAgICAgICAgLy8gUmVtb3ZlIGFsbCBjbGFzcyBhZnRlciA6Z2xvYmFsIGFuZCB0aGVpciB0cmFpbGluZyBzcGFjZVxuICAgICAgICBzZWxlY3Rvck5vZGUucmVtb3ZlQ2hpbGQoaSk7XG4gICAgICAgIGlmIChzZWxlY3RvckNvbnRlbnRbaV0gJiYgc2VsZWN0b3JDb250ZW50W2ldLmlzKCdzcGFjZScpKSB7XG4gICAgICAgICAgc2VsZWN0b3JOb2RlLnJlbW92ZUNoaWxkKGkpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpKys7XG4gICAgICB9XG5cbiAgICAgIGN1cnJOb2RlID0gc2VsZWN0b3JDb250ZW50W2ldO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gUmVtb3ZlIGFsbCBydWxlc2V0IHdpdGggbm8gc2VsZWN0b3JzXG4gIGFzdC50cmF2ZXJzZUJ5VHlwZSgncnVsZXNldCcsIChub2RlLCBpbmRleCwgcGFyZW50KSA9PiB7XG4gICAgY29uc3QgcnVsZXNldENvbnRlbnQgPSBub2RlLmNvbnRlbnQ7XG5cbiAgICAvLyBSZW1vdmUgZW1wdHkgc2VsZWN0b3JzIGFuZCB0cmFpbGluZyBkZWxpbWluYXRvciBhbmQgc3BhY2VcbiAgICBsZXQgaSA9IDA7XG4gICAgbGV0IGN1cnJOb2RlID0gcnVsZXNldENvbnRlbnRbaV07XG4gICAgd2hpbGUgKGN1cnJOb2RlKSB7XG4gICAgICBpZiAoY3Vyck5vZGUuaXMoJ3NlbGVjdG9yJykgJiYgY3Vyck5vZGUuY29udGVudC5sZW5ndGggPT09IDApIHtcbiAgICAgICAgbm9kZS5yZW1vdmVDaGlsZChpKTtcbiAgICAgICAgaWYgKHJ1bGVzZXRDb250ZW50W2ldLmlzKCdkZWxpbWl0ZXInKSkgbm9kZS5yZW1vdmVDaGlsZChpKTtcbiAgICAgICAgaWYgKHJ1bGVzZXRDb250ZW50W2ldLmlzKCdzcGFjZScpKSBub2RlLnJlbW92ZUNoaWxkKGkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaSsrO1xuICAgICAgfVxuICAgICAgY3Vyck5vZGUgPSBydWxlc2V0Q29udGVudFtpXTtcbiAgICB9XG5cbiAgICAvLyBSZW1vdmUgdGhlIHJ1bGVzZXQgaWYgbm8gc2VsZWN0b3JzXG4gICAgaWYgKHJ1bGVzZXRDb250ZW50LmZpbHRlcigobm9kZSkgPT4gbm9kZS5pcygnc2VsZWN0b3InKSkubGVuZ3RoID09PSAwKSB7XG4gICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoaW5kZXgpO1xuICAgIH1cbiAgfSk7XG59O1xuIl0sIm1hcHBpbmdzIjoiQUFDQTtBQVFBLE9BQU8sTUFBTUEscUJBQXFCLEdBQUlDLEdBQWEsSUFBbUI7RUFDcEUsTUFBTUMsUUFBeUIsR0FBRyxFQUFFO0VBQ3BDRCxHQUFHLENBQUNFLGNBQWMs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
|
package/build/index.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import rules from './rules/index.js';
|
|
3
|
+
const pkg = JSON.parse(fs.readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
4
|
+
const plugin = {
|
|
5
|
+
meta: {
|
|
6
|
+
name: pkg.name,
|
|
7
|
+
version: pkg.version,
|
|
8
|
+
namespace: 'css-modules'
|
|
9
|
+
},
|
|
10
|
+
configs: {},
|
|
11
|
+
rules
|
|
12
|
+
};
|
|
13
|
+
Object.assign(plugin.configs, {
|
|
14
|
+
recommended: [{
|
|
15
|
+
plugins: {
|
|
16
|
+
'css-modules': plugin
|
|
17
|
+
},
|
|
18
|
+
rules: {
|
|
19
|
+
'css-modules/no-unused-class': 2,
|
|
20
|
+
// error
|
|
21
|
+
'css-modules/no-undef-class': 2 // error
|
|
22
|
+
}
|
|
23
|
+
}]
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export default plugin;
|
|
27
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmcyIsInJ1bGVzIiwicGtnIiwiSlNPTiIsInBhcnNlIiwicmVhZEZpbGVTeW5jIiwiVVJMIiwiaW1wb3J0IiwibWV0YSIsInVybCIsInBsdWdpbiIsIm5hbWUiLCJ2ZXJzaW9uIiwibmFtZXNwYWNlIiwiY29uZmlncyIsIk9iamVjdCIsImFzc2lnbiIsInJlY29tbWVuZGVkIiwicGx1Z2lucyJdLCJzb3VyY2VzIjpbIi4uL2xpYi9pbmRleC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZnMgZnJvbSAnbm9kZTpmcyc7XG5pbXBvcnQgcnVsZXMgZnJvbSAnLi9ydWxlcy9pbmRleC5qcyc7XG5cbmNvbnN0IHBrZyA9IEpTT04ucGFyc2UoXG4gIGZzLnJlYWRGaWxlU3luYyhuZXcgVVJMKCcuLi9wYWNrYWdlLmpzb24nLCBpbXBvcnQubWV0YS51cmwpLCAndXRmOCcpLFxuKTtcblxuY29uc3QgcGx1Z2luID0ge1xuICBtZXRhOiB7XG4gICAgbmFtZTogcGtnLm5hbWUsXG4gICAgdmVyc2lvbjogcGtnLnZlcnNpb24sXG4gICAgbmFtZXNwYWNlOiAnY3NzLW1vZHVsZXMnLFxuICB9LFxuICBjb25maWdzOiB7fSxcbiAgcnVsZXMsXG59O1xuXG5PYmplY3QuYXNzaWduKHBsdWdpbi5jb25maWdzLCB7XG4gIHJlY29tbWVuZGVkOiBbXG4gICAge1xuICAgICAgcGx1Z2luczoge1xuICAgICAgICAnY3NzLW1vZHVsZXMnOiBwbHVnaW4sXG4gICAgICB9LFxuICAgICAgcnVsZXM6IHtcbiAgICAgICAgJ2Nzcy1tb2R1bGVzL25vLXVudXNlZC1jbGFzcyc6IDIsIC8vIGVycm9yXG4gICAgICAgICdjc3MtbW9kdWxlcy9uby11bmRlZi1jbGFzcyc6IDIsIC8vIGVycm9yXG4gICAgICB9LFxuICAgIH0sXG4gIF0sXG59KTtcblxuZXhwb3J0IGRlZmF1bHQgcGx1Z2luO1xuIl0sIm1hcHBpbmdzIjoiQUFBQSxPQUFPQSxFQUFFLE1BQU0sU0FBUztBQUN4QixPQUFPQyxLQUFLLE1BQU0sa0JBQWtCO0FBRXBDLE1BQU1DLEdBQUcsR0FBR0MsSUFBSSxDQUFDQyxLQUFLLENBQ3BCSixFQUFFLENBQUNLLFlBQVksQ0FBQyxJQUFJQyxHQUFHLENBQUMsaUJBQWlCLEVBQUVDLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQ3JFLENBQUM7QUFFRCxNQUFNQyxNQUFNLEdBQUc7RUFDYkYsSUFBSSxFQUFFO0lBQ0pHLElBQUksRUFBRVQsR0FBRyxDQUFDUyxJQUFJO0lBQ2RDLE9BQU8sRUFBRVYsR0FBRyxDQUFDVSxPQUFPO0lBQ3BCQyxTQUFTLEVBQUU7RUFDYixDQUFDO0VBQ0RDLE9BQU8sRUFBRSxDQUFDLENBQUM7RUFDWGI7QUFDRixDQUFDO0FBRURjLE1BQU0sQ0FBQ0MsTUFBTSxDQUFDTixNQUFNLENBQUNJLE9BQU8sRUFBRTtFQUM1QkcsV0FBVyxFQUFFLENBQ1g7SUFDRUMsT0FBTyxFQUFFO01BQ1AsYUFBYSxFQUFFUjtJQUNqQixDQUFDO0lBQ0RULEtBQUssRUFBRTtNQUNMLDZCQUE2QixFQUFFLENBQUM7TUFBRTtNQUNsQyw0QkFBNEIsRUFBRSxDQUFDLENBQUU7SUFDbkM7RUFDRixDQUFDO0FBRUwsQ0FBQyxDQUFDOztBQUVGLGVBQWVTLE1BQU0ifQ==
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import noUnusedClass from './no-unused-class.js';
|
|
2
|
+
import noUndefClass from './no-undef-class.js';
|
|
3
|
+
export default {
|
|
4
|
+
'no-unused-class': noUnusedClass,
|
|
5
|
+
'no-undef-class': noUndefClass
|
|
6
|
+
};
|
|
7
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJub1VudXNlZENsYXNzIiwibm9VbmRlZkNsYXNzIl0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3J1bGVzL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBub1VudXNlZENsYXNzIGZyb20gJy4vbm8tdW51c2VkLWNsYXNzLmpzJztcbmltcG9ydCBub1VuZGVmQ2xhc3MgZnJvbSAnLi9uby11bmRlZi1jbGFzcy5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgJ25vLXVudXNlZC1jbGFzcyc6IG5vVW51c2VkQ2xhc3MsXG4gICduby11bmRlZi1jbGFzcyc6IG5vVW5kZWZDbGFzcyxcbn07XG4iXSwibWFwcGluZ3MiOiJBQUFBLE9BQU9BLGFBQWEsTUFBTSxzQkFBc0I7QUFDaEQsT0FBT0MsWUFBWSxNQUFNLHFCQUFxQjtBQUU5QyxlQUFlO0VBQ2IsaUJBQWlCLEVBQUVELGFBQWE7RUFDaEMsZ0JBQWdCLEVBQUVDO0FBQ3BCLENBQUMifQ==
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { getStyleImportNodeData, getAST, fileExists, getStyleClasses, getPropertyName, getClassesMap, getExportPropsMap, getFilePath } from '../core/index.js';
|
|
2
|
+
export default {
|
|
3
|
+
meta: {
|
|
4
|
+
docs: {
|
|
5
|
+
description: 'Checks that you are using the existent css/scss/less classes',
|
|
6
|
+
recommended: true
|
|
7
|
+
},
|
|
8
|
+
schema: [{
|
|
9
|
+
type: 'object',
|
|
10
|
+
properties: {
|
|
11
|
+
camelCase: {
|
|
12
|
+
enum: [true, 'dashes', 'only', 'dashes-only']
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}]
|
|
16
|
+
},
|
|
17
|
+
create(context) {
|
|
18
|
+
const camelCase = context?.options[0]?.camelCase;
|
|
19
|
+
|
|
20
|
+
/*
|
|
21
|
+
maps variable name to property Object
|
|
22
|
+
map = {
|
|
23
|
+
[variableName]: {
|
|
24
|
+
classesMap: { foo: 'foo', fooBar: 'foo-bar', 'foo-bar': 'foo-bar' },
|
|
25
|
+
node: {...}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
example:
|
|
29
|
+
import s from './foo.scss';
|
|
30
|
+
s is variable name
|
|
31
|
+
property Object has two keys
|
|
32
|
+
1. classesMap: an object with propertyName as key and its className as value
|
|
33
|
+
2. node: node that correspond to s (see example above)
|
|
34
|
+
*/
|
|
35
|
+
const map = {};
|
|
36
|
+
return {
|
|
37
|
+
ImportDeclaration(node) {
|
|
38
|
+
const styleImportNodeData = getStyleImportNodeData(node);
|
|
39
|
+
if (!styleImportNodeData) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const {
|
|
43
|
+
importName,
|
|
44
|
+
styleFilePath,
|
|
45
|
+
importNode
|
|
46
|
+
} = styleImportNodeData;
|
|
47
|
+
const styleFileAbsolutePath = getFilePath(context, styleFilePath);
|
|
48
|
+
let classesMap = {};
|
|
49
|
+
let exportPropsMap = {};
|
|
50
|
+
if (fileExists(styleFileAbsolutePath)) {
|
|
51
|
+
const ast = getAST(styleFileAbsolutePath);
|
|
52
|
+
const classes = ast && getStyleClasses(ast);
|
|
53
|
+
classesMap = classes && getClassesMap(classes, camelCase);
|
|
54
|
+
exportPropsMap = ast && getExportPropsMap(ast);
|
|
55
|
+
}
|
|
56
|
+
map[importName] ??= {};
|
|
57
|
+
|
|
58
|
+
// this will be used to check if classes are defined
|
|
59
|
+
map[importName].classesMap = classesMap;
|
|
60
|
+
|
|
61
|
+
// this will be used to check if :export properties are defined
|
|
62
|
+
map[importName].exportPropsMap = exportPropsMap;
|
|
63
|
+
|
|
64
|
+
// save node for reporting unused styles
|
|
65
|
+
map[importName].node = importNode;
|
|
66
|
+
},
|
|
67
|
+
MemberExpression: node => {
|
|
68
|
+
/*
|
|
69
|
+
Check if property exists in css/scss file as class
|
|
70
|
+
*/
|
|
71
|
+
|
|
72
|
+
const objectName = node.object.name;
|
|
73
|
+
const propertyName = getPropertyName(node, camelCase);
|
|
74
|
+
if (!propertyName) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
const classesMap = map[objectName]?.classesMap;
|
|
78
|
+
const exportPropsMap = map[objectName]?.exportPropsMap;
|
|
79
|
+
if (classesMap && classesMap[propertyName] == null && exportPropsMap && exportPropsMap[propertyName] == null) {
|
|
80
|
+
context.report(node.property, `Class or exported property '${propertyName}' not found`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJnZXRTdHlsZUltcG9ydE5vZGVEYXRhIiwiZ2V0QVNUIiwiZmlsZUV4aXN0cyIsImdldFN0eWxlQ2xhc3NlcyIsImdldFByb3BlcnR5TmFtZSIsImdldENsYXNzZXNNYXAiLCJnZXRFeHBvcnRQcm9wc01hcCIsImdldEZpbGVQYXRoIiwibWV0YSIsImRvY3MiLCJkZXNjcmlwdGlvbiIsInJlY29tbWVuZGVkIiwic2NoZW1hIiwidHlwZSIsInByb3BlcnRpZXMiLCJjYW1lbENhc2UiLCJlbnVtIiwiY3JlYXRlIiwiY29udGV4dCIsIm9wdGlvbnMiLCJtYXAiLCJJbXBvcnREZWNsYXJhdGlvbiIsIm5vZGUiLCJzdHlsZUltcG9ydE5vZGVEYXRhIiwiaW1wb3J0TmFtZSIsInN0eWxlRmlsZVBhdGgiLCJpbXBvcnROb2RlIiwic3R5bGVGaWxlQWJzb2x1dGVQYXRoIiwiY2xhc3Nlc01hcCIsImV4cG9ydFByb3BzTWFwIiwiYXN0IiwiY2xhc3NlcyIsIk1lbWJlckV4cHJlc3Npb24iLCJvYmplY3ROYW1lIiwib2JqZWN0IiwibmFtZSIsInByb3BlcnR5TmFtZSIsInJlcG9ydCIsInByb3BlcnR5Il0sInNvdXJjZXMiOlsiLi4vLi4vbGliL3J1bGVzL25vLXVuZGVmLWNsYXNzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qIEBmbG93ICovXG5pbXBvcnQge1xuICBnZXRTdHlsZUltcG9ydE5vZGVEYXRhLFxuICBnZXRBU1QsXG4gIGZpbGVFeGlzdHMsXG4gIGdldFN0eWxlQ2xhc3NlcyxcbiAgZ2V0UHJvcGVydHlOYW1lLFxuICBnZXRDbGFzc2VzTWFwLFxuICBnZXRFeHBvcnRQcm9wc01hcCxcbiAgZ2V0RmlsZVBhdGgsXG59IGZyb20gJy4uL2NvcmUvaW5kZXguanMnO1xuXG5pbXBvcnQgdHlwZSB7IEpzTm9kZSB9IGZyb20gJy4uL3R5cGVzL2luZGV4LmpzJztcblxuZXhwb3J0IGRlZmF1bHQge1xuICBtZXRhOiB7XG4gICAgZG9jczoge1xuICAgICAgZGVzY3JpcHRpb246ICdDaGVja3MgdGhhdCB5b3UgYXJlIHVzaW5nIHRoZSBleGlzdGVudCBjc3Mvc2Nzcy9sZXNzIGNsYXNzZXMnLFxuICAgICAgcmVjb21tZW5kZWQ6IHRydWUsXG4gICAgfSxcbiAgICBzY2hlbWE6IFtcbiAgICAgIHtcbiAgICAgICAgdHlwZTogJ29iamVjdCcsXG4gICAgICAgIHByb3BlcnRpZXM6IHtcbiAgICAgICAgICBjYW1lbENhc2U6IHsgZW51bTogW3RydWUsICdkYXNoZXMnLCAnb25seScsICdkYXNoZXMtb25seSddIH1cbiAgICAgICAgfSxcbiAgICAgIH1cbiAgICBdLFxuICB9LFxuICBjcmVhdGUgKGNvbnRleHQ6IE9iamVjdCkge1xuICAgIGNvbnN0IGNhbWVsQ2FzZSA9IGNvbnRleHQ/Lm9wdGlvbnNbMF0/LmNhbWVsQ2FzZTtcblxuICAgIC8qXG4gICAgICAgbWFwcyB2YXJpYWJsZSBuYW1lIHRvIHByb3BlcnR5IE9iamVjdFxuICAgICAgIG1hcCA9IHtcbiAgICAgICAgIFt2YXJpYWJsZU5hbWVdOiB7XG4gICAgICAgICAgIGNsYXNzZXNNYXA6IHsgZm9vOiAnZm9vJywgZm9vQmFyOiAnZm9vLWJhcicsICdmb28tYmFyJzogJ2Zvby1iYXInIH0sXG4gICAgICAgICAgIG5vZGU6IHsuLi59XG4gICAgICAgICB9XG4gICAgICAgfVxuXG4gICAgICAgZXhhbXBsZTpcbiAgICAgICBpbXBvcnQgcyBmcm9tICcuL2Zvby5zY3NzJztcbiAgICAgICBzIGlzIHZhcmlhYmxlIG5hbWVcblxuICAgICAgIHByb3BlcnR5IE9iamVjdCBoYXMgdHdvIGtleXNcbiAgICAgICAxLiBjbGFzc2VzTWFwOiBhbiBvYmplY3Qgd2l0aCBwcm9wZXJ0eU5hbWUgYXMga2V5IGFuZCBpdHMgY2xhc3NOYW1lIGFzIHZhbHVlXG4gICAgICAgMi4gbm9kZTogbm9kZSB0aGF0IGNvcnJlc3BvbmQgdG8gcyAoc2VlIGV4YW1wbGUgYWJvdmUpXG4gICAgICovXG4gICAgY29uc3QgbWFwID0ge307XG5cbiAgICByZXR1cm4ge1xuICAgICAgSW1wb3J0RGVjbGFyYXRpb24gKG5vZGU6IEpzTm9kZSkge1xuICAgICAgICBjb25zdCBzdHlsZUltcG9ydE5vZGVEYXRhID0gZ2V0U3R5bGVJbXBvcnROb2RlRGF0YShub2RlKTtcblxuICAgICAgICBpZiAoIXN0eWxlSW1wb3J0Tm9kZURhdGEpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB7XG4gICAgICAgICAgaW1wb3J0TmFtZSxcbiAgICAgICAgICBzdHlsZUZpbGVQYXRoLFxuICAgICAgICAgIGltcG9ydE5vZGUsXG4gICAgICAgIH0gPSBzdHlsZUltcG9ydE5vZGVEYXRhO1xuXG4gICAgICAgIGNvbnN0IHN0eWxlRmlsZUFic29sdXRlUGF0aCA9IGdldEZpbGVQYXRoKGNvbnRleHQsIHN0eWxlRmlsZVBhdGgpO1xuICAgICAgICBsZXQgY2xhc3Nlc01hcCA9IHt9O1xuICAgICAgICBsZXQgZXhwb3J0UHJvcHNNYXAgPSB7fTtcblxuICAgICAgICBpZiAoZmlsZUV4aXN0cyhzdHlsZUZpbGVBYnNvbHV0ZVBhdGgpKSB7XG4gICAgICAgICAgY29uc3QgYXN0ID0gZ2V0QVNUKHN0eWxlRmlsZUFic29sdXRlUGF0aCk7XG4gICAgICAgICAgY29uc3QgY2xhc3NlcyA9IGFzdCAmJiBnZXRTdHlsZUNsYXNzZXMoYXN0KTtcblxuICAgICAgICAgIGNsYXNzZXNNYXAgPSBjbGFzc2VzICYmIGdldENsYXNzZXNNYXAoY2xhc3NlcywgY2FtZWxDYXNlKTtcbiAgICAgICAgICBleHBvcnRQcm9wc01hcCA9IGFzdCAmJiBnZXRFeHBvcnRQcm9wc01hcChhc3QpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFwW2ltcG9ydE5hbWVdID8/PSB7fTtcblxuICAgICAgICAvLyB0aGlzIHdpbGwgYmUgdXNlZCB0byBjaGVjayBpZiBjbGFzc2VzIGFyZSBkZWZpbmVkXG4gICAgICAgIG1hcFtpbXBvcnROYW1lXS5jbGFzc2VzTWFwID0gY2xhc3Nlc01hcDtcblxuICAgICAgICAvLyB0aGlzIHdpbGwgYmUgdXNlZCB0byBjaGVjayBpZiA6ZXhwb3J0IHByb3BlcnRpZXMgYXJlIGRlZmluZWRcbiAgICAgICAgbWFwW2ltcG9ydE5hbWVdLmV4cG9ydFByb3BzTWFwID0gZXhwb3J0UHJvcHNNYXA7XG5cbiAgICAgICAgLy8gc2F2ZSBub2RlIGZvciByZXBvcnRpbmcgdW51c2VkIHN0eWxlc1xuICAgICAgICBtYXBbaW1wb3J0TmFtZV0ubm9kZSA9IGltcG9ydE5vZGU7XG4gICAgICB9LFxuICAgICAgTWVtYmVyRXhwcmVzc2lvbjogKG5vZGU6IEpzTm9kZSkgPT4ge1xuICAgICAgICAvKlxuICAgICAgICAgICBDaGVjayBpZiBwcm9wZXJ0eSBleGlzdHMgaW4gY3NzL3Njc3MgZmlsZSBhcyBjbGFzc1xuICAgICAgICAgKi9cblxuICAgICAgICBjb25zdCBvYmplY3ROYW1lID0gbm9kZS5vYmplY3QubmFtZTtcblxuICAgICAgICBjb25zdCBwcm9wZXJ0eU5hbWUgPSBnZXRQcm9wZXJ0eU5hbWUobm9kZSwgY2FtZWxDYXNlKTtcblxuICAgICAgICBpZiAoIXByb3BlcnR5TmFtZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzZXNNYXAgPSBtYXBbb2JqZWN0TmFtZV0/LmNsYXNzZXNNYXA7XG4gICAgICAgIGNvbnN0IGV4cG9ydFByb3BzTWFwID0gbWFwW29iamVjdE5hbWVdPy5leHBvcnRQcm9wc01hcDtcblxuICAgICAgICBpZiAoY2xhc3Nlc01hcCAmJiBjbGFzc2VzTWFwW3Byb3BlcnR5TmFtZV0gPT0gbnVsbCAmJlxuICAgICAgICAgICAgZXhwb3J0UHJvcHNNYXAgJiYgZXhwb3J0UHJvcHNNYXBbcHJvcGVydHlOYW1lXSA9PSBudWxsKSB7XG4gICAgICAgICAgY29udGV4dC5yZXBvcnQobm9kZS5wcm9wZXJ0eSwgYENsYXNzIG9yIGV4cG9ydGVkIHByb3BlcnR5ICcke3Byb3BlcnR5TmFt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
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { getStyleImportNodeData, getStyleClasses, getPropertyName, getClassesMap, getFilePath, getAST, fileExists } from '../core/index.js';
|
|
3
|
+
export default {
|
|
4
|
+
meta: {
|
|
5
|
+
docs: {
|
|
6
|
+
description: 'Checks that you are using all css/scss/less classes',
|
|
7
|
+
recommended: true
|
|
8
|
+
},
|
|
9
|
+
schema: [{
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
camelCase: {
|
|
13
|
+
enum: [true, 'dashes', 'only', 'dashes-only']
|
|
14
|
+
},
|
|
15
|
+
markAsUsed: {
|
|
16
|
+
type: 'array'
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}]
|
|
20
|
+
},
|
|
21
|
+
create(context) {
|
|
22
|
+
const markAsUsed = context?.options?.[0]?.markAsUsed;
|
|
23
|
+
const camelCase = context?.options?.[0]?.camelCase;
|
|
24
|
+
|
|
25
|
+
/*
|
|
26
|
+
maps variable name to property Object
|
|
27
|
+
map = {
|
|
28
|
+
[variableName]: {
|
|
29
|
+
classes: { foo: false, 'foo-bar': false },
|
|
30
|
+
classesMap: { foo: 'foo', fooBar: 'foo-bar', 'foo-bar': 'foo-bar' },
|
|
31
|
+
node: {...}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
example:
|
|
35
|
+
import s from './foo.scss';
|
|
36
|
+
s is variable name
|
|
37
|
+
property Object has two keys
|
|
38
|
+
1. classes: an object with className as key and a boolean as value. The boolean is marked if it is used in file
|
|
39
|
+
2. classesMap: an object with propertyName as key and its className as value
|
|
40
|
+
3. node: node that correspond to s (see example above)
|
|
41
|
+
*/
|
|
42
|
+
const map = {};
|
|
43
|
+
return {
|
|
44
|
+
ImportDeclaration(node) {
|
|
45
|
+
const styleImportNodeData = getStyleImportNodeData(node);
|
|
46
|
+
if (!styleImportNodeData) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
const {
|
|
50
|
+
importName,
|
|
51
|
+
styleFilePath,
|
|
52
|
+
importNode
|
|
53
|
+
} = styleImportNodeData;
|
|
54
|
+
const styleFileAbsolutePath = getFilePath(context, styleFilePath);
|
|
55
|
+
let classes = {};
|
|
56
|
+
let classesMap = {};
|
|
57
|
+
if (fileExists(styleFileAbsolutePath)) {
|
|
58
|
+
// this will be used to mark s.foo as used in MemberExpression
|
|
59
|
+
const ast = getAST(styleFileAbsolutePath);
|
|
60
|
+
classes = ast && getStyleClasses(ast);
|
|
61
|
+
classesMap = classes && getClassesMap(classes, camelCase);
|
|
62
|
+
}
|
|
63
|
+
map[importName] ??= {};
|
|
64
|
+
map[importName].classes = classes;
|
|
65
|
+
map[importName].classesMap = classesMap;
|
|
66
|
+
|
|
67
|
+
// save node for reporting unused styles
|
|
68
|
+
map[importName].node = importNode;
|
|
69
|
+
|
|
70
|
+
// save file path for reporting unused styles
|
|
71
|
+
map[importName].filePath = styleFilePath;
|
|
72
|
+
},
|
|
73
|
+
MemberExpression: node => {
|
|
74
|
+
/*
|
|
75
|
+
Check if property exists in css/scss file as class
|
|
76
|
+
*/
|
|
77
|
+
|
|
78
|
+
const objectName = node.object.name;
|
|
79
|
+
const propertyName = getPropertyName(node, camelCase);
|
|
80
|
+
if (!propertyName) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
const className = map[objectName]?.classesMap?.[propertyName];
|
|
84
|
+
if (className == null) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// mark this property has used
|
|
89
|
+
(map[objectName] ??= {
|
|
90
|
+
classes: {}
|
|
91
|
+
}).classes[className] = true;
|
|
92
|
+
},
|
|
93
|
+
'Program:exit'() {
|
|
94
|
+
/*
|
|
95
|
+
Check if all classes defined in css/scss file are used
|
|
96
|
+
*/
|
|
97
|
+
|
|
98
|
+
/*
|
|
99
|
+
we are looping over each import style node in program
|
|
100
|
+
example:
|
|
101
|
+
```
|
|
102
|
+
import s from './foo.css';
|
|
103
|
+
import x from './bar.scss';
|
|
104
|
+
```
|
|
105
|
+
then the loop will be run 2 times
|
|
106
|
+
*/
|
|
107
|
+
for (const o of Object.values(map)) {
|
|
108
|
+
const {
|
|
109
|
+
classes,
|
|
110
|
+
node,
|
|
111
|
+
filePath
|
|
112
|
+
} = o;
|
|
113
|
+
|
|
114
|
+
/*
|
|
115
|
+
if option is passed to mark a class as used, example:
|
|
116
|
+
eslint css-modules/no-unused-class: [2, { markAsUsed: ['container'] }]
|
|
117
|
+
*/
|
|
118
|
+
for (const usedClass of markAsUsed ?? []) {
|
|
119
|
+
classes[usedClass] = true;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// classNames not marked as true are unused
|
|
123
|
+
const unusedClasses = classes ? Object.entries(classes).filter(([_k, v]) => !v).map(([k, _v]) => k) : [];
|
|
124
|
+
if (unusedClasses.length > 0) {
|
|
125
|
+
context.report(node, `Unused classes found in ${path.basename(filePath)}: ${unusedClasses.join(', ')}`);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJwYXRoIiwiZ2V0U3R5bGVJbXBvcnROb2RlRGF0YSIsImdldFN0eWxlQ2xhc3NlcyIsImdldFByb3BlcnR5TmFtZSIsImdldENsYXNzZXNNYXAiLCJnZXRGaWxlUGF0aCIsImdldEFTVCIsImZpbGVFeGlzdHMiLCJtZXRhIiwiZG9jcyIsImRlc2NyaXB0aW9uIiwicmVjb21tZW5kZWQiLCJzY2hlbWEiLCJ0eXBlIiwicHJvcGVydGllcyIsImNhbWVsQ2FzZSIsImVudW0iLCJtYXJrQXNVc2VkIiwiY3JlYXRlIiwiY29udGV4dCIsIm9wdGlvbnMiLCJtYXAiLCJJbXBvcnREZWNsYXJhdGlvbiIsIm5vZGUiLCJzdHlsZUltcG9ydE5vZGVEYXRhIiwiaW1wb3J0TmFtZSIsInN0eWxlRmlsZVBhdGgiLCJpbXBvcnROb2RlIiwic3R5bGVGaWxlQWJzb2x1dGVQYXRoIiwiY2xhc3NlcyIsImNsYXNzZXNNYXAiLCJhc3QiLCJmaWxlUGF0aCIsIk1lbWJlckV4cHJlc3Npb24iLCJvYmplY3ROYW1lIiwib2JqZWN0IiwibmFtZSIsInByb3BlcnR5TmFtZSIsImNsYXNzTmFtZSIsIlByb2dyYW06ZXhpdCIsIm8iLCJPYmplY3QiLCJ2YWx1ZXMiLCJ1c2VkQ2xhc3MiLCJ1bnVzZWRDbGFzc2VzIiwiZW50cmllcyIsImZpbHRlciIsIl9rIiwidiIsImsiLCJfdiIsImxlbmd0aCIsInJlcG9ydCIsImJhc2VuYW1lIiwiam9pbiJdLCJzb3VyY2VzIjpbIi4uLy4uL2xpYi9ydWxlcy9uby11bnVzZWQtY2xhc3MuanMiXSwic291cmNlc0NvbnRlbnQiOlsiLyogQGZsb3cgKi9cbmltcG9ydCBwYXRoIGZyb20gJ25vZGU6cGF0aCc7XG5cbmltcG9ydCB7XG4gIGdldFN0eWxlSW1wb3J0Tm9kZURhdGEsXG4gIGdldFN0eWxlQ2xhc3NlcyxcbiAgZ2V0UHJvcGVydHlOYW1lLFxuICBnZXRDbGFzc2VzTWFwLFxuICBnZXRGaWxlUGF0aCxcbiAgZ2V0QVNULFxuICBmaWxlRXhpc3RzLFxufSBmcm9tICcuLi9jb3JlL2luZGV4LmpzJztcblxuaW1wb3J0IHR5cGUgeyBKc05vZGUgfSBmcm9tICcuLi90eXBlcy9pbmRleC5qcyc7XG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbWV0YToge1xuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOiAnQ2hlY2tzIHRoYXQgeW91IGFyZSB1c2luZyBhbGwgY3NzL3Njc3MvbGVzcyBjbGFzc2VzJyxcbiAgICAgIHJlY29tbWVuZGVkOiB0cnVlLFxuICAgIH0sXG4gICAgc2NoZW1hOiBbXG4gICAgICB7XG4gICAgICAgIHR5cGU6ICdvYmplY3QnLFxuICAgICAgICBwcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgY2FtZWxDYXNlOiB7IGVudW06IFt0cnVlLCAnZGFzaGVzJywgJ29ubHknLCAnZGFzaGVzLW9ubHknXSB9LFxuICAgICAgICAgIG1hcmtBc1VzZWQ6IHsgdHlwZTogJ2FycmF5JyB9LFxuICAgICAgICB9LFxuICAgICAgfVxuICAgIF0sXG4gIH0sXG4gIGNyZWF0ZSAoY29udGV4dDogT2JqZWN0KSB7XG4gICAgY29uc3QgbWFya0FzVXNlZCA9IGNvbnRleHQ/Lm9wdGlvbnM/LlswXT8ubWFya0FzVXNlZDtcbiAgICBjb25zdCBjYW1lbENhc2UgPSBjb250ZXh0Py5vcHRpb25zPy5bMF0/LmNhbWVsQ2FzZTtcblxuICAgIC8qXG4gICAgICAgbWFwcyB2YXJpYWJsZSBuYW1lIHRvIHByb3BlcnR5IE9iamVjdFxuICAgICAgIG1hcCA9IHtcbiAgICAgICAgIFt2YXJpYWJsZU5hbWVdOiB7XG4gICAgICAgICAgIGNsYXNzZXM6IHsgZm9vOiBmYWxzZSwgJ2Zvby1iYXInOiBmYWxzZSB9LFxuICAgICAgICAgICBjbGFzc2VzTWFwOiB7IGZvbzogJ2ZvbycsIGZvb0JhcjogJ2Zvby1iYXInLCAnZm9vLWJhcic6ICdmb28tYmFyJyB9LFxuICAgICAgICAgICBub2RlOiB7Li4ufVxuICAgICAgICAgfVxuICAgICAgIH1cblxuICAgICAgIGV4YW1wbGU6XG4gICAgICAgaW1wb3J0IHMgZnJvbSAnLi9mb28uc2Nzcyc7XG4gICAgICAgcyBpcyB2YXJpYWJsZSBuYW1lXG5cbiAgICAgICBwcm9wZXJ0eSBPYmplY3QgaGFzIHR3byBrZXlzXG4gICAgICAgMS4gY2xhc3NlczogYW4gb2JqZWN0IHdpdGggY2xhc3NOYW1lIGFzIGtleSBhbmQgYSBib29sZWFuIGFzIHZhbHVlLiBUaGUgYm9vbGVhbiBpcyBtYXJrZWQgaWYgaXQgaXMgdXNlZCBpbiBmaWxlXG4gICAgICAgMi4gY2xhc3Nlc01hcDogYW4gb2JqZWN0IHdpdGggcHJvcGVydHlOYW1lIGFzIGtleSBhbmQgaXRzIGNsYXNzTmFtZSBhcyB2YWx1ZVxuICAgICAgIDMuIG5vZGU6IG5vZGUgdGhhdCBjb3JyZXNwb25kIHRvIHMgKHNlZSBleGFtcGxlIGFib3ZlKVxuICAgICAqL1xuICAgIGNvbnN0IG1hcCA9IHt9O1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIEltcG9ydERlY2xhcmF0aW9uIChub2RlOiBKc05vZGUpIHtcbiAgICAgICAgY29uc3Qgc3R5bGVJbXBvcnROb2RlRGF0YSA9IGdldFN0eWxlSW1wb3J0Tm9kZURhdGEobm9kZSk7XG5cbiAgICAgICAgaWYgKCFzdHlsZUltcG9ydE5vZGVEYXRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3Qge1xuICAgICAgICAgIGltcG9ydE5hbWUsXG4gICAgICAgICAgc3R5bGVGaWxlUGF0aCxcbiAgICAgICAgICBpbXBvcnROb2RlLFxuICAgICAgICB9ID0gc3R5bGVJbXBvcnROb2RlRGF0YTtcblxuICAgICAgICBjb25zdCBzdHlsZUZpbGVBYnNvbHV0ZVBhdGggPSBnZXRGaWxlUGF0aChjb250ZXh0LCBzdHlsZUZpbGVQYXRoKTtcblxuICAgICAgICBsZXQgY2xhc3NlcyA9IHt9O1xuICAgICAgICBsZXQgY2xhc3Nlc01hcCA9IHt9O1xuXG4gICAgICAgIGlmIChmaWxlRXhpc3RzKHN0eWxlRmlsZUFic29sdXRlUGF0aCkpIHtcbiAgICAgICAgICAvLyB0aGlzIHdpbGwgYmUgdXNlZCB0byBtYXJrIHMuZm9vIGFzIHVzZWQgaW4gTWVtYmVyRXhwcmVzc2lvblxuICAgICAgICAgIGNvbnN0IGFzdCA9IGdldEFTVChzdHlsZUZpbGVBYnNvbHV0ZVBhdGgpO1xuICAgICAgICAgIGNsYXNzZXMgPSBhc3QgJiYgZ2V0U3R5bGVDbGFzc2VzKGFzdCk7XG4gICAgICAgICAgY2xhc3Nlc01hcCA9IGNsYXNzZXMgJiYgZ2V0Q2xhc3Nlc01hcChjbGFzc2VzLCBjYW1lbENhc2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgbWFwW2ltcG9ydE5hbWVdID8/PSB7fTtcblxuICAgICAgICBtYXBbaW1wb3J0TmFtZV0uY2xhc3NlcyA9IGNsYXNzZXM7XG4gICAgICAgIG1hcFtpbXBvcnROYW1lXS5jbGFzc2VzTWFwID0gY2xhc3Nlc01hcDtcblxuICAgICAgICAvLyBzYXZlIG5vZGUgZm9yIHJlcG9ydGluZyB1bnVzZWQgc3R5bGVzXG4gICAgICAgIG1hcFtpbXBvcnROYW1lXS5ub2RlID0gaW1wb3J0Tm9kZTtcblxuICAgICAgICAvLyBzYXZlIGZpbGUgcGF0aCBmb3IgcmVwb3J0aW5nIHVudXNlZCBzdHlsZXNcbiAgICAgICAgbWFwW2ltcG9ydE5hbWVdLmZpbGVQYXRoID0gc3R5bGVGaWxlUGF0aDtcbiAgICAgIH0sXG4gICAgICBNZW1iZXJFeHByZXNzaW9uOiAobm9kZTogSnNOb2RlKSA9PiB7XG4gICAgICAgIC8qXG4gICAgICAgICAgIENoZWNrIGlmIHByb3BlcnR5IGV4aXN0cyBpbiBjc3Mvc2NzcyBmaWxlIGFzIGNsYXNzXG4gICAgICAgICAqL1xuXG4gICAgICAgIGNvbnN0IG9iamVjdE5hbWUgPSBub2RlLm9iamVjdC5uYW1lO1xuICAgICAgICBjb25zdCBwcm9wZXJ0eU5hbWUgPSBnZXRQcm9wZXJ0eU5hbWUobm9kZSwgY2FtZWxDYXNlKTtcblxuICAgICAgICBpZiAoIXByb3BlcnR5TmFtZSkge1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNsYXNzTmFtZSA9IG1hcFtvYmplY3ROYW1lXT8uY2xhc3Nlc01hcD8uW3Byb3BlcnR5TmFtZV07XG5cbiAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbWFyayB0aGlzIHByb3BlcnR5IGhhcyB1c2VkXG4gICAgICAgIChtYXBbb2JqZWN0TmFtZV0gPz89IHsgY2xhc3Nlczoge30gfSkuY2xhc3Nlc1tjbGFzc05hbWVdID0gdHJ1ZTtcbiAgICAgIH0sXG4gICAgICAnUHJvZ3JhbTpleGl0JyAoKSB7XG4gICAgICAgIC8qXG4gICAgICAgICAgIENoZWNrIGlmIGFsbCBjbGFzc2VzIGRlZmluZWQgaW4gY3NzL3Njc3MgZmlsZSBhcmUgdXNlZFxuICAgICAgICAgKi9cblxuICAgICAgICAvKlxuICAgICAgICAgICB3ZSBhcmUgbG9vcGluZyBvdmVyIGVhY2ggaW1wb3J0IHN0eWxlIG5vZGUgaW4gcHJvZ3JhbVxuICAgICAgICAgICBleGFtcGxlOlxuICAgICAgICAgICBgYGBcbiAgICAgICAgICAgICBpbXBvcnQgcyBmcm9tICcuL2Zvby5jc3MnO1xuICAgICAgICAgICAgIGltcG9ydCB4IGZyb20gJy4vYmFyLnNjc3MnO1xuICAgICAgICAgICBgYGBcbiAgICAgICAgICAgdGhlbiB0aGUgbG9vcCB3aWxsIGJlIHJ1biAyIHRpbWVzXG4gICAgICAgICAqL1xuICAgICAgICBmb3IgKGNvbnN0IG8gb2YgT2JqZWN0LnZhbHVlcyhtYXApKSB7XG4gICAgICAgICAgY29uc3QgeyBjbGFzc2VzLCBub2RlLCBmaWxlUGF0aCB9ID0gbztcblxuICAgICAgICAgIC8qXG4gICAgICAgICAgICAgaWYgb3B0aW9uIGlzIHBhc3NlZCB0byBtYXJrIGEgY2xhc3MgYXMgdXNlZCwgZXhhbXBsZTpcbiAgICAgICAgICAgICBlc2xpbnQgY3NzLW1vZHVsZXMvbm8tdW51c2VkLWNsYXNzOiBbMiwgeyBtYXJrQXNVc2VkOiBbJ2NvbnRhaW5lciddIH1dXG4gICAgICAgICAgICovXG4gICAgICAgICAgZm9yIChjb25zdCB1c2VkQ2xhc3Mgb2YgbWFya0FzVXNlZCA/PyBbXSkge1xuICAgICAgICAgICAgY2xhc3Nlc1t1c2VkQ2xhc3NdID0gdHJ1ZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBjbGFzc05hbWVzIG5vdCBtYXJrZWQgYXMgdHJ1ZSBhcmUgdW51c2VkXG4gICAgICAgICAgY29uc3QgdW51c2VkQ2xhc3NlcyA9IGNsYXNzZXMgPyBPYmplY3QuZW50cmllcyhjbGFzc2VzKS5maWx0ZXIoKFtfaywgdl0pID0+ICF2KS5tYXAoKFtrLCBfdl0pID0+IGspIDogW107XG5cbiAgICAgICAgICBpZiAodW51c2VkQ2xhc3Nlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBjb250ZXh0LnJlcG9ydChub2RlLCBgVW51c2VkIGNsYXNzZXMgZm91bmQgaW4gJHtwYXRoLmJhc2VuYW1lKGZpbGVQYXRoKX06ICR7dW51c2VkQ2xhc3Nlcy5qb2luKCcsICcpfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4gIH1cbn07XG4iXSwibWFwcGluZ3MiOiJBQUNBLE9BQU9BLElBQUksTUFBTSxXQUFXO0FBRTVCLFNBQ0VDLHNCQUFzQixFQUN0QkMsZUFBZSxFQUNmQyxlQUFlLEVBQ2ZDLGFBQWEsRUFDYkMsV0FBVyxFQUNYQyxNQUFNLEVBQ05DLFVBQVUsUUFDTCxrQkFBa0I7QUFJekIsZUFBZTtFQUNiQyxJQUFJLEVBQUU7SUFDSkMsSUFBSSxFQUFFO01BQ0pDLFdBQVcsRUFBRSxxREFBcUQ7TUFDbEVDLFdBQVcsRUFBRTtJQUNmLENBQUM7SUFDREMsTUFBTSxFQUFFLENBQ047TUFDRUMsSUFBSSxFQUFFLFFBQVE7TUFDZEMsVUFBVSxFQUFFO1FBQ1ZDLFNBQVMsRUFBRTtVQUFFQyxJQUFJLEVBQUUsQ0FBQyxJQUFJLEVBQUUsUUFBUSxF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
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
|
|
2
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6W10sInNvdXJjZXMiOlsiLi4vLi4vbGliL3R5cGVzL2luZGV4LmpzIl0sInNvdXJjZXNDb250ZW50IjpbIi8vIGpzIE5vZGVcbmV4cG9ydCB0eXBlIFBvc2l0aW9uID0ge1xuICBsaW5lOiBudW1iZXIsIC8vIDEgaW5kZXhlZFxuICBjb2x1bW46IG51bWJlciwgLy8gMCBpbmRleGVkXG59O1xuXG5leHBvcnQgdHlwZSBTb3VyY2VMb2NhdGlvbiA9IHtcbiAgc3RhcnQ6IFBvc2l0aW9uLFxuICBlbmQ6IFBvc2l0aW9uLFxuICBpZGVudGlmaWVyTmFtZT86IHN0cmluZyxcbn07XG5cbmV4cG9ydCB0eXBlIEpzTm9kZSA9IHtcbiAgdHlwZTogJ0ltcG9ydERlY2xhcmF0aW9uJyB8ICdJbXBvcnREZWZhdWx0U3BlY2lmaWVyJyxcbiAgc3RhcnQ6IG51bWJlcixcbiAgZW5kOiBudW1iZXIsXG4gIGxvYzogSnNOb2RlLFxuICBsb2NhbD86IEpzTm9kZSxcbiAgbmFtZT86IHN0cmluZyxcbiAgdmFsdWU/OiBzdHJpbmcsXG4gIHNwZWNpZmllcnM/OiBBcnJheTxKc05vZGU+LFxuICBpbXBvcnRLaW5kPzogJ3ZhbHVlJyxcbiAgZXh0cmE/OiB7XG4gICAgcmF3VmFsdWU6IHN0cmluZyxcbiAgICByYXc6IHN0cmluZyxcbiAgfSxcbiAgc291cmNlOiBKc05vZGUsXG4gIHJhbmdlOiBBcnJheTxudW1iZXI+LCAvLyBtb3N0IHByb2JhYmx5IGFycmF5IG9mIDIgbnVtYmVycyA/LFxuICBfYmFiZWxUeXBlOiBzdHJpbmcsXG4gIHBhcmVudDogSnNOb2RlLFxufTtcblxuLy8gZ29uemFsZXMgQVNUIE5vZGUgVHlwZVxuZXhwb3J0IHR5cGUgZ0FTVE5vZGUgPSB7XG4gIHRyYXZlcnNlQnlUeXBlOiBGdW5jdGlvbixcblxuICB0eXBlOiAnc3R5bGVzaGVldCdcbiAgICAgIHwgJ2lkZW50J1xuICAgICAgfCAnY2xhc3MnXG4gICAgICB8ICdzZWxlY3RvcidcbiAgICAgIHwgJ3ZhbHVlJ1xuICAgICAgfCAncHJvcGVydHknXG4gICAgICB8ICdydWxlc2V0J1xuICAgICAgfCAnZXh0ZW5kJ1xuICAgICAgfCAnZGVjbGFyYXRpb24nLFxuICBjb250ZW50OiBzdHJpbmcgfCBBcnJheTxnQVNUTm9kZT4sXG4gIHN5bnRheDogJ2NzcycgfCAnc2NzcycgfCAnbGVzcycsXG59O1xuIl0sIm1hcHBpbmdzIjoiIn0=
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bhollis/eslint-plugin-css-modules",
|
|
3
|
+
"version": "1.0.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
|
+
"type": "module",
|
|
11
|
+
"scripts": {
|
|
12
|
+
"watch": "babel lib -d build --watch",
|
|
13
|
+
"build": "rm -rf build && babel lib -d build",
|
|
14
|
+
"lint": "eslint lib test",
|
|
15
|
+
"test": "npm run build && rm -rf test-out && babel test -d test-out && cp -r test/files test-out/ && node --test test-out/**/*.test.js",
|
|
16
|
+
"my-pre-publish": "npm run test && npm run build",
|
|
17
|
+
"my-publish": "npm run my-pre-publish && yarn publish"
|
|
18
|
+
},
|
|
19
|
+
"engines": {
|
|
20
|
+
"node": ">=20.0.0"
|
|
21
|
+
},
|
|
22
|
+
"keywords": [
|
|
23
|
+
"eslint",
|
|
24
|
+
"eslintplugin",
|
|
25
|
+
"eslint-plugin",
|
|
26
|
+
"css-modules"
|
|
27
|
+
],
|
|
28
|
+
"author": {
|
|
29
|
+
"name": "Atif Afzal",
|
|
30
|
+
"email": "atif5801@gmail.com",
|
|
31
|
+
"url": "http://atfzl.me"
|
|
32
|
+
},
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "git://github.com/bhollis/eslint-plugin-css-modules.git"
|
|
36
|
+
},
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"bugs": {
|
|
39
|
+
"url": "https://github.com/bhollis/eslint-plugin-css-modules/issues"
|
|
40
|
+
},
|
|
41
|
+
"homepage": "https://github.com/bhollis/eslint-plugin-css-modules#readme",
|
|
42
|
+
"peerDependencies": {
|
|
43
|
+
"eslint": ">=2.0.0"
|
|
44
|
+
},
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"@babel/cli": "^7.23.0",
|
|
47
|
+
"@babel/core": "^7.23.0",
|
|
48
|
+
"@babel/eslint-parser": "^7.22.15",
|
|
49
|
+
"@babel/plugin-proposal-export-default-from": "^7.22.17",
|
|
50
|
+
"@babel/plugin-syntax-flow": "^7.22.5",
|
|
51
|
+
"@babel/plugin-transform-flow-strip-types": "^7.22.5",
|
|
52
|
+
"@babel/preset-env": "^7.22.20",
|
|
53
|
+
"@babel/register": "^7.22.15",
|
|
54
|
+
"eslint": "^8.50.0",
|
|
55
|
+
"eslint-config-standard": "^17.1.0",
|
|
56
|
+
"eslint-plugin-import": "^2.28.1",
|
|
57
|
+
"eslint-plugin-n": "^16.1.0",
|
|
58
|
+
"eslint-plugin-promise": "^6.1.1",
|
|
59
|
+
"flow-bin": "^0.36.0",
|
|
60
|
+
"nodemon": "^3.0.1"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"es-toolkit": "^1.42.0",
|
|
64
|
+
"gonzales-pe": "^4.3.0"
|
|
65
|
+
}
|
|
66
|
+
}
|