@atlaskit/eslint-plugin-design-system 8.33.0 → 8.36.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 (124) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +1 -0
  3. package/constellation/ensure-design-token-usage/usage.mdx +2 -2
  4. package/constellation/index/usage.mdx +1 -0
  5. package/constellation/use-primitives-text/usage.mdx +13 -3
  6. package/constellation/use-tokens-typography/usage.mdx +42 -0
  7. package/dist/cjs/ast-nodes/index.js +7 -0
  8. package/dist/cjs/ast-nodes/object-entry.js +27 -0
  9. package/dist/cjs/ast-nodes/object.js +1 -1
  10. package/dist/cjs/presets/all.codegen.js +2 -1
  11. package/dist/cjs/rules/ensure-design-token-usage/index.js +5 -4
  12. package/dist/cjs/rules/ensure-design-token-usage/rule-meta.js +1 -1
  13. package/dist/cjs/rules/ensure-design-token-usage/spacing.js +5 -1
  14. package/dist/cjs/rules/ensure-design-token-usage/utils.js +52 -42
  15. package/dist/cjs/rules/index.codegen.js +3 -1
  16. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/find-valid-jsx-usage-to-transform.js +24 -1
  17. package/dist/cjs/rules/use-primitives/transformers/compiled-styled/index.js +2 -1
  18. package/dist/cjs/rules/use-primitives-text/config/index.js +2 -1
  19. package/dist/cjs/rules/use-primitives-text/transformers/common.js +10 -1
  20. package/dist/cjs/rules/use-primitives-text/transformers/emphasis-elements.js +6 -3
  21. package/dist/cjs/rules/use-primitives-text/transformers/paragraph-elements.js +19 -4
  22. package/dist/cjs/rules/use-primitives-text/transformers/span-elements.js +6 -4
  23. package/dist/cjs/rules/use-primitives-text/transformers/strong-elements.js +6 -3
  24. package/dist/cjs/rules/use-tokens-typography/config/index.js +26 -0
  25. package/dist/cjs/rules/use-tokens-typography/error-boundary.js +24 -0
  26. package/dist/cjs/rules/use-tokens-typography/index.js +44 -0
  27. package/dist/cjs/rules/use-tokens-typography/transformers/style-object.js +212 -0
  28. package/dist/cjs/rules/use-tokens-typography/utils.js +146 -0
  29. package/dist/es2019/ast-nodes/index.js +1 -0
  30. package/dist/es2019/ast-nodes/object-entry.js +22 -0
  31. package/dist/es2019/ast-nodes/object.js +1 -1
  32. package/dist/es2019/presets/all.codegen.js +2 -1
  33. package/dist/es2019/rules/ensure-design-token-usage/index.js +6 -5
  34. package/dist/es2019/rules/ensure-design-token-usage/rule-meta.js +1 -1
  35. package/dist/es2019/rules/ensure-design-token-usage/spacing.js +5 -1
  36. package/dist/es2019/rules/ensure-design-token-usage/utils.js +42 -38
  37. package/dist/es2019/rules/index.codegen.js +3 -1
  38. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/find-valid-jsx-usage-to-transform.js +17 -3
  39. package/dist/es2019/rules/use-primitives/transformers/compiled-styled/index.js +2 -1
  40. package/dist/es2019/rules/use-primitives-text/config/index.js +2 -1
  41. package/dist/es2019/rules/use-primitives-text/transformers/common.js +9 -2
  42. package/dist/es2019/rules/use-primitives-text/transformers/emphasis-elements.js +7 -4
  43. package/dist/es2019/rules/use-primitives-text/transformers/paragraph-elements.js +20 -5
  44. package/dist/es2019/rules/use-primitives-text/transformers/span-elements.js +7 -5
  45. package/dist/es2019/rules/use-primitives-text/transformers/strong-elements.js +7 -4
  46. package/dist/es2019/rules/use-tokens-typography/config/index.js +20 -0
  47. package/dist/es2019/rules/use-tokens-typography/error-boundary.js +19 -0
  48. package/dist/es2019/rules/use-tokens-typography/index.js +36 -0
  49. package/dist/es2019/rules/use-tokens-typography/transformers/style-object.js +209 -0
  50. package/dist/es2019/rules/use-tokens-typography/utils.js +99 -0
  51. package/dist/esm/ast-nodes/index.js +1 -0
  52. package/dist/esm/ast-nodes/object-entry.js +22 -0
  53. package/dist/esm/ast-nodes/object.js +1 -1
  54. package/dist/esm/presets/all.codegen.js +2 -1
  55. package/dist/esm/rules/ensure-design-token-usage/index.js +6 -5
  56. package/dist/esm/rules/ensure-design-token-usage/rule-meta.js +1 -1
  57. package/dist/esm/rules/ensure-design-token-usage/spacing.js +5 -1
  58. package/dist/esm/rules/ensure-design-token-usage/utils.js +46 -38
  59. package/dist/esm/rules/index.codegen.js +3 -1
  60. package/dist/esm/rules/use-primitives/transformers/compiled-styled/find-valid-jsx-usage-to-transform.js +23 -2
  61. package/dist/esm/rules/use-primitives/transformers/compiled-styled/index.js +2 -1
  62. package/dist/esm/rules/use-primitives-text/config/index.js +2 -1
  63. package/dist/esm/rules/use-primitives-text/transformers/common.js +9 -2
  64. package/dist/esm/rules/use-primitives-text/transformers/emphasis-elements.js +7 -4
  65. package/dist/esm/rules/use-primitives-text/transformers/paragraph-elements.js +20 -5
  66. package/dist/esm/rules/use-primitives-text/transformers/span-elements.js +7 -5
  67. package/dist/esm/rules/use-primitives-text/transformers/strong-elements.js +7 -4
  68. package/dist/esm/rules/use-tokens-typography/config/index.js +20 -0
  69. package/dist/esm/rules/use-tokens-typography/error-boundary.js +18 -0
  70. package/dist/esm/rules/use-tokens-typography/index.js +38 -0
  71. package/dist/esm/rules/use-tokens-typography/transformers/style-object.js +206 -0
  72. package/dist/esm/rules/use-tokens-typography/utils.js +129 -0
  73. package/dist/types/ast-nodes/index.d.ts +1 -0
  74. package/dist/types/ast-nodes/object-entry.d.ts +6 -0
  75. package/dist/types/ast-nodes/object.d.ts +1 -1
  76. package/dist/types/index.codegen.d.ts +1 -0
  77. package/dist/types/presets/all.codegen.d.ts +2 -1
  78. package/dist/types/rules/ensure-design-token-usage/types.d.ts +1 -1
  79. package/dist/types/rules/ensure-design-token-usage/utils.d.ts +22 -22
  80. package/dist/types/rules/index.codegen.d.ts +1 -0
  81. package/dist/types/rules/use-primitives/config/index.d.ts +1 -1
  82. package/dist/types/rules/use-primitives/transformers/compiled-styled/find-valid-jsx-usage-to-transform.d.ts +3 -1
  83. package/dist/types/rules/use-primitives/transformers/compiled-styled/index.d.ts +1 -1
  84. package/dist/types/rules/use-primitives/transformers/emotion-css/index.d.ts +1 -2
  85. package/dist/types/rules/use-primitives-text/config/index.d.ts +1 -0
  86. package/dist/types/rules/use-primitives-text/transformers/common.d.ts +6 -0
  87. package/dist/types/rules/use-primitives-text/transformers/emphasis-elements.d.ts +2 -10
  88. package/dist/types/rules/use-primitives-text/transformers/paragraph-elements.d.ts +4 -12
  89. package/dist/types/rules/use-primitives-text/transformers/span-elements.d.ts +2 -10
  90. package/dist/types/rules/use-primitives-text/transformers/strong-elements.d.ts +2 -10
  91. package/dist/types/rules/use-tokens-typography/config/index.d.ts +6 -0
  92. package/dist/types/rules/use-tokens-typography/error-boundary.d.ts +11 -0
  93. package/dist/types/rules/use-tokens-typography/index.d.ts +3 -0
  94. package/dist/types/rules/use-tokens-typography/transformers/style-object.d.ts +31 -0
  95. package/dist/types/rules/use-tokens-typography/utils.d.ts +194 -0
  96. package/dist/types-ts4.5/ast-nodes/index.d.ts +1 -0
  97. package/dist/types-ts4.5/ast-nodes/object-entry.d.ts +6 -0
  98. package/dist/types-ts4.5/ast-nodes/object.d.ts +1 -1
  99. package/dist/types-ts4.5/index.codegen.d.ts +1 -0
  100. package/dist/types-ts4.5/presets/all.codegen.d.ts +2 -1
  101. package/dist/types-ts4.5/rules/ensure-design-token-usage/types.d.ts +1 -1
  102. package/dist/types-ts4.5/rules/ensure-design-token-usage/utils.d.ts +22 -22
  103. package/dist/types-ts4.5/rules/index.codegen.d.ts +1 -0
  104. package/dist/types-ts4.5/rules/use-primitives/config/index.d.ts +1 -1
  105. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/find-valid-jsx-usage-to-transform.d.ts +3 -1
  106. package/dist/types-ts4.5/rules/use-primitives/transformers/compiled-styled/index.d.ts +1 -1
  107. package/dist/types-ts4.5/rules/use-primitives/transformers/emotion-css/index.d.ts +1 -2
  108. package/dist/types-ts4.5/rules/use-primitives-text/config/index.d.ts +1 -0
  109. package/dist/types-ts4.5/rules/use-primitives-text/transformers/common.d.ts +6 -0
  110. package/dist/types-ts4.5/rules/use-primitives-text/transformers/emphasis-elements.d.ts +2 -10
  111. package/dist/types-ts4.5/rules/use-primitives-text/transformers/paragraph-elements.d.ts +4 -12
  112. package/dist/types-ts4.5/rules/use-primitives-text/transformers/span-elements.d.ts +2 -10
  113. package/dist/types-ts4.5/rules/use-primitives-text/transformers/strong-elements.d.ts +2 -10
  114. package/dist/types-ts4.5/rules/use-tokens-typography/config/index.d.ts +6 -0
  115. package/dist/types-ts4.5/rules/use-tokens-typography/error-boundary.d.ts +11 -0
  116. package/dist/types-ts4.5/rules/use-tokens-typography/index.d.ts +3 -0
  117. package/dist/types-ts4.5/rules/use-tokens-typography/transformers/style-object.d.ts +31 -0
  118. package/dist/types-ts4.5/rules/use-tokens-typography/utils.d.ts +194 -0
  119. package/package.json +1 -1
  120. package/dist/cjs/rules/ensure-design-token-usage/typography.js +0 -39
  121. package/dist/es2019/rules/ensure-design-token-usage/typography.js +0 -19
  122. package/dist/esm/rules/ensure-design-token-usage/typography.js +0 -33
  123. package/dist/types/rules/ensure-design-token-usage/typography.d.ts +0 -9
  124. package/dist/types-ts4.5/rules/ensure-design-token-usage/typography.d.ts +0 -9
@@ -36,7 +36,8 @@ var EmphasisElements = exports.EmphasisElements = {
36
36
  suggest: [{
37
37
  desc: "Convert to Text",
38
38
  fix: EmphasisElements._fix(node, {
39
- context: context
39
+ context: context,
40
+ config: config
40
41
  })
41
42
  }]
42
43
  });
@@ -65,7 +66,8 @@ var EmphasisElements = exports.EmphasisElements = {
65
66
  return true;
66
67
  },
67
68
  _fix: function _fix(node, _ref3) {
68
- var context = _ref3.context;
69
+ var context = _ref3.context,
70
+ config = _ref3.config;
69
71
  return function (fixer) {
70
72
  var importFix = (0, _upsertImportDeclaration.upsertImportDeclaration)({
71
73
  module: '@atlaskit/primitives',
@@ -73,8 +75,9 @@ var EmphasisElements = exports.EmphasisElements = {
73
75
  }, context, fixer);
74
76
  var elementNameFixes = ast.JSXElement.updateName(node, 'Text', fixer);
75
77
  var asAttributeFix = ast.JSXElement.addAttribute(node, 'as', 'em', fixer);
78
+ var colorAttributeFix = (0, _common.addColorInheritAttributeFix)(node, config, fixer);
76
79
  var testAttributeFix = (0, _common.updateTestIdAttributeFix)(node, fixer);
77
- return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [asAttributeFix, testAttributeFix]).filter(function (fix) {
80
+ return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [asAttributeFix, colorAttributeFix, testAttributeFix]).filter(function (fix) {
78
81
  return Boolean(fix);
79
82
  }); // Some of the transformers can return arrays with undefined, so filter them out
80
83
  };
@@ -53,6 +53,7 @@ var ParagraphElements = exports.ParagraphElements = {
53
53
  desc: 'Convert to Text and Stack',
54
54
  fix: ParagraphElements._fixMultiple(node, {
55
55
  context: context,
56
+ config: config,
56
57
  refs: refs
57
58
  })
58
59
  }]
@@ -64,7 +65,8 @@ var ParagraphElements = exports.ParagraphElements = {
64
65
  suggest: [{
65
66
  desc: 'Convert to Text',
66
67
  fix: ParagraphElements._fixSingle(node, {
67
- context: context
68
+ context: context,
69
+ config: config
68
70
  })
69
71
  }]
70
72
  });
@@ -130,6 +132,13 @@ var ParagraphElements = exports.ParagraphElements = {
130
132
  }
131
133
  };
132
134
  }
135
+ } else if (!ast.JSXElement.hasAllowedAttrsOnly(node, _common.allowedAttrs)) {
136
+ return {
137
+ success: false,
138
+ refs: {
139
+ siblings: siblings
140
+ }
141
+ };
133
142
  }
134
143
  var importDeclaration = ast.Root.findImportsByModule(context.getSourceCode().ast.body, '@atlaskit/primitives');
135
144
 
@@ -150,21 +159,25 @@ var ParagraphElements = exports.ParagraphElements = {
150
159
  };
151
160
  },
152
161
  _fixSingle: function _fixSingle(node, _ref3) {
153
- var context = _ref3.context;
162
+ var context = _ref3.context,
163
+ config = _ref3.config;
154
164
  return function (fixer) {
155
165
  var importFix = (0, _upsertImportDeclaration.upsertImportDeclaration)({
156
166
  module: '@atlaskit/primitives',
157
167
  specifiers: ['Text']
158
168
  }, context, fixer);
159
169
  var elementNameFixes = ast.JSXElement.updateName(node, 'Text', fixer);
170
+ var asAttributeFix = ast.JSXElement.addAttribute(node, 'as', 'p', fixer);
171
+ var colorAttributeFix = (0, _common.addColorInheritAttributeFix)(node, config, fixer);
160
172
  var testAttributeFix = (0, _common.updateTestIdAttributeFix)(node, fixer);
161
- return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [testAttributeFix]).filter(function (fix) {
173
+ return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [asAttributeFix, colorAttributeFix, testAttributeFix]).filter(function (fix) {
162
174
  return Boolean(fix);
163
175
  }); // Some of the transformers can return arrays with undefined, so filter them out
164
176
  };
165
177
  },
166
178
  _fixMultiple: function _fixMultiple(node, _ref4) {
167
179
  var context = _ref4.context,
180
+ config = _ref4.config,
168
181
  refs = _ref4.refs;
169
182
  return function (fixer) {
170
183
  if (!(0, _eslintCodemodUtils.isNodeOfType)(node.parent, 'JSXElement') || !node.parent.closingElement) {
@@ -179,8 +192,10 @@ var ParagraphElements = exports.ParagraphElements = {
179
192
  var siblingFixes = refs.siblings.map(function (sibling) {
180
193
  if ((0, _eslintCodemodUtils.isNodeOfType)(sibling, 'JSXElement')) {
181
194
  var elementNameFixes = ast.JSXElement.updateName(sibling, 'Text', fixer);
195
+ var asAttributeFix = ast.JSXElement.addAttribute(sibling, 'as', 'p', fixer);
196
+ var colorAttributeFix = (0, _common.addColorInheritAttributeFix)(sibling, config, fixer);
182
197
  var testAttributeFix = (0, _common.updateTestIdAttributeFix)(sibling, fixer);
183
- return [].concat((0, _toConsumableArray2.default)(elementNameFixes), [testAttributeFix]);
198
+ return [].concat((0, _toConsumableArray2.default)(elementNameFixes), [asAttributeFix, colorAttributeFix, testAttributeFix]);
184
199
  }
185
200
  return undefined;
186
201
  }).flat();
@@ -36,7 +36,8 @@ var SpanElements = exports.SpanElements = {
36
36
  suggest: [{
37
37
  desc: "Convert to Text",
38
38
  fix: SpanElements._fix(node, {
39
- context: context
39
+ context: context,
40
+ config: config
40
41
  })
41
42
  }]
42
43
  });
@@ -70,16 +71,17 @@ var SpanElements = exports.SpanElements = {
70
71
  return true;
71
72
  },
72
73
  _fix: function _fix(node, _ref3) {
73
- var context = _ref3.context;
74
+ var context = _ref3.context,
75
+ config = _ref3.config;
74
76
  return function (fixer) {
75
77
  var importFix = (0, _upsertImportDeclaration.upsertImportDeclaration)({
76
78
  module: '@atlaskit/primitives',
77
79
  specifiers: ['Text']
78
80
  }, context, fixer);
79
81
  var elementNameFixes = ast.JSXElement.updateName(node, 'Text', fixer);
80
- var variantAttributeFix = ast.JSXElement.addAttribute(node, 'variant', 'ui', fixer);
82
+ var colorAttributeFix = (0, _common.addColorInheritAttributeFix)(node, config, fixer);
81
83
  var testAttributeFix = (0, _common.updateTestIdAttributeFix)(node, fixer);
82
- return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [variantAttributeFix, testAttributeFix]).filter(function (fix) {
84
+ return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [colorAttributeFix, testAttributeFix]).filter(function (fix) {
83
85
  return Boolean(fix);
84
86
  }); // Some of the transformers can return arrays with undefined, so filter them out
85
87
  };
@@ -36,7 +36,8 @@ var StrongElements = exports.StrongElements = {
36
36
  suggest: [{
37
37
  desc: "Convert to Text",
38
38
  fix: StrongElements._fix(node, {
39
- context: context
39
+ context: context,
40
+ config: config
40
41
  })
41
42
  }]
42
43
  });
@@ -65,7 +66,8 @@ var StrongElements = exports.StrongElements = {
65
66
  return true;
66
67
  },
67
68
  _fix: function _fix(node, _ref3) {
68
- var context = _ref3.context;
69
+ var context = _ref3.context,
70
+ config = _ref3.config;
69
71
  return function (fixer) {
70
72
  var importFix = (0, _upsertImportDeclaration.upsertImportDeclaration)({
71
73
  module: '@atlaskit/primitives',
@@ -73,8 +75,9 @@ var StrongElements = exports.StrongElements = {
73
75
  }, context, fixer);
74
76
  var elementNameFixes = ast.JSXElement.updateName(node, 'Text', fixer);
75
77
  var asAttributeFix = ast.JSXElement.addAttribute(node, 'as', 'strong', fixer);
78
+ var colorAttributeFix = (0, _common.addColorInheritAttributeFix)(node, config, fixer);
76
79
  var testAttributeFix = (0, _common.updateTestIdAttributeFix)(node, fixer);
77
- return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [asAttributeFix, testAttributeFix]).filter(function (fix) {
80
+ return [importFix].concat((0, _toConsumableArray2.default)(elementNameFixes), [asAttributeFix, colorAttributeFix, testAttributeFix]).filter(function (fix) {
78
81
  return Boolean(fix);
79
82
  }); // Some of the transformers can return arrays with undefined, so filter them out
80
83
  };
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.ruleSchema = exports.getConfig = void 0;
7
+ var ruleSchema = exports.ruleSchema = {
8
+ type: 'array',
9
+ items: {
10
+ type: 'object',
11
+ properties: {
12
+ failSilently: {
13
+ type: 'boolean'
14
+ }
15
+ }
16
+ }
17
+ };
18
+ var defaultConfig = {
19
+ failSilently: false
20
+ };
21
+ var getConfig = exports.getConfig = function getConfig(overrides) {
22
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
23
+ // start with an empty object, then merge in the defaults, then merge in overrides.
24
+ // The empty object is returned, as well as modified in place
25
+ return Object.assign({}, defaultConfig, overrides);
26
+ };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.errorBoundary = void 0;
7
+ /**
8
+ * ESLint rules should NEVER throw exceptions, because that breaks the VSCode ESLint server
9
+ * (and probably the IntelliJ one too), which causes linting to fail in a file.
10
+ *
11
+ * It also breaks CI, which was the reason this error boundary was added. It's a final
12
+ * catch all.
13
+ */
14
+ var errorBoundary = exports.errorBoundary = function errorBoundary(func, _ref) {
15
+ var config = _ref.config;
16
+ try {
17
+ func();
18
+ } catch (err) {
19
+ if (!config.failSilently) {
20
+ // eslint-disable-next-line no-console
21
+ console.warn(err);
22
+ }
23
+ }
24
+ };
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _createRule = require("../utils/create-rule");
8
+ var _config = require("./config");
9
+ var _errorBoundary = require("./error-boundary");
10
+ var _styleObject = require("./transformers/style-object");
11
+ var create = function create(context) {
12
+ var config = (0, _config.getConfig)(context.options[0]);
13
+ return {
14
+ // const styles = css({ fontSize: '14px, ... }), styled.div({ fontSize: 14, ... })
15
+ ObjectExpression: function ObjectExpression(node) {
16
+ return (0, _errorBoundary.errorBoundary)(function () {
17
+ return _styleObject.StyleObject.lint(node, {
18
+ context: context
19
+ });
20
+ }, {
21
+ config: config
22
+ });
23
+ }
24
+ };
25
+ };
26
+ var rule = (0, _createRule.createLintRule)({
27
+ meta: {
28
+ name: 'use-tokens-typography',
29
+ type: 'problem',
30
+ fixable: 'code',
31
+ hasSuggestions: true,
32
+ docs: {
33
+ description: 'Enforces usage of design tokens for typography properties rather than hard-coded values.',
34
+ recommended: false,
35
+ severity: 'warn'
36
+ },
37
+ messages: {
38
+ noRawTypographyValues: 'Typography primitives or tokens should be used instead of hard-coded values.\n\n@meta <<{{payload}}>>.'
39
+ },
40
+ schema: _config.ruleSchema
41
+ },
42
+ create: create
43
+ });
44
+ var _default = exports.default = rule;
@@ -0,0 +1,212 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.StyleObject = void 0;
7
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
8
+ var _astNodes = require("../../../ast-nodes");
9
+ var _utils = require("../../ensure-design-token-usage/utils");
10
+ var _isNode = require("../../utils/is-node");
11
+ var _utils2 = require("../utils");
12
+ /* eslint-disable @repo/internal/react/require-jsdoc */
13
+
14
+ var StyleObject = exports.StyleObject = {
15
+ lint: function lint(node, _ref) {
16
+ var context = _ref.context;
17
+ // To force the correct node type
18
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'ObjectExpression')) {
19
+ return {
20
+ success: false
21
+ };
22
+ }
23
+
24
+ // Check whether all criteria needed to make a transformation are met
25
+ var _StyleObject$_check = StyleObject._check(node, {
26
+ context: context
27
+ }),
28
+ success = _StyleObject$_check.success,
29
+ refs = _StyleObject$_check.refs;
30
+ if (!success || !refs) {
31
+ return;
32
+ }
33
+ var fontSizeNode = refs.fontSizeNode,
34
+ fontSizeRaw = refs.fontSizeRaw,
35
+ tokensImportNode = refs.tokensImportNode;
36
+ var fontSizeValue = (0, _utils.normaliseValue)('fontSize', fontSizeRaw);
37
+
38
+ // -- Font weight --
39
+ var fontWeightNode = _astNodes.Object.getEntryByPropertyName(node, 'fontWeight');
40
+ var fontWeightRaw = fontWeightNode && (0, _utils.getValueForPropertyNode)(fontWeightNode, context);
41
+
42
+ // If no fontWeight value exists, default to 400 to avoid matching with a bolder token resulting in a visual change
43
+ var fontWeightValue = fontWeightRaw && (0, _utils.normaliseValue)('fontWeight', fontWeightRaw) || _utils2.defaultFontWeight;
44
+ fontWeightValue = fontWeightValue.length === 3 ? fontWeightValue : _utils2.fontWeightMap[fontWeightValue] || _utils2.defaultFontWeight;
45
+
46
+ // -- Line height --
47
+ var lineHeightNode = _astNodes.Object.getEntryByPropertyName(node, 'lineHeight');
48
+ var lineHeightRaw = lineHeightNode && (0, _utils.getValueForPropertyNode)(lineHeightNode, context);
49
+ var shouldAddFontWeight = false;
50
+ var lineHeightValue = lineHeightRaw && (0, _utils.normaliseValue)('lineHeight', lineHeightRaw) || undefined;
51
+ if (lineHeightValue === fontSizeValue) {
52
+ lineHeightValue = '1';
53
+ }
54
+
55
+ // -- Match tokens --
56
+ var matchingTokens = (0, _utils2.findTypographyTokenForValues)(fontSizeValue, lineHeightValue);
57
+ if (matchingTokens.length) {
58
+ // If we have multiple matching tokens, try matching fontWeight
59
+ var matchingTokensWithWeight = matchingTokens.filter(function (token) {
60
+ return fontWeightValue ? token.values.fontWeight === fontWeightValue : token;
61
+ });
62
+ if (matchingTokensWithWeight.length) {
63
+ // Possibly narrowed down tokens
64
+ matchingTokens = matchingTokensWithWeight;
65
+ } else {
66
+ // Ended up with 0 matches by matching fontWeight
67
+ // return body token and add fontWeight manually
68
+ matchingTokens = matchingTokens.filter(function (token) {
69
+ return token.tokenName.includes('.body');
70
+ });
71
+ shouldAddFontWeight = true;
72
+ }
73
+ }
74
+
75
+ // Get other font-* nodes that we can replace/remove.
76
+ // These aren't needed for token matching.
77
+
78
+ // -- Font family --
79
+ var fontFamilyNode = _astNodes.Object.getEntryByPropertyName(node, 'fontFamily');
80
+ var fontFamilyRaw = fontFamilyNode && (0, _utils.getValueForPropertyNode)(fontFamilyNode, context);
81
+ var fontFamilyValue = fontFamilyRaw && (0, _utils.normaliseValue)('fontFamily', fontFamilyRaw) || undefined;
82
+ var fontFamilyToAdd;
83
+ // If font family uses the Charlie font we can't replace; exit
84
+ if (fontFamilyValue) {
85
+ if (fontFamilyValue.toLowerCase().includes('charlie display')) {
86
+ fontFamilyToAdd = 'heading';
87
+ } else if (fontFamilyValue.toLowerCase().includes('charlie text')) {
88
+ fontFamilyToAdd = 'body';
89
+ }
90
+ } else {
91
+ // Font family node exists but we can't resolve its value
92
+ // Will need to re-add it below the font property to ensure it still applies
93
+ fontFamilyToAdd = fontFamilyNode ? 'original' : undefined;
94
+ }
95
+
96
+ // -- Font style --
97
+ var fontStyleNode = _astNodes.Object.getEntryByPropertyName(node, 'fontStyle');
98
+ var fontStyleRaw = fontStyleNode && (0, _utils.getValueForPropertyNode)(fontStyleNode, context);
99
+ var fontStyleValue = fontStyleRaw && (0, _utils.normaliseValue)('fontStyle', fontStyleRaw) || undefined;
100
+ var fontStyleToAdd;
101
+ if (fontStyleValue === 'italic') {
102
+ fontStyleToAdd = 'italic';
103
+ }
104
+
105
+ // -- Letter spacing --
106
+ var letterSpacingNode = _astNodes.Object.getEntryByPropertyName(node, 'letterSpacing');
107
+
108
+ // A single matching token
109
+ // TOOD: Maybe suggest options if > 1 matching token
110
+ if (matchingTokens.length === 1) {
111
+ var matchingToken = matchingTokens[0];
112
+
113
+ // fontSize node is always first
114
+ var nodesToReplace = [fontSizeNode, fontWeightNode, lineHeightNode, fontFamilyNode, fontStyleNode, letterSpacingNode].filter(_utils2.notUndefined);
115
+ var fontFamilyTokenName = fontFamilyToAdd ? "font.family.brand.".concat(fontFamilyToAdd) : '';
116
+ var fontWeightReplacementToken = shouldAddFontWeight ? (0, _utils2.findFontWeightTokenForValue)(fontWeightValue) : undefined;
117
+ var fontWeightReplacement = fontWeightReplacementToken && (0, _utils2.getTokenProperty)('fontWeight', fontWeightReplacementToken.tokenName, fontWeightValue);
118
+ var fontFamilyReplacement = fontFamilyToAdd && (fontFamilyToAdd === 'original' ? (0, _utils2.convertPropertyNodeToStringableNode)(
119
+ // This will always exist if fontFamilyToAdd === 'original', TS can't figure that out.
120
+ fontFamilyNode) : (0, _utils2.getTokenProperty)('fontFamily', fontFamilyTokenName, (0, _utils2.findFontFamilyValueForToken)(fontFamilyTokenName)));
121
+ var fontStyleReplacement = fontStyleToAdd && (0, _utils2.getLiteralProperty)('fontStyle', fontStyleToAdd);
122
+ var fixerRefs = {
123
+ matchingToken: matchingToken,
124
+ nodesToReplace: nodesToReplace,
125
+ tokensImportNode: tokensImportNode,
126
+ fontWeightReplacement: fontWeightReplacement,
127
+ fontFamilyReplacement: fontFamilyReplacement,
128
+ fontStyleReplacement: fontStyleReplacement
129
+ };
130
+ context.report({
131
+ node: fontSizeNode,
132
+ messageId: 'noRawTypographyValues',
133
+ data: {
134
+ payload: "fontSize:".concat(fontSizeRaw)
135
+ },
136
+ fix: StyleObject._fix(fixerRefs, context)
137
+ });
138
+ } else if (!matchingTokens.length) {
139
+ context.report({
140
+ node: fontSizeNode,
141
+ messageId: 'noRawTypographyValues',
142
+ data: {
143
+ payload: "fontSize:".concat(fontSizeRaw)
144
+ }
145
+ });
146
+ }
147
+ return;
148
+ },
149
+ _check: function _check(node, _ref2) {
150
+ var context = _ref2.context;
151
+ if (!(0, _isNode.isDecendantOfStyleBlock)(node) && !(0, _isNode.isDecendantOfType)(node, 'JSXExpressionContainer')) {
152
+ return {
153
+ success: false
154
+ };
155
+ }
156
+
157
+ // -- Font size --
158
+ var fontSizeNode = _astNodes.Object.getEntryByPropertyName(node, 'fontSize');
159
+ if (!fontSizeNode || !(0, _utils2.isValidPropertyNode)(fontSizeNode) || (0, _isNode.isDecendantOfGlobalToken)(fontSizeNode.value)) {
160
+ return {
161
+ success: false
162
+ };
163
+ }
164
+ var fontSizeRaw = (0, _utils.getValueForPropertyNode)(fontSizeNode, context);
165
+
166
+ // Without a valid fontSize value we can't be certain what token should be used; exit
167
+ if (!fontSizeRaw) {
168
+ return {
169
+ success: false
170
+ };
171
+ }
172
+ var importDeclaration = _astNodes.Root.findImportsByModule(context.getSourceCode().ast.body, '@atlaskit/tokens');
173
+
174
+ // If there is more than one `@atlaskit/tokens` import, then it becomes difficult to determine which import to transform
175
+ if (importDeclaration.length > 1) {
176
+ return {
177
+ success: false
178
+ };
179
+ }
180
+ return {
181
+ success: true,
182
+ refs: {
183
+ fontSizeNode: fontSizeNode,
184
+ fontSizeRaw: fontSizeRaw,
185
+ tokensImportNode: importDeclaration[0]
186
+ }
187
+ };
188
+ },
189
+ _fix: function _fix(refs, context) {
190
+ return function (fixer) {
191
+ var matchingToken = refs.matchingToken,
192
+ nodesToReplace = refs.nodesToReplace,
193
+ tokensImportNode = refs.tokensImportNode,
194
+ fontWeightReplacement = refs.fontWeightReplacement,
195
+ fontFamilyReplacement = refs.fontFamilyReplacement,
196
+ fontStyleReplacement = refs.fontStyleReplacement;
197
+ var fontSizeNode = nodesToReplace[0];
198
+ return (!tokensImportNode ? [(0, _utils.insertTokensImport)(fixer)] : []).concat(nodesToReplace.map(function (node, index) {
199
+ // Replace first node with token, delete remaining nodes. Guaranteed to be fontSize
200
+ if (index === 0) {
201
+ return fixer.replaceText(node, "".concat((0, _utils2.getTokenProperty)('font', matchingToken.tokenName, matchingToken.tokenValue)));
202
+ }
203
+
204
+ // We don't replace fontWeight/fontFamily/fontStyle here in case it occurs before the font property.
205
+ // Instead delete the original property and add below
206
+ return _astNodes.ObjectEntry.deleteEntry(node, context, fixer);
207
+ }),
208
+ // Make sure font weight/family/style properties are added AFTER font property to ensure they override corectly
209
+ fontWeightReplacement ? [fixer.insertTextAfter(fontSizeNode, ",\n".concat(fontWeightReplacement))] : [], fontFamilyReplacement ? [fixer.insertTextAfter(fontSizeNode, ",\n".concat(fontFamilyReplacement))] : [], fontStyleReplacement ? [fixer.insertTextAfter(fontSizeNode, ",\n".concat(fontStyleReplacement))] : []);
210
+ };
211
+ }
212
+ };
@@ -0,0 +1,146 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.convertPropertyNodeToStringableNode = convertPropertyNodeToStringableNode;
7
+ exports.defaultFontWeight = void 0;
8
+ exports.findFontFamilyValueForToken = findFontFamilyValueForToken;
9
+ exports.findFontWeightTokenForValue = findFontWeightTokenForValue;
10
+ exports.findTypographyTokenForValues = findTypographyTokenForValues;
11
+ exports.fontWeightTokens = exports.fontWeightMap = exports.fontFamilyTokens = void 0;
12
+ exports.getLiteralProperty = getLiteralProperty;
13
+ exports.getTokenProperty = getTokenProperty;
14
+ exports.isTypographyProperty = exports.isFontSizeSmall = exports.isFontSize = exports.isFontFamily = exports.isCodeFontFamily = void 0;
15
+ exports.isValidPropertyNode = isValidPropertyNode;
16
+ exports.notUndefined = notUndefined;
17
+ exports.typographyValueToToken = exports.typographyProperties = void 0;
18
+ var _eslintCodemodUtils = require("eslint-codemod-utils");
19
+ var _palettesRaw = require("@atlaskit/tokens/palettes-raw");
20
+ var _tokensRaw = require("@atlaskit/tokens/tokens-raw");
21
+ var typographyProperties = exports.typographyProperties = ['fontSize', 'fontWeight', 'fontFamily', 'lineHeight'];
22
+ var isTypographyProperty = exports.isTypographyProperty = function isTypographyProperty(propertyName) {
23
+ return typographyProperties.includes(propertyName);
24
+ };
25
+ var isFontSize = exports.isFontSize = function isFontSize(node) {
26
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontSize' || node.callee.name === 'getFontSize');
27
+ };
28
+ var isFontSizeSmall = exports.isFontSizeSmall = function isFontSizeSmall(node) {
29
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && node.callee.name === 'fontSizeSmall';
30
+ };
31
+ var isFontFamily = exports.isFontFamily = function isFontFamily(node) {
32
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'fontFamily' || node.callee.name === 'getFontFamily');
33
+ };
34
+ var isCodeFontFamily = exports.isCodeFontFamily = function isCodeFontFamily(node) {
35
+ return (0, _eslintCodemodUtils.isNodeOfType)(node, 'CallExpression') && (0, _eslintCodemodUtils.isNodeOfType)(node.callee, 'Identifier') && (node.callee.name === 'codeFontFamily' || node.callee.name === 'getCodeFontFamily');
36
+ };
37
+ var typographyValueToToken = exports.typographyValueToToken = _tokensRaw.typographyAdg3
38
+ // we're filtering here to remove the `font` tokens.
39
+ .filter(function (t) {
40
+ return t.attributes.group === 'typography';
41
+ }).filter(function (t) {
42
+ return t.cleanName.includes('font.heading') || t.cleanName.includes('font.body');
43
+ }).map(function (currentToken) {
44
+ var _typographyPalette$fi, _typographyPalette$fi2, _typographyPalette$fi3;
45
+ var individualValues = {
46
+ fontSize: (_typographyPalette$fi = _palettesRaw.typographyPalette.find(function (baseToken) {
47
+ return baseToken.path.slice(-1)[0] ===
48
+ // @ts-expect-error token.original.value can be a string, due to the typographyTokens export including deprecated tokens
49
+ currentToken.original.value.fontSize;
50
+ })) === null || _typographyPalette$fi === void 0 ? void 0 : _typographyPalette$fi.value,
51
+ fontWeight: (_typographyPalette$fi2 = _palettesRaw.typographyPalette.find(function (baseToken) {
52
+ return baseToken.path.slice(-1)[0] ===
53
+ // @ts-expect-error token.original.value can be a string, due to the typographyTokens export including deprecated tokens
54
+ currentToken.original.value.fontWeight;
55
+ })) === null || _typographyPalette$fi2 === void 0 ? void 0 : _typographyPalette$fi2.value,
56
+ lineHeight: (_typographyPalette$fi3 = _palettesRaw.typographyPalette.find(function (baseToken) {
57
+ return baseToken.path.slice(-1)[0] ===
58
+ // @ts-expect-error token.original.value can be a string, due to the typographyTokens export including deprecated tokens
59
+ currentToken.original.value.lineHeight;
60
+ })) === null || _typographyPalette$fi3 === void 0 ? void 0 : _typographyPalette$fi3.value
61
+ };
62
+ return {
63
+ tokenName: currentToken.cleanName,
64
+ tokenValue: currentToken.value,
65
+ values: individualValues
66
+ };
67
+ });
68
+ function findTypographyTokenForValues(fontSize, lineHeight) {
69
+ var matchingTokens = typographyValueToToken.filter(function (token) {
70
+ return token.values.fontSize === fontSize;
71
+ })
72
+ // If lineHeight == 1, we don't match to a token
73
+ .filter(function () {
74
+ return lineHeight === '1' ? false : true;
75
+ });
76
+ return matchingTokens;
77
+ }
78
+ var fontWeightTokens = exports.fontWeightTokens = _tokensRaw.typographyAdg3.filter(function (token) {
79
+ return token.attributes.group === 'fontWeight';
80
+ }).map(function (token) {
81
+ return {
82
+ tokenName: token.cleanName,
83
+ tokenValue: token.value,
84
+ values: {}
85
+ };
86
+ });
87
+ function findFontWeightTokenForValue(fontWeight) {
88
+ return fontWeightTokens.find(function (token) {
89
+ return token.tokenValue === fontWeight;
90
+ });
91
+ }
92
+ var fontWeightMap = exports.fontWeightMap = {
93
+ regular: '400',
94
+ medium: '500',
95
+ semibold: '600',
96
+ bold: '700'
97
+ };
98
+ var defaultFontWeight = exports.defaultFontWeight = fontWeightMap.regular;
99
+ var fontFamilyTokens = exports.fontFamilyTokens = _tokensRaw.typographyAdg3.filter(function (token) {
100
+ return token.attributes.group === 'fontFamily';
101
+ });
102
+ function findFontFamilyValueForToken(tokenName) {
103
+ var _fontFamilyTokens$fin;
104
+ // Note this will only ever be undefined if the tokens get renamed, and should never happen.
105
+ return ((_fontFamilyTokens$fin = fontFamilyTokens.find(function (token) {
106
+ return token.cleanName === tokenName;
107
+ })) === null || _fontFamilyTokens$fin === void 0 ? void 0 : _fontFamilyTokens$fin.value) || '';
108
+ }
109
+ function notUndefined(value) {
110
+ return value !== undefined;
111
+ }
112
+ function isValidPropertyNode(node) {
113
+ if (!(0, _eslintCodemodUtils.isNodeOfType)(node.key, 'Identifier') && !(0, _eslintCodemodUtils.isNodeOfType)(node.key, 'Literal')) {
114
+ return false;
115
+ }
116
+ return true;
117
+ }
118
+ function getTokenNode(tokenName, tokenValue) {
119
+ return (0, _eslintCodemodUtils.callExpression)({
120
+ callee: (0, _eslintCodemodUtils.identifier)({
121
+ name: 'token'
122
+ }),
123
+ arguments: [(0, _eslintCodemodUtils.literal)({
124
+ value: "'".concat(tokenName, "'")
125
+ }), (0, _eslintCodemodUtils.literal)(tokenValue)],
126
+ optional: false
127
+ });
128
+ }
129
+ function getTokenProperty(propertyName, tokenName, tokenFallback) {
130
+ return (0, _eslintCodemodUtils.property)({
131
+ key: (0, _eslintCodemodUtils.identifier)(propertyName),
132
+ value: getTokenNode(tokenName, tokenFallback)
133
+ });
134
+ }
135
+ function getLiteralProperty(propertyName, propertyValue) {
136
+ return (0, _eslintCodemodUtils.property)({
137
+ key: (0, _eslintCodemodUtils.identifier)(propertyName),
138
+ value: (0, _eslintCodemodUtils.literal)(propertyValue)
139
+ });
140
+ }
141
+ function convertPropertyNodeToStringableNode(node) {
142
+ return (0, _eslintCodemodUtils.property)({
143
+ key: node.key,
144
+ value: node.value
145
+ });
146
+ }
@@ -3,4 +3,5 @@ export { Import } from './import';
3
3
  export { JSXAttribute } from './jsx-attribute';
4
4
  export { JSXElement } from './jsx-element';
5
5
  export { Object } from './object';
6
+ export { ObjectEntry } from './object-entry';
6
7
  export { Root } from './root';
@@ -0,0 +1,22 @@
1
+ const ObjectEntry = {
2
+ deleteEntry(node, context, fixer) {
3
+ var _lastToken;
4
+ // context.getSourceCode() is deprecated in favour of context.sourceCode, however this returns undefined for some reason
5
+ const sourceCode = context.getSourceCode();
6
+
7
+ // fixer.remove() doesn't account for things like commas or newlines within an ObjectExpression and will result in invalid output.
8
+ // This approach specifically removes the node and trailing comma, and should work for single- and multi-line objects.
9
+ // From https://github.com/eslint/eslint/issues/9576#issuecomment-341737453
10
+ let prevToken = sourceCode.getTokenBefore(node);
11
+ while (((_prevToken = prevToken) === null || _prevToken === void 0 ? void 0 : _prevToken.value) !== ',' && ((_prevToken2 = prevToken) === null || _prevToken2 === void 0 ? void 0 : _prevToken2.value) !== '{') {
12
+ var _prevToken, _prevToken2;
13
+ prevToken = sourceCode.getTokenBefore(node);
14
+ }
15
+ let lastToken = sourceCode.getTokenAfter(node);
16
+ if (((_lastToken = lastToken) === null || _lastToken === void 0 ? void 0 : _lastToken.value) !== ',') {
17
+ lastToken = sourceCode.getTokenBefore(lastToken);
18
+ }
19
+ return fixer.removeRange([prevToken.range[1], lastToken.range[1]]);
20
+ }
21
+ };
22
+ export { ObjectEntry };
@@ -27,7 +27,7 @@ const ASTObjectExpression = {
27
27
  });
28
28
  },
29
29
  /**
30
- * Returns a key-value pair like: `padding: '8px'` from: `{ padding: '8px' }`.
30
+ * Returns the first Property node from an Object that matches the provided name.
31
31
  */
32
32
  getEntryByPropertyName(node, name) {
33
33
  return node.properties.find(property => {