@atlaskit/eslint-plugin-design-system 11.1.0 → 11.2.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/eslint-plugin-design-system
2
2
 
3
+ ## 11.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#175583](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/175583)
8
+ [`75911cb003bd5`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/75911cb003bd5) - ####
9
+ no-legacy-icons
10
+
11
+ Add new `shouldUseSafeMigrationMode` flag to no-legacy-icons rule. When set to true, the autofixer
12
+ will only attempt to migrate icons that are visually similar and do not include secondary colors
13
+ or sizes other than medium.
14
+
15
+ Additionally, the autofixer will no longer attempt to explicity add `color="currentColor"` for
16
+ every migration as this is now the default.
17
+
18
+ #### no-deprecated-apis
19
+
20
+ Refactored to fix type errors and match code style of other rules.
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies
25
+
3
26
  ## 11.1.0
4
27
 
5
28
  ### Minor Changes
@@ -1,43 +1,36 @@
1
1
  "use strict";
2
2
 
3
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
3
  Object.defineProperty(exports, "__esModule", {
5
4
  value: true
6
5
  });
7
6
  exports.noDeprecatedJSXAttributeMessageId = exports.name = exports.default = void 0;
8
- var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
- var _utils = require("@typescript-eslint/utils");
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
10
8
  var _createRule = require("../utils/create-rule");
11
9
  var _getDeprecatedConfig = require("../utils/get-deprecated-config");
12
10
  var _types = require("../utils/types");
13
11
  var noDeprecatedJSXAttributeMessageId = exports.noDeprecatedJSXAttributeMessageId = 'noDeprecatedJSXAttributes';
14
- var isNodeOfType = function isNodeOfType(node, nodeType) {
15
- return _utils.ASTUtils.isNodeOfType(nodeType)(node);
16
- };
17
12
  var isImportDeclaration = function isImportDeclaration(programStatement) {
18
13
  return (programStatement === null || programStatement === void 0 ? void 0 : programStatement.type) === 'ImportDeclaration';
19
14
  };
20
15
  var findJSXElementName = function findJSXElementName(jsxAttributeNode) {
21
- if (!jsxAttributeNode.parent || !isNodeOfType(jsxAttributeNode.parent, _utils.AST_NODE_TYPES.JSXOpeningElement)) {
16
+ if (!jsxAttributeNode.parent || !(0, _eslintCodemodUtils.isNodeOfType)(jsxAttributeNode === null || jsxAttributeNode === void 0 ? void 0 : jsxAttributeNode.parent, 'JSXOpeningElement')) {
22
17
  return;
23
18
  }
24
19
  var openingElement = jsxAttributeNode.parent;
25
- if (!isNodeOfType(openingElement.name, _utils.AST_NODE_TYPES.JSXIdentifier)) {
20
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(openingElement.name, 'JSXIdentifier')) {
26
21
  return;
27
22
  }
28
23
  return openingElement.name.name;
29
24
  };
30
25
  var name = exports.name = 'no-deprecated-apis';
31
- var rule = (0, _createRule.createRule)({
32
- name: name,
33
- defaultOptions: [{
34
- deprecatedConfig: (0, _getDeprecatedConfig.getConfig)('jsxAttributes')
35
- }],
26
+ var rule = (0, _createRule.createLintRule)({
36
27
  meta: {
28
+ name: name,
37
29
  type: 'suggestion',
38
30
  docs: {
39
31
  description: 'Disallow using deprecated APIs.',
40
- recommended: 'strict'
32
+ recommended: true,
33
+ severity: 'error'
41
34
  },
42
35
  messages: {
43
36
  noDeprecatedJSXAttributes: 'The JSX attribute {{propName}} has been deprecated.'
@@ -75,24 +68,18 @@ var rule = (0, _createRule.createRule)({
75
68
  }
76
69
  }]
77
70
  },
78
- create: function create(context, _ref) {
71
+ create: function create(context) {
79
72
  var _context$options$;
80
- var _ref2 = (0, _slicedToArray2.default)(_ref, 1),
81
- options = _ref2[0];
82
- // Get rule configuration
83
- var defaultDeprecatedConfig = options.deprecatedConfig;
84
-
85
73
  // Get the rule configuration specified otherwise use default config.
86
74
  // A bit confusing as it seems that the default options have precedence over the user specified options.
87
- var deprecatedConfig = ((_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.deprecatedConfig) || defaultDeprecatedConfig;
75
+ var deprecatedConfig = ((_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.deprecatedConfig) || (0, _getDeprecatedConfig.getConfig)('jsxAttributes');
88
76
  return {
89
77
  // find JSX atribute - find name of attribute - get source and find relevant identifiers.
90
78
  JSXAttribute: function JSXAttribute(node) {
91
- var jsxAttributeIdentifier = node.name;
92
- if (!isNodeOfType(jsxAttributeIdentifier, _utils.AST_NODE_TYPES.JSXIdentifier)) {
79
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXAttribute') || !(0, _eslintCodemodUtils.isNodeOfType)(node.name, 'JSXIdentifier')) {
93
80
  return;
94
81
  }
95
- var jsxAttributeName = jsxAttributeIdentifier.name;
82
+ var jsxAttributeName = node.name.name;
96
83
  if (!(0, _types.isDeprecatedJSXAttributeConfig)(deprecatedConfig) || !deprecatedConfig[jsxAttributeName]) {
97
84
  return;
98
85
  }
@@ -100,13 +87,13 @@ var rule = (0, _createRule.createRule)({
100
87
  if (!jsxElementName) {
101
88
  return;
102
89
  }
103
- var source = context.getSourceCode();
90
+ var source = context.sourceCode;
104
91
 
105
92
  // find an import for the path of the banned api
106
93
  deprecatedConfig[jsxAttributeName].forEach(function (importItem) {
107
94
  var _importItem$namedSpec;
108
95
  var importNode = source.ast.body.filter(isImportDeclaration).find(function (node) {
109
- return node.source.value.includes(importItem.moduleSpecifier);
96
+ return node && node.source.value && typeof node.source.value === 'string' && node.source.value.includes(importItem.moduleSpecifier);
110
97
  });
111
98
  if (!importNode) {
112
99
  return;
@@ -10,7 +10,7 @@ function _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol
10
10
  function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
11
11
  function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
12
12
  var createChecks = exports.createChecks = function createChecks(context) {
13
- //create global variables to be shared by the checks
13
+ // Create global variables to be shared by the checks
14
14
  var _createHelpers = (0, _helpers.createHelpers)(context),
15
15
  getPrimaryColor = _createHelpers.getPrimaryColor,
16
16
  getConfigFlag = _createHelpers.getConfigFlag;
@@ -27,6 +27,7 @@ var createChecks = exports.createChecks = function createChecks(context) {
27
27
  var shouldErrorForAutoMigration = getConfigFlag('shouldErrorForAutoMigration', true);
28
28
  var isQuietMode = getConfigFlag('quiet', false);
29
29
  var shouldUseMigrationPath = getConfigFlag('shouldUseMigrationPath', true);
30
+ var shouldUseSafeMigrationMode = getConfigFlag('shouldUseSafeMigrationMode', false);
30
31
 
31
32
  // Sorted list of ranges
32
33
  var errorRanges = [];
@@ -411,10 +412,11 @@ var createChecks = exports.createChecks = function createChecks(context) {
411
412
  // Find size prop on node
412
413
  var size = 'medium';
413
414
  var primaryColor = null;
415
+ var hasPrimaryColorProp = false;
416
+ var hasSecondaryColorProp = false;
414
417
  var afterSpreadSet = new Set();
415
418
  var requiredAttributesAfterSpread = new Set(['size', 'primaryColor', 'secondaryColor']);
416
419
  var hasSpread = false;
417
- var hasPrimaryColorProp = false;
418
420
  var _iterator8 = _createForOfIteratorHelper(node.openingElement.attributes),
419
421
  _step8;
420
422
  try {
@@ -449,6 +451,9 @@ var createChecks = exports.createChecks = function createChecks(context) {
449
451
  primaryColor = getPrimaryColor(attr);
450
452
  hasPrimaryColorProp = true;
451
453
  break;
454
+ case 'secondaryColor':
455
+ hasSecondaryColorProp = true;
456
+ break;
452
457
  }
453
458
  }
454
459
  } catch (err) {
@@ -457,6 +462,8 @@ var createChecks = exports.createChecks = function createChecks(context) {
457
462
  _iterator8.f();
458
463
  }
459
464
  var hasManualMigration = false;
465
+
466
+ // Flag manual migration if primary color cannot be migrated
460
467
  if (primaryColor && !(0, _helpers.canMigrateColor)(primaryColor) || hasPrimaryColorProp && !primaryColor) {
461
468
  (0, _helpers.createCantMigrateColorError)(node, primaryColor ? "the value of '".concat(primaryColor, "'") : 'a statically unknown value', errorsManual, legacyIconImports[name].packageName, name);
462
469
  hasManualMigration = true;
@@ -468,6 +475,7 @@ var createChecks = exports.createChecks = function createChecks(context) {
468
475
  (0, _helpers.createCantMigrateSizeUnknown)(node, errorsManual, legacyIconImports[name].packageName, name);
469
476
  hasManualMigration = true;
470
477
  }
478
+
471
479
  // Do a set comparison - is requiredAttributesAfterSpread a subset of afterSpreadSet?
472
480
  if (hasSpread === true && !Array.from(requiredAttributesAfterSpread).every(function (val) {
473
481
  return afterSpreadSet.has(val);
@@ -478,6 +486,7 @@ var createChecks = exports.createChecks = function createChecks(context) {
478
486
  (0, _helpers.createCantMigrateSpreadPropsError)(node, missingProps, errorsManual, legacyIconImports[name].packageName, name);
479
487
  hasManualMigration = true;
480
488
  }
489
+
481
490
  // Check if it is an exported component?
482
491
  if (legacyIconImports[name].exported) {
483
492
  (0, _helpers.createCantMigrateReExportError)(node, legacyIconImports[name].packageName, name, errorsManual);
@@ -507,7 +516,9 @@ var createChecks = exports.createChecks = function createChecks(context) {
507
516
  spacing = 'spacious';
508
517
  }
509
518
  }
510
- if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
519
+ if (shouldUseSafeMigrationMode && !hasManualMigration && (newIcon !== null && newIcon !== void 0 && newIcon.isMigrationUnsafe || size !== 'medium' || hasSecondaryColorProp)) {
520
+ (0, _helpers.createCantFindSuitableReplacementError)(node, legacyIconImports[name].packageName, name, errorsManual, upcomingIcon ? true : migrationMapObject ? true : false);
521
+ } else if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
511
522
  (0, _helpers.createAutoMigrationError)({
512
523
  node: node,
513
524
  importSource: legacyIconImports[name].packageName,
@@ -480,8 +480,7 @@ var createPropFixes = function createPropFixes(_ref7) {
480
480
  migrationImportNode = _ref7.migrationImportNode,
481
481
  newIconName = _ref7.newIconName;
482
482
  var fixes = [];
483
- var spacing = metadata.spacing,
484
- insideNewButton = metadata.insideNewButton;
483
+ var spacing = metadata.spacing;
485
484
  if (shouldUseMigrationPath && !legacyImportNode) {
486
485
  return fixes;
487
486
  }
@@ -498,16 +497,6 @@ var createPropFixes = function createPropFixes(_ref7) {
498
497
  fixes.push(fixer.replaceText(primaryColor.name, 'color'));
499
498
  }
500
499
 
501
- // add color="currentColor" if
502
- // 1. primaryColor prop is not set
503
- // 2. icon is not imported from migration entrypoint
504
- // 3. icon element is not inside a new button
505
- if (legacyImportNode && !primaryColor && !migrationImportNode &&
506
- // value type need to be a string in Rule.ReportDescriptor
507
- insideNewButton !== 'true') {
508
- fixes.push(fixer.insertTextAfter(openingElement.name, " color=\"currentColor\""));
509
- }
510
-
511
500
  // rename or remove size prop based on shouldUseMigrationPath,
512
501
  // add spacing="spacious" if
513
502
  // 1. it's in error metadata, which means size is medium
@@ -637,12 +626,12 @@ var throwAutoErrors = exports.throwAutoErrors = function throwAutoErrors(_ref10)
637
626
  }
638
627
  return result;
639
628
  }, new Set());
640
- //group errors by import source and remove any unwanted errors
629
+ // Group errors by import source and remove any unwanted errors
641
630
  var groupedErrorList = Object.entries(errorsAuto).reduce(function (result, option) {
642
631
  var _option2 = (0, _slicedToArray2.default)(option, 2),
643
632
  key = _option2[0],
644
633
  error = _option2[1];
645
- //return early if no data
634
+ // Return early if no data
646
635
  if (!error.data) {
647
636
  return result;
648
637
  }
@@ -28,6 +28,9 @@ var rule = (0, _createRule.createLintRule)({
28
28
  shouldErrorForAutoMigration: {
29
29
  type: 'boolean'
30
30
  },
31
+ shouldUseSafeMigrationMode: {
32
+ type: 'boolean'
33
+ },
31
34
  quiet: {
32
35
  type: 'boolean'
33
36
  },
@@ -1,33 +1,30 @@
1
- import { AST_NODE_TYPES, ASTUtils } from '@typescript-eslint/utils';
2
- import { createRule } from '../utils/create-rule';
1
+ import { isNodeOfType } from 'eslint-codemod-utils';
2
+ import { createLintRule } from '../utils/create-rule';
3
3
  import { getConfig } from '../utils/get-deprecated-config';
4
4
  import { isDeprecatedJSXAttributeConfig } from '../utils/types';
5
5
  export const noDeprecatedJSXAttributeMessageId = 'noDeprecatedJSXAttributes';
6
- const isNodeOfType = (node, nodeType) => ASTUtils.isNodeOfType(nodeType)(node);
7
6
  const isImportDeclaration = programStatement => {
8
7
  return (programStatement === null || programStatement === void 0 ? void 0 : programStatement.type) === 'ImportDeclaration';
9
8
  };
10
9
  const findJSXElementName = jsxAttributeNode => {
11
- 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')) {
12
11
  return;
13
12
  }
14
13
  const openingElement = jsxAttributeNode.parent;
15
- if (!isNodeOfType(openingElement.name, AST_NODE_TYPES.JSXIdentifier)) {
14
+ if (!isNodeOfType(openingElement.name, 'JSXIdentifier')) {
16
15
  return;
17
16
  }
18
17
  return openingElement.name.name;
19
18
  };
20
19
  export const name = 'no-deprecated-apis';
21
- const rule = createRule({
22
- name,
23
- defaultOptions: [{
24
- deprecatedConfig: getConfig('jsxAttributes')
25
- }],
20
+ const rule = createLintRule({
26
21
  meta: {
22
+ name,
27
23
  type: 'suggestion',
28
24
  docs: {
29
25
  description: 'Disallow using deprecated APIs.',
30
- recommended: 'strict'
26
+ recommended: true,
27
+ severity: 'error'
31
28
  },
32
29
  messages: {
33
30
  noDeprecatedJSXAttributes: 'The JSX attribute {{propName}} has been deprecated.'
@@ -65,24 +62,18 @@ const rule = createRule({
65
62
  }
66
63
  }]
67
64
  },
68
- create(context, [options]) {
65
+ create(context) {
69
66
  var _context$options$;
70
- // Get rule configuration
71
- const {
72
- deprecatedConfig: defaultDeprecatedConfig
73
- } = options;
74
-
75
67
  // Get the rule configuration specified otherwise use default config.
76
68
  // A bit confusing as it seems that the default options have precedence over the user specified options.
77
- const deprecatedConfig = ((_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.deprecatedConfig) || defaultDeprecatedConfig;
69
+ const deprecatedConfig = ((_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.deprecatedConfig) || getConfig('jsxAttributes');
78
70
  return {
79
71
  // find JSX atribute - find name of attribute - get source and find relevant identifiers.
80
72
  JSXAttribute(node) {
81
- const jsxAttributeIdentifier = node.name;
82
- if (!isNodeOfType(jsxAttributeIdentifier, AST_NODE_TYPES.JSXIdentifier)) {
73
+ if (!isNodeOfType(node, 'JSXAttribute') || !isNodeOfType(node.name, 'JSXIdentifier')) {
83
74
  return;
84
75
  }
85
- const jsxAttributeName = jsxAttributeIdentifier.name;
76
+ const jsxAttributeName = node.name.name;
86
77
  if (!isDeprecatedJSXAttributeConfig(deprecatedConfig) || !deprecatedConfig[jsxAttributeName]) {
87
78
  return;
88
79
  }
@@ -90,12 +81,12 @@ const rule = createRule({
90
81
  if (!jsxElementName) {
91
82
  return;
92
83
  }
93
- const source = context.getSourceCode();
84
+ const source = context.sourceCode;
94
85
 
95
86
  // find an import for the path of the banned api
96
87
  deprecatedConfig[jsxAttributeName].forEach(importItem => {
97
88
  var _importItem$namedSpec;
98
- const importNode = source.ast.body.filter(isImportDeclaration).find(node => node.source.value.includes(importItem.moduleSpecifier));
89
+ const importNode = source.ast.body.filter(isImportDeclaration).find(node => node && node.source.value && typeof node.source.value === 'string' && node.source.value.includes(importItem.moduleSpecifier));
99
90
  if (!importNode) {
100
91
  return;
101
92
  }
@@ -1,7 +1,7 @@
1
1
  import { isNodeOfType } from 'eslint-codemod-utils';
2
2
  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';
3
3
  export const createChecks = context => {
4
- //create global variables to be shared by the checks
4
+ // Create global variables to be shared by the checks
5
5
  const {
6
6
  getPrimaryColor,
7
7
  getConfigFlag
@@ -19,6 +19,7 @@ export const createChecks = context => {
19
19
  const shouldErrorForAutoMigration = getConfigFlag('shouldErrorForAutoMigration', true);
20
20
  const isQuietMode = getConfigFlag('quiet', false);
21
21
  const shouldUseMigrationPath = getConfigFlag('shouldUseMigrationPath', true);
22
+ const shouldUseSafeMigrationMode = getConfigFlag('shouldUseSafeMigrationMode', false);
22
23
 
23
24
  // Sorted list of ranges
24
25
  let errorRanges = [];
@@ -334,10 +335,11 @@ export const createChecks = context => {
334
335
  // Find size prop on node
335
336
  let size = 'medium';
336
337
  let primaryColor = null;
338
+ let hasPrimaryColorProp = false;
339
+ let hasSecondaryColorProp = false;
337
340
  let afterSpreadSet = new Set();
338
341
  let requiredAttributesAfterSpread = new Set(['size', 'primaryColor', 'secondaryColor']);
339
342
  let hasSpread = false;
340
- let hasPrimaryColorProp = false;
341
343
  for (const attr of node.openingElement.attributes) {
342
344
  // Detect spread props
343
345
  if (isNodeOfType(attr, 'JSXSpreadAttribute')) {
@@ -368,9 +370,14 @@ export const createChecks = context => {
368
370
  primaryColor = getPrimaryColor(attr);
369
371
  hasPrimaryColorProp = true;
370
372
  break;
373
+ case 'secondaryColor':
374
+ hasSecondaryColorProp = true;
375
+ break;
371
376
  }
372
377
  }
373
378
  let hasManualMigration = false;
379
+
380
+ // Flag manual migration if primary color cannot be migrated
374
381
  if (primaryColor && !canMigrateColor(primaryColor) || hasPrimaryColorProp && !primaryColor) {
375
382
  createCantMigrateColorError(node, primaryColor ? `the value of '${primaryColor}'` : 'a statically unknown value', errorsManual, legacyIconImports[name].packageName, name);
376
383
  hasManualMigration = true;
@@ -382,12 +389,14 @@ export const createChecks = context => {
382
389
  createCantMigrateSizeUnknown(node, errorsManual, legacyIconImports[name].packageName, name);
383
390
  hasManualMigration = true;
384
391
  }
392
+
385
393
  // Do a set comparison - is requiredAttributesAfterSpread a subset of afterSpreadSet?
386
394
  if (hasSpread === true && !Array.from(requiredAttributesAfterSpread).every(val => afterSpreadSet.has(val)) && !insideNewButton) {
387
395
  const missingProps = Array.from(requiredAttributesAfterSpread).filter(val => !afterSpreadSet.has(val));
388
396
  createCantMigrateSpreadPropsError(node, missingProps, errorsManual, legacyIconImports[name].packageName, name);
389
397
  hasManualMigration = true;
390
398
  }
399
+
391
400
  // Check if it is an exported component?
392
401
  if (legacyIconImports[name].exported) {
393
402
  createCantMigrateReExportError(node, legacyIconImports[name].packageName, name, errorsManual);
@@ -415,7 +424,9 @@ export const createChecks = context => {
415
424
  spacing = 'spacious';
416
425
  }
417
426
  }
418
- if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
427
+ if (shouldUseSafeMigrationMode && !hasManualMigration && (newIcon !== null && newIcon !== void 0 && newIcon.isMigrationUnsafe || size !== 'medium' || hasSecondaryColorProp)) {
428
+ createCantFindSuitableReplacementError(node, legacyIconImports[name].packageName, name, errorsManual, upcomingIcon ? true : migrationMapObject ? true : false);
429
+ } else if (!hasManualMigration && (newIcon || upcomingIcon) && isNewIconMigratable) {
419
430
  createAutoMigrationError({
420
431
  node,
421
432
  importSource: legacyIconImports[name].packageName,
@@ -462,8 +462,7 @@ const createPropFixes = ({
462
462
  }) => {
463
463
  const fixes = [];
464
464
  const {
465
- spacing,
466
- insideNewButton
465
+ spacing
467
466
  } = metadata;
468
467
  if (shouldUseMigrationPath && !legacyImportNode) {
469
468
  return fixes;
@@ -485,16 +484,6 @@ const createPropFixes = ({
485
484
  fixes.push(fixer.replaceText(primaryColor.name, 'color'));
486
485
  }
487
486
 
488
- // add color="currentColor" if
489
- // 1. primaryColor prop is not set
490
- // 2. icon is not imported from migration entrypoint
491
- // 3. icon element is not inside a new button
492
- if (legacyImportNode && !primaryColor && !migrationImportNode &&
493
- // value type need to be a string in Rule.ReportDescriptor
494
- insideNewButton !== 'true') {
495
- fixes.push(fixer.insertTextAfter(openingElement.name, ` color="currentColor"`));
496
- }
497
-
498
487
  // rename or remove size prop based on shouldUseMigrationPath,
499
488
  // add spacing="spacious" if
500
489
  // 1. it's in error metadata, which means size is medium
@@ -611,10 +600,10 @@ export const throwAutoErrors = ({
611
600
  }
612
601
  return result;
613
602
  }, new Set());
614
- //group errors by import source and remove any unwanted errors
603
+ // Group errors by import source and remove any unwanted errors
615
604
  const groupedErrorList = Object.entries(errorsAuto).reduce((result, option) => {
616
605
  const [key, error] = option;
617
- //return early if no data
606
+ // Return early if no data
618
607
  if (!error.data) {
619
608
  return result;
620
609
  }
@@ -22,6 +22,9 @@ const 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
  },
@@ -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
  },
@@ -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;
@@ -13,11 +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
- {
18
- deprecatedConfig: import("./rules/utils/types").DeprecatedConfig;
19
- }
20
- ], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
16
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
21
17
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
22
18
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
23
19
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -351,11 +347,7 @@ export declare const configs: {
351
347
  'no-css-tagged-template-expression': import("eslint").Rule.RuleModule;
352
348
  'no-custom-icons': import("eslint").Rule.RuleModule;
353
349
  'no-dark-theme-vr-tests': import("eslint").Rule.RuleModule;
354
- 'no-deprecated-apis': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [
355
- {
356
- deprecatedConfig: import("./rules/utils/types").DeprecatedConfig;
357
- }
358
- ], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
350
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
359
351
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
360
352
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
361
353
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -516,11 +508,7 @@ export declare const configs: {
516
508
  'no-css-tagged-template-expression': import("eslint").Rule.RuleModule;
517
509
  'no-custom-icons': import("eslint").Rule.RuleModule;
518
510
  'no-dark-theme-vr-tests': import("eslint").Rule.RuleModule;
519
- 'no-deprecated-apis': import("@typescript-eslint/utils/dist/ts-eslint").RuleModule<string, [
520
- {
521
- deprecatedConfig: import("./rules/utils/types").DeprecatedConfig;
522
- }
523
- ], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
511
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
524
512
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
525
513
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
526
514
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -8,11 +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
- {
13
- deprecatedConfig: import("./utils/types").DeprecatedConfig;
14
- }
15
- ], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
11
+ 'no-deprecated-apis': import("eslint").Rule.RuleModule;
16
12
  'no-deprecated-design-token-usage': import("eslint").Rule.RuleModule;
17
13
  'no-deprecated-imports': import("eslint").Rule.RuleModule;
18
14
  'no-direct-use-of-web-platform-drag-and-drop': import("eslint").Rule.RuleModule;
@@ -1,9 +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
- {
6
- deprecatedConfig: DeprecatedConfig;
7
- }
8
- ], import("@typescript-eslint/utils/dist/ts-eslint").RuleListener>;
4
+ declare const rule: Rule.RuleModule;
9
5
  export default rule;
@@ -53,6 +53,7 @@ export declare const getMigrationMapObject: (iconPackage: string) => {
53
53
  name: string;
54
54
  type: string;
55
55
  package: string;
56
+ isMigrationUnsafe?: boolean | undefined;
56
57
  } | undefined;
57
58
  additionalIcons?: {
58
59
  name: string;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@atlaskit/eslint-plugin-design-system",
3
3
  "description": "The essential plugin for use with the Atlassian Design System.",
4
- "version": "11.1.0",
4
+ "version": "11.2.0",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
7
7
  "publishConfig": {
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "@atlaskit/eslint-utils": "^1.7.0",
47
- "@atlaskit/icon": "^23.0.0",
47
+ "@atlaskit/icon": "^23.1.0",
48
48
  "@atlaskit/icon-lab": "^2.0.0",
49
49
  "@atlaskit/tokens": "*",
50
50
  "@babel/runtime": "^7.0.0",