@hero-design/snowflake-guard 1.2.4-alpha.4 → 1.2.4
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 +0 -2
- package/lib/src/index.js +22 -30
- package/lib/src/reports/mobile/constants.d.ts +1 -176
- package/lib/src/reports/mobile/constants.js +18 -59
- package/lib/src/reports/mobile/reportStyledComponents.d.ts +1 -1
- package/lib/src/reports/reportCustomStyleProperties.d.ts +1 -1
- package/lib/src/reports/reportStyledComponents.d.ts +1 -1
- package/package.json +1 -1
- package/lib/src/parseMobileSource.d.ts +0 -15
- package/lib/src/parseMobileSource.js +0 -118
- package/lib/src/parsers/flow.d.ts +0 -3
- package/lib/src/parsers/flow.js +0 -37
- package/lib/src/reports/mobile/__tests__/reportCustomStyleProperties.spec.d.ts +0 -1
- package/lib/src/reports/mobile/__tests__/reportCustomStyleProperties.spec.js +0 -123
- package/lib/src/reports/mobile/__tests__/reportInlineStyle.spec.d.ts +0 -1
- package/lib/src/reports/mobile/__tests__/reportInlineStyle.spec.js +0 -103
- package/lib/src/reports/mobile/reportCustomStyleProperties.d.ts +0 -38
- package/lib/src/reports/mobile/reportCustomStyleProperties.js +0 -155
- package/lib/src/reports/mobile/reportInlineStyle.d.ts +0 -21
- package/lib/src/reports/mobile/reportInlineStyle.js +0 -215
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const reportCustomStyleProperties_1 = __importDefault(require("../reportCustomStyleProperties"));
|
|
7
|
-
const testUtils_1 = require("../testUtils");
|
|
8
|
-
const componentList = {
|
|
9
|
-
Card: 'Card',
|
|
10
|
-
Button: 'Button',
|
|
11
|
-
};
|
|
12
|
-
const commentList = {
|
|
13
|
-
styleCmts: [],
|
|
14
|
-
};
|
|
15
|
-
describe('reportCustomStyleProperties', () => {
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
jest.clearAllMocks();
|
|
18
|
-
});
|
|
19
|
-
it('should detect component with inline styles', () => {
|
|
20
|
-
const source = `const styles = {
|
|
21
|
-
card: {
|
|
22
|
-
padding: 10,
|
|
23
|
-
},
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const App = () => (
|
|
27
|
-
<Card style={styles.card}>Content</Card>
|
|
28
|
-
);
|
|
29
|
-
`;
|
|
30
|
-
const ast = (0, testUtils_1.parseTypeScript)(source);
|
|
31
|
-
const result = (0, reportCustomStyleProperties_1.default)(ast, componentList, commentList);
|
|
32
|
-
expect(result).toEqual({
|
|
33
|
-
style: [8],
|
|
34
|
-
violatingAttributes: [
|
|
35
|
-
{
|
|
36
|
-
attributeName: 'padding',
|
|
37
|
-
attributeValue: '10',
|
|
38
|
-
componentName: 'Card',
|
|
39
|
-
inlineStyleProps: 'style',
|
|
40
|
-
loc: 8,
|
|
41
|
-
},
|
|
42
|
-
],
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
it('should detect compound component with inline styles', () => {
|
|
46
|
-
const source = `const App = () => (
|
|
47
|
-
<Button.Icon style={{ padding: 10 }} />
|
|
48
|
-
);
|
|
49
|
-
`;
|
|
50
|
-
const ast = (0, testUtils_1.parseTypeScript)(source);
|
|
51
|
-
const result = (0, reportCustomStyleProperties_1.default)(ast, componentList, commentList);
|
|
52
|
-
expect(result).toEqual({
|
|
53
|
-
style: [2],
|
|
54
|
-
violatingAttributes: [
|
|
55
|
-
{
|
|
56
|
-
attributeName: 'padding',
|
|
57
|
-
attributeValue: '10',
|
|
58
|
-
componentName: 'Button.Icon',
|
|
59
|
-
inlineStyleProps: 'style',
|
|
60
|
-
loc: 2,
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
it('should detect compound component using spread operator with inline styles', () => {
|
|
66
|
-
const source = `const { Icon } = Button;
|
|
67
|
-
const App = () => (
|
|
68
|
-
<Icon style={{ padding: 10 }} />
|
|
69
|
-
);
|
|
70
|
-
`;
|
|
71
|
-
const ast = (0, testUtils_1.parseTypeScript)(source);
|
|
72
|
-
const result = (0, reportCustomStyleProperties_1.default)(ast, componentList, commentList);
|
|
73
|
-
expect(result).toEqual({
|
|
74
|
-
style: [3],
|
|
75
|
-
violatingAttributes: [
|
|
76
|
-
{
|
|
77
|
-
attributeName: 'padding',
|
|
78
|
-
attributeValue: '10',
|
|
79
|
-
componentName: 'Button.Icon',
|
|
80
|
-
inlineStyleProps: 'style',
|
|
81
|
-
loc: 3,
|
|
82
|
-
},
|
|
83
|
-
],
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
it('should not detect non-custom style properties', () => {
|
|
87
|
-
const source = `
|
|
88
|
-
const App = () => (
|
|
89
|
-
<Card>Content</Card>
|
|
90
|
-
);
|
|
91
|
-
`;
|
|
92
|
-
const ast = (0, testUtils_1.parseTypeScript)(source);
|
|
93
|
-
const result = (0, reportCustomStyleProperties_1.default)(ast, componentList, commentList);
|
|
94
|
-
expect(result).toEqual({ style: [], violatingAttributes: [] });
|
|
95
|
-
});
|
|
96
|
-
it('should ignore approved inline styles', () => {
|
|
97
|
-
const mockedCommentList = {
|
|
98
|
-
styleCmts: [
|
|
99
|
-
{
|
|
100
|
-
loc: 10,
|
|
101
|
-
comment: '@snowflake-guard/approved-inline-style attributes: padding',
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
};
|
|
105
|
-
const source = `
|
|
106
|
-
const styles = {
|
|
107
|
-
button: {
|
|
108
|
-
padding: 10,
|
|
109
|
-
},
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const App = () => (
|
|
113
|
-
<>
|
|
114
|
-
{/* @snowflake-guard/approved-inline-style attributes: padding */}
|
|
115
|
-
<Button style={styles.button} />
|
|
116
|
-
</>
|
|
117
|
-
);
|
|
118
|
-
`;
|
|
119
|
-
const ast = (0, testUtils_1.parseTypeScript)(source);
|
|
120
|
-
const result = (0, reportCustomStyleProperties_1.default)(ast, componentList, mockedCommentList);
|
|
121
|
-
expect(result).toEqual({ style: [], violatingAttributes: [] });
|
|
122
|
-
});
|
|
123
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
const recast = __importStar(require("recast"));
|
|
30
|
-
const reportInlineStyle_1 = __importDefault(require("../reportInlineStyle"));
|
|
31
|
-
const constants_1 = require("../constants");
|
|
32
|
-
const tsParser = __importStar(require("../../../parsers/typescript"));
|
|
33
|
-
describe('reportInlineStyle', () => {
|
|
34
|
-
it('should return line numbers and violating attributes for inline styles that violate the ruleset', () => {
|
|
35
|
-
const code = `
|
|
36
|
-
const MyComponent = () => (
|
|
37
|
-
<Card style={{
|
|
38
|
-
color: 'red',
|
|
39
|
-
backgroundColor: 'blue'
|
|
40
|
-
}}
|
|
41
|
-
/>
|
|
42
|
-
);
|
|
43
|
-
`;
|
|
44
|
-
// Step 1: Parse the code to generate the AST
|
|
45
|
-
const ast = recast.parse(code, { parser: tsParser });
|
|
46
|
-
const attributes = [];
|
|
47
|
-
// Step 2: Traverse the AST to extract relevant JSXAttributes (style)
|
|
48
|
-
recast.visit(ast, {
|
|
49
|
-
visitJSXAttribute(path) {
|
|
50
|
-
const { node } = path;
|
|
51
|
-
attributes.push(node);
|
|
52
|
-
this.traverse(path);
|
|
53
|
-
},
|
|
54
|
-
});
|
|
55
|
-
const componentName = 'Card';
|
|
56
|
-
// Mock the RULESET_MAP for this test
|
|
57
|
-
constants_1.MOBILE_RULESET_MAP.Card = ['color', 'backgroundColor'];
|
|
58
|
-
// Step 3: Run the function with the dynamically extracted attributes
|
|
59
|
-
const result = (0, reportInlineStyle_1.default)(ast, attributes, componentName);
|
|
60
|
-
expect(result.locs.style).toEqual(3);
|
|
61
|
-
expect(result.violatingAttributes).toEqual([
|
|
62
|
-
{
|
|
63
|
-
attributeName: 'color',
|
|
64
|
-
attributeValue: "'red'",
|
|
65
|
-
componentName: 'Card',
|
|
66
|
-
inlineStyleProps: 'style',
|
|
67
|
-
loc: 3,
|
|
68
|
-
},
|
|
69
|
-
{
|
|
70
|
-
attributeName: 'backgroundColor',
|
|
71
|
-
attributeValue: "'blue'",
|
|
72
|
-
componentName: 'Card',
|
|
73
|
-
inlineStyleProps: 'style',
|
|
74
|
-
loc: 3,
|
|
75
|
-
},
|
|
76
|
-
]);
|
|
77
|
-
});
|
|
78
|
-
it('should return empty arrays when no violations are found', () => {
|
|
79
|
-
const code = `
|
|
80
|
-
const MyComponent = () => (
|
|
81
|
-
<Card style={{ margin: 10 }} />
|
|
82
|
-
);
|
|
83
|
-
`;
|
|
84
|
-
// Step 1: Parse the code to generate the AST
|
|
85
|
-
const ast = recast.parse(code, { parser: tsParser });
|
|
86
|
-
const attributes = [];
|
|
87
|
-
// Step 2: Traverse the AST to extract relevant JSXAttributes (style)
|
|
88
|
-
recast.visit(ast, {
|
|
89
|
-
visitJSXAttribute(path) {
|
|
90
|
-
const { node } = path;
|
|
91
|
-
attributes.push(node);
|
|
92
|
-
this.traverse(path);
|
|
93
|
-
},
|
|
94
|
-
});
|
|
95
|
-
const componentName = 'Card';
|
|
96
|
-
// Mock the RULESET_MAP and SX_RULESET_MAP for this test
|
|
97
|
-
constants_1.MOBILE_RULESET_MAP.Card = ['color'];
|
|
98
|
-
const result = (0, reportInlineStyle_1.default)(ast, attributes, componentName);
|
|
99
|
-
expect(result.locs.style).toEqual(undefined);
|
|
100
|
-
expect(result.violatingAttributes).toEqual([]);
|
|
101
|
-
expect(result.violatingAttributes).toEqual([]);
|
|
102
|
-
});
|
|
103
|
-
});
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import * as recast from 'recast';
|
|
2
|
-
import { InlineStyleProps, ViolatingAttribute } from './reportInlineStyle';
|
|
3
|
-
import type { CompoundMobileComponentName, MobileComponentName } from './types';
|
|
4
|
-
export declare const getNonApprovedInlineLocs: (reportedLocs: {
|
|
5
|
-
style?: number;
|
|
6
|
-
barStyle?: number;
|
|
7
|
-
containerStyle?: number;
|
|
8
|
-
textStyle?: number;
|
|
9
|
-
}, violatingAttributes: ViolatingAttribute[], approvedCmts: {
|
|
10
|
-
loc: number;
|
|
11
|
-
comment: string;
|
|
12
|
-
}[], elementLoc: number) => {
|
|
13
|
-
reportedLocs: {
|
|
14
|
-
style?: number | undefined;
|
|
15
|
-
barStyle?: number | undefined;
|
|
16
|
-
containerStyle?: number | undefined;
|
|
17
|
-
textStyle?: number | undefined;
|
|
18
|
-
};
|
|
19
|
-
noneApprovedAttributes: ViolatingAttribute[];
|
|
20
|
-
};
|
|
21
|
-
declare const reportCustomProperties: (ast: recast.types.ASTNode, componentList: {
|
|
22
|
-
[k: string]: "Accordion" | "Alert" | "Attachment" | "Avatar" | "Badge" | "BottomNavigation" | "BottomSheet" | "Box" | "Button" | "Calendar" | "Carousel" | "Card" | "Chip" | "Collapse" | "Checkbox" | "ContentNavigator" | "DatePicker" | "Divider" | "Drawer" | "Empty" | "Error" | "FAB" | "HeroDesignProvider" | "MapPin" | "Icon" | "Image" | "List" | "PinInput" | "Progress" | "Slider" | "Spinner" | "Swipeable" | "Radio" | "SectionHeading" | "Select" | "Skeleton" | "Success" | "Switch" | "Tabs" | "Tag" | "TextInput" | "TimePicker" | "Toast" | "Toolbar" | "Typography" | "Rate" | "RefreshControl" | "RichTextEditor" | "PageControl" | "Portal" | "ScrollViewWithFAB" | "SectionListWithFAB" | "FlatListWithFAB" | "Search" | "FloatingIsland";
|
|
23
|
-
}, commentList: {
|
|
24
|
-
styleCmts: {
|
|
25
|
-
loc: number;
|
|
26
|
-
comment: string;
|
|
27
|
-
}[];
|
|
28
|
-
}) => {
|
|
29
|
-
style: number[];
|
|
30
|
-
violatingAttributes: {
|
|
31
|
-
attributeName: string;
|
|
32
|
-
attributeValue: string | null;
|
|
33
|
-
inlineStyleProps: InlineStyleProps;
|
|
34
|
-
componentName: CompoundMobileComponentName;
|
|
35
|
-
loc: number | undefined;
|
|
36
|
-
}[];
|
|
37
|
-
};
|
|
38
|
-
export default reportCustomProperties;
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.getNonApprovedInlineLocs = void 0;
|
|
30
|
-
const recast = __importStar(require("recast"));
|
|
31
|
-
const reportInlineStyle_1 = __importDefault(require("./reportInlineStyle"));
|
|
32
|
-
const mapViolatingAttributesAndAdditionalProps = (violatingAttributes) => {
|
|
33
|
-
return violatingAttributes.map((violatingAttribute) => (Object.assign({}, violatingAttribute)));
|
|
34
|
-
};
|
|
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 nonApprovedBarStyleAttributes = violatingAttributes.filter((attr) => attr.loc === reportedLocs.barStyle &&
|
|
46
|
-
!approvedCmtAttrNames.includes(attr.attributeName.toLowerCase()));
|
|
47
|
-
const nonApprovedContainerStyleAttributes = violatingAttributes.filter((attr) => attr.loc === reportedLocs.containerStyle &&
|
|
48
|
-
!approvedCmtAttrNames.includes(attr.attributeName.toLowerCase()));
|
|
49
|
-
const nonApprovedTextStyleAttributes = violatingAttributes.filter((attr) => attr.loc === reportedLocs.textStyle &&
|
|
50
|
-
!approvedCmtAttrNames.includes(attr.attributeName.toLowerCase()));
|
|
51
|
-
if (noneApprovedStyleAttributes.length > 0) {
|
|
52
|
-
return {
|
|
53
|
-
reportedLocs,
|
|
54
|
-
noneApprovedAttributes: [
|
|
55
|
-
...noneApprovedStyleAttributes,
|
|
56
|
-
...nonApprovedBarStyleAttributes,
|
|
57
|
-
...nonApprovedContainerStyleAttributes,
|
|
58
|
-
...nonApprovedTextStyleAttributes,
|
|
59
|
-
],
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
return { reportedLocs: {}, noneApprovedAttributes: [] };
|
|
63
|
-
}
|
|
64
|
-
return { reportedLocs, noneApprovedAttributes: violatingAttributes };
|
|
65
|
-
};
|
|
66
|
-
exports.getNonApprovedInlineLocs = getNonApprovedInlineLocs;
|
|
67
|
-
const reportCustomProperties = (ast, componentList, commentList) => {
|
|
68
|
-
const report = {
|
|
69
|
-
style: [],
|
|
70
|
-
violatingAttributes: [],
|
|
71
|
-
};
|
|
72
|
-
const localComponentList = Object.keys(componentList);
|
|
73
|
-
recast.visit(ast, {
|
|
74
|
-
visitJSXOpeningElement(path) {
|
|
75
|
-
this.traverse(path);
|
|
76
|
-
// Case 1: Custom default component, e.g. <Card />
|
|
77
|
-
if (path.value.name.type === 'JSXIdentifier' &&
|
|
78
|
-
localComponentList.includes(path.value.name.name)) {
|
|
79
|
-
const attributes = path.value
|
|
80
|
-
.attributes;
|
|
81
|
-
const { locs: styleObjectLocs, violatingAttributes } = (0, reportInlineStyle_1.default)(ast, attributes, componentList[path.value.name.name]);
|
|
82
|
-
const { reportedLocs, noneApprovedAttributes } = (0, exports.getNonApprovedInlineLocs)(styleObjectLocs, violatingAttributes, commentList.styleCmts, path.value.loc.start.line);
|
|
83
|
-
if (reportedLocs.style) {
|
|
84
|
-
report.style.push(reportedLocs.style);
|
|
85
|
-
}
|
|
86
|
-
report.violatingAttributes = [
|
|
87
|
-
...report.violatingAttributes,
|
|
88
|
-
...mapViolatingAttributesAndAdditionalProps(noneApprovedAttributes),
|
|
89
|
-
];
|
|
90
|
-
}
|
|
91
|
-
// Case 2: Custom compound component, e.g. <Card.Header />
|
|
92
|
-
if (path.value.name.type === 'JSXMemberExpression' &&
|
|
93
|
-
localComponentList.includes(path.value.name.object.name)) {
|
|
94
|
-
const compoundComponentName = [
|
|
95
|
-
componentList[path.value.name.object.name],
|
|
96
|
-
path.value.name.property.name,
|
|
97
|
-
].join('.');
|
|
98
|
-
const attributes = path.value
|
|
99
|
-
.attributes;
|
|
100
|
-
const { locs: styleObjectLocs, violatingAttributes } = (0, reportInlineStyle_1.default)(ast, attributes, compoundComponentName);
|
|
101
|
-
const { reportedLocs, noneApprovedAttributes } = (0, exports.getNonApprovedInlineLocs)(styleObjectLocs, violatingAttributes, commentList.styleCmts, path.value.loc.start.line);
|
|
102
|
-
if (reportedLocs.style) {
|
|
103
|
-
report.style.push(reportedLocs.style);
|
|
104
|
-
}
|
|
105
|
-
report.violatingAttributes = [
|
|
106
|
-
...report.violatingAttributes,
|
|
107
|
-
...mapViolatingAttributesAndAdditionalProps(noneApprovedAttributes),
|
|
108
|
-
];
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
// Case 3: Custom compound component with spead operator. e.g. const { Header } = Card, then <Header />
|
|
112
|
-
visitVariableDeclaration(path) {
|
|
113
|
-
this.traverse(path);
|
|
114
|
-
const declaration = path.value
|
|
115
|
-
.declarations[0];
|
|
116
|
-
if (declaration.init &&
|
|
117
|
-
declaration.init.type === 'Identifier' &&
|
|
118
|
-
localComponentList.includes(declaration.init.name)) {
|
|
119
|
-
const componentName = declaration.init.name;
|
|
120
|
-
const { id } = declaration;
|
|
121
|
-
if (id.type === 'ObjectPattern') {
|
|
122
|
-
const compoundComponentNames = id.properties
|
|
123
|
-
.map((prop) => prop.type === 'ObjectProperty' && prop.key.type === 'Identifier'
|
|
124
|
-
? prop.key.name
|
|
125
|
-
: null)
|
|
126
|
-
.filter((name) => name !== null);
|
|
127
|
-
recast.visit(ast, {
|
|
128
|
-
visitJSXOpeningElement(openPath) {
|
|
129
|
-
this.traverse(openPath);
|
|
130
|
-
if (openPath.value.name.type === 'JSXIdentifier' &&
|
|
131
|
-
compoundComponentNames.includes(openPath.value.name.name)) {
|
|
132
|
-
const compoundComponentName = [
|
|
133
|
-
componentList[componentName],
|
|
134
|
-
openPath.value.name.name,
|
|
135
|
-
].join('.');
|
|
136
|
-
const { attributes } = openPath.value;
|
|
137
|
-
const { locs: styleObjectLocs, violatingAttributes } = (0, reportInlineStyle_1.default)(ast, attributes, compoundComponentName);
|
|
138
|
-
const { reportedLocs, noneApprovedAttributes } = (0, exports.getNonApprovedInlineLocs)(styleObjectLocs, violatingAttributes, commentList.styleCmts, openPath.value.loc.start.line);
|
|
139
|
-
if (reportedLocs.style) {
|
|
140
|
-
report.style.push(reportedLocs.style);
|
|
141
|
-
}
|
|
142
|
-
report.violatingAttributes = [
|
|
143
|
-
...report.violatingAttributes,
|
|
144
|
-
...mapViolatingAttributesAndAdditionalProps(noneApprovedAttributes),
|
|
145
|
-
];
|
|
146
|
-
}
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
return report;
|
|
154
|
-
};
|
|
155
|
-
exports.default = reportCustomProperties;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import * as recast from 'recast';
|
|
2
|
-
import type { CompoundMobileComponentName } from './types';
|
|
3
|
-
export type InlineStyleProps = 'style' | 'barStyle' | 'containerStyle' | 'textStyle';
|
|
4
|
-
export declare const INLINE_STYLE_PROPERTIES: string[];
|
|
5
|
-
export type ViolatingAttribute = {
|
|
6
|
-
attributeName: string;
|
|
7
|
-
attributeValue: string | null;
|
|
8
|
-
inlineStyleProps: InlineStyleProps;
|
|
9
|
-
componentName: CompoundMobileComponentName;
|
|
10
|
-
loc: number | undefined;
|
|
11
|
-
};
|
|
12
|
-
declare const reportInlineStyle: (ast: recast.types.ASTNode, attributes: recast.types.namedTypes.JSXAttribute[], componentName: CompoundMobileComponentName) => {
|
|
13
|
-
locs: {
|
|
14
|
-
style?: number | undefined;
|
|
15
|
-
barStyle?: number | undefined;
|
|
16
|
-
containerStyle?: number | undefined;
|
|
17
|
-
textStyle?: number | undefined;
|
|
18
|
-
};
|
|
19
|
-
violatingAttributes: ViolatingAttribute[];
|
|
20
|
-
};
|
|
21
|
-
export default reportInlineStyle;
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.INLINE_STYLE_PROPERTIES = void 0;
|
|
27
|
-
const recast = __importStar(require("recast"));
|
|
28
|
-
const constants_1 = require("./constants");
|
|
29
|
-
const BLACKLIST_PROPERTIES = {
|
|
30
|
-
style: constants_1.MOBILE_RULESET_MAP,
|
|
31
|
-
barStyle: constants_1.BAR_STYLE_RULESET_MAP,
|
|
32
|
-
containerStyle: constants_1.CONTAINER_STYLE_RULESET_MAP,
|
|
33
|
-
textStyle: constants_1.TEXT_STYLE_RULESET_MAP,
|
|
34
|
-
};
|
|
35
|
-
exports.INLINE_STYLE_PROPERTIES = [
|
|
36
|
-
'style',
|
|
37
|
-
'barStyle',
|
|
38
|
-
'containerStyle',
|
|
39
|
-
'textStyle',
|
|
40
|
-
];
|
|
41
|
-
const addViolatingAttribute = (prop, styleObjName, componentName, loc, violatingAttributes) => {
|
|
42
|
-
if (prop.key.type !== 'Identifier') {
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
violatingAttributes.push({
|
|
46
|
-
attributeName: prop.key.name,
|
|
47
|
-
attributeValue: recast.print(prop.value).code,
|
|
48
|
-
inlineStyleProps: styleObjName,
|
|
49
|
-
componentName,
|
|
50
|
-
loc,
|
|
51
|
-
});
|
|
52
|
-
};
|
|
53
|
-
const reportInlineStyle = (ast, attributes, componentName) => {
|
|
54
|
-
const locs = {};
|
|
55
|
-
const violatingAttributes = [];
|
|
56
|
-
let hasCustomStyle = false;
|
|
57
|
-
let styleObjName;
|
|
58
|
-
attributes.forEach((attr) => {
|
|
59
|
-
var _a;
|
|
60
|
-
if (attr.type !== 'JSXAttribute') {
|
|
61
|
-
return;
|
|
62
|
-
}
|
|
63
|
-
if (typeof attr.name.name !== 'string') {
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
if (((_a = attr.value) === null || _a === void 0 ? void 0 : _a.type) !== 'JSXExpressionContainer') {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (exports.INLINE_STYLE_PROPERTIES.includes(attr.name.name)) {
|
|
70
|
-
styleObjName = attr.name.name;
|
|
71
|
-
const PROHIBITED_PROPERTIES = BLACKLIST_PROPERTIES[styleObjName][componentName] || [];
|
|
72
|
-
console.log(PROHIBITED_PROPERTIES);
|
|
73
|
-
const { expression } = attr.value;
|
|
74
|
-
if (expression.type === 'ObjectExpression') {
|
|
75
|
-
expression.properties.forEach((prop) => {
|
|
76
|
-
var _a;
|
|
77
|
-
// Case 1: Use direct object, e.g. <Card style={{ color: 'red' }} />
|
|
78
|
-
if (prop.type === 'ObjectProperty' &&
|
|
79
|
-
prop.key.type === 'Identifier' &&
|
|
80
|
-
PROHIBITED_PROPERTIES.includes(prop.key.name)) {
|
|
81
|
-
hasCustomStyle = true;
|
|
82
|
-
addViolatingAttribute(prop, styleObjName, componentName, (_a = attr.loc) === null || _a === void 0 ? void 0 : _a.start.line, violatingAttributes);
|
|
83
|
-
}
|
|
84
|
-
// Case 2: Use spread operator, e.g. <Card style={{ ...customStyle }} />
|
|
85
|
-
if (prop.type === 'SpreadElement' &&
|
|
86
|
-
prop.argument.type === 'Identifier') {
|
|
87
|
-
const variableName = prop.argument.name;
|
|
88
|
-
recast.visit(ast, {
|
|
89
|
-
visitVariableDeclaration(path) {
|
|
90
|
-
var _a;
|
|
91
|
-
this.traverse(path);
|
|
92
|
-
const declaration = path.value
|
|
93
|
-
.declarations[0];
|
|
94
|
-
if (declaration.id.type === 'Identifier' &&
|
|
95
|
-
declaration.id.name === variableName &&
|
|
96
|
-
((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
|
|
97
|
-
declaration.init.properties.forEach((deProp) => {
|
|
98
|
-
var _a;
|
|
99
|
-
if (deProp.type === 'ObjectProperty' &&
|
|
100
|
-
deProp.key.type === 'Identifier' &&
|
|
101
|
-
PROHIBITED_PROPERTIES.includes(deProp.key.name)) {
|
|
102
|
-
hasCustomStyle = true;
|
|
103
|
-
addViolatingAttribute(deProp, styleObjName, componentName, (_a = attr.loc) === null || _a === void 0 ? void 0 : _a.start.line, violatingAttributes);
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
},
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
// Case 3: Use spread operator with variable's property, e.g. <Card style={{ ...customStyle.tileCard }} />
|
|
111
|
-
if (prop.type === 'SpreadElement' &&
|
|
112
|
-
prop.argument.type === 'MemberExpression' &&
|
|
113
|
-
prop.argument.object.type === 'Identifier' &&
|
|
114
|
-
prop.argument.property.type === 'Identifier') {
|
|
115
|
-
const variableName = prop.argument.object.name;
|
|
116
|
-
const propName = prop.argument.property.name;
|
|
117
|
-
recast.visit(ast, {
|
|
118
|
-
visitVariableDeclaration(path) {
|
|
119
|
-
var _a;
|
|
120
|
-
this.traverse(path);
|
|
121
|
-
const declaration = path.value
|
|
122
|
-
.declarations[0];
|
|
123
|
-
if (declaration.id.type === 'Identifier' &&
|
|
124
|
-
declaration.id.name === variableName &&
|
|
125
|
-
((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
|
|
126
|
-
declaration.init.properties.forEach((deProp) => {
|
|
127
|
-
if (deProp.type === 'ObjectProperty' &&
|
|
128
|
-
deProp.key.type === 'Identifier' &&
|
|
129
|
-
deProp.key.name === propName &&
|
|
130
|
-
deProp.value.type === 'ObjectExpression') {
|
|
131
|
-
deProp.value.properties.forEach((p) => {
|
|
132
|
-
var _a;
|
|
133
|
-
if (p.type === 'ObjectProperty' &&
|
|
134
|
-
p.key.type === 'Identifier' &&
|
|
135
|
-
PROHIBITED_PROPERTIES.includes(p.key.name)) {
|
|
136
|
-
hasCustomStyle = true;
|
|
137
|
-
addViolatingAttribute(p, styleObjName, componentName, (_a = attr.loc) === null || _a === void 0 ? void 0 : _a.start.line, violatingAttributes);
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
},
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
}
|
|
148
|
-
// Case 4: Use variable, e.g. <Card style={customStyle} />
|
|
149
|
-
if (expression.type === 'Identifier') {
|
|
150
|
-
const variableName = expression.name;
|
|
151
|
-
recast.visit(ast, {
|
|
152
|
-
visitVariableDeclaration(path) {
|
|
153
|
-
var _a;
|
|
154
|
-
this.traverse(path);
|
|
155
|
-
const declaration = path.value
|
|
156
|
-
.declarations[0];
|
|
157
|
-
if (declaration.id.type === 'Identifier' &&
|
|
158
|
-
declaration.id.name === variableName &&
|
|
159
|
-
((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
|
|
160
|
-
declaration.init.properties.forEach((prop) => {
|
|
161
|
-
var _a;
|
|
162
|
-
if (prop.type === 'ObjectProperty' &&
|
|
163
|
-
prop.key.type === 'Identifier' &&
|
|
164
|
-
PROHIBITED_PROPERTIES.includes(prop.key.name)) {
|
|
165
|
-
hasCustomStyle = true;
|
|
166
|
-
addViolatingAttribute(prop, styleObjName, componentName, (_a = attr.loc) === null || _a === void 0 ? void 0 : _a.start.line, violatingAttributes);
|
|
167
|
-
}
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
},
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
// Case 5: Use variable's property, e.g. <Card style={customStyle.tileCard} />
|
|
174
|
-
if (expression.type === 'MemberExpression' &&
|
|
175
|
-
expression.object.type === 'Identifier' &&
|
|
176
|
-
expression.property.type === 'Identifier') {
|
|
177
|
-
const objectName = expression.object.name;
|
|
178
|
-
const propName = expression.property.name;
|
|
179
|
-
recast.visit(ast, {
|
|
180
|
-
visitVariableDeclaration(path) {
|
|
181
|
-
var _a;
|
|
182
|
-
this.traverse(path);
|
|
183
|
-
const declaration = path.value
|
|
184
|
-
.declarations[0];
|
|
185
|
-
if (declaration.id.type === 'Identifier' &&
|
|
186
|
-
declaration.id.name === objectName &&
|
|
187
|
-
((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
|
|
188
|
-
declaration.init.properties.forEach((prop) => {
|
|
189
|
-
if (prop.type === 'ObjectProperty' &&
|
|
190
|
-
prop.key.type === 'Identifier' &&
|
|
191
|
-
prop.key.name === propName &&
|
|
192
|
-
prop.value.type === 'ObjectExpression') {
|
|
193
|
-
prop.value.properties.forEach((p) => {
|
|
194
|
-
var _a;
|
|
195
|
-
if (p.type === 'ObjectProperty' &&
|
|
196
|
-
p.key.type === 'Identifier' &&
|
|
197
|
-
PROHIBITED_PROPERTIES.includes(p.key.name)) {
|
|
198
|
-
hasCustomStyle = true;
|
|
199
|
-
addViolatingAttribute(p, styleObjName, componentName, (_a = attr.loc) === null || _a === void 0 ? void 0 : _a.start.line, violatingAttributes);
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
if (hasCustomStyle && attr.loc) {
|
|
209
|
-
locs[styleObjName] = attr.loc.start.line;
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
return { locs, violatingAttributes };
|
|
214
|
-
};
|
|
215
|
-
exports.default = reportInlineStyle;
|