@atlaskit/eslint-plugin-design-system 11.1.0 → 11.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/dist/cjs/rules/no-deprecated-apis/index.js +13 -26
  3. package/dist/cjs/rules/no-legacy-icons/checks.js +14 -3
  4. package/dist/cjs/rules/no-legacy-icons/helpers.js +3 -14
  5. package/dist/cjs/rules/no-legacy-icons/index.js +3 -0
  6. package/dist/cjs/rules/use-tokens-typography/config/index.js +2 -1
  7. package/dist/cjs/rules/use-tokens-typography/index.js +15 -6
  8. package/dist/cjs/rules/use-tokens-typography/transformers/font-weight.js +96 -0
  9. package/dist/cjs/rules/use-tokens-typography/transformers/style-object.js +5 -0
  10. package/dist/cjs/rules/use-tokens-typography/utils.js +6 -0
  11. package/dist/es2019/rules/no-deprecated-apis/index.js +14 -23
  12. package/dist/es2019/rules/no-legacy-icons/checks.js +14 -3
  13. package/dist/es2019/rules/no-legacy-icons/helpers.js +3 -14
  14. package/dist/es2019/rules/no-legacy-icons/index.js +3 -0
  15. package/dist/es2019/rules/use-tokens-typography/config/index.js +2 -1
  16. package/dist/es2019/rules/use-tokens-typography/index.js +13 -6
  17. package/dist/es2019/rules/use-tokens-typography/transformers/font-weight.js +92 -0
  18. package/dist/es2019/rules/use-tokens-typography/transformers/style-object.js +5 -0
  19. package/dist/es2019/rules/use-tokens-typography/utils.js +6 -0
  20. package/dist/esm/rules/no-deprecated-apis/index.js +14 -26
  21. package/dist/esm/rules/no-legacy-icons/checks.js +14 -3
  22. package/dist/esm/rules/no-legacy-icons/helpers.js +3 -14
  23. package/dist/esm/rules/no-legacy-icons/index.js +3 -0
  24. package/dist/esm/rules/use-tokens-typography/config/index.js +2 -1
  25. package/dist/esm/rules/use-tokens-typography/index.js +15 -6
  26. package/dist/esm/rules/use-tokens-typography/transformers/font-weight.js +90 -0
  27. package/dist/esm/rules/use-tokens-typography/transformers/style-object.js +5 -0
  28. package/dist/esm/rules/use-tokens-typography/utils.js +6 -0
  29. package/dist/types/index.codegen.d.ts +3 -9
  30. package/dist/types/rules/index.codegen.d.ts +1 -3
  31. package/dist/types/rules/no-deprecated-apis/index.d.ts +2 -4
  32. package/dist/types/rules/no-legacy-icons/helpers.d.ts +1 -0
  33. package/dist/types/rules/use-tokens-typography/config/index.d.ts +3 -0
  34. package/dist/types/rules/use-tokens-typography/transformers/font-weight.d.ts +13 -0
  35. package/dist/types-ts4.5/index.codegen.d.ts +3 -15
  36. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -5
  37. package/dist/types-ts4.5/rules/no-deprecated-apis/index.d.ts +2 -6
  38. package/dist/types-ts4.5/rules/no-legacy-icons/helpers.d.ts +1 -0
  39. package/dist/types-ts4.5/rules/use-tokens-typography/config/index.d.ts +3 -0
  40. package/dist/types-ts4.5/rules/use-tokens-typography/transformers/font-weight.d.ts +13 -0
  41. package/package.json +2 -2
@@ -20,7 +20,8 @@ export const ruleSchema = {
20
20
  const defaultConfig = {
21
21
  failSilently: false,
22
22
  shouldEnforceFallbacks: false,
23
- enableUnsafeAutofix: false
23
+ enableUnsafeAutofix: false,
24
+ patterns: ['style-object']
24
25
  };
25
26
  export const getConfig = overrides => {
26
27
  return Object.assign({}, defaultConfig, overrides);
@@ -1,16 +1,22 @@
1
1
  import { createLintRule } from '../utils/create-rule';
2
2
  import { errorBoundary } from '../utils/error-boundary';
3
3
  import { getConfig, ruleSchema } from './config';
4
+ import { FontWeight } from './transformers/font-weight';
4
5
  import { StyleObject } from './transformers/style-object';
5
6
  const create = context => {
6
7
  const config = getConfig(context.options[0]);
7
- return {
8
- // const styles = css({ fontSize: '14px, ... }), styled.div({ fontSize: 14, ... })
9
- ObjectExpression: errorBoundary(node => StyleObject.lint(node, {
8
+ return errorBoundary({
9
+ // const styles = css({ fontSize: '14px', ... }), styled.div({ fontSize: 14, ... })
10
+ ObjectExpression: node => StyleObject.lint(node, {
10
11
  context,
11
12
  config
12
- }), config)
13
- };
13
+ }),
14
+ // const styles = css({ fontWeight: 600, 'bold', ... })
15
+ 'ObjectExpression > Property > Identifier[name=/fontWeight/]': node => FontWeight.lint(node, {
16
+ context,
17
+ config
18
+ })
19
+ }, config);
14
20
  };
15
21
  const rule = createLintRule({
16
22
  meta: {
@@ -24,7 +30,8 @@ const rule = createLintRule({
24
30
  severity: 'warn'
25
31
  },
26
32
  messages: {
27
- noRawTypographyValues: 'Typography primitives or tokens should be used instead of hard-coded values.\n\n@meta <<{{payload}}>>.\n\nNOTE: Using tokens with the `fontSize` property is invalid. Any `font.heading` or `font.body` tokens must use the CSS `font` property.'
33
+ noRawTypographyValues: 'Typography primitives or tokens should be used instead of hard-coded values.\n\n@meta <<{{payload}}>>.\n\nNOTE: Using tokens with the `fontSize` property is invalid. Any `font.heading` or `font.body` tokens must use the CSS `font` property.',
34
+ noRawFontWeightValues: 'Font weight tokens should be used instead of hard-coded values.'
28
35
  },
29
36
  schema: ruleSchema
30
37
  },
@@ -0,0 +1,92 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { isNodeOfType } from 'eslint-codemod-utils';
4
+ import { Root } from '../../../ast-nodes';
5
+ import { getValueForPropertyNode } from '../../ensure-design-token-usage/utils';
6
+ import { isDecendantOfStyleBlock, isDecendantOfType } from '../../utils/is-node';
7
+ import { findFontWeightTokenForValue, insertTokensImport } from '../utils';
8
+ export const FontWeight = {
9
+ lint(node, {
10
+ context,
11
+ config
12
+ }) {
13
+ // To force the correct node type
14
+ if (!isNodeOfType(node, 'Identifier')) {
15
+ return;
16
+ }
17
+
18
+ // Check whether all criteria needed to make a transformation are met
19
+ const success = FontWeight._check(node, {
20
+ context,
21
+ config
22
+ });
23
+ if (success) {
24
+ return context.report({
25
+ node,
26
+ messageId: 'noRawFontWeightValues',
27
+ fix: FontWeight._fix(node, context)
28
+ });
29
+ }
30
+ },
31
+ _check(node, {
32
+ context,
33
+ config
34
+ }) {
35
+ if (!config.patterns.includes('font-weight')) {
36
+ return false;
37
+ }
38
+ if (!isDecendantOfStyleBlock(node) && !isDecendantOfType(node, 'JSXExpressionContainer')) {
39
+ return false;
40
+ }
41
+ if (!isNodeOfType(node.parent, 'Property')) {
42
+ return false;
43
+ }
44
+ const fontWeightValue = getValueForPropertyNode(node.parent, context);
45
+ if (typeof fontWeightValue === 'string' && fontWeightValue.includes('font.weight.')) {
46
+ return false;
47
+ }
48
+ return true;
49
+ },
50
+ _fix(node, context) {
51
+ return fixer => {
52
+ var _findFontWeightTokenF;
53
+ const fixes = [];
54
+
55
+ // -- Type assertions to force the correct node type --
56
+
57
+ if (!isNodeOfType(node.parent, 'Property')) {
58
+ return [];
59
+ }
60
+ if (!isNodeOfType(node.parent.value, 'Literal')) {
61
+ return [];
62
+ }
63
+ if (!node.parent.value.raw) {
64
+ return [];
65
+ }
66
+
67
+ // -- Fix: Replace raw value with token --
68
+
69
+ const matchingToken = (_findFontWeightTokenF = findFontWeightTokenForValue(node.parent.value.raw)) === null || _findFontWeightTokenF === void 0 ? void 0 : _findFontWeightTokenF.tokenName;
70
+ if (!matchingToken) {
71
+ return [];
72
+ }
73
+ const fontWeightValueFix = fixer.replaceText(node.parent.value, `token('${matchingToken}')`);
74
+ fixes.push(fontWeightValueFix);
75
+
76
+ // -- Fix: Add import if it doesn't exist --
77
+
78
+ const body = context.sourceCode.ast.body;
79
+ const tokensImportDeclarations = Root.findImportsByModule(body, '@atlaskit/tokens');
80
+
81
+ // If there is more than one `@atlaskit/tokens` import, then it becomes difficult to determine which import to transform
82
+ if (tokensImportDeclarations.length > 1) {
83
+ return fixes;
84
+ }
85
+ const tokensImportDeclaration = tokensImportDeclarations[0];
86
+ if (!tokensImportDeclaration) {
87
+ fixes.push(insertTokensImport(body, fixer));
88
+ }
89
+ return fixes;
90
+ };
91
+ }
92
+ };
@@ -198,6 +198,11 @@ export const StyleObject = {
198
198
  context,
199
199
  config
200
200
  }) {
201
+ if (!config.patterns.includes('style-object')) {
202
+ return {
203
+ success: false
204
+ };
205
+ }
201
206
  if (!isDecendantOfStyleBlock(node) && !isDecendantOfType(node, 'JSXExpressionContainer')) {
202
207
  return {
203
208
  success: false
@@ -48,6 +48,12 @@ export const fontWeightTokens = typographyTokens.filter(token => token.attribute
48
48
  };
49
49
  });
50
50
  export function findFontWeightTokenForValue(fontWeight) {
51
+ if (fontWeight === "'normal'") {
52
+ fontWeight = '400';
53
+ }
54
+ if (fontWeight === "'bold'") {
55
+ fontWeight = '700';
56
+ }
51
57
  return fontWeightTokens.find(token => token.tokenValue === fontWeight);
52
58
  }
53
59
  export const fontWeightMap = {
@@ -1,36 +1,30 @@
1
- import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
- import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils';
3
- import { createRule } from '../utils/create-rule';
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import { createLintRule } from '../utils/create-rule';
4
3
  import { getConfig } from '../utils/get-deprecated-config';
5
4
  import { isDeprecatedJSXAttributeConfig } from '../utils/types';
6
5
  export var noDeprecatedJSXAttributeMessageId = 'noDeprecatedJSXAttributes';
7
- var isNodeOfType = function isNodeOfType(node, nodeType) {
8
- return ASTUtils.isNodeOfType(nodeType)(node);
9
- };
10
6
  var isImportDeclaration = function isImportDeclaration(programStatement) {
11
7
  return (programStatement === null || programStatement === void 0 ? void 0 : programStatement.type) === 'ImportDeclaration';
12
8
  };
13
9
  var findJSXElementName = function findJSXElementName(jsxAttributeNode) {
14
- if (!jsxAttributeNode.parent || !isNodeOfType(jsxAttributeNode.parent, AST_NODE_TYPES.JSXOpeningElement)) {
10
+ if (!jsxAttributeNode.parent || !isNodeOfType(jsxAttributeNode === null || jsxAttributeNode === void 0 ? void 0 : jsxAttributeNode.parent, 'JSXOpeningElement')) {
15
11
  return;
16
12
  }
17
13
  var openingElement = jsxAttributeNode.parent;
18
- if (!isNodeOfType(openingElement.name, AST_NODE_TYPES.JSXIdentifier)) {
14
+ if (!isNodeOfType(openingElement.name, 'JSXIdentifier')) {
19
15
  return;
20
16
  }
21
17
  return openingElement.name.name;
22
18
  };
23
19
  export var name = 'no-deprecated-apis';
24
- var rule = createRule({
25
- name: name,
26
- defaultOptions: [{
27
- deprecatedConfig: getConfig('jsxAttributes')
28
- }],
20
+ var rule = createLintRule({
29
21
  meta: {
22
+ name: name,
30
23
  type: 'suggestion',
31
24
  docs: {
32
25
  description: 'Disallow using deprecated APIs.',
33
- recommended: 'strict'
26
+ recommended: true,
27
+ severity: 'error'
34
28
  },
35
29
  messages: {
36
30
  noDeprecatedJSXAttributes: 'The JSX attribute {{propName}} has been deprecated.'
@@ -68,24 +62,18 @@ var rule = createRule({
68
62
  }
69
63
  }]
70
64
  },
71
- create: function create(context, _ref) {
65
+ create: function create(context) {
72
66
  var _context$options$;
73
- var _ref2 = _slicedToArray(_ref, 1),
74
- options = _ref2[0];
75
- // Get rule configuration
76
- var defaultDeprecatedConfig = options.deprecatedConfig;
77
-
78
67
  // Get the rule configuration specified otherwise use default config.
79
68
  // A bit confusing as it seems that the default options have precedence over the user specified options.
80
- var deprecatedConfig = ((_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.deprecatedConfig) || defaultDeprecatedConfig;
69
+ var deprecatedConfig = ((_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.deprecatedConfig) || getConfig('jsxAttributes');
81
70
  return {
82
71
  // find JSX atribute - find name of attribute - get source and find relevant identifiers.
83
72
  JSXAttribute: function JSXAttribute(node) {
84
- var jsxAttributeIdentifier = node.name;
85
- if (!isNodeOfType(jsxAttributeIdentifier, AST_NODE_TYPES.JSXIdentifier)) {
73
+ if (!isNodeOfType(node, 'JSXAttribute') || !isNodeOfType(node.name, 'JSXIdentifier')) {
86
74
  return;
87
75
  }
88
- var jsxAttributeName = jsxAttributeIdentifier.name;
76
+ var jsxAttributeName = node.name.name;
89
77
  if (!isDeprecatedJSXAttributeConfig(deprecatedConfig) || !deprecatedConfig[jsxAttributeName]) {
90
78
  return;
91
79
  }
@@ -93,13 +81,13 @@ var rule = createRule({
93
81
  if (!jsxElementName) {
94
82
  return;
95
83
  }
96
- var source = context.getSourceCode();
84
+ var source = context.sourceCode;
97
85
 
98
86
  // find an import for the path of the banned api
99
87
  deprecatedConfig[jsxAttributeName].forEach(function (importItem) {
100
88
  var _importItem$namedSpec;
101
89
  var importNode = source.ast.body.filter(isImportDeclaration).find(function (node) {
102
- return node.source.value.includes(importItem.moduleSpecifier);
90
+ return node && node.source.value && typeof node.source.value === 'string' && node.source.value.includes(importItem.moduleSpecifier);
103
91
  });
104
92
  if (!importNode) {
105
93
  return;
@@ -4,7 +4,7 @@ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length)
4
4
  import { isNodeOfType } from 'eslint-codemod-utils';
5
5
  import { addToListOfRanges, canAutoMigrateNewIconBasedOnSize, canMigrateColor, createAutoMigrationError, createCantFindSuitableReplacementError, createCantMigrateColorError, createCantMigrateFunctionUnknownError, createCantMigrateIdentifierError, createCantMigrateIdentifierMapOrArrayError, createCantMigrateReExportError, createCantMigrateSizeUnknown, createCantMigrateSpreadPropsError, createGuidance, createHelpers, getMigrationMapObject, getUpcomingIcons, isInsideLegacyButton, isInsideNewButton, isSize, locToString, throwAutoErrors, throwManualErrors } from './helpers';
6
6
  export var createChecks = function createChecks(context) {
7
- //create global variables to be shared by the checks
7
+ // Create global variables to be shared by the checks
8
8
  var _createHelpers = createHelpers(context),
9
9
  getPrimaryColor = _createHelpers.getPrimaryColor,
10
10
  getConfigFlag = _createHelpers.getConfigFlag;
@@ -21,6 +21,7 @@ export var createChecks = function createChecks(context) {
21
21
  var shouldErrorForAutoMigration = getConfigFlag('shouldErrorForAutoMigration', true);
22
22
  var isQuietMode = getConfigFlag('quiet', false);
23
23
  var shouldUseMigrationPath = getConfigFlag('shouldUseMigrationPath', true);
24
+ var shouldUseSafeMigrationMode = getConfigFlag('shouldUseSafeMigrationMode', false);
24
25
 
25
26
  // Sorted list of ranges
26
27
  var errorRanges = [];
@@ -405,10 +406,11 @@ export var createChecks = function createChecks(context) {
405
406
  // Find size prop on node
406
407
  var size = 'medium';
407
408
  var primaryColor = null;
409
+ var hasPrimaryColorProp = false;
410
+ var hasSecondaryColorProp = false;
408
411
  var afterSpreadSet = new Set();
409
412
  var requiredAttributesAfterSpread = new Set(['size', 'primaryColor', 'secondaryColor']);
410
413
  var hasSpread = false;
411
- var hasPrimaryColorProp = false;
412
414
  var _iterator8 = _createForOfIteratorHelper(node.openingElement.attributes),
413
415
  _step8;
414
416
  try {
@@ -443,6 +445,9 @@ export var createChecks = function createChecks(context) {
443
445
  primaryColor = getPrimaryColor(attr);
444
446
  hasPrimaryColorProp = true;
445
447
  break;
448
+ case 'secondaryColor':
449
+ hasSecondaryColorProp = true;
450
+ break;
446
451
  }
447
452
  }
448
453
  } catch (err) {
@@ -451,6 +456,8 @@ export var createChecks = function createChecks(context) {
451
456
  _iterator8.f();
452
457
  }
453
458
  var hasManualMigration = false;
459
+
460
+ // Flag manual migration if primary color cannot be migrated
454
461
  if (primaryColor && !canMigrateColor(primaryColor) || hasPrimaryColorProp && !primaryColor) {
455
462
  createCantMigrateColorError(node, primaryColor ? "the value of '".concat(primaryColor, "'") : 'a statically unknown value', errorsManual, legacyIconImports[name].packageName, name);
456
463
  hasManualMigration = true;
@@ -462,6 +469,7 @@ export var createChecks = function createChecks(context) {
462
469
  createCantMigrateSizeUnknown(node, errorsManual, legacyIconImports[name].packageName, name);
463
470
  hasManualMigration = true;
464
471
  }
472
+
465
473
  // Do a set comparison - is requiredAttributesAfterSpread a subset of afterSpreadSet?
466
474
  if (hasSpread === true && !Array.from(requiredAttributesAfterSpread).every(function (val) {
467
475
  return afterSpreadSet.has(val);
@@ -472,6 +480,7 @@ export var createChecks = function createChecks(context) {
472
480
  createCantMigrateSpreadPropsError(node, missingProps, errorsManual, legacyIconImports[name].packageName, name);
473
481
  hasManualMigration = true;
474
482
  }
483
+
475
484
  // Check if it is an exported component?
476
485
  if (legacyIconImports[name].exported) {
477
486
  createCantMigrateReExportError(node, legacyIconImports[name].packageName, name, errorsManual);
@@ -501,7 +510,9 @@ export var createChecks = function createChecks(context) {
501
510
  spacing = 'spacious';
502
511
  }
503
512
  }
504
- if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
513
+ if (shouldUseSafeMigrationMode && !hasManualMigration && (newIcon !== null && newIcon !== void 0 && newIcon.isMigrationUnsafe || size !== 'medium' || hasSecondaryColorProp)) {
514
+ createCantFindSuitableReplacementError(node, legacyIconImports[name].packageName, name, errorsManual, upcomingIcon ? true : migrationMapObject ? true : false);
515
+ } else if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
505
516
  createAutoMigrationError({
506
517
  node: node,
507
518
  importSource: legacyIconImports[name].packageName,
@@ -470,8 +470,7 @@ var createPropFixes = function createPropFixes(_ref7) {
470
470
  migrationImportNode = _ref7.migrationImportNode,
471
471
  newIconName = _ref7.newIconName;
472
472
  var fixes = [];
473
- var spacing = metadata.spacing,
474
- insideNewButton = metadata.insideNewButton;
473
+ var spacing = metadata.spacing;
475
474
  if (shouldUseMigrationPath && !legacyImportNode) {
476
475
  return fixes;
477
476
  }
@@ -488,16 +487,6 @@ var createPropFixes = function createPropFixes(_ref7) {
488
487
  fixes.push(fixer.replaceText(primaryColor.name, 'color'));
489
488
  }
490
489
 
491
- // add color="currentColor" if
492
- // 1. primaryColor prop is not set
493
- // 2. icon is not imported from migration entrypoint
494
- // 3. icon element is not inside a new button
495
- if (legacyImportNode && !primaryColor && !migrationImportNode &&
496
- // value type need to be a string in Rule.ReportDescriptor
497
- insideNewButton !== 'true') {
498
- fixes.push(fixer.insertTextAfter(openingElement.name, " color=\"currentColor\""));
499
- }
500
-
501
490
  // rename or remove size prop based on shouldUseMigrationPath,
502
491
  // add spacing="spacious" if
503
492
  // 1. it's in error metadata, which means size is medium
@@ -627,12 +616,12 @@ export var throwAutoErrors = function throwAutoErrors(_ref10) {
627
616
  }
628
617
  return result;
629
618
  }, new Set());
630
- //group errors by import source and remove any unwanted errors
619
+ // Group errors by import source and remove any unwanted errors
631
620
  var groupedErrorList = Object.entries(errorsAuto).reduce(function (result, option) {
632
621
  var _option2 = _slicedToArray(option, 2),
633
622
  key = _option2[0],
634
623
  error = _option2[1];
635
- //return early if no data
624
+ // Return early if no data
636
625
  if (!error.data) {
637
626
  return result;
638
627
  }
@@ -22,6 +22,9 @@ var rule = createLintRule({
22
22
  shouldErrorForAutoMigration: {
23
23
  type: 'boolean'
24
24
  },
25
+ shouldUseSafeMigrationMode: {
26
+ type: 'boolean'
27
+ },
25
28
  quiet: {
26
29
  type: 'boolean'
27
30
  },
@@ -20,7 +20,8 @@ export var ruleSchema = {
20
20
  var defaultConfig = {
21
21
  failSilently: false,
22
22
  shouldEnforceFallbacks: false,
23
- enableUnsafeAutofix: false
23
+ enableUnsafeAutofix: false,
24
+ patterns: ['style-object']
24
25
  };
25
26
  export var getConfig = function getConfig(overrides) {
26
27
  return Object.assign({}, defaultConfig, overrides);
@@ -1,18 +1,26 @@
1
1
  import { createLintRule } from '../utils/create-rule';
2
2
  import { errorBoundary } from '../utils/error-boundary';
3
3
  import { getConfig, ruleSchema } from './config';
4
+ import { FontWeight } from './transformers/font-weight';
4
5
  import { StyleObject } from './transformers/style-object';
5
6
  var create = function create(context) {
6
7
  var config = getConfig(context.options[0]);
7
- return {
8
- // const styles = css({ fontSize: '14px, ... }), styled.div({ fontSize: 14, ... })
9
- ObjectExpression: errorBoundary(function (node) {
8
+ return errorBoundary({
9
+ // const styles = css({ fontSize: '14px', ... }), styled.div({ fontSize: 14, ... })
10
+ ObjectExpression: function ObjectExpression(node) {
10
11
  return StyleObject.lint(node, {
11
12
  context: context,
12
13
  config: config
13
14
  });
14
- }, config)
15
- };
15
+ },
16
+ // const styles = css({ fontWeight: 600, 'bold', ... })
17
+ 'ObjectExpression > Property > Identifier[name=/fontWeight/]': function ObjectExpressionPropertyIdentifierNameFontWeight(node) {
18
+ return FontWeight.lint(node, {
19
+ context: context,
20
+ config: config
21
+ });
22
+ }
23
+ }, config);
16
24
  };
17
25
  var rule = createLintRule({
18
26
  meta: {
@@ -26,7 +34,8 @@ var rule = createLintRule({
26
34
  severity: 'warn'
27
35
  },
28
36
  messages: {
29
- noRawTypographyValues: 'Typography primitives or tokens should be used instead of hard-coded values.\n\n@meta <<{{payload}}>>.\n\nNOTE: Using tokens with the `fontSize` property is invalid. Any `font.heading` or `font.body` tokens must use the CSS `font` property.'
37
+ noRawTypographyValues: 'Typography primitives or tokens should be used instead of hard-coded values.\n\n@meta <<{{payload}}>>.\n\nNOTE: Using tokens with the `fontSize` property is invalid. Any `font.heading` or `font.body` tokens must use the CSS `font` property.',
38
+ noRawFontWeightValues: 'Font weight tokens should be used instead of hard-coded values.'
30
39
  },
31
40
  schema: ruleSchema
32
41
  },
@@ -0,0 +1,90 @@
1
+ /* eslint-disable @repo/internal/react/require-jsdoc */
2
+
3
+ import { isNodeOfType } from 'eslint-codemod-utils';
4
+ import { Root } from '../../../ast-nodes';
5
+ import { getValueForPropertyNode } from '../../ensure-design-token-usage/utils';
6
+ import { isDecendantOfStyleBlock, isDecendantOfType } from '../../utils/is-node';
7
+ import { findFontWeightTokenForValue, insertTokensImport } from '../utils';
8
+ export var FontWeight = {
9
+ lint: function lint(node, _ref) {
10
+ var context = _ref.context,
11
+ config = _ref.config;
12
+ // To force the correct node type
13
+ if (!isNodeOfType(node, 'Identifier')) {
14
+ return;
15
+ }
16
+
17
+ // Check whether all criteria needed to make a transformation are met
18
+ var success = FontWeight._check(node, {
19
+ context: context,
20
+ config: config
21
+ });
22
+ if (success) {
23
+ return context.report({
24
+ node: node,
25
+ messageId: 'noRawFontWeightValues',
26
+ fix: FontWeight._fix(node, context)
27
+ });
28
+ }
29
+ },
30
+ _check: function _check(node, _ref2) {
31
+ var context = _ref2.context,
32
+ config = _ref2.config;
33
+ if (!config.patterns.includes('font-weight')) {
34
+ return false;
35
+ }
36
+ if (!isDecendantOfStyleBlock(node) && !isDecendantOfType(node, 'JSXExpressionContainer')) {
37
+ return false;
38
+ }
39
+ if (!isNodeOfType(node.parent, 'Property')) {
40
+ return false;
41
+ }
42
+ var fontWeightValue = getValueForPropertyNode(node.parent, context);
43
+ if (typeof fontWeightValue === 'string' && fontWeightValue.includes('font.weight.')) {
44
+ return false;
45
+ }
46
+ return true;
47
+ },
48
+ _fix: function _fix(node, context) {
49
+ return function (fixer) {
50
+ var _findFontWeightTokenF;
51
+ var fixes = [];
52
+
53
+ // -- Type assertions to force the correct node type --
54
+
55
+ if (!isNodeOfType(node.parent, 'Property')) {
56
+ return [];
57
+ }
58
+ if (!isNodeOfType(node.parent.value, 'Literal')) {
59
+ return [];
60
+ }
61
+ if (!node.parent.value.raw) {
62
+ return [];
63
+ }
64
+
65
+ // -- Fix: Replace raw value with token --
66
+
67
+ var matchingToken = (_findFontWeightTokenF = findFontWeightTokenForValue(node.parent.value.raw)) === null || _findFontWeightTokenF === void 0 ? void 0 : _findFontWeightTokenF.tokenName;
68
+ if (!matchingToken) {
69
+ return [];
70
+ }
71
+ var fontWeightValueFix = fixer.replaceText(node.parent.value, "token('".concat(matchingToken, "')"));
72
+ fixes.push(fontWeightValueFix);
73
+
74
+ // -- Fix: Add import if it doesn't exist --
75
+
76
+ var body = context.sourceCode.ast.body;
77
+ var tokensImportDeclarations = Root.findImportsByModule(body, '@atlaskit/tokens');
78
+
79
+ // If there is more than one `@atlaskit/tokens` import, then it becomes difficult to determine which import to transform
80
+ if (tokensImportDeclarations.length > 1) {
81
+ return fixes;
82
+ }
83
+ var tokensImportDeclaration = tokensImportDeclarations[0];
84
+ if (!tokensImportDeclaration) {
85
+ fixes.push(insertTokensImport(body, fixer));
86
+ }
87
+ return fixes;
88
+ };
89
+ }
90
+ };
@@ -199,6 +199,11 @@ export var StyleObject = {
199
199
  _check: function _check(node, _ref2) {
200
200
  var context = _ref2.context,
201
201
  config = _ref2.config;
202
+ if (!config.patterns.includes('style-object')) {
203
+ return {
204
+ success: false
205
+ };
206
+ }
202
207
  if (!isDecendantOfStyleBlock(node) && !isDecendantOfType(node, 'JSXExpressionContainer')) {
203
208
  return {
204
209
  success: false
@@ -78,6 +78,12 @@ export var fontWeightTokens = typographyTokens.filter(function (token) {
78
78
  };
79
79
  });
80
80
  export function findFontWeightTokenForValue(fontWeight) {
81
+ if (fontWeight === "'normal'") {
82
+ fontWeight = '400';
83
+ }
84
+ if (fontWeight === "'bold'") {
85
+ fontWeight = '700';
86
+ }
81
87
  return fontWeightTokens.find(function (token) {
82
88
  return token.tokenValue === fontWeight;
83
89
  });
@@ -13,9 +13,7 @@ export declare const plugin: {
13
13
  'no-css-tagged-template-expression': import("eslint").Rule.RuleModule;
14
14
  'no-custom-icons': import("eslint").Rule.RuleModule;
15
15
  'no-dark-theme-vr-tests': import("eslint").Rule.RuleModule;
16
- 'no-deprecated-apis': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [{
17
- deprecatedConfig: import("./rules/utils/types").DeprecatedConfig;
18
- }], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
16
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
19
17
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
20
18
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
21
19
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -303,9 +301,7 @@ export declare const configs: {
303
301
  'no-css-tagged-template-expression': import("eslint").Rule.RuleModule;
304
302
  'no-custom-icons': import("eslint").Rule.RuleModule;
305
303
  'no-dark-theme-vr-tests': import("eslint").Rule.RuleModule;
306
- 'no-deprecated-apis': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [{
307
- deprecatedConfig: import("./rules/utils/types").DeprecatedConfig;
308
- }], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
304
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
309
305
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
310
306
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
311
307
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -448,9 +444,7 @@ export declare const configs: {
448
444
  'no-css-tagged-template-expression': import("eslint").Rule.RuleModule;
449
445
  'no-custom-icons': import("eslint").Rule.RuleModule;
450
446
  'no-dark-theme-vr-tests': import("eslint").Rule.RuleModule;
451
- 'no-deprecated-apis': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [{
452
- deprecatedConfig: import("./rules/utils/types").DeprecatedConfig;
453
- }], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
447
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
454
448
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
455
449
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
456
450
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -8,9 +8,7 @@ export declare const rules: {
8
8
  'no-css-tagged-template-expression': import("eslint").Rule.RuleModule;
9
9
  'no-custom-icons': import("eslint").Rule.RuleModule;
10
10
  'no-dark-theme-vr-tests': import("eslint").Rule.RuleModule;
11
- 'no-deprecated-apis': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [{
12
- deprecatedConfig: import("./utils/types").DeprecatedConfig;
13
- }], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
11
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
14
12
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
15
13
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
16
14
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -1,7 +1,5 @@
1
- import { type DeprecatedConfig } from '../utils/types';
1
+ import type { Rule } from 'eslint';
2
2
  export declare const noDeprecatedJSXAttributeMessageId = "noDeprecatedJSXAttributes";
3
3
  export declare const name = "no-deprecated-apis";
4
- declare const rule: import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [{
5
- deprecatedConfig: DeprecatedConfig;
6
- }], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
4
+ declare const rule: Rule.RuleModule;
7
5
  export default rule;
@@ -48,6 +48,7 @@ export declare const getMigrationMapObject: (iconPackage: string) => {
48
48
  name: string;
49
49
  type: string;
50
50
  package: string;
51
+ isMigrationUnsafe?: boolean | undefined;
51
52
  } | undefined;
52
53
  additionalIcons?: {
53
54
  name: string;
@@ -1,8 +1,11 @@
1
1
  import { type JSONSchema4 } from '@typescript-eslint/utils/dist/json-schema';
2
+ type Pattern = 'style-object' | 'font-weight';
2
3
  export type RuleConfig = {
3
4
  failSilently: boolean;
4
5
  shouldEnforceFallbacks: boolean;
5
6
  enableUnsafeAutofix: boolean;
7
+ patterns: Pattern[];
6
8
  };
7
9
  export declare const ruleSchema: JSONSchema4;
8
10
  export declare const getConfig: (overrides: Partial<RuleConfig>) => RuleConfig;
11
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { Rule } from 'eslint';
2
+ import { Identifier } from 'eslint-codemod-utils';
3
+ import { type RuleConfig } from '../config';
4
+ interface MetaData {
5
+ context: Rule.RuleContext;
6
+ config: RuleConfig;
7
+ }
8
+ export declare const FontWeight: {
9
+ lint(node: Rule.Node, { context, config }: MetaData): void;
10
+ _check(node: Identifier & Rule.NodeParentExtension, { context, config }: MetaData): boolean;
11
+ _fix(node: Identifier & Rule.NodeParentExtension, context: Rule.RuleContext): (fixer: Rule.RuleFixer) => Rule.Fix[];
12
+ };
13
+ export {};