@hero-design/snowflake-guard 1.0.7-alpha0

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.
Files changed (49) hide show
  1. package/.dockerignore +12 -0
  2. package/.env.example +9 -0
  3. package/.eslintrc.js +8 -0
  4. package/CHANGELOG.md +47 -0
  5. package/Dockerfile +8 -0
  6. package/LICENSE +15 -0
  7. package/README.md +33 -0
  8. package/app.yml +137 -0
  9. package/jest.config.js +9 -0
  10. package/lib/netlify/functions/snowflake.d.ts +2 -0
  11. package/lib/netlify/functions/snowflake.js +10 -0
  12. package/lib/src/__mocks__/sourceSample.d.ts +2 -0
  13. package/lib/src/__mocks__/sourceSample.js +27 -0
  14. package/lib/src/__tests__/parseSource.spec.d.ts +1 -0
  15. package/lib/src/__tests__/parseSource.spec.js +41 -0
  16. package/lib/src/index.d.ts +3 -0
  17. package/lib/src/index.js +142 -0
  18. package/lib/src/parseSource.d.ts +7 -0
  19. package/lib/src/parseSource.js +102 -0
  20. package/lib/src/parsers/typescript.d.ts +3 -0
  21. package/lib/src/parsers/typescript.js +37 -0
  22. package/lib/src/reports/constants.d.ts +215 -0
  23. package/lib/src/reports/constants.js +848 -0
  24. package/lib/src/reports/reportClassName.d.ts +3 -0
  25. package/lib/src/reports/reportClassName.js +15 -0
  26. package/lib/src/reports/reportCustomStyleProperties.d.ts +10 -0
  27. package/lib/src/reports/reportCustomStyleProperties.js +109 -0
  28. package/lib/src/reports/reportInlineStyle.d.ts +7 -0
  29. package/lib/src/reports/reportInlineStyle.js +179 -0
  30. package/lib/src/reports/reportStyledComponents.d.ts +6 -0
  31. package/lib/src/reports/reportStyledComponents.js +95 -0
  32. package/lib/src/reports/types.d.ts +3 -0
  33. package/lib/src/reports/types.js +2 -0
  34. package/lib/src/test.tsx +123 -0
  35. package/netlify/functions/snowflake.ts +9 -0
  36. package/netlify.toml +21 -0
  37. package/package.json +44 -0
  38. package/src/__mocks__/sourceSample.tsx +67 -0
  39. package/src/__tests__/parseSource.spec.ts +15 -0
  40. package/src/index.ts +201 -0
  41. package/src/parseSource.ts +97 -0
  42. package/src/parsers/typescript.ts +8 -0
  43. package/src/reports/constants.ts +965 -0
  44. package/src/reports/reportClassName.ts +20 -0
  45. package/src/reports/reportCustomStyleProperties.ts +125 -0
  46. package/src/reports/reportInlineStyle.ts +221 -0
  47. package/src/reports/reportStyledComponents.ts +109 -0
  48. package/src/reports/types.ts +5 -0
  49. package/tsconfig.json +15 -0
@@ -0,0 +1,3 @@
1
+ import { types } from 'recast';
2
+ declare const reportClassName: (attributes: types.namedTypes.JSXAttribute[]) => number[];
3
+ export default reportClassName;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const reportClassName = (attributes) => {
4
+ const locs = [];
5
+ attributes.forEach((attr) => {
6
+ if (attr.type === 'JSXAttribute' &&
7
+ attr.name.type === 'JSXIdentifier' &&
8
+ attr.name.name === 'className' &&
9
+ attr.loc) {
10
+ locs.push(attr.loc.start.line);
11
+ }
12
+ });
13
+ return locs;
14
+ };
15
+ exports.default = reportClassName;
@@ -0,0 +1,10 @@
1
+ import * as recast from 'recast';
2
+ import type { ComponentName } from './types';
3
+ declare const reportCustomProperties: (ast: recast.types.ASTNode, componentList: {
4
+ [k: string]: "Alert" | "Badge" | "Banner" | "Breadcrumb" | "Button" | "Card" | "Carousel" | "Chart" | "Checkbox" | "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";
5
+ }) => {
6
+ className: number[];
7
+ style: number[];
8
+ sx: number[];
9
+ };
10
+ export default reportCustomProperties;
@@ -0,0 +1,109 @@
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 reportClassName_1 = __importDefault(require("./reportClassName"));
31
+ const reportInlineStyle_1 = __importDefault(require("./reportInlineStyle"));
32
+ const reportCustomProperties = (ast, componentList) => {
33
+ const locs = {
34
+ className: [],
35
+ style: [],
36
+ sx: [],
37
+ };
38
+ const localComponentList = Object.keys(componentList);
39
+ recast.visit(ast, {
40
+ visitJSXOpeningElement(path) {
41
+ this.traverse(path);
42
+ // Case 1: Custom default component, e.g. <Card />
43
+ if (path.value.name.type === 'JSXIdentifier' &&
44
+ localComponentList.includes(path.value.name.name)) {
45
+ const attributes = path.value
46
+ .attributes;
47
+ const styleObjectLocs = (0, reportInlineStyle_1.default)(ast, attributes, componentList[path.value.name.name]);
48
+ locs.className = [...locs.className, ...(0, reportClassName_1.default)(attributes)];
49
+ locs.style = [...locs.style, ...styleObjectLocs.style];
50
+ locs.sx = [...locs.sx, ...styleObjectLocs.sx];
51
+ }
52
+ // Case 2: Custom compound component, e.g. <Card.Header />
53
+ if (path.value.name.type === 'JSXMemberExpression' &&
54
+ localComponentList.includes(path.value.name.object.name)) {
55
+ const compoundComponentName = [
56
+ componentList[path.value.name.object.name],
57
+ path.value.name.property.name,
58
+ ].join('.');
59
+ const attributes = path.value
60
+ .attributes;
61
+ const styleObjectLocs = (0, reportInlineStyle_1.default)(ast, attributes, compoundComponentName);
62
+ locs.className = [...locs.className, ...(0, reportClassName_1.default)(attributes)];
63
+ locs.style = [...locs.style, ...styleObjectLocs.style];
64
+ locs.sx = [...locs.sx, ...styleObjectLocs.sx];
65
+ }
66
+ },
67
+ // Case 3: Custom compound component with spead operator. e.g. const { Header } = Card, then <Header />
68
+ visitVariableDeclaration(path) {
69
+ this.traverse(path);
70
+ const declaration = path.value
71
+ .declarations[0];
72
+ if (declaration.init &&
73
+ declaration.init.type === 'Identifier' &&
74
+ localComponentList.includes(declaration.init.name)) {
75
+ const componentName = declaration.init.name;
76
+ const { id } = declaration;
77
+ if (id.type === 'ObjectPattern') {
78
+ const compoundComponentNames = id.properties
79
+ .map((prop) => prop.type === 'ObjectProperty' && prop.key.type === 'Identifier'
80
+ ? prop.key.name
81
+ : null)
82
+ .filter((name) => name !== null);
83
+ recast.visit(ast, {
84
+ visitJSXOpeningElement(openPath) {
85
+ this.traverse(openPath);
86
+ if (openPath.value.name.type === 'JSXIdentifier' &&
87
+ compoundComponentNames.includes(openPath.value.name.name)) {
88
+ const compoundComponentName = [
89
+ componentList[componentName],
90
+ openPath.value.name.name,
91
+ ].join('.');
92
+ const { attributes } = openPath.value;
93
+ const styleObjectLocs = (0, reportInlineStyle_1.default)(ast, attributes, compoundComponentName);
94
+ locs.className = [
95
+ ...locs.className,
96
+ ...(0, reportClassName_1.default)(attributes),
97
+ ];
98
+ locs.style = [...locs.style, ...styleObjectLocs.style];
99
+ locs.sx = [...locs.sx, ...styleObjectLocs.sx];
100
+ }
101
+ },
102
+ });
103
+ }
104
+ }
105
+ },
106
+ });
107
+ return locs;
108
+ };
109
+ exports.default = reportCustomProperties;
@@ -0,0 +1,7 @@
1
+ import * as recast from 'recast';
2
+ import type { CompoundComponentName } from './types';
3
+ declare const reportInlineStyle: (ast: recast.types.ASTNode, attributes: recast.types.namedTypes.JSXAttribute[], componentName: CompoundComponentName) => {
4
+ style: number[];
5
+ sx: number[];
6
+ };
7
+ export default reportInlineStyle;
@@ -0,0 +1,179 @@
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
+ const recast = __importStar(require("recast"));
27
+ const constants_1 = require("./constants");
28
+ const BLACKLIST_PROPERTIES = {
29
+ style: constants_1.RULESET_MAP,
30
+ sx: constants_1.SX_RULESET_MAP,
31
+ };
32
+ const INLINE_STYLE_PROPERTIES = ['style', 'sx'];
33
+ const reportInlineStyle = (ast, attributes, componentName) => {
34
+ const locs = {
35
+ style: [],
36
+ sx: [],
37
+ };
38
+ let hasCustomStyle = false;
39
+ let styleObjName;
40
+ attributes.forEach((attr) => {
41
+ var _a;
42
+ if (attr.type === 'JSXAttribute' &&
43
+ typeof attr.name.name === 'string' &&
44
+ INLINE_STYLE_PROPERTIES.includes(attr.name.name) &&
45
+ ((_a = attr.value) === null || _a === void 0 ? void 0 : _a.type) === 'JSXExpressionContainer') {
46
+ styleObjName = attr.name.name;
47
+ const { expression } = attr.value;
48
+ if (expression.type === 'ObjectExpression') {
49
+ expression.properties.forEach((prop) => {
50
+ // Case 1: Use direct object, e.g. <Card style={{ color: 'red' }} />
51
+ if (prop.type === 'ObjectProperty' &&
52
+ prop.key.type === 'Identifier' &&
53
+ BLACKLIST_PROPERTIES[styleObjName][componentName].includes(prop.key.name)) {
54
+ hasCustomStyle = true;
55
+ }
56
+ // Case 2: Use spread operator, e.g. <Card style={{ ...customStyle }} />
57
+ if (prop.type === 'SpreadElement' &&
58
+ prop.argument.type === 'Identifier') {
59
+ const variableName = prop.argument.name;
60
+ recast.visit(ast, {
61
+ visitVariableDeclaration(path) {
62
+ var _a;
63
+ this.traverse(path);
64
+ const declaration = path.value
65
+ .declarations[0];
66
+ if (declaration.id.type === 'Identifier' &&
67
+ declaration.id.name === variableName &&
68
+ ((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
69
+ declaration.init.properties.forEach((deProp) => {
70
+ if (deProp.type === 'ObjectProperty' &&
71
+ deProp.key.type === 'Identifier' &&
72
+ BLACKLIST_PROPERTIES[styleObjName][componentName].includes(deProp.key.name)) {
73
+ hasCustomStyle = true;
74
+ }
75
+ });
76
+ }
77
+ },
78
+ });
79
+ }
80
+ // Case 3: Use spread operator with variable's property, e.g. <Card style={{ ...customStyle.tileCard }} />
81
+ if (prop.type === 'SpreadElement' &&
82
+ prop.argument.type === 'MemberExpression' &&
83
+ prop.argument.object.type === 'Identifier' &&
84
+ prop.argument.property.type === 'Identifier') {
85
+ const variableName = prop.argument.object.name;
86
+ const propName = prop.argument.property.name;
87
+ recast.visit(ast, {
88
+ visitVariableDeclaration(path) {
89
+ var _a;
90
+ this.traverse(path);
91
+ const declaration = path.value
92
+ .declarations[0];
93
+ if (declaration.id.type === 'Identifier' &&
94
+ declaration.id.name === variableName &&
95
+ ((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
96
+ declaration.init.properties.forEach((deProp) => {
97
+ if (deProp.type === 'ObjectProperty' &&
98
+ deProp.key.type === 'Identifier' &&
99
+ deProp.key.name === propName &&
100
+ deProp.value.type === 'ObjectExpression') {
101
+ deProp.value.properties.forEach((p) => {
102
+ if (p.type === 'ObjectProperty' &&
103
+ p.key.type === 'Identifier' &&
104
+ BLACKLIST_PROPERTIES[styleObjName][componentName].includes(p.key.name)) {
105
+ hasCustomStyle = true;
106
+ }
107
+ });
108
+ }
109
+ });
110
+ }
111
+ },
112
+ });
113
+ }
114
+ });
115
+ }
116
+ // Case 4: Use variable, e.g. <Card style={customStyle} />
117
+ if (expression.type === 'Identifier') {
118
+ const variableName = expression.name;
119
+ recast.visit(ast, {
120
+ visitVariableDeclaration(path) {
121
+ var _a;
122
+ this.traverse(path);
123
+ const declaration = path.value
124
+ .declarations[0];
125
+ if (declaration.id.type === 'Identifier' &&
126
+ declaration.id.name === variableName &&
127
+ ((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
128
+ declaration.init.properties.forEach((prop) => {
129
+ if (prop.type === 'ObjectProperty' &&
130
+ prop.key.type === 'Identifier' &&
131
+ BLACKLIST_PROPERTIES[styleObjName][componentName].includes(prop.key.name)) {
132
+ hasCustomStyle = true;
133
+ }
134
+ });
135
+ }
136
+ },
137
+ });
138
+ }
139
+ // Case 5: Use variable's property, e.g. <Card style={customStyle.tileCard} />
140
+ if (expression.type === 'MemberExpression' &&
141
+ expression.object.type === 'Identifier' &&
142
+ expression.property.type === 'Identifier') {
143
+ const objectName = expression.object.name;
144
+ const propName = expression.property.name;
145
+ recast.visit(ast, {
146
+ visitVariableDeclaration(path) {
147
+ var _a;
148
+ this.traverse(path);
149
+ const declaration = path.value
150
+ .declarations[0];
151
+ if (declaration.id.type === 'Identifier' &&
152
+ declaration.id.name === objectName &&
153
+ ((_a = declaration.init) === null || _a === void 0 ? void 0 : _a.type) === 'ObjectExpression') {
154
+ declaration.init.properties.forEach((prop) => {
155
+ if (prop.type === 'ObjectProperty' &&
156
+ prop.key.type === 'Identifier' &&
157
+ prop.key.name === propName &&
158
+ prop.value.type === 'ObjectExpression') {
159
+ prop.value.properties.forEach((p) => {
160
+ if (p.type === 'ObjectProperty' &&
161
+ p.key.type === 'Identifier' &&
162
+ BLACKLIST_PROPERTIES[styleObjName][componentName].includes(p.key.name)) {
163
+ hasCustomStyle = true;
164
+ }
165
+ });
166
+ }
167
+ });
168
+ }
169
+ },
170
+ });
171
+ }
172
+ if (hasCustomStyle && attr.loc) {
173
+ locs[styleObjName].push(attr.loc.start.line);
174
+ }
175
+ }
176
+ });
177
+ return locs;
178
+ };
179
+ exports.default = reportInlineStyle;
@@ -0,0 +1,6 @@
1
+ import * as recast from 'recast';
2
+ import type { ComponentName } from './types';
3
+ declare const reportStyledComponents: (ast: recast.types.ASTNode, componentList: {
4
+ [k: string]: "Alert" | "Badge" | "Banner" | "Breadcrumb" | "Button" | "Card" | "Carousel" | "Chart" | "Checkbox" | "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";
5
+ }, styledAliasName: string) => number[];
6
+ export default reportStyledComponents;
@@ -0,0 +1,95 @@
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
+ const recast = __importStar(require("recast"));
27
+ const reportStyledComponents = (ast, componentList, styledAliasName) => {
28
+ const locs = [];
29
+ const localComponentList = Object.keys(componentList);
30
+ recast.visit(ast, {
31
+ visitVariableDeclaration(path) {
32
+ this.traverse(path);
33
+ const declaration = path.value
34
+ .declarations[0];
35
+ if (declaration.init &&
36
+ declaration.init.type === 'TaggedTemplateExpression') {
37
+ const { tag } = declaration.init;
38
+ if (tag.type === 'CallExpression' &&
39
+ tag.callee.type === 'Identifier' &&
40
+ tag.callee.name === styledAliasName) {
41
+ const arg = tag.arguments[0];
42
+ // Case 1: Custom default component, e.g. styled(Card)
43
+ if (arg.type === 'Identifier' &&
44
+ localComponentList.includes(arg.name) &&
45
+ tag.loc) {
46
+ locs.push(tag.loc.start.line);
47
+ }
48
+ // Case 2: Custom compound component, e.g. styled(Card.Header)
49
+ if (arg.type === 'MemberExpression' &&
50
+ arg.object.type === 'Identifier' &&
51
+ localComponentList.includes(arg.object.name) &&
52
+ tag.loc) {
53
+ locs.push(tag.loc.start.line);
54
+ }
55
+ }
56
+ }
57
+ // Case 3: Custom compound component with spead operator. e.g. const { Header } = Card, then styled(Header)
58
+ if (declaration.init &&
59
+ declaration.init.type === 'Identifier' &&
60
+ localComponentList.includes(declaration.init.name)) {
61
+ const { id } = declaration;
62
+ if (id.type === 'ObjectPattern') {
63
+ const compoundComponentNames = id.properties
64
+ .map((prop) => prop.type === 'ObjectProperty' && prop.key.type === 'Identifier'
65
+ ? prop.key.name
66
+ : null)
67
+ .filter((name) => name !== null);
68
+ recast.visit(ast, {
69
+ visitVariableDeclaration(spreadPath) {
70
+ this.traverse(spreadPath);
71
+ const spreadDeclaration = spreadPath.value
72
+ .declarations[0];
73
+ if (spreadDeclaration.init &&
74
+ spreadDeclaration.init.type === 'TaggedTemplateExpression') {
75
+ const { tag } = spreadDeclaration.init;
76
+ if (tag.type === 'CallExpression' &&
77
+ tag.callee.type === 'Identifier' &&
78
+ tag.callee.name === styledAliasName) {
79
+ const arg = tag.arguments[0];
80
+ if (arg.type === 'Identifier' &&
81
+ compoundComponentNames.includes(arg.name) &&
82
+ tag.loc) {
83
+ locs.push(tag.loc.start.line);
84
+ }
85
+ }
86
+ }
87
+ },
88
+ });
89
+ }
90
+ }
91
+ },
92
+ });
93
+ return locs;
94
+ };
95
+ exports.default = reportStyledComponents;
@@ -0,0 +1,3 @@
1
+ import { HD_COMPONENTS, RULESET_MAP } from './constants';
2
+ export type ComponentName = typeof HD_COMPONENTS[number];
3
+ export type CompoundComponentName = keyof typeof RULESET_MAP;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,123 @@
1
+ import React from 'react';
2
+ import { Intl } from 'redux-intl';
3
+ import { Button, Dropdown, Menu } from '@hero-design/react';
4
+
5
+ import { MODAL_NAMES } from './constants';
6
+ import { TRACK_PREVIEW_DOCUMENT } from '../../HrDocumentsTab/tracks';
7
+
8
+ const ActionDropdown = ({
9
+ additionalPropsForCustomComponents: {
10
+ updatingSelectContract,
11
+ selectContract,
12
+ selectedContractId,
13
+ track,
14
+ },
15
+
16
+ openModal,
17
+ rowData,
18
+ setCustomData,
19
+ value,
20
+ }: any) => {
21
+ const [open, setOpen] = React.useState(false);
22
+ const toggleDropdown = () => setOpen(!open);
23
+ const closeDropdown = () => setOpen(false);
24
+ const dropdownTarget = (
25
+ <Button
26
+ variant="text"
27
+ rightIcon="carat-down-small"
28
+ text={Intl.formatMessage({ id: 'actions' })}
29
+ onClick={toggleDropdown}
30
+ style={{ padding: 0, width: 110}}
31
+ />
32
+ );
33
+ const dropdownContent = (
34
+ <Menu>
35
+ <Menu.Item
36
+ className="dropdown-item"
37
+ icon="eye-outlined"
38
+ text={Intl.formatMessage({ id: 'preview' })}
39
+ onClick={() => {
40
+ openModal(MODAL_NAMES.PREVIEW_TEMPLATE);
41
+ setCustomData(rowData);
42
+ closeDropdown();
43
+ track(TRACK_PREVIEW_DOCUMENT);
44
+ }}
45
+ />
46
+ <Menu.Item
47
+ icon="enter-arrow"
48
+ text={Intl.formatMessage({ id: 'select' })}
49
+ disabled={updatingSelectContract || !!selectedContractId}
50
+ onClick={() => {
51
+ selectContract(value);
52
+ closeDropdown();
53
+ }}
54
+ sx={{ padding: 0, width: 100}}
55
+ />
56
+ </Menu>
57
+ );
58
+
59
+ return (
60
+ <Dropdown
61
+ open={open}
62
+ target={dropdownTarget}
63
+ content={dropdownContent}
64
+ onClose={closeDropdown}
65
+ />
66
+ );
67
+ };
68
+
69
+ import styled from 'styled-components';
70
+ import { Select } from '@hero-design/react';
71
+
72
+ import { mediaQueries } from '@ehrocks/hero-theme';
73
+
74
+ export const Body = styled.div`
75
+ text-align: left;
76
+ padding: ${({ theme }) => theme.space.xxlarge}px
77
+ ${({ theme }) => theme.space.xxlarge}px 0
78
+ ${({ theme }) => theme.space.xxlarge}px;
79
+ table tr td {
80
+ vertical-align: middle;
81
+ }
82
+ .search-select {
83
+ margin-bottom: ${({ theme }) => theme.space.medium}px;
84
+ div[data-popper-reference-hidden] {
85
+ ${mediaQueries.sm} {
86
+ transform: translate(
87
+ ${({ theme }) => theme.space.xxlarge}px,
88
+ 241px
89
+ ) !important;
90
+ }
91
+
92
+ ${mediaQueries.md} {
93
+ transform: translate(
94
+ ${({ theme }) => theme.space.xxlarge}px,
95
+ 219px
96
+ ) !important;
97
+ }
98
+ }
99
+ }
100
+ `;
101
+
102
+ export const StyledSelectField = styled(Select)`
103
+ width: calc(100% - 30px);
104
+ display: inline-block;
105
+ padding: 50px;
106
+ `;
107
+
108
+ export const StyledRemove = styled.a`
109
+ display: inline-block;
110
+ width: 30px;
111
+ text-align: right;
112
+ vertical-align: top;
113
+ height: 36px;
114
+ line-height: 36px;
115
+ `;
116
+
117
+ export const ROLE_OPTIONS = [
118
+ { value: 'employee', text: 'Employee' },
119
+ { value: 'employer', text: 'Admin' },
120
+ ];
121
+
122
+
123
+ export default ActionDropdown;
@@ -0,0 +1,9 @@
1
+ import {
2
+ createLambdaFunction,
3
+ createProbot,
4
+ } from '@probot/adapter-aws-lambda-serverless';
5
+ import snowflakeBot from '../../src/index';
6
+
7
+ const handler = createLambdaFunction(snowflakeBot, { probot: createProbot() });
8
+
9
+ export { handler };
package/netlify.toml ADDED
@@ -0,0 +1,21 @@
1
+ # example netlify.toml
2
+ [build]
3
+ command = "# no build command"
4
+ functions = "packages/snowflake-guard/netlify/functions"
5
+ publish = "packages/snowflake-guard/lib"
6
+
7
+ ## Uncomment to use this redirect for Single Page Applications like create-react-app.
8
+ ## Not needed for static site generators.
9
+ #[[redirects]]
10
+ # from = "/*"
11
+ # to = "/index.html"
12
+ # status = 200
13
+
14
+ ## (optional) Settings for Netlify Dev
15
+ ## https://github.com/netlify/cli/blob/main/docs/netlify-dev.md#project-detection
16
+ #[dev]
17
+ # command = "yarn start" # Command to start your dev server
18
+ # port = 3000 # Port that the dev server will be listening on
19
+ # publish = "dist" # Folder with the static content for _redirect file
20
+
21
+ ## more info on configuring this file: https://ntl.fyi/file-based-build-config
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@hero-design/snowflake-guard",
3
+ "version": "1.0.7-alpha0",
4
+ "description": "A hero-design bot detecting snowflake usage",
5
+ "author": "Hau Dao",
6
+ "license": "ISC",
7
+ "main": "lib/src/parseSource.js",
8
+ "types": "lib/src/parseSource.d.ts",
9
+ "homepage": "https://github.com//",
10
+ "keywords": [
11
+ "probot",
12
+ "github",
13
+ "probot-app"
14
+ ],
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "start": "probot run ./lib/src/index.js",
18
+ "test": "jest --passWithNoTests",
19
+ "deploy": "netlify deploy --site snowflake-guard.netlify.app --prod --auth $NETLIFY_AUTH_TOKEN",
20
+ "publish:npm": "yarn publish --access public"
21
+ },
22
+ "dependencies": {
23
+ "@babel/parser": "^7.24.7",
24
+ "@probot/adapter-aws-lambda-serverless": "^3.0.4",
25
+ "probot": "^12.2.4",
26
+ "recast": "^0.23.9"
27
+ },
28
+ "devDependencies": {
29
+ "@types/jest": "^29.0.0",
30
+ "@types/node": "^18.0.0",
31
+ "config-tsconfig": "8.42.4",
32
+ "eslint-config-hd": "8.42.4",
33
+ "jest": "^29.0.0",
34
+ "nock": "^13.0.5",
35
+ "prettier-config-hd": "8.42.4",
36
+ "smee-client": "^1.2.2",
37
+ "ts-jest": "^29.0.0",
38
+ "typescript": "^4.1.3"
39
+ },
40
+ "prettier": "prettier-config-hd",
41
+ "engines": {
42
+ "node": ">= 10.13.0"
43
+ }
44
+ }