@atlaskit/eslint-plugin-design-system 9.3.1 → 9.4.1
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/CHANGELOG.md +12 -0
- package/README.md +36 -35
- package/constellation/index/usage.mdx +36 -35
- package/constellation/no-direct-use-of-web-platform-drag-and-drop/usage.mdx +140 -0
- package/constellation/use-tokens-typography/usage.mdx +6 -2
- package/dist/cjs/presets/all.codegen.js +2 -1
- package/dist/cjs/presets/recommended.codegen.js +2 -1
- package/dist/cjs/rules/index.codegen.js +3 -1
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-add-event-listener.js +31 -0
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind-all.js +63 -0
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind.js +48 -0
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-jsx-attribute.js +55 -0
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/index.js +55 -0
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/shared/blocked.js +8 -0
- package/dist/cjs/rules/no-direct-use-of-web-platform-drag-and-drop/shared/is-blocked-event-binding.js +31 -0
- package/dist/cjs/rules/use-tokens-typography/config/index.js +5 -1
- package/dist/cjs/rules/use-tokens-typography/index.js +2 -1
- package/dist/cjs/rules/use-tokens-typography/transformers/style-object.js +16 -9
- package/dist/cjs/rules/use-tokens-typography/utils.js +9 -9
- package/dist/es2019/presets/all.codegen.js +2 -1
- package/dist/es2019/presets/recommended.codegen.js +2 -1
- package/dist/es2019/rules/index.codegen.js +3 -1
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-add-event-listener.js +25 -0
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind-all.js +38 -0
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind.js +33 -0
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-jsx-attribute.js +49 -0
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/index.js +49 -0
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/shared/blocked.js +2 -0
- package/dist/es2019/rules/no-direct-use-of-web-platform-drag-and-drop/shared/is-blocked-event-binding.js +25 -0
- package/dist/es2019/rules/use-tokens-typography/config/index.js +5 -1
- package/dist/es2019/rules/use-tokens-typography/index.js +2 -1
- package/dist/es2019/rules/use-tokens-typography/transformers/style-object.js +16 -9
- package/dist/es2019/rules/use-tokens-typography/utils.js +8 -9
- package/dist/esm/presets/all.codegen.js +2 -1
- package/dist/esm/presets/recommended.codegen.js +2 -1
- package/dist/esm/rules/index.codegen.js +3 -1
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-add-event-listener.js +25 -0
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind-all.js +59 -0
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind.js +44 -0
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-jsx-attribute.js +49 -0
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/index.js +49 -0
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/shared/blocked.js +2 -0
- package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/shared/is-blocked-event-binding.js +25 -0
- package/dist/esm/rules/use-tokens-typography/config/index.js +5 -1
- package/dist/esm/rules/use-tokens-typography/index.js +2 -1
- package/dist/esm/rules/use-tokens-typography/transformers/style-object.js +16 -9
- package/dist/esm/rules/use-tokens-typography/utils.js +9 -9
- package/dist/types/index.codegen.d.ts +2 -0
- package/dist/types/presets/all.codegen.d.ts +2 -1
- package/dist/types/presets/recommended.codegen.d.ts +2 -1
- package/dist/types/rules/index.codegen.d.ts +1 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-add-event-listener.d.ts +2 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind-all.d.ts +3 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind.d.ts +3 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-jsx-attribute.d.ts +3 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/index.d.ts +2 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/shared/blocked.d.ts +2 -0
- package/dist/types/rules/no-direct-use-of-web-platform-drag-and-drop/shared/is-blocked-event-binding.d.ts +2 -0
- package/dist/types/rules/use-tokens-typography/config/index.d.ts +1 -0
- package/dist/types/rules/use-tokens-typography/transformers/style-object.d.ts +6 -2
- package/dist/types/rules/use-tokens-typography/utils.d.ts +1 -1
- package/dist/types-ts4.5/index.codegen.d.ts +2 -0
- package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
- package/dist/types-ts4.5/presets/recommended.codegen.d.ts +2 -1
- package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-add-event-listener.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind-all.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-jsx-attribute.d.ts +3 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/index.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/shared/blocked.d.ts +2 -0
- package/dist/types-ts4.5/rules/no-direct-use-of-web-platform-drag-and-drop/shared/is-blocked-event-binding.d.ts +2 -0
- package/dist/types-ts4.5/rules/use-tokens-typography/config/index.d.ts +1 -0
- package/dist/types-ts4.5/rules/use-tokens-typography/transformers/style-object.d.ts +6 -2
- package/dist/types-ts4.5/rules/use-tokens-typography/utils.d.ts +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { isBlockedAddEventListener } from './checks/is-blocked-add-event-listener';
|
|
4
|
+
import { isBlockedBind } from './checks/is-blocked-bind';
|
|
5
|
+
import { isBlockedBindAll } from './checks/is-blocked-bind-all';
|
|
6
|
+
import { isBlockedJSXAttribute } from './checks/is-blocked-jsx-attribute';
|
|
7
|
+
const rule = createLintRule({
|
|
8
|
+
meta: {
|
|
9
|
+
name: 'no-direct-use-of-web-platform-drag-and-drop',
|
|
10
|
+
type: 'problem',
|
|
11
|
+
docs: {
|
|
12
|
+
recommended: true,
|
|
13
|
+
severity: 'error',
|
|
14
|
+
description: 'Disallow using direct use of native drag and drop (please use Pragmatic drag and drop)'
|
|
15
|
+
},
|
|
16
|
+
messages: {
|
|
17
|
+
usePragmaticDnd: 'Please use Pragmatic drag and drop, which makes web platform drag and drop safe and easy to work with.'
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
create(context) {
|
|
21
|
+
return {
|
|
22
|
+
JSXAttribute(node) {
|
|
23
|
+
if (!isNodeOfType(node, 'JSXAttribute')) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (isBlockedJSXAttribute(context, node)) {
|
|
27
|
+
context.report({
|
|
28
|
+
messageId: 'usePragmaticDnd',
|
|
29
|
+
node
|
|
30
|
+
});
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
CallExpression(node) {
|
|
35
|
+
if (!isNodeOfType(node, 'CallExpression')) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (isBlockedAddEventListener(node) || isBlockedBind(context, node) || isBlockedBindAll(context, node)) {
|
|
39
|
+
context.report({
|
|
40
|
+
messageId: 'usePragmaticDnd',
|
|
41
|
+
node
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
export default rule;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { blockedEventNameLookup } from './blocked';
|
|
3
|
+
export function isBlockedEventBinding(property) {
|
|
4
|
+
if (!isNodeOfType(property, 'Property')) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// are we looking at the "type" property?
|
|
9
|
+
|
|
10
|
+
const key = property.key;
|
|
11
|
+
if (!isNodeOfType(key, 'Identifier')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (key.name !== 'type') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// is the "type" property value blocked?
|
|
19
|
+
|
|
20
|
+
const value = property.value;
|
|
21
|
+
if (!isNodeOfType(value, 'Literal')) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return typeof value.value === 'string' && blockedEventNameLookup.has(value.value);
|
|
25
|
+
}
|
|
@@ -5,12 +5,16 @@ export const ruleSchema = {
|
|
|
5
5
|
properties: {
|
|
6
6
|
failSilently: {
|
|
7
7
|
type: 'boolean'
|
|
8
|
+
},
|
|
9
|
+
shouldEnforceFallbacks: {
|
|
10
|
+
type: 'boolean'
|
|
8
11
|
}
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
};
|
|
12
15
|
const defaultConfig = {
|
|
13
|
-
failSilently: false
|
|
16
|
+
failSilently: false,
|
|
17
|
+
shouldEnforceFallbacks: true
|
|
14
18
|
};
|
|
15
19
|
export const getConfig = overrides => {
|
|
16
20
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|
|
@@ -7,7 +7,8 @@ import { isDecendantOfGlobalToken, isDecendantOfStyleBlock, isDecendantOfType }
|
|
|
7
7
|
import { convertPropertyNodeToStringableNode, defaultFontWeight, findFontFamilyValueForToken, findFontWeightTokenForValue, findTypographyTokenForValues, fontWeightMap, getLiteralProperty, getTokenProperty, insertFallbackImportFull, insertFallbackImportSpecifier, insertTokensImport, isValidPropertyNode, notUndefined } from '../utils';
|
|
8
8
|
export const StyleObject = {
|
|
9
9
|
lint(node, {
|
|
10
|
-
context
|
|
10
|
+
context,
|
|
11
|
+
config
|
|
11
12
|
}) {
|
|
12
13
|
// To force the correct node type
|
|
13
14
|
if (!isNodeOfType(node, 'ObjectExpression')) {
|
|
@@ -21,7 +22,8 @@ export const StyleObject = {
|
|
|
21
22
|
success,
|
|
22
23
|
refs
|
|
23
24
|
} = StyleObject._check(node, {
|
|
24
|
-
context
|
|
25
|
+
context,
|
|
26
|
+
config
|
|
25
27
|
});
|
|
26
28
|
if (!success || !refs) {
|
|
27
29
|
return;
|
|
@@ -31,6 +33,7 @@ export const StyleObject = {
|
|
|
31
33
|
fontSizeRaw,
|
|
32
34
|
tokensImportNode,
|
|
33
35
|
themeImportNode,
|
|
36
|
+
shouldAddFallback,
|
|
34
37
|
shouldAddFallbackImport
|
|
35
38
|
} = refs;
|
|
36
39
|
const fontSizeValue = normaliseValue('fontSize', fontSizeRaw);
|
|
@@ -110,16 +113,17 @@ export const StyleObject = {
|
|
|
110
113
|
const nodesToReplace = [fontSizeNode, fontWeightNode, lineHeightNode, fontFamilyNode, fontStyleNode, letterSpacingNode].filter(notUndefined);
|
|
111
114
|
const fontFamilyTokenName = fontFamilyToAdd ? `font.family.brand.${fontFamilyToAdd}` : '';
|
|
112
115
|
const fontWeightReplacementToken = shouldAddFontWeight ? findFontWeightTokenForValue(fontWeightValue) : undefined;
|
|
113
|
-
const fontWeightReplacement = fontWeightReplacementToken && getTokenProperty('fontWeight', fontWeightReplacementToken.tokenName, fontWeightValue);
|
|
116
|
+
const fontWeightReplacement = fontWeightReplacementToken && getTokenProperty('fontWeight', fontWeightReplacementToken.tokenName, shouldAddFallback ? fontWeightValue : undefined);
|
|
114
117
|
const fontFamilyReplacement = fontFamilyToAdd && (fontFamilyToAdd === 'original' ? convertPropertyNodeToStringableNode(
|
|
115
118
|
// This will always exist if fontFamilyToAdd === 'original', TS can't figure that out.
|
|
116
|
-
fontFamilyNode) : getTokenProperty('fontFamily', fontFamilyTokenName, findFontFamilyValueForToken(fontFamilyTokenName)));
|
|
119
|
+
fontFamilyNode) : getTokenProperty('fontFamily', fontFamilyTokenName, shouldAddFallback ? findFontFamilyValueForToken(fontFamilyTokenName) : undefined));
|
|
117
120
|
const fontStyleReplacement = fontStyleToAdd && getLiteralProperty('fontStyle', fontStyleToAdd);
|
|
118
121
|
const fixerRefs = {
|
|
119
122
|
matchingToken,
|
|
120
123
|
nodesToReplace,
|
|
121
124
|
tokensImportNode,
|
|
122
125
|
themeImportNode,
|
|
126
|
+
shouldAddFallback,
|
|
123
127
|
shouldAddFallbackImport,
|
|
124
128
|
fontWeightReplacement,
|
|
125
129
|
fontFamilyReplacement,
|
|
@@ -145,7 +149,8 @@ export const StyleObject = {
|
|
|
145
149
|
return;
|
|
146
150
|
},
|
|
147
151
|
_check(node, {
|
|
148
|
-
context
|
|
152
|
+
context,
|
|
153
|
+
config
|
|
149
154
|
}) {
|
|
150
155
|
if (!isDecendantOfStyleBlock(node) && !isDecendantOfType(node, 'JSXExpressionContainer')) {
|
|
151
156
|
return {
|
|
@@ -176,13 +181,13 @@ export const StyleObject = {
|
|
|
176
181
|
success: false
|
|
177
182
|
};
|
|
178
183
|
}
|
|
179
|
-
|
|
184
|
+
const shouldAddFallback = Boolean(config.shouldEnforceFallbacks);
|
|
180
185
|
// This exists purely because we're not inlining the fallback values
|
|
181
186
|
// and instead referencing a `fontFallback` object that exists in @atlaskit/theme/typography.
|
|
182
187
|
// This is a temporary measure until fallbacks are no longer required
|
|
183
|
-
let shouldAddFallbackImport = 'full';
|
|
188
|
+
let shouldAddFallbackImport = shouldAddFallback && 'full';
|
|
184
189
|
const themeImportDeclaration = Root.findImportsByModule(context.getSourceCode().ast.body, '@atlaskit/theme/typography');
|
|
185
|
-
if (themeImportDeclaration.length) {
|
|
190
|
+
if (themeImportDeclaration.length && shouldAddFallback) {
|
|
186
191
|
// Import exists, check if specifier exists
|
|
187
192
|
shouldAddFallbackImport = 'specifier';
|
|
188
193
|
const fallbackImport = themeImportDeclaration[0].specifiers.find(specifier => {
|
|
@@ -208,6 +213,7 @@ export const StyleObject = {
|
|
|
208
213
|
fontSizeRaw,
|
|
209
214
|
tokensImportNode: tokensImportDeclaration[0],
|
|
210
215
|
themeImportNode: themeImportDeclaration[0],
|
|
216
|
+
shouldAddFallback,
|
|
211
217
|
shouldAddFallbackImport
|
|
212
218
|
}
|
|
213
219
|
};
|
|
@@ -219,6 +225,7 @@ export const StyleObject = {
|
|
|
219
225
|
nodesToReplace,
|
|
220
226
|
tokensImportNode,
|
|
221
227
|
themeImportNode,
|
|
228
|
+
shouldAddFallback,
|
|
222
229
|
shouldAddFallbackImport,
|
|
223
230
|
fontWeightReplacement,
|
|
224
231
|
fontFamilyReplacement,
|
|
@@ -236,7 +243,7 @@ export const StyleObject = {
|
|
|
236
243
|
return (!tokensImportNode ? [insertTokensImport(root, fixer)] : []).concat(fallbackImport ? [fallbackImport] : [], nodesToReplace.map((node, index) => {
|
|
237
244
|
// Replace first node with token, delete remaining nodes. Guaranteed to be fontSize
|
|
238
245
|
if (index === 0) {
|
|
239
|
-
return fixer.replaceText(node, `${getTokenProperty('font', matchingToken.tokenName, fallbackName, true)}`);
|
|
246
|
+
return fixer.replaceText(node, `${getTokenProperty('font', matchingToken.tokenName, shouldAddFallback ? fallbackName : undefined, true)}`);
|
|
240
247
|
}
|
|
241
248
|
|
|
242
249
|
// We don't replace fontWeight/fontFamily/fontStyle here in case it occurs before the font property.
|
|
@@ -69,20 +69,19 @@ export function isValidPropertyNode(node) {
|
|
|
69
69
|
}
|
|
70
70
|
return true;
|
|
71
71
|
}
|
|
72
|
-
function getTokenNode(tokenName,
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
fallback = literal(
|
|
72
|
+
function getTokenNode(tokenName, fallbackValue, isFallbackMember = false) {
|
|
73
|
+
const callExpressionArgs = [literal({
|
|
74
|
+
value: `'${tokenName}'`
|
|
75
|
+
})];
|
|
76
|
+
if (fallbackValue) {
|
|
77
|
+
const fallback = isFallbackMember ? createMemberExpressionFromArray(fallbackValue.split('.')) : literal(fallbackValue);
|
|
78
|
+
callExpressionArgs.push(fallback);
|
|
78
79
|
}
|
|
79
80
|
return callExpression({
|
|
80
81
|
callee: identifier({
|
|
81
82
|
name: 'token'
|
|
82
83
|
}),
|
|
83
|
-
arguments:
|
|
84
|
-
value: `'${tokenName}'`
|
|
85
|
-
}), fallback],
|
|
84
|
+
arguments: callExpressionArgs,
|
|
86
85
|
optional: false
|
|
87
86
|
});
|
|
88
87
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::1ab11547db880eba1206f334a9b2150f>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -15,6 +15,7 @@ export default {
|
|
|
15
15
|
'@atlaskit/design-system/no-deprecated-apis': 'error',
|
|
16
16
|
'@atlaskit/design-system/no-deprecated-design-token-usage': 'warn',
|
|
17
17
|
'@atlaskit/design-system/no-deprecated-imports': 'error',
|
|
18
|
+
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
18
19
|
'@atlaskit/design-system/no-empty-styled-expression': 'warn',
|
|
19
20
|
'@atlaskit/design-system/no-exported-css': 'warn',
|
|
20
21
|
'@atlaskit/design-system/no-exported-keyframes': 'warn',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::05b4fe8f97edc4f7e46ded52b4917037>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
export default {
|
|
@@ -13,6 +13,7 @@ export default {
|
|
|
13
13
|
'@atlaskit/design-system/no-deprecated-apis': 'error',
|
|
14
14
|
'@atlaskit/design-system/no-deprecated-design-token-usage': 'warn',
|
|
15
15
|
'@atlaskit/design-system/no-deprecated-imports': 'error',
|
|
16
|
+
'@atlaskit/design-system/no-direct-use-of-web-platform-drag-and-drop': 'error',
|
|
16
17
|
'@atlaskit/design-system/no-empty-styled-expression': 'warn',
|
|
17
18
|
'@atlaskit/design-system/no-exported-css': 'warn',
|
|
18
19
|
'@atlaskit/design-system/no-exported-keyframes': 'warn',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* THIS FILE WAS CREATED VIA CODEGEN DO NOT MODIFY {@see http://go/af-codegen}
|
|
3
|
-
* @codegen <<SignedSource::
|
|
3
|
+
* @codegen <<SignedSource::293575f7bd0150862f792e3fffc286c4>>
|
|
4
4
|
* @codegenCommand yarn workspace @atlaskit/eslint-plugin-design-system codegen
|
|
5
5
|
*/
|
|
6
6
|
import consistentCssPropUsage from './consistent-css-prop-usage';
|
|
@@ -12,6 +12,7 @@ import noCssTaggedTemplateExpression from './no-css-tagged-template-expression';
|
|
|
12
12
|
import noDeprecatedApis from './no-deprecated-apis';
|
|
13
13
|
import noDeprecatedDesignTokenUsage from './no-deprecated-design-token-usage';
|
|
14
14
|
import noDeprecatedImports from './no-deprecated-imports';
|
|
15
|
+
import noDirectUseOfWebPlatformDragAndDrop from './no-direct-use-of-web-platform-drag-and-drop';
|
|
15
16
|
import noEmptyStyledExpression from './no-empty-styled-expression';
|
|
16
17
|
import noExportedCss from './no-exported-css';
|
|
17
18
|
import noExportedKeyframes from './no-exported-keyframes';
|
|
@@ -46,6 +47,7 @@ export default {
|
|
|
46
47
|
'no-deprecated-apis': noDeprecatedApis,
|
|
47
48
|
'no-deprecated-design-token-usage': noDeprecatedDesignTokenUsage,
|
|
48
49
|
'no-deprecated-imports': noDeprecatedImports,
|
|
50
|
+
'no-direct-use-of-web-platform-drag-and-drop': noDirectUseOfWebPlatformDragAndDrop,
|
|
49
51
|
'no-empty-styled-expression': noEmptyStyledExpression,
|
|
50
52
|
'no-exported-css': noExportedCss,
|
|
51
53
|
'no-exported-keyframes': noExportedKeyframes,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { blockedEventNameLookup } from '../shared/blocked';
|
|
3
|
+
export function isBlockedAddEventListener(node) {
|
|
4
|
+
var callee = node.callee;
|
|
5
|
+
if (!isNodeOfType(callee, 'MemberExpression')) {
|
|
6
|
+
return false;
|
|
7
|
+
}
|
|
8
|
+
var property = callee.property;
|
|
9
|
+
if (!isNodeOfType(property, 'Identifier')) {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
if (property.name !== 'addEventListener') {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// check the first argument
|
|
17
|
+
var first = node.arguments[0];
|
|
18
|
+
|
|
19
|
+
// only checking literals for this eslint rule
|
|
20
|
+
if (!isNodeOfType(first, 'Literal')) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
var value = first.value;
|
|
24
|
+
return typeof value === 'string' && blockedEventNameLookup.has(value);
|
|
25
|
+
}
|
package/dist/esm/rules/no-direct-use-of-web-platform-drag-and-drop/checks/is-blocked-bind-all.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
2
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
3
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
4
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
5
|
+
|
|
6
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
7
|
+
import { getModuleOfIdentifier } from '../../utils/get-import-node-by-source';
|
|
8
|
+
import { isBlockedEventBinding } from '../shared/is-blocked-event-binding';
|
|
9
|
+
export function isBlockedBindAll(context, node) {
|
|
10
|
+
var callee = node.callee;
|
|
11
|
+
if (!isNodeOfType(callee, 'Identifier')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (callee.name !== 'bindAll') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
var module = getModuleOfIdentifier(context.sourceCode, 'bindAll');
|
|
18
|
+
if ((module === null || module === void 0 ? void 0 : module.moduleName) !== 'bind-event-listener') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
var secondArg = node.arguments[1];
|
|
22
|
+
if (!isNodeOfType(secondArg, 'ArrayExpression')) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
var _iterator = _createForOfIteratorHelper(secondArg.elements),
|
|
26
|
+
_step;
|
|
27
|
+
try {
|
|
28
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
29
|
+
var element = _step.value;
|
|
30
|
+
if (!element) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
if (!isNodeOfType(element, 'ObjectExpression')) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
var _iterator2 = _createForOfIteratorHelper(element.properties),
|
|
37
|
+
_step2;
|
|
38
|
+
try {
|
|
39
|
+
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
|
|
40
|
+
var property = _step2.value;
|
|
41
|
+
if (isBlockedEventBinding(property)) {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} catch (err) {
|
|
46
|
+
_iterator2.e(err);
|
|
47
|
+
} finally {
|
|
48
|
+
_iterator2.f();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// no exit conditions hit
|
|
53
|
+
} catch (err) {
|
|
54
|
+
_iterator.e(err);
|
|
55
|
+
} finally {
|
|
56
|
+
_iterator.f();
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
2
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
3
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
4
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
5
|
+
|
|
6
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
7
|
+
import { getModuleOfIdentifier } from '../../utils/get-import-node-by-source';
|
|
8
|
+
import { isBlockedEventBinding } from '../shared/is-blocked-event-binding';
|
|
9
|
+
export function isBlockedBind(context, node) {
|
|
10
|
+
var callee = node.callee;
|
|
11
|
+
if (!isNodeOfType(callee, 'Identifier')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (callee.name !== 'bind') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
var module = getModuleOfIdentifier(context.sourceCode, 'bind');
|
|
18
|
+
if ((module === null || module === void 0 ? void 0 : module.moduleName) !== 'bind-event-listener') {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
var secondArg = node.arguments[1];
|
|
22
|
+
if (!isNodeOfType(secondArg, 'ObjectExpression')) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// using a for loop for speed 🚀
|
|
27
|
+
var _iterator = _createForOfIteratorHelper(secondArg.properties),
|
|
28
|
+
_step;
|
|
29
|
+
try {
|
|
30
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
31
|
+
var property = _step.value;
|
|
32
|
+
if (isBlockedEventBinding(property)) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// no exit conditions hit
|
|
38
|
+
} catch (err) {
|
|
39
|
+
_iterator.e(err);
|
|
40
|
+
} finally {
|
|
41
|
+
_iterator.f();
|
|
42
|
+
}
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
2
|
+
|
|
3
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
4
|
+
import { getModuleOfIdentifier } from '../../utils/get-import-node-by-source';
|
|
5
|
+
import { blockedJSXAttributeLookup } from '../shared/blocked';
|
|
6
|
+
function getJSXElementNameFromAttribute(attribute) {
|
|
7
|
+
var parent = attribute.parent;
|
|
8
|
+
if (!parent) {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
if (!isNodeOfType(parent, 'JSXOpeningElement')) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
var identifier = parent.name;
|
|
15
|
+
if (!isNodeOfType(identifier, 'JSXIdentifier')) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return identifier.name;
|
|
19
|
+
}
|
|
20
|
+
function isOnIntrinsicJSXElement(attribute) {
|
|
21
|
+
var name = getJSXElementNameFromAttribute(attribute);
|
|
22
|
+
if (!name) {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
var firstLetter = name.at(0);
|
|
26
|
+
if (!firstLetter) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
return firstLetter === firstLetter.toLocaleLowerCase();
|
|
30
|
+
}
|
|
31
|
+
function isOnBoxPrimitive(context, attribute) {
|
|
32
|
+
if (getJSXElementNameFromAttribute(attribute) !== 'Box') {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
var module = getModuleOfIdentifier(context.sourceCode, 'Box');
|
|
36
|
+
return (module === null || module === void 0 ? void 0 : module.moduleName) === '@atlaskit/primitives';
|
|
37
|
+
}
|
|
38
|
+
export function isBlockedJSXAttribute(context, node) {
|
|
39
|
+
var attributeName = node.name;
|
|
40
|
+
if (!isNodeOfType(attributeName, 'JSXIdentifier')) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// not using a blocked attribute name, can continue on
|
|
45
|
+
if (!blockedJSXAttributeLookup.has(attributeName.name)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return isOnIntrinsicJSXElement(node) || isOnBoxPrimitive(context, node);
|
|
49
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { createLintRule } from '../utils/create-rule';
|
|
3
|
+
import { isBlockedAddEventListener } from './checks/is-blocked-add-event-listener';
|
|
4
|
+
import { isBlockedBind } from './checks/is-blocked-bind';
|
|
5
|
+
import { isBlockedBindAll } from './checks/is-blocked-bind-all';
|
|
6
|
+
import { isBlockedJSXAttribute } from './checks/is-blocked-jsx-attribute';
|
|
7
|
+
var rule = createLintRule({
|
|
8
|
+
meta: {
|
|
9
|
+
name: 'no-direct-use-of-web-platform-drag-and-drop',
|
|
10
|
+
type: 'problem',
|
|
11
|
+
docs: {
|
|
12
|
+
recommended: true,
|
|
13
|
+
severity: 'error',
|
|
14
|
+
description: 'Disallow using direct use of native drag and drop (please use Pragmatic drag and drop)'
|
|
15
|
+
},
|
|
16
|
+
messages: {
|
|
17
|
+
usePragmaticDnd: 'Please use Pragmatic drag and drop, which makes web platform drag and drop safe and easy to work with.'
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
create: function create(context) {
|
|
21
|
+
return {
|
|
22
|
+
JSXAttribute: function JSXAttribute(node) {
|
|
23
|
+
if (!isNodeOfType(node, 'JSXAttribute')) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (isBlockedJSXAttribute(context, node)) {
|
|
27
|
+
context.report({
|
|
28
|
+
messageId: 'usePragmaticDnd',
|
|
29
|
+
node: node
|
|
30
|
+
});
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
CallExpression: function CallExpression(node) {
|
|
35
|
+
if (!isNodeOfType(node, 'CallExpression')) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (isBlockedAddEventListener(node) || isBlockedBind(context, node) || isBlockedBindAll(context, node)) {
|
|
39
|
+
context.report({
|
|
40
|
+
messageId: 'usePragmaticDnd',
|
|
41
|
+
node: node
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
export default rule;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { isNodeOfType } from 'eslint-codemod-utils';
|
|
2
|
+
import { blockedEventNameLookup } from './blocked';
|
|
3
|
+
export function isBlockedEventBinding(property) {
|
|
4
|
+
if (!isNodeOfType(property, 'Property')) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// are we looking at the "type" property?
|
|
9
|
+
|
|
10
|
+
var key = property.key;
|
|
11
|
+
if (!isNodeOfType(key, 'Identifier')) {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
if (key.name !== 'type') {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// is the "type" property value blocked?
|
|
19
|
+
|
|
20
|
+
var value = property.value;
|
|
21
|
+
if (!isNodeOfType(value, 'Literal')) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return typeof value.value === 'string' && blockedEventNameLookup.has(value.value);
|
|
25
|
+
}
|
|
@@ -5,12 +5,16 @@ export var ruleSchema = {
|
|
|
5
5
|
properties: {
|
|
6
6
|
failSilently: {
|
|
7
7
|
type: 'boolean'
|
|
8
|
+
},
|
|
9
|
+
shouldEnforceFallbacks: {
|
|
10
|
+
type: 'boolean'
|
|
8
11
|
}
|
|
9
12
|
}
|
|
10
13
|
}
|
|
11
14
|
};
|
|
12
15
|
var defaultConfig = {
|
|
13
|
-
failSilently: false
|
|
16
|
+
failSilently: false,
|
|
17
|
+
shouldEnforceFallbacks: true
|
|
14
18
|
};
|
|
15
19
|
export var getConfig = function getConfig(overrides) {
|
|
16
20
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
|