@hero-design/snowflake-guard 1.2.1 → 1.2.3
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/lib/src/__tests__/parseSource.spec.js +34 -20
- package/lib/src/parseSource.js +29 -17
- package/lib/src/reports/__tests__/reportInlineStyle.spec.js +4 -4
- package/lib/src/reports/constants.d.ts +6 -3
- package/lib/src/reports/constants.js +15 -4
- package/lib/src/reports/reportClassName.d.ts +1 -1
- package/lib/src/reports/reportClassName.js +7 -10
- package/lib/src/reports/reportCustomStyleProperties.d.ts +6 -0
- package/lib/src/reports/reportCustomStyleProperties.js +66 -22
- package/lib/src/reports/reportInlineStyle.d.ts +2 -2
- package/lib/src/reports/reportInlineStyle.js +2 -5
- package/package.json +1 -1
|
@@ -32,67 +32,81 @@ describe('parseSource', () => {
|
|
|
32
32
|
it('reports correct snowflakes', () => {
|
|
33
33
|
const source = fs.readFileSync('./src/__mocks__/sourceSample.tsx', 'utf-8');
|
|
34
34
|
expect((0, parseSource_1.default)(source)).toEqual({
|
|
35
|
-
approvedLocs: [
|
|
36
|
-
classNameLocs: [
|
|
37
|
-
styleLocs: [
|
|
38
|
-
styledComponentLocs: [6,
|
|
39
|
-
sxLocs: [
|
|
35
|
+
approvedLocs: [60, 78, 85, 92, 70, 80, 10],
|
|
36
|
+
classNameLocs: [49, 47, 48],
|
|
37
|
+
styleLocs: [59, 73, 87, 52, 54, 55, 56, 57, 58],
|
|
38
|
+
styledComponentLocs: [6, 15, 20],
|
|
39
|
+
sxLocs: [69, 94, 64, 65, 66, 67, 68],
|
|
40
40
|
violatingAttributes: [
|
|
41
41
|
{
|
|
42
42
|
attributeName: 'padding',
|
|
43
43
|
attributeValue: '20',
|
|
44
44
|
componentName: 'Button.Link',
|
|
45
45
|
inlineStyleProps: 'style',
|
|
46
|
-
loc:
|
|
46
|
+
loc: 59,
|
|
47
47
|
},
|
|
48
48
|
{
|
|
49
49
|
attributeName: 'padding',
|
|
50
50
|
attributeValue: '20',
|
|
51
51
|
componentName: 'Button.Link',
|
|
52
52
|
inlineStyleProps: 'sx',
|
|
53
|
-
loc:
|
|
53
|
+
loc: 69,
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
attributeName: 'padding',
|
|
57
57
|
attributeValue: '20',
|
|
58
58
|
componentName: 'Button.Link',
|
|
59
59
|
inlineStyleProps: 'style',
|
|
60
|
-
loc:
|
|
60
|
+
loc: 73,
|
|
61
61
|
},
|
|
62
62
|
{
|
|
63
63
|
attributeName: 'backgroundColor',
|
|
64
64
|
attributeValue: "'red'",
|
|
65
65
|
componentName: 'Button.Link',
|
|
66
66
|
inlineStyleProps: 'style',
|
|
67
|
-
loc:
|
|
67
|
+
loc: 73,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
attributeName: 'padding',
|
|
71
|
+
attributeValue: '20',
|
|
72
|
+
componentName: 'Button.Link',
|
|
73
|
+
inlineStyleProps: 'style',
|
|
74
|
+
loc: 87,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
attributeName: 'backgroundColor',
|
|
78
|
+
attributeValue: "'red'",
|
|
79
|
+
componentName: 'Button.Link',
|
|
80
|
+
inlineStyleProps: 'sx',
|
|
81
|
+
loc: 94,
|
|
68
82
|
},
|
|
69
83
|
{
|
|
70
84
|
attributeName: 'width',
|
|
71
85
|
attributeValue: '200',
|
|
72
86
|
componentName: 'Empty',
|
|
73
87
|
inlineStyleProps: 'style',
|
|
74
|
-
loc:
|
|
88
|
+
loc: 52,
|
|
75
89
|
},
|
|
76
90
|
{
|
|
77
91
|
attributeName: 'width',
|
|
78
92
|
attributeValue: '200',
|
|
79
93
|
componentName: 'Card.Header',
|
|
80
94
|
inlineStyleProps: 'style',
|
|
81
|
-
loc:
|
|
95
|
+
loc: 54,
|
|
82
96
|
},
|
|
83
97
|
{
|
|
84
98
|
attributeName: 'padding',
|
|
85
99
|
attributeValue: '30',
|
|
86
100
|
componentName: 'Button',
|
|
87
101
|
inlineStyleProps: 'style',
|
|
88
|
-
loc:
|
|
102
|
+
loc: 55,
|
|
89
103
|
},
|
|
90
104
|
{
|
|
91
105
|
attributeName: 'padding',
|
|
92
106
|
attributeValue: '30',
|
|
93
107
|
componentName: 'Button',
|
|
94
108
|
inlineStyleProps: 'style',
|
|
95
|
-
loc:
|
|
109
|
+
loc: 56,
|
|
96
110
|
additionalProps: [
|
|
97
111
|
{
|
|
98
112
|
propName: 'variant',
|
|
@@ -105,49 +119,49 @@ describe('parseSource', () => {
|
|
|
105
119
|
attributeValue: '30',
|
|
106
120
|
componentName: 'Button',
|
|
107
121
|
inlineStyleProps: 'style',
|
|
108
|
-
loc:
|
|
122
|
+
loc: 57,
|
|
109
123
|
},
|
|
110
124
|
{
|
|
111
125
|
attributeName: 'padding',
|
|
112
126
|
attributeValue: '30',
|
|
113
127
|
componentName: 'Button',
|
|
114
128
|
inlineStyleProps: 'style',
|
|
115
|
-
loc:
|
|
129
|
+
loc: 58,
|
|
116
130
|
},
|
|
117
131
|
{
|
|
118
132
|
attributeName: 'mt',
|
|
119
133
|
attributeValue: '10',
|
|
120
134
|
componentName: 'Badge.Count',
|
|
121
135
|
inlineStyleProps: 'sx',
|
|
122
|
-
loc:
|
|
136
|
+
loc: 64,
|
|
123
137
|
},
|
|
124
138
|
{
|
|
125
139
|
attributeName: 'pt',
|
|
126
140
|
attributeValue: '10',
|
|
127
141
|
componentName: 'Badge',
|
|
128
142
|
inlineStyleProps: 'sx',
|
|
129
|
-
loc:
|
|
143
|
+
loc: 65,
|
|
130
144
|
},
|
|
131
145
|
{
|
|
132
146
|
attributeName: 'pt',
|
|
133
147
|
attributeValue: '10',
|
|
134
148
|
componentName: 'Badge',
|
|
135
149
|
inlineStyleProps: 'sx',
|
|
136
|
-
loc:
|
|
150
|
+
loc: 66,
|
|
137
151
|
},
|
|
138
152
|
{
|
|
139
153
|
attributeName: 'pt',
|
|
140
154
|
attributeValue: '10',
|
|
141
155
|
componentName: 'Badge',
|
|
142
156
|
inlineStyleProps: 'sx',
|
|
143
|
-
loc:
|
|
157
|
+
loc: 67,
|
|
144
158
|
},
|
|
145
159
|
{
|
|
146
160
|
attributeName: 'pt',
|
|
147
161
|
attributeValue: '10',
|
|
148
162
|
componentName: 'Badge',
|
|
149
163
|
inlineStyleProps: 'sx',
|
|
150
|
-
loc:
|
|
164
|
+
loc: 68,
|
|
151
165
|
},
|
|
152
166
|
],
|
|
153
167
|
});
|
package/lib/src/parseSource.js
CHANGED
|
@@ -41,8 +41,9 @@ const parseSource = (source) => {
|
|
|
41
41
|
let styleLocs = [];
|
|
42
42
|
let sxLocs = [];
|
|
43
43
|
let violatingAttributes = [];
|
|
44
|
-
const
|
|
44
|
+
const approvedInlineStyleCmts = [];
|
|
45
45
|
const approvedClassnameLocs = [];
|
|
46
|
+
const approvedStyledComponentLocs = [];
|
|
46
47
|
const ast = recast.parse(source, { parser: tsParser });
|
|
47
48
|
recast.visit(ast, {
|
|
48
49
|
visitImportDeclaration(path) {
|
|
@@ -75,41 +76,52 @@ const parseSource = (source) => {
|
|
|
75
76
|
visitComment(path) {
|
|
76
77
|
this.traverse(path);
|
|
77
78
|
const comment = path.value.value;
|
|
78
|
-
if (comment
|
|
79
|
-
|
|
79
|
+
if (comment
|
|
80
|
+
.toLowerCase()
|
|
81
|
+
.includes(constants_1.APPROVED_INLINE_STYLE_COMMENT.toLowerCase())) {
|
|
82
|
+
approvedInlineStyleCmts.push({
|
|
83
|
+
loc: path.value.loc.start.line,
|
|
84
|
+
comment,
|
|
85
|
+
});
|
|
80
86
|
}
|
|
81
87
|
if (comment.toLowerCase().includes(constants_1.APPROVED_CLASSNAME_COMMENT.toLowerCase())) {
|
|
82
88
|
approvedClassnameLocs.push(path.value.loc.start.line);
|
|
83
89
|
}
|
|
90
|
+
if (comment
|
|
91
|
+
.toLowerCase()
|
|
92
|
+
.includes(constants_1.APPROVED_STYLED_COMPONENTS_COMMENT.toLowerCase())) {
|
|
93
|
+
approvedStyledComponentLocs.push(path.value.loc.start.line);
|
|
94
|
+
}
|
|
84
95
|
},
|
|
85
96
|
});
|
|
86
|
-
const
|
|
87
|
-
const isNotApprovedClassnameSnowflakes = (loc) => !approvedClassnameLocs.includes(loc);
|
|
97
|
+
const isNotApprovedStyledComponentSnowflakes = (loc) => !approvedStyledComponentLocs.includes(loc - 1);
|
|
88
98
|
if (hasHeroDesignImport) {
|
|
89
99
|
// Case 1: Using className to customise components
|
|
90
100
|
// Case 2: Using style object to customise components
|
|
91
101
|
// Case 3: Using sx object to customise components
|
|
92
|
-
const customPropLocs = (0, reportCustomStyleProperties_1.default)(ast, componentList
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
const customPropLocs = (0, reportCustomStyleProperties_1.default)(ast, componentList, {
|
|
103
|
+
classNameCmts: approvedClassnameLocs,
|
|
104
|
+
styleCmts: approvedInlineStyleCmts,
|
|
105
|
+
});
|
|
106
|
+
classNameLocs = customPropLocs.className;
|
|
107
|
+
styleLocs = customPropLocs.style;
|
|
108
|
+
sxLocs = customPropLocs.sx;
|
|
96
109
|
// Case 4: Using styled-components to customise components
|
|
97
110
|
if (hasStyledComponentsImport) {
|
|
98
|
-
styledComponentLocs = (0, reportStyledComponents_1.default)(ast, componentList, styledAliasName).filter(
|
|
111
|
+
styledComponentLocs = (0, reportStyledComponents_1.default)(ast, componentList, styledAliasName).filter(isNotApprovedStyledComponentSnowflakes);
|
|
99
112
|
}
|
|
100
|
-
violatingAttributes = customPropLocs.violatingAttributes
|
|
101
|
-
if (report.loc) {
|
|
102
|
-
return !approvedCmtLocs.includes(report.loc);
|
|
103
|
-
}
|
|
104
|
-
return true;
|
|
105
|
-
});
|
|
113
|
+
violatingAttributes = customPropLocs.violatingAttributes;
|
|
106
114
|
}
|
|
107
115
|
return {
|
|
108
116
|
classNameLocs,
|
|
109
117
|
styleLocs,
|
|
110
118
|
sxLocs,
|
|
111
119
|
styledComponentLocs,
|
|
112
|
-
approvedLocs: [
|
|
120
|
+
approvedLocs: [
|
|
121
|
+
...approvedInlineStyleCmts.map((cmt) => cmt.loc),
|
|
122
|
+
...approvedClassnameLocs,
|
|
123
|
+
...approvedStyledComponentLocs,
|
|
124
|
+
],
|
|
113
125
|
violatingAttributes,
|
|
114
126
|
};
|
|
115
127
|
};
|
|
@@ -70,8 +70,8 @@ describe('reportInlineStyle', () => {
|
|
|
70
70
|
propName: 'variant',
|
|
71
71
|
},
|
|
72
72
|
]);
|
|
73
|
-
expect(result.locs.style).toEqual(
|
|
74
|
-
expect(result.locs.sx).toEqual(
|
|
73
|
+
expect(result.locs.style).toEqual(3);
|
|
74
|
+
expect(result.locs.sx).toEqual(7);
|
|
75
75
|
expect(result.violatingAttributes).toEqual([
|
|
76
76
|
{
|
|
77
77
|
attributeName: 'color',
|
|
@@ -125,8 +125,8 @@ describe('reportInlineStyle', () => {
|
|
|
125
125
|
constants_1.RULESET_MAP.Card = ['color'];
|
|
126
126
|
constants_1.SX_RULESET_MAP.Card = ['padding'];
|
|
127
127
|
const result = (0, reportInlineStyle_1.default)(ast, attributes, componentName);
|
|
128
|
-
expect(result.locs.style).toEqual(
|
|
129
|
-
expect(result.locs.sx).toEqual(
|
|
128
|
+
expect(result.locs.style).toEqual(undefined);
|
|
129
|
+
expect(result.locs.sx).toEqual(undefined);
|
|
130
130
|
expect(result.violatingAttributes).toEqual([]);
|
|
131
131
|
expect(result.violatingAttributes).toEqual([]);
|
|
132
132
|
});
|
|
@@ -45,6 +45,7 @@ declare const RULESET_MAP: {
|
|
|
45
45
|
Empty: string[];
|
|
46
46
|
'File.DragAndDrop': string[];
|
|
47
47
|
'File.UploadButton': string[];
|
|
48
|
+
'File.UploadIconButton': string[];
|
|
48
49
|
Filters: string[];
|
|
49
50
|
'Filters.Label': string[];
|
|
50
51
|
'Filters.Filter': string[];
|
|
@@ -153,6 +154,7 @@ declare const SX_RULESET_MAP: {
|
|
|
153
154
|
Empty: string[];
|
|
154
155
|
'File.DragAndDrop': string[];
|
|
155
156
|
'File.UploadButton': string[];
|
|
157
|
+
'File.UploadIconButton': string[];
|
|
156
158
|
Filters: string[];
|
|
157
159
|
'Filters.Label': string[];
|
|
158
160
|
'Filters.Filter': string[];
|
|
@@ -215,6 +217,7 @@ declare const SX_RULESET_MAP: {
|
|
|
215
217
|
Widget: string[];
|
|
216
218
|
};
|
|
217
219
|
declare const HD_COMPONENTS: readonly ["Alert", "Badge", "Banner", "Breadcrumb", "Button", "Card", "Carousel", "Chart", "Checkbox", "Chip", "Collapse", "Comment", "ContextPanel", "DatePicker", "Divider", "Dropdown", "Empty", "File", "Filters", "Form", "Grid", "Icon", "InPageNavigation", "Input", "MediaQuery", "Menu", "Modal", "Notification", "PageHeader", "Pagination", "Portal", "Portlet", "Progress", "Radio", "Rate", "Result", "Select", "SelectButton", "SideBar", "Slider", "Spinner", "Statistic", "Steps", "Switch", "Table", "Tabs", "Tag", "TagInput", "TimePicker", "Timeline", "Tooltip", "Typography", "Widget"];
|
|
218
|
-
declare const
|
|
219
|
-
declare const APPROVED_CLASSNAME_COMMENT = "@snowflake-guard/
|
|
220
|
-
|
|
220
|
+
declare const APPROVED_INLINE_STYLE_COMMENT = "@snowflake-guard/approved-inline-style";
|
|
221
|
+
declare const APPROVED_CLASSNAME_COMMENT = "@snowflake-guard/approved-classname";
|
|
222
|
+
declare const APPROVED_STYLED_COMPONENTS_COMMENT = "@snowflake-guard/approved-styled-components";
|
|
223
|
+
export { HD_COMPONENTS, RULESET_MAP, SX_RULESET_MAP, APPROVED_INLINE_STYLE_COMMENT, APPROVED_CLASSNAME_COMMENT, APPROVED_STYLED_COMPONENTS_COMMENT, };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.APPROVED_CLASSNAME_COMMENT = exports.
|
|
3
|
+
exports.APPROVED_STYLED_COMPONENTS_COMMENT = exports.APPROVED_CLASSNAME_COMMENT = exports.APPROVED_INLINE_STYLE_COMMENT = exports.SX_RULESET_MAP = exports.RULESET_MAP = exports.HD_COMPONENTS = void 0;
|
|
4
4
|
const PADDING_ATTRS = [
|
|
5
5
|
'padding',
|
|
6
6
|
'paddingTop',
|
|
@@ -297,6 +297,12 @@ const RULESET_MAP = {
|
|
|
297
297
|
...WIDTH_ATTRS,
|
|
298
298
|
...HEIGHT_ATTRS,
|
|
299
299
|
],
|
|
300
|
+
'File.UploadIconButton': [
|
|
301
|
+
...COMMON_PROHIBITED_ATTRS,
|
|
302
|
+
...SHADOW_ATTRS,
|
|
303
|
+
...WIDTH_ATTRS,
|
|
304
|
+
...HEIGHT_ATTRS,
|
|
305
|
+
],
|
|
300
306
|
Filters: [
|
|
301
307
|
...COMMON_PROHIBITED_ATTRS,
|
|
302
308
|
...SHADOW_ATTRS,
|
|
@@ -675,6 +681,9 @@ const SX_RULESET_MAP = Object.assign(Object.assign({}, RULESET_MAP), { Alert: [.
|
|
|
675
681
|
], 'File.UploadButton': [
|
|
676
682
|
...RULESET_MAP['File.UploadButton'],
|
|
677
683
|
...COMMON_SX_PROHIBITED_ATTRS,
|
|
684
|
+
], 'File.UploadIconButton': [
|
|
685
|
+
...RULESET_MAP['File.UploadIconButton'],
|
|
686
|
+
...COMMON_SX_PROHIBITED_ATTRS,
|
|
678
687
|
], Filters: [...RULESET_MAP.Filters, ...COMMON_SX_PROHIBITED_ATTRS], 'Filters.Label': [
|
|
679
688
|
...RULESET_MAP['Filters.Label'],
|
|
680
689
|
...COMMON_SX_PROHIBITED_ATTRS,
|
|
@@ -849,7 +858,9 @@ const HD_COMPONENTS = [
|
|
|
849
858
|
'Widget',
|
|
850
859
|
];
|
|
851
860
|
exports.HD_COMPONENTS = HD_COMPONENTS;
|
|
852
|
-
const
|
|
853
|
-
exports.
|
|
854
|
-
const APPROVED_CLASSNAME_COMMENT = '@snowflake-guard/
|
|
861
|
+
const APPROVED_INLINE_STYLE_COMMENT = '@snowflake-guard/approved-inline-style';
|
|
862
|
+
exports.APPROVED_INLINE_STYLE_COMMENT = APPROVED_INLINE_STYLE_COMMENT;
|
|
863
|
+
const APPROVED_CLASSNAME_COMMENT = '@snowflake-guard/approved-classname';
|
|
855
864
|
exports.APPROVED_CLASSNAME_COMMENT = APPROVED_CLASSNAME_COMMENT;
|
|
865
|
+
const APPROVED_STYLED_COMPONENTS_COMMENT = '@snowflake-guard/approved-styled-components';
|
|
866
|
+
exports.APPROVED_STYLED_COMPONENTS_COMMENT = APPROVED_STYLED_COMPONENTS_COMMENT;
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const reportClassName = (attributes) => {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
}
|
|
12
|
-
});
|
|
13
|
-
return locs;
|
|
4
|
+
const classNameAttr = attributes.find((attr) => attr.type === 'JSXAttribute' &&
|
|
5
|
+
attr.name.type === 'JSXIdentifier' &&
|
|
6
|
+
attr.name.name === 'className');
|
|
7
|
+
if (classNameAttr && classNameAttr.loc) {
|
|
8
|
+
return classNameAttr.loc.start.line;
|
|
9
|
+
}
|
|
10
|
+
return undefined;
|
|
14
11
|
};
|
|
15
12
|
exports.default = reportClassName;
|
|
@@ -3,6 +3,12 @@ import { AdditionalProp, InlineStyleProps } from './reportInlineStyle';
|
|
|
3
3
|
import type { ComponentName, CompoundComponentName } from './types';
|
|
4
4
|
declare const reportCustomProperties: (ast: recast.types.ASTNode, componentList: {
|
|
5
5
|
[k: string]: "Alert" | "Badge" | "Banner" | "Breadcrumb" | "Button" | "Card" | "Carousel" | "Chart" | "Checkbox" | "Chip" | "Collapse" | "Comment" | "ContextPanel" | "DatePicker" | "Divider" | "Dropdown" | "Empty" | "File" | "Filters" | "Form" | "Grid" | "Icon" | "InPageNavigation" | "Input" | "MediaQuery" | "Menu" | "Modal" | "Notification" | "PageHeader" | "Pagination" | "Portal" | "Portlet" | "Progress" | "Radio" | "Rate" | "Result" | "Select" | "SelectButton" | "SideBar" | "Slider" | "Spinner" | "Statistic" | "Steps" | "Switch" | "Table" | "Tabs" | "Tag" | "TagInput" | "TimePicker" | "Timeline" | "Tooltip" | "Typography" | "Widget";
|
|
6
|
+
}, commentList: {
|
|
7
|
+
classNameCmts: number[];
|
|
8
|
+
styleCmts: {
|
|
9
|
+
loc: number;
|
|
10
|
+
comment: string;
|
|
11
|
+
}[];
|
|
6
12
|
}) => {
|
|
7
13
|
className: number[];
|
|
8
14
|
style: number[];
|
|
@@ -32,7 +32,33 @@ const reportInlineStyle_1 = __importDefault(require("./reportInlineStyle"));
|
|
|
32
32
|
const mapViolatingAttributesAndAdditionalProps = (violatingAttributes, additionalProps) => {
|
|
33
33
|
return violatingAttributes.map((violatingAttribute) => (Object.assign(Object.assign({}, violatingAttribute), (additionalProps && additionalProps.length ? { additionalProps } : {}))));
|
|
34
34
|
};
|
|
35
|
-
const
|
|
35
|
+
const getNonApprovedInlineLocs = (reportedLocs, violatingAttributes, approvedCmts, elementLoc) => {
|
|
36
|
+
var _a, _b;
|
|
37
|
+
const approvedCmt = approvedCmts.find((cmt) => cmt.loc === elementLoc - 1);
|
|
38
|
+
if (approvedCmt) {
|
|
39
|
+
const approvedCmtAttrNames = (_b = (_a = approvedCmt.comment
|
|
40
|
+
.toLowerCase()
|
|
41
|
+
.replace(/\s+/g, '')
|
|
42
|
+
.split('attributes:')[1]) === null || _a === void 0 ? void 0 : _a.split(',')) !== null && _b !== void 0 ? _b : [];
|
|
43
|
+
const noneApprovedStyleAttributes = violatingAttributes.filter((attr) => attr.loc === reportedLocs.style &&
|
|
44
|
+
!approvedCmtAttrNames.includes(attr.attributeName.toLowerCase()));
|
|
45
|
+
const noneApprovedSxAttributes = violatingAttributes.filter((attr) => attr.loc === reportedLocs.sx &&
|
|
46
|
+
!approvedCmtAttrNames.includes(attr.attributeName.toLowerCase()));
|
|
47
|
+
if (noneApprovedStyleAttributes.length > 0 ||
|
|
48
|
+
noneApprovedSxAttributes.length > 0) {
|
|
49
|
+
return {
|
|
50
|
+
reportedLocs,
|
|
51
|
+
noneApprovedAttributes: [
|
|
52
|
+
...noneApprovedStyleAttributes,
|
|
53
|
+
...noneApprovedSxAttributes,
|
|
54
|
+
],
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
return { reportedLocs: {}, noneApprovedAttributes: [] };
|
|
58
|
+
}
|
|
59
|
+
return { reportedLocs, noneApprovedAttributes: violatingAttributes };
|
|
60
|
+
};
|
|
61
|
+
const reportCustomProperties = (ast, componentList, commentList) => {
|
|
36
62
|
const report = {
|
|
37
63
|
className: [],
|
|
38
64
|
style: [],
|
|
@@ -48,16 +74,22 @@ const reportCustomProperties = (ast, componentList) => {
|
|
|
48
74
|
localComponentList.includes(path.value.name.name)) {
|
|
49
75
|
const attributes = path.value
|
|
50
76
|
.attributes;
|
|
77
|
+
const classNameLoc = (0, reportClassName_1.default)(attributes);
|
|
78
|
+
if (classNameLoc &&
|
|
79
|
+
!commentList.classNameCmts.includes(path.value.loc.start.line - 1)) {
|
|
80
|
+
report.className.push(classNameLoc);
|
|
81
|
+
}
|
|
51
82
|
const { locs: styleObjectLocs, violatingAttributes, additionalProps, } = (0, reportInlineStyle_1.default)(ast, attributes, componentList[path.value.name.name]);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
83
|
+
const { reportedLocs, noneApprovedAttributes } = getNonApprovedInlineLocs(styleObjectLocs, violatingAttributes, commentList.styleCmts, path.value.loc.start.line);
|
|
84
|
+
if (reportedLocs.style) {
|
|
85
|
+
report.style.push(reportedLocs.style);
|
|
86
|
+
}
|
|
87
|
+
if (reportedLocs.sx) {
|
|
88
|
+
report.sx.push(reportedLocs.sx);
|
|
89
|
+
}
|
|
58
90
|
report.violatingAttributes = [
|
|
59
91
|
...report.violatingAttributes,
|
|
60
|
-
...mapViolatingAttributesAndAdditionalProps(
|
|
92
|
+
...mapViolatingAttributesAndAdditionalProps(noneApprovedAttributes, additionalProps),
|
|
61
93
|
];
|
|
62
94
|
}
|
|
63
95
|
// Case 2: Custom compound component, e.g. <Card.Header />
|
|
@@ -69,16 +101,22 @@ const reportCustomProperties = (ast, componentList) => {
|
|
|
69
101
|
].join('.');
|
|
70
102
|
const attributes = path.value
|
|
71
103
|
.attributes;
|
|
104
|
+
const classNameLoc = (0, reportClassName_1.default)(attributes);
|
|
105
|
+
if (classNameLoc &&
|
|
106
|
+
!commentList.classNameCmts.includes(path.value.loc.start.line - 1)) {
|
|
107
|
+
report.className.push(classNameLoc);
|
|
108
|
+
}
|
|
72
109
|
const { locs: styleObjectLocs, violatingAttributes, additionalProps, } = (0, reportInlineStyle_1.default)(ast, attributes, compoundComponentName);
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
110
|
+
const { reportedLocs, noneApprovedAttributes } = getNonApprovedInlineLocs(styleObjectLocs, violatingAttributes, commentList.styleCmts, path.value.loc.start.line);
|
|
111
|
+
if (reportedLocs.style) {
|
|
112
|
+
report.style.push(reportedLocs.style);
|
|
113
|
+
}
|
|
114
|
+
if (reportedLocs.sx) {
|
|
115
|
+
report.sx.push(reportedLocs.sx);
|
|
116
|
+
}
|
|
79
117
|
report.violatingAttributes = [
|
|
80
118
|
...report.violatingAttributes,
|
|
81
|
-
...mapViolatingAttributesAndAdditionalProps(
|
|
119
|
+
...mapViolatingAttributesAndAdditionalProps(noneApprovedAttributes, additionalProps),
|
|
82
120
|
];
|
|
83
121
|
}
|
|
84
122
|
},
|
|
@@ -108,16 +146,22 @@ const reportCustomProperties = (ast, componentList) => {
|
|
|
108
146
|
openPath.value.name.name,
|
|
109
147
|
].join('.');
|
|
110
148
|
const { attributes } = openPath.value;
|
|
149
|
+
const classNameLoc = (0, reportClassName_1.default)(attributes);
|
|
150
|
+
if (classNameLoc &&
|
|
151
|
+
!commentList.classNameCmts.includes(openPath.value.loc.start.line - 1)) {
|
|
152
|
+
report.className.push(classNameLoc);
|
|
153
|
+
}
|
|
111
154
|
const { locs: styleObjectLocs, violatingAttributes, additionalProps, } = (0, reportInlineStyle_1.default)(ast, attributes, compoundComponentName);
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
155
|
+
const { reportedLocs, noneApprovedAttributes } = getNonApprovedInlineLocs(styleObjectLocs, violatingAttributes, commentList.styleCmts, openPath.value.loc.start.line);
|
|
156
|
+
if (reportedLocs.style) {
|
|
157
|
+
report.style.push(reportedLocs.style);
|
|
158
|
+
}
|
|
159
|
+
if (reportedLocs.sx) {
|
|
160
|
+
report.sx.push(reportedLocs.sx);
|
|
161
|
+
}
|
|
118
162
|
report.violatingAttributes = [
|
|
119
163
|
...report.violatingAttributes,
|
|
120
|
-
...mapViolatingAttributesAndAdditionalProps(
|
|
164
|
+
...mapViolatingAttributesAndAdditionalProps(noneApprovedAttributes, additionalProps),
|
|
121
165
|
];
|
|
122
166
|
}
|
|
123
167
|
},
|
|
@@ -16,8 +16,8 @@ export type AdditionalProp = {
|
|
|
16
16
|
};
|
|
17
17
|
declare const reportInlineStyle: (ast: recast.types.ASTNode, attributes: recast.types.namedTypes.JSXAttribute[], componentName: CompoundComponentName) => {
|
|
18
18
|
locs: {
|
|
19
|
-
style
|
|
20
|
-
sx
|
|
19
|
+
style?: number | undefined;
|
|
20
|
+
sx?: number | undefined;
|
|
21
21
|
};
|
|
22
22
|
violatingAttributes: ViolatingAttribute[];
|
|
23
23
|
additionalProps: AdditionalProp[];
|
|
@@ -59,10 +59,7 @@ const getPropValue = (attr) => {
|
|
|
59
59
|
return recast.print(attr.value).code;
|
|
60
60
|
};
|
|
61
61
|
const reportInlineStyle = (ast, attributes, componentName) => {
|
|
62
|
-
const locs = {
|
|
63
|
-
style: [],
|
|
64
|
-
sx: [],
|
|
65
|
-
};
|
|
62
|
+
const locs = {};
|
|
66
63
|
const violatingAttributes = [];
|
|
67
64
|
const additionalProps = [];
|
|
68
65
|
let hasCustomStyle = false;
|
|
@@ -223,7 +220,7 @@ const reportInlineStyle = (ast, attributes, componentName) => {
|
|
|
223
220
|
});
|
|
224
221
|
}
|
|
225
222
|
if (hasCustomStyle && attr.loc) {
|
|
226
|
-
locs[styleObjName]
|
|
223
|
+
locs[styleObjName] = attr.loc.start.line;
|
|
227
224
|
}
|
|
228
225
|
}
|
|
229
226
|
});
|