@atlaskit/codemod-cli 0.13.4 → 0.15.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 (89) hide show
  1. package/CHANGELOG.md +71 -52
  2. package/dist/cjs/main.js +3 -3
  3. package/dist/cjs/presets/css-to-design-tokens/css-to-design-tokens.js +65 -135
  4. package/dist/cjs/presets/css-to-design-tokens/lib/colors.js +49 -0
  5. package/dist/cjs/presets/css-to-design-tokens/lib/declaration.js +29 -0
  6. package/dist/cjs/presets/css-to-design-tokens/{utils → lib}/legacy-colors.js +13 -17
  7. package/dist/cjs/presets/css-to-design-tokens/lib/logger.js +18 -0
  8. package/dist/cjs/presets/css-to-design-tokens/lib/meta.js +157 -0
  9. package/dist/cjs/presets/css-to-design-tokens/lib/tokens.js +47 -0
  10. package/dist/cjs/presets/css-to-design-tokens/lib/value.js +80 -0
  11. package/dist/cjs/presets/index.js +1 -2
  12. package/dist/cjs/presets/styled-to-emotion/styled-to-emotion.js +1 -2
  13. package/dist/cjs/presets/theme-remove-deprecated-mixins/utils/replacements.js +2 -3
  14. package/dist/cjs/presets/theme-to-design-tokens/theme-to-design-tokens.js +348 -104
  15. package/dist/cjs/presets/theme-to-design-tokens/utils/ast.js +1 -1
  16. package/dist/cjs/presets/theme-to-design-tokens/utils/color.js +17 -17
  17. package/dist/cjs/presets/theme-to-design-tokens/utils/css-utils.js +38 -0
  18. package/dist/cjs/presets/theme-to-design-tokens/utils/fuzzy-search.js +1 -2
  19. package/dist/cjs/presets/theme-to-design-tokens/utils/legacy-colors.js +4 -7
  20. package/dist/cjs/presets/theme-to-design-tokens/utils/named-colors.js +1 -2
  21. package/dist/cjs/presets/theme-to-design-tokens/utils/string-utils.js +25 -0
  22. package/dist/cjs/presets/theme-to-design-tokens/utils/tokens.js +3 -5
  23. package/dist/cjs/sinceRef.js +1 -2
  24. package/dist/cjs/transforms.js +6 -12
  25. package/dist/cjs/types.js +3 -5
  26. package/dist/cjs/utils.js +2 -3
  27. package/dist/es2019/presets/css-to-design-tokens/css-to-design-tokens.js +61 -115
  28. package/dist/es2019/presets/css-to-design-tokens/lib/colors.js +34 -0
  29. package/dist/es2019/presets/css-to-design-tokens/lib/declaration.js +17 -0
  30. package/dist/es2019/presets/css-to-design-tokens/{utils → lib}/legacy-colors.js +9 -10
  31. package/dist/es2019/presets/css-to-design-tokens/lib/logger.js +11 -0
  32. package/dist/es2019/presets/css-to-design-tokens/lib/meta.js +133 -0
  33. package/dist/es2019/presets/css-to-design-tokens/lib/tokens.js +24 -0
  34. package/dist/es2019/presets/css-to-design-tokens/lib/value.js +68 -0
  35. package/dist/es2019/presets/theme-to-design-tokens/theme-to-design-tokens.js +191 -32
  36. package/dist/es2019/presets/theme-to-design-tokens/utils/ast.js +1 -1
  37. package/dist/es2019/presets/theme-to-design-tokens/utils/color.js +12 -10
  38. package/dist/es2019/presets/theme-to-design-tokens/utils/css-utils.js +31 -0
  39. package/dist/es2019/presets/theme-to-design-tokens/utils/string-utils.js +13 -0
  40. package/dist/esm/main.js +3 -3
  41. package/dist/esm/presets/css-to-design-tokens/css-to-design-tokens.js +65 -135
  42. package/dist/esm/presets/css-to-design-tokens/lib/colors.js +38 -0
  43. package/dist/esm/presets/css-to-design-tokens/lib/declaration.js +19 -0
  44. package/dist/esm/presets/css-to-design-tokens/{utils → lib}/legacy-colors.js +9 -10
  45. package/dist/esm/presets/css-to-design-tokens/lib/logger.js +11 -0
  46. package/dist/esm/presets/css-to-design-tokens/lib/meta.js +146 -0
  47. package/dist/esm/presets/css-to-design-tokens/lib/tokens.js +40 -0
  48. package/dist/esm/presets/css-to-design-tokens/lib/value.js +73 -0
  49. package/dist/esm/presets/theme-to-design-tokens/theme-to-design-tokens.js +346 -100
  50. package/dist/esm/presets/theme-to-design-tokens/utils/ast.js +1 -1
  51. package/dist/esm/presets/theme-to-design-tokens/utils/color.js +12 -10
  52. package/dist/esm/presets/theme-to-design-tokens/utils/css-utils.js +31 -0
  53. package/dist/esm/presets/theme-to-design-tokens/utils/string-utils.js +17 -0
  54. package/dist/types/main.d.ts +0 -1
  55. package/dist/types/presets/css-to-design-tokens/css-to-design-tokens.d.ts +1 -1
  56. package/dist/types/presets/css-to-design-tokens/lib/colors.d.ts +6 -0
  57. package/dist/types/presets/css-to-design-tokens/lib/declaration.d.ts +5 -0
  58. package/dist/types/presets/css-to-design-tokens/{utils → lib}/legacy-colors.d.ts +1 -1
  59. package/dist/types/presets/css-to-design-tokens/lib/logger.d.ts +4 -0
  60. package/dist/types/presets/css-to-design-tokens/lib/meta.d.ts +6 -0
  61. package/dist/types/presets/css-to-design-tokens/lib/tokens.d.ts +7 -0
  62. package/dist/types/presets/css-to-design-tokens/lib/value.d.ts +6 -0
  63. package/dist/types/presets/theme-to-design-tokens/theme-to-design-tokens.d.ts +1 -1
  64. package/dist/types/presets/theme-to-design-tokens/utils/ast.d.ts +1 -1
  65. package/dist/types/presets/theme-to-design-tokens/utils/color.d.ts +2 -1
  66. package/dist/types/presets/theme-to-design-tokens/utils/css-utils.d.ts +2 -0
  67. package/dist/types/presets/theme-to-design-tokens/utils/string-utils.d.ts +3 -0
  68. package/dist/types-ts4.5/main.d.ts +0 -1
  69. package/dist/types-ts4.5/presets/css-to-design-tokens/css-to-design-tokens.d.ts +1 -1
  70. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/colors.d.ts +6 -0
  71. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/declaration.d.ts +5 -0
  72. package/dist/types-ts4.5/presets/css-to-design-tokens/{utils → lib}/legacy-colors.d.ts +1 -1
  73. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/logger.d.ts +4 -0
  74. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/meta.d.ts +6 -0
  75. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/tokens.d.ts +7 -0
  76. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/value.d.ts +6 -0
  77. package/dist/types-ts4.5/presets/theme-to-design-tokens/theme-to-design-tokens.d.ts +1 -1
  78. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/ast.d.ts +1 -1
  79. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/color.d.ts +2 -1
  80. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/css-utils.d.ts +2 -0
  81. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/string-utils.d.ts +6 -0
  82. package/package.json +2 -2
  83. package/report.api.md +0 -2
  84. package/tmp/api-report-tmp.d.ts +0 -2
  85. package/dist/cjs/presets/css-to-design-tokens/utils/meta.js +0 -53
  86. package/dist/es2019/presets/css-to-design-tokens/utils/meta.js +0 -33
  87. package/dist/esm/presets/css-to-design-tokens/utils/meta.js +0 -46
  88. package/dist/types/presets/css-to-design-tokens/utils/meta.d.ts +0 -1
  89. package/dist/types-ts4.5/presets/css-to-design-tokens/utils/meta.d.ts +0 -1
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = parseValue;
8
+ var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
+ var _colors = require("./colors");
10
+ var _declaration = require("./declaration");
11
+ var _meta = require("./meta");
12
+ var _tokens = _interopRequireDefault(require("./tokens"));
13
+ var _logger = require("./logger");
14
+ function parseValue(value) {
15
+ if ((0, _colors.isLessFunction)(value)) {
16
+ _logger.logger.warn('Cannot parse - less function detected, would cause compilation error');
17
+ return null;
18
+ }
19
+ if ((0, _colors.isGradient)(value)) {
20
+ return {
21
+ getReplacement: function getReplacement() {
22
+ var additionalMeta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
23
+ var gradientContent = (0, _colors.extractBetweenParentheses)(value);
24
+ var values = gradientContent.split(',');
25
+ var replacedValues = values.map(function (val) {
26
+ var parsedValue = parseValue(val.trim());
27
+ return parsedValue ? parsedValue.getReplacement(additionalMeta) : val;
28
+ });
29
+ return value.replace(gradientContent, replacedValues.join(', '));
30
+ },
31
+ getMeta: function getMeta() {
32
+ var BASE_META = [];
33
+ var gradientContent = (0, _colors.extractBetweenParentheses)(value);
34
+ var values = gradientContent.split(',');
35
+ var metas = values.reduce(function (acc, val) {
36
+ var parsedValue = parseValue(val.trim());
37
+ return parsedValue ? [].concat((0, _toConsumableArray2.default)(acc), (0, _toConsumableArray2.default)(parsedValue.getMeta())) : acc;
38
+ }, BASE_META);
39
+ return metas;
40
+ }
41
+ };
42
+ }
43
+ if ((0, _colors.isKnownCssVariable)((0, _declaration.extractCssVarName)(value))) {
44
+ return {
45
+ getReplacement: function getReplacement() {
46
+ var additionalMeta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
47
+ var token = (0, _tokens.default)([].concat((0, _toConsumableArray2.default)(additionalMeta), (0, _toConsumableArray2.default)(this.getMeta())));
48
+ return "var(".concat(token, ", ").concat(value, ")");
49
+ },
50
+ getMeta: function getMeta() {
51
+ return (0, _meta.getCssVarMeta)(value);
52
+ }
53
+ };
54
+ }
55
+ if ((0, _colors.isRawColor)(value)) {
56
+ return {
57
+ getReplacement: function getReplacement() {
58
+ var additionalMeta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
59
+ var token = (0, _tokens.default)([].concat((0, _toConsumableArray2.default)(additionalMeta), (0, _toConsumableArray2.default)(this.getMeta())));
60
+ return "var(".concat(token, ", ").concat(value, ")");
61
+ },
62
+ getMeta: function getMeta() {
63
+ return (0, _meta.getRawColorMeta)(value);
64
+ }
65
+ };
66
+ }
67
+ if ((0, _colors.isNamedColor)(value)) {
68
+ return {
69
+ getReplacement: function getReplacement() {
70
+ var additionalMeta = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
71
+ var token = (0, _tokens.default)([].concat((0, _toConsumableArray2.default)(additionalMeta), (0, _toConsumableArray2.default)(this.getMeta())));
72
+ return "var(".concat(token, ", ").concat(value, ")");
73
+ },
74
+ getMeta: function getMeta() {
75
+ return (0, _meta.getNamedColorMeta)(value);
76
+ }
77
+ };
78
+ }
79
+ return null;
80
+ }
@@ -18,5 +18,4 @@ require("./css-to-design-tokens/css-to-design-tokens");
18
18
  var presets = ['styled-to-emotion', 'theme-to-design-tokens', 'theme-remove-deprecated-mixins', 'css-to-design-tokens'].map(function (preset) {
19
19
  return _path.default.join(__dirname, preset, "".concat(preset, ".@(ts|js|tsx)"));
20
20
  });
21
- var _default = presets;
22
- exports.default = _default;
21
+ var _default = exports.default = presets;
@@ -46,5 +46,4 @@ function transformer(fileInfo, _ref, options) {
46
46
  });
47
47
  return source;
48
48
  }
49
- var parser = 'tsx';
50
- exports.parser = parser;
49
+ var parser = exports.parser = 'tsx';
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.colorReplacements = void 0;
7
- var colorReplacements = {
7
+ var colorReplacements = exports.colorReplacements = {
8
8
  background: {
9
9
  fullReplacement: "themed({ light: token('elevation.surface', N0), dark: token('elevation.surface', DN30) })",
10
10
  staticReplacement: 'N0',
@@ -142,5 +142,4 @@ var colorReplacements = {
142
142
  tokenId: 'color.skeleton',
143
143
  importSpecifiers: ['N20A']
144
144
  }
145
- };
146
- exports.colorReplacements = colorReplacements;
145
+ };
@@ -5,6 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.default = transformer;
8
+ var _regenerator = _interopRequireDefault(require("@babel/runtime/regenerator"));
9
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
10
+ var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime/helpers/asyncToGenerator"));
8
11
  var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
9
12
  var _utils = require("@codeshift/utils");
10
13
  var _ast = require("./utils/ast");
@@ -13,17 +16,12 @@ var _color = require("./utils/color");
13
16
  var _fuzzySearch = _interopRequireDefault(require("./utils/fuzzy-search"));
14
17
  var _legacyColors = require("./utils/legacy-colors");
15
18
  var _tokens = require("./utils/tokens");
16
- /* eslint-disable no-console */
17
-
18
- var kebabize = function kebabize(str) {
19
- return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) {
20
- return (ofs ? '-' : '') + $.toLowerCase();
21
- });
22
- };
23
- function isBoldColor(color) {
24
- var number = parseInt(color.replace(/^./, ''), 10);
25
- return number > 300;
26
- }
19
+ var _stringUtils = require("./utils/string-utils");
20
+ var _cssUtils = require("./utils/css-utils");
21
+ var _cssToDesignTokens = _interopRequireDefault(require("../css-to-design-tokens/css-to-design-tokens"));
22
+ function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
23
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
24
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } /* eslint-disable no-console */
27
25
  function insertTokenImport(j, source) {
28
26
  if ((0, _utils.hasImportDeclaration)(j, source, '@atlaskit/tokens')) {
29
27
  return;
@@ -35,6 +33,24 @@ function buildToken(j, tokenId, node) {
35
33
  var callExpr = j.callExpression(j.identifier('token'), [j.stringLiteral(tokenId), node].filter(Boolean));
36
34
  return callExpr;
37
35
  }
36
+
37
+ // Wrap over the j.templateElement builder to provide a more convenient API.
38
+ function buildTemplateElement(j, text) {
39
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
40
+ tail: false,
41
+ fromNode: null
42
+ };
43
+ var tail;
44
+ if (options.fromNode) {
45
+ tail = options.fromNode.tail;
46
+ } else {
47
+ tail = !!options.tail;
48
+ }
49
+ return j.templateElement({
50
+ raw: text,
51
+ cooked: null
52
+ }, tail);
53
+ }
38
54
  function getColorFromIdentifier(expression) {
39
55
  var value = '';
40
56
  if (expression.type === 'Identifier') {
@@ -50,8 +66,8 @@ function getColorFromIdentifier(expression) {
50
66
  }
51
67
  function getTokenFromNode(j, path, value, propertyName) {
52
68
  var valueMeta = (0, _astMeta.cleanMeta)(_legacyColors.legacyColorMetaMap[value] || []);
53
- var ancestorMeta = (0, _astMeta.cleanMeta)([].concat((0, _toConsumableArray2.default)((0, _astMeta.getMetaFromAncestors)(j, path)), (0, _toConsumableArray2.default)(kebabize(propertyName).split('-'))) || []);
54
- var property = (0, _astMeta.cleanMeta)([kebabize(propertyName)])[0];
69
+ var ancestorMeta = (0, _astMeta.cleanMeta)([].concat((0, _toConsumableArray2.default)((0, _astMeta.getMetaFromAncestors)(j, path)), (0, _toConsumableArray2.default)((0, _stringUtils.kebabize)(propertyName).split('-'))) || []);
70
+ var property = (0, _astMeta.cleanMeta)([(0, _stringUtils.kebabize)(propertyName)])[0];
55
71
 
56
72
  // Attempt to find a property from ancestors if one is not found
57
73
  if (!property || !['border', 'icon', 'background', 'text'].includes(property)) {
@@ -100,7 +116,7 @@ function getTokenFromNode(j, path, value, propertyName) {
100
116
  } else if (value.includes('N0')) {
101
117
  // default surface
102
118
  meta.push('elevation', 'surface');
103
- } else if (valueMeta.includes('neutral') && isBoldColor(value)) {
119
+ } else if (valueMeta.includes('neutral') && (0, _color.isBoldColor)(value)) {
104
120
  // bold netural backgrounds
105
121
  meta.push('background', 'neutral', 'bold');
106
122
  } else if (valueMeta.includes('neutral')) {
@@ -146,100 +162,328 @@ function getTokenFromNode(j, path, value, propertyName) {
146
162
  }
147
163
  function parseCSSPropertyName(cssString) {
148
164
  var lastColonIndex = cssString.lastIndexOf(':');
149
- var propertyNameEndIndex = Math.max(cssString.lastIndexOf(';', lastColonIndex), cssString.lastIndexOf(' ', lastColonIndex));
150
- return cssString.slice(propertyNameEndIndex + 1, lastColonIndex).trim();
165
+ if (lastColonIndex === -1) {
166
+ return {
167
+ colonIndex: null,
168
+ cssPropertyName: null
169
+ };
170
+ }
171
+ var propertyNameEndIndex = Math.max(cssString.lastIndexOf(';', lastColonIndex), cssString.lastIndexOf(' ', lastColonIndex), -1);
172
+ var startIndex = propertyNameEndIndex + 1;
173
+ return {
174
+ cssPropertyName: cssString.slice(startIndex, lastColonIndex).trim(),
175
+ colonIndex: lastColonIndex
176
+ };
177
+ }
178
+ function transformer(_x, _x2) {
179
+ return _transformer.apply(this, arguments);
151
180
  }
152
- function transformer(file, api) {
153
- var debug = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
154
- var j = api.jscodeshift;
155
- var source = j(file.source);
156
- var transformed = false;
181
+ function _transformer() {
182
+ _transformer = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(file, api) {
183
+ var debug,
184
+ j,
185
+ source,
186
+ transformed,
187
+ templateLiteralPaths,
188
+ _iterator,
189
+ _step,
190
+ _loop,
191
+ replaceStringLiteralIfItConsistsOnlyOfColor,
192
+ replaceTemplateLiteralExpression,
193
+ _args2 = arguments;
194
+ return _regenerator.default.wrap(function _callee$(_context2) {
195
+ while (1) switch (_context2.prev = _context2.next) {
196
+ case 0:
197
+ replaceTemplateLiteralExpression = function _replaceTemplateLiter(j, mainPath, expressionPath, expressionIndex) {
198
+ var expression = expressionPath.value;
199
+ if (!(expression.type === 'MemberExpression' || expression.type === 'Identifier')) {
200
+ return false;
201
+ }
202
+ if ((0, _ast.isDecendantOfToken)(j, expressionPath)) {
203
+ return false;
204
+ }
205
+ var value = getColorFromIdentifier(expression);
206
+ if (!value || !(0, _color.includesHardCodedColor)(value) && !(0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
207
+ return false;
208
+ }
209
+ var precedingQuasi = mainPath.value.quasis[expressionIndex];
210
+ var precedingQuasiText = precedingQuasi.value.raw;
211
+ var _parseCSSPropertyName = parseCSSPropertyName(precedingQuasiText),
212
+ cssPropertyName = _parseCSSPropertyName.cssPropertyName,
213
+ colonIndex = _parseCSSPropertyName.colonIndex;
214
+ if (!cssPropertyName) {
215
+ return false;
216
+ }
217
+ var tokenId = getTokenFromNode(j, expressionPath, value, cssPropertyName);
218
+ insertTokenImport(j, source);
219
+ var newQuasis = (0, _toConsumableArray2.default)(mainPath.value.quasis);
220
+ var newExpressions = (0, _toConsumableArray2.default)(mainPath.value.expressions);
221
+ if (cssPropertyName !== 'box-shadow') {
222
+ var tokenExpression = buildToken(j, tokenId, expressionPath.value);
223
+ newExpressions[expressionIndex] = tokenExpression;
224
+ } else {
225
+ // box-shadow is a multi-part property where the color can appear at any
226
+ // part position (even though the standard suggests that color comes
227
+ // last, browsers' CSS parsers are more lax). If we get here, then the
228
+ // color part is replaceable. Textually, it's something like:
229
+ //
230
+ // <rules before>; box-shadow: 0 1px ${colors.N50} 2rem; <rules after>
231
+ //
232
+ // the fallback value will be multipart, i.e. the token call is
233
+ //
234
+ // token(<replacedValue>, `0 1px ${colors.N50} 2rem`)
235
+ //
236
+ // and it's wrapped in a substitution like this:
237
+ //
238
+ // <rules before>; box-shadow: ${token(<...>)}; <rules after>
239
+ //
240
+ // We stich the fallback from the last part of preceding quasi (after
241
+ // colon) and the first part of the following quasi (before ';' or '}').
242
+ //
243
+ // If multiple box-shadows are comma-separated but only one of them has a
244
+ // replaceable color and others are hard-coded, this logic would still
245
+ // work. When multiple shadows have expressions, it's unfortunately not
246
+ // possible to proceed because we cannot find where the value ends from a
247
+ // single following quasi.
248
+ var valueStartIndex = (0, _stringUtils.findFirstNonspaceIndexAfter)(precedingQuasiText, colonIndex);
249
+ var _splitAtIndex = (0, _stringUtils.splitAtIndex)(precedingQuasiText, valueStartIndex),
250
+ _splitAtIndex2 = (0, _slicedToArray2.default)(_splitAtIndex, 2),
251
+ newPrecedingQuasiText = _splitAtIndex2[0],
252
+ partialValueBeginning = _splitAtIndex2[1];
253
+ var followingQuasi = mainPath.value.quasis[expressionIndex + 1];
254
+ var followingQuasiText = followingQuasi.value.raw;
255
+ var valueEndIndex = (0, _cssUtils.findEndIndexOfCSSExpression)(followingQuasiText, followingQuasi.tail);
256
+ if (!valueEndIndex) {
257
+ console.warn('cannot find end of box-shadow value, please check manually');
258
+ return false;
259
+ }
260
+ var _splitAtIndex3 = (0, _stringUtils.splitAtIndex)(followingQuasiText, valueEndIndex + 1),
261
+ _splitAtIndex4 = (0, _slicedToArray2.default)(_splitAtIndex3, 2),
262
+ partialValueEnd = _splitAtIndex4[0],
263
+ newFollowingQuasiText = _splitAtIndex4[1];
264
+ var internalQuasis = [buildTemplateElement(j, partialValueBeginning, {
265
+ tail: false
266
+ }), buildTemplateElement(j, partialValueEnd, {
267
+ tail: true
268
+ })];
269
+ var internalExpressions = [expressionPath.value];
270
+ var newFallback = j.templateLiteral(internalQuasis, internalExpressions);
271
+ var newExpression = buildToken(j, tokenId, newFallback);
272
+ newQuasis[expressionIndex] = buildTemplateElement(j, newPrecedingQuasiText, {
273
+ fromNode: newQuasis[expressionIndex]
274
+ });
275
+ newExpressions[expressionIndex] = newExpression;
276
+ newQuasis[expressionIndex + 1] = buildTemplateElement(j, newFollowingQuasiText, {
277
+ fromNode: newQuasis[expressionIndex]
278
+ });
279
+ }
280
+ mainPath.replace(j.templateLiteral(newQuasis, newExpressions));
281
+ return true;
282
+ };
283
+ replaceStringLiteralIfItConsistsOnlyOfColor = function _replaceStringLiteral(j, path, value) {
284
+ if ((0, _ast.isDecendantOfToken)(j, path)) {
285
+ return false;
286
+ }
287
+ if ((0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
288
+ var parent = path.parent.value;
289
+ var key = '';
290
+ if (parent.type === 'VariableDeclarator') {
291
+ key = parent.id.name;
292
+ }
293
+ var tokenId = getTokenFromNode(j, path, value, key);
294
+ insertTokenImport(j, source);
295
+ j(path).replaceWith(buildToken(j, tokenId, path.value));
296
+ return true;
297
+ }
298
+ return false;
299
+ };
300
+ debug = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : false;
301
+ j = api.jscodeshift;
302
+ source = j(file.source);
303
+ transformed = false; // Objects
304
+ source.find(j.ObjectProperty).forEach(function (path) {
305
+ if (path.value.value.type === 'ObjectExpression') {
306
+ return;
307
+ }
157
308
 
158
- // Objects
159
- source.find(j.ObjectProperty).forEach(function (path) {
160
- if (path.value.value.type === 'ObjectExpression') {
161
- return;
162
- }
309
+ // Avoid transforming objects that are default arguments
310
+ if (path.parent.parent.value.type === 'ArrowFunctionExpression' || path.parent.parent.value.type === 'FunctionDeclaration') {
311
+ return;
312
+ }
313
+ if ((0, _ast.isParentOfToken)(j, path.value.value)) {
314
+ return;
315
+ }
316
+ var value = getColorFromIdentifier(path.value.value);
317
+ if (!value || !(0, _color.includesHardCodedColor)(value) && !(0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
318
+ return;
319
+ }
320
+ var key;
321
+ if (path.value.key.type === 'NumericLiteral' || path.value.key.type === 'StringLiteral') {
322
+ key = path.value.key.value.toString();
323
+ }
324
+ if (path.value.key.type === 'Identifier') {
325
+ key = path.value.key.name;
326
+ }
163
327
 
164
- // Avoid transforming objects that are default arguments
165
- if (path.parent.parent.value.type === 'ArrowFunctionExpression' || path.parent.parent.value.type === 'FunctionDeclaration') {
166
- return;
167
- }
168
- if ((0, _ast.isParentOfToken)(j, path.value.value)) {
169
- return;
170
- }
171
- var value = getColorFromIdentifier(path.value.value);
172
- if (!value || !(0, _color.includesHardCodedColor)(value) && !(0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
173
- return;
174
- }
175
- var key;
176
- if (path.value.key.type === 'NumericLiteral' || path.value.key.type === 'StringLiteral') {
177
- key = path.value.key.value.toString();
178
- }
179
- if (path.value.key.type === 'Identifier') {
180
- key = path.value.key.name;
181
- }
328
+ // Key is a node type we do not support
329
+ if (!key) {
330
+ return;
331
+ }
332
+ var tokenId = getTokenFromNode(j, path, value, key);
333
+ insertTokenImport(j, source);
334
+ j(path).replaceWith(j.objectProperty(path.value.key, buildToken(j, tokenId, path.value.value)));
335
+ transformed = true;
336
+ });
182
337
 
183
- // Key is a node type we do not support
184
- if (!key) {
185
- return;
186
- }
187
- var tokenId = getTokenFromNode(j, path, value, key);
188
- insertTokenImport(j, source);
189
- j(path).replaceWith(j.objectProperty(path.value.key, buildToken(j, tokenId, path.value.value)));
190
- transformed = true;
191
- });
338
+ // JSX props
339
+ source.find(j.JSXAttribute).forEach(function (path) {
340
+ var _path$value;
341
+ if (((_path$value = path.value) === null || _path$value === void 0 || (_path$value = _path$value.value) === null || _path$value === void 0 ? void 0 : _path$value.type) !== 'JSXExpressionContainer') {
342
+ return;
343
+ }
344
+ if ((0, _ast.isParentOfToken)(j, path)) {
345
+ return;
346
+ }
347
+ var expression = path.value.value.expression;
348
+ var value = getColorFromIdentifier(expression);
349
+ if (!value || !(0, _color.includesHardCodedColor)(value) && !(0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
350
+ return;
351
+ }
352
+ var tokenId = getTokenFromNode(j, path, value, path.value.name.name);
353
+ insertTokenImport(j, source);
354
+ j(path).find(j.JSXExpressionContainer).forEach(function (path) {
355
+ var tokenNode = buildToken(j, tokenId, path.value.expression);
356
+ j(path).replaceWith(j.jsxExpressionContainer(tokenNode));
357
+ });
358
+ transformed = true;
359
+ });
192
360
 
193
- // Template literals
194
- source.find(j.TemplateLiteral).forEach(function (path) {
195
- function replaceTemplateLiteralExpressions(j, expression, index) {
196
- if ((0, _ast.isDecendantOfToken)(j, expression)) {
197
- return;
198
- }
199
- if (index >= path.value.quasis.length) {
200
- return;
201
- }
202
- var quasi = path.value.quasis[index];
203
- var value = getColorFromIdentifier(expression.value);
204
- if (!value || !(0, _color.includesHardCodedColor)(value) && !(0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
205
- return;
206
- }
207
- var tokenId = getTokenFromNode(j, expression, value, parseCSSPropertyName(quasi.value.cooked || ''));
208
- insertTokenImport(j, source);
209
- expression.replace(buildToken(j, tokenId, expression.value));
210
- }
211
- j(path).find(j.Identifier).filter(function (expression) {
212
- return !(0, _utils.isDecendantOfType)(j, expression, j.MemberExpression);
213
- }).forEach(function (expression, i) {
214
- return replaceTemplateLiteralExpressions(j, expression, i);
215
- });
216
- j(path).find(j.MemberExpression).forEach(function (expression, i) {
217
- return replaceTemplateLiteralExpressions(j, expression, i);
218
- });
219
- transformed = true;
220
- });
361
+ // Strings
362
+ source.find(j.StringLiteral).forEach(function (path) {
363
+ j(path).filter(function (expression) {
364
+ return !(0, _utils.isDecendantOfType)(j, expression, j.ObjectExpression);
365
+ }).forEach(function (path) {
366
+ var value = path.value.value;
367
+ if (replaceStringLiteralIfItConsistsOnlyOfColor(j, path, value)) {
368
+ transformed = true;
369
+ }
370
+ });
371
+ });
372
+ templateLiteralPaths = source.find(j.TemplateLiteral).paths();
373
+ _iterator = _createForOfIteratorHelper(templateLiteralPaths);
374
+ _context2.prev = 11;
375
+ _loop = /*#__PURE__*/_regenerator.default.mark(function _loop() {
376
+ var path, text, quasiPaths, _iterator2, _step2, quasiPath, _text, newCSS;
377
+ return _regenerator.default.wrap(function _loop$(_context) {
378
+ while (1) switch (_context.prev = _context.next) {
379
+ case 0:
380
+ path = _step.value;
381
+ // Background: a 'type: TemplateLiteral' Node has quasis and expressions
382
+ // (see ast-types/src/gen/namedTypes.ts), and invariant holds that
383
+ // quasis.length === expression.length + 1.
384
+ //
385
+ // eg `${foo}bar` has quasis [Node(''), Node('bar')] and expressions
386
+ // [Node('foo')]. Each quasi has type: 'TemplateElement'; expressions are
387
+ // probably safe to treat as subtypes of Expression, though ast-types
388
+ // codebase has a more involved definition.
389
+ if (path.value.expressions.length === 0) {
390
+ // A single-quasi (equivalently, no-expression) template literal is
391
+ // basically just a string literal, possibly multi-line. We handle the
392
+ // simple `#ababab` case here, and the multi-line case after.
393
+ text = path.value.quasis[0].value.raw;
394
+ if (replaceStringLiteralIfItConsistsOnlyOfColor(j, path, text)) {
395
+ transformed = true;
396
+ }
397
+ } else {
398
+ j(path).find(j.Expression).filter(function (expressionPath) {
399
+ // jscodeshift walks over the whole tree; we are interested only in
400
+ // the direct children: i.e. top-level expressions appearing in ${}.
401
+ return expressionPath.parent === path;
402
+ }).forEach(function (expressionPath, expressionIndex) {
403
+ if (replaceTemplateLiteralExpression(j, path, expressionPath, expressionIndex)) {
404
+ transformed = true;
405
+ }
406
+ });
407
+ }
221
408
 
222
- // JSX props
223
- source.find(j.JSXAttribute).forEach(function (path) {
224
- var _path$value, _path$value$value;
225
- if (((_path$value = path.value) === null || _path$value === void 0 ? void 0 : (_path$value$value = _path$value.value) === null || _path$value$value === void 0 ? void 0 : _path$value$value.type) !== 'JSXExpressionContainer') {
226
- return;
227
- }
228
- if ((0, _ast.isParentOfToken)(j, path)) {
229
- return;
230
- }
231
- var expression = path.value.value.expression;
232
- var value = getColorFromIdentifier(expression);
233
- if (!value || !(0, _color.includesHardCodedColor)(value) && !(0, _color.isHardCodedColor)(value) && !(0, _color.isLegacyColor)(value) && !(0, _color.isLegacyNamedColor)(value)) {
234
- return;
235
- }
236
- var tokenId = getTokenFromNode(j, path, value, path.value.name.name);
237
- insertTokenImport(j, source);
238
- j(path).find(j.JSXExpressionContainer).forEach(function (path) {
239
- var tokenNode = buildToken(j, tokenId, path.value.expression);
240
- j(path).replaceWith(j.jsxExpressionContainer(tokenNode));
241
- });
242
- transformed = true;
243
- });
244
- return transformed ? source.toSource() : file.source;
409
+ // No matter if we have one big quasi or many small chunks between
410
+ // expressions (which potentially have been transformed), try to pass them
411
+ // through the CSS transformer; it's robust enough to understand malformed
412
+ // CSS that would result if we split e.g. this template:
413
+ //
414
+ // `${gridSize}px; color: red;`, giving `px; color: red;` as input; or
415
+ // `@media ${mobile} { color: red }`, giving `{ color: red }`.
416
+ quasiPaths = j(path).find(j.TemplateElement).filter(function (quasiPath) {
417
+ return quasiPath.parent === path;
418
+ }).paths();
419
+ _iterator2 = _createForOfIteratorHelper(quasiPaths);
420
+ _context.prev = 4;
421
+ _iterator2.s();
422
+ case 6:
423
+ if ((_step2 = _iterator2.n()).done) {
424
+ _context.next = 17;
425
+ break;
426
+ }
427
+ quasiPath = _step2.value;
428
+ _text = quasiPath.value.value.raw;
429
+ if (!((0, _color.includesHardCodedColor)(_text) && (0, _cssUtils.containsReplaceableCSSDeclarations)(_text))) {
430
+ _context.next = 15;
431
+ break;
432
+ }
433
+ _context.next = 12;
434
+ return (0, _cssToDesignTokens.default)(_text);
435
+ case 12:
436
+ newCSS = _context.sent;
437
+ j(quasiPath).replaceWith(buildTemplateElement(j, newCSS));
438
+ transformed = true;
439
+ case 15:
440
+ _context.next = 6;
441
+ break;
442
+ case 17:
443
+ _context.next = 22;
444
+ break;
445
+ case 19:
446
+ _context.prev = 19;
447
+ _context.t0 = _context["catch"](4);
448
+ _iterator2.e(_context.t0);
449
+ case 22:
450
+ _context.prev = 22;
451
+ _iterator2.f();
452
+ return _context.finish(22);
453
+ case 25:
454
+ case "end":
455
+ return _context.stop();
456
+ }
457
+ }, _loop, null, [[4, 19, 22, 25]]);
458
+ });
459
+ _iterator.s();
460
+ case 14:
461
+ if ((_step = _iterator.n()).done) {
462
+ _context2.next = 18;
463
+ break;
464
+ }
465
+ return _context2.delegateYield(_loop(), "t0", 16);
466
+ case 16:
467
+ _context2.next = 14;
468
+ break;
469
+ case 18:
470
+ _context2.next = 23;
471
+ break;
472
+ case 20:
473
+ _context2.prev = 20;
474
+ _context2.t1 = _context2["catch"](11);
475
+ _iterator.e(_context2.t1);
476
+ case 23:
477
+ _context2.prev = 23;
478
+ _iterator.f();
479
+ return _context2.finish(23);
480
+ case 26:
481
+ return _context2.abrupt("return", transformed ? source.toSource() : file.source);
482
+ case 27:
483
+ case "end":
484
+ return _context2.stop();
485
+ }
486
+ }, _callee, null, [[11, 20, 23, 26]]);
487
+ }));
488
+ return _transformer.apply(this, arguments);
245
489
  }
@@ -8,7 +8,7 @@ exports.isDecendantOfToken = isDecendantOfToken;
8
8
  exports.isParentOfToken = isParentOfToken;
9
9
  var _utils = require("@codeshift/utils");
10
10
  function isDecendantOfToken(j, path) {
11
- if (path.type === 'CallExpression' && path.callee.type === 'Identifier' && path.callee.name === 'token') {
11
+ if ('type' in path && path.type === 'CallExpression' && path.callee.type === 'Identifier' && path.callee.name === 'token') {
12
12
  return true;
13
13
  }
14
14
  return j(path).closest(j.CallExpression, {