@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
@@ -1,22 +1,22 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
1
3
  import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
+ import _regeneratorRuntime from "@babel/runtime/regenerator";
5
+ 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; } } }; }
6
+ 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); }
7
+ 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; }
2
8
  /* eslint-disable no-console */
3
9
 
4
10
  import { isDecendantOfType, hasImportDeclaration } from '@codeshift/utils';
5
11
  import { isDecendantOfToken, isParentOfToken } from './utils/ast';
6
12
  import { cleanMeta, getMetaFromAncestors } from './utils/ast-meta';
7
- import { includesHardCodedColor, isHardCodedColor, isLegacyColor, isLegacyNamedColor } from './utils/color';
13
+ import { includesHardCodedColor, isHardCodedColor, isLegacyColor, isLegacyNamedColor, isBoldColor } from './utils/color';
8
14
  import Search from './utils/fuzzy-search';
9
15
  import { legacyColorMetaMap } from './utils/legacy-colors';
10
16
  import { tokens } from './utils/tokens';
11
- var kebabize = function kebabize(str) {
12
- return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) {
13
- return (ofs ? '-' : '') + $.toLowerCase();
14
- });
15
- };
16
- function isBoldColor(color) {
17
- var number = parseInt(color.replace(/^./, ''), 10);
18
- return number > 300;
19
- }
17
+ import { kebabize, findFirstNonspaceIndexAfter, splitAtIndex } from './utils/string-utils';
18
+ import { containsReplaceableCSSDeclarations, findEndIndexOfCSSExpression } from './utils/css-utils';
19
+ import CSSTransformer from '../css-to-design-tokens/css-to-design-tokens';
20
20
  function insertTokenImport(j, source) {
21
21
  if (hasImportDeclaration(j, source, '@atlaskit/tokens')) {
22
22
  return;
@@ -28,6 +28,24 @@ function buildToken(j, tokenId, node) {
28
28
  var callExpr = j.callExpression(j.identifier('token'), [j.stringLiteral(tokenId), node].filter(Boolean));
29
29
  return callExpr;
30
30
  }
31
+
32
+ // Wrap over the j.templateElement builder to provide a more convenient API.
33
+ function buildTemplateElement(j, text) {
34
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
35
+ tail: false,
36
+ fromNode: null
37
+ };
38
+ var tail;
39
+ if (options.fromNode) {
40
+ tail = options.fromNode.tail;
41
+ } else {
42
+ tail = !!options.tail;
43
+ }
44
+ return j.templateElement({
45
+ raw: text,
46
+ cooked: null
47
+ }, tail);
48
+ }
31
49
  function getColorFromIdentifier(expression) {
32
50
  var value = '';
33
51
  if (expression.type === 'Identifier') {
@@ -139,100 +157,328 @@ function getTokenFromNode(j, path, value, propertyName) {
139
157
  }
140
158
  function parseCSSPropertyName(cssString) {
141
159
  var lastColonIndex = cssString.lastIndexOf(':');
142
- var propertyNameEndIndex = Math.max(cssString.lastIndexOf(';', lastColonIndex), cssString.lastIndexOf(' ', lastColonIndex));
143
- return cssString.slice(propertyNameEndIndex + 1, lastColonIndex).trim();
160
+ if (lastColonIndex === -1) {
161
+ return {
162
+ colonIndex: null,
163
+ cssPropertyName: null
164
+ };
165
+ }
166
+ var propertyNameEndIndex = Math.max(cssString.lastIndexOf(';', lastColonIndex), cssString.lastIndexOf(' ', lastColonIndex), -1);
167
+ var startIndex = propertyNameEndIndex + 1;
168
+ return {
169
+ cssPropertyName: cssString.slice(startIndex, lastColonIndex).trim(),
170
+ colonIndex: lastColonIndex
171
+ };
172
+ }
173
+ export default function transformer(_x, _x2) {
174
+ return _transformer.apply(this, arguments);
144
175
  }
145
- export default function transformer(file, api) {
146
- var debug = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
147
- var j = api.jscodeshift;
148
- var source = j(file.source);
149
- var transformed = false;
176
+ function _transformer() {
177
+ _transformer = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee(file, api) {
178
+ var debug,
179
+ j,
180
+ source,
181
+ transformed,
182
+ templateLiteralPaths,
183
+ _iterator,
184
+ _step,
185
+ _loop,
186
+ replaceStringLiteralIfItConsistsOnlyOfColor,
187
+ replaceTemplateLiteralExpression,
188
+ _args2 = arguments;
189
+ return _regeneratorRuntime.wrap(function _callee$(_context2) {
190
+ while (1) switch (_context2.prev = _context2.next) {
191
+ case 0:
192
+ replaceTemplateLiteralExpression = function _replaceTemplateLiter(j, mainPath, expressionPath, expressionIndex) {
193
+ var expression = expressionPath.value;
194
+ if (!(expression.type === 'MemberExpression' || expression.type === 'Identifier')) {
195
+ return false;
196
+ }
197
+ if (isDecendantOfToken(j, expressionPath)) {
198
+ return false;
199
+ }
200
+ var value = getColorFromIdentifier(expression);
201
+ if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
202
+ return false;
203
+ }
204
+ var precedingQuasi = mainPath.value.quasis[expressionIndex];
205
+ var precedingQuasiText = precedingQuasi.value.raw;
206
+ var _parseCSSPropertyName = parseCSSPropertyName(precedingQuasiText),
207
+ cssPropertyName = _parseCSSPropertyName.cssPropertyName,
208
+ colonIndex = _parseCSSPropertyName.colonIndex;
209
+ if (!cssPropertyName) {
210
+ return false;
211
+ }
212
+ var tokenId = getTokenFromNode(j, expressionPath, value, cssPropertyName);
213
+ insertTokenImport(j, source);
214
+ var newQuasis = _toConsumableArray(mainPath.value.quasis);
215
+ var newExpressions = _toConsumableArray(mainPath.value.expressions);
216
+ if (cssPropertyName !== 'box-shadow') {
217
+ var tokenExpression = buildToken(j, tokenId, expressionPath.value);
218
+ newExpressions[expressionIndex] = tokenExpression;
219
+ } else {
220
+ // box-shadow is a multi-part property where the color can appear at any
221
+ // part position (even though the standard suggests that color comes
222
+ // last, browsers' CSS parsers are more lax). If we get here, then the
223
+ // color part is replaceable. Textually, it's something like:
224
+ //
225
+ // <rules before>; box-shadow: 0 1px ${colors.N50} 2rem; <rules after>
226
+ //
227
+ // the fallback value will be multipart, i.e. the token call is
228
+ //
229
+ // token(<replacedValue>, `0 1px ${colors.N50} 2rem`)
230
+ //
231
+ // and it's wrapped in a substitution like this:
232
+ //
233
+ // <rules before>; box-shadow: ${token(<...>)}; <rules after>
234
+ //
235
+ // We stich the fallback from the last part of preceding quasi (after
236
+ // colon) and the first part of the following quasi (before ';' or '}').
237
+ //
238
+ // If multiple box-shadows are comma-separated but only one of them has a
239
+ // replaceable color and others are hard-coded, this logic would still
240
+ // work. When multiple shadows have expressions, it's unfortunately not
241
+ // possible to proceed because we cannot find where the value ends from a
242
+ // single following quasi.
243
+ var valueStartIndex = findFirstNonspaceIndexAfter(precedingQuasiText, colonIndex);
244
+ var _splitAtIndex = splitAtIndex(precedingQuasiText, valueStartIndex),
245
+ _splitAtIndex2 = _slicedToArray(_splitAtIndex, 2),
246
+ newPrecedingQuasiText = _splitAtIndex2[0],
247
+ partialValueBeginning = _splitAtIndex2[1];
248
+ var followingQuasi = mainPath.value.quasis[expressionIndex + 1];
249
+ var followingQuasiText = followingQuasi.value.raw;
250
+ var valueEndIndex = findEndIndexOfCSSExpression(followingQuasiText, followingQuasi.tail);
251
+ if (!valueEndIndex) {
252
+ console.warn('cannot find end of box-shadow value, please check manually');
253
+ return false;
254
+ }
255
+ var _splitAtIndex3 = splitAtIndex(followingQuasiText, valueEndIndex + 1),
256
+ _splitAtIndex4 = _slicedToArray(_splitAtIndex3, 2),
257
+ partialValueEnd = _splitAtIndex4[0],
258
+ newFollowingQuasiText = _splitAtIndex4[1];
259
+ var internalQuasis = [buildTemplateElement(j, partialValueBeginning, {
260
+ tail: false
261
+ }), buildTemplateElement(j, partialValueEnd, {
262
+ tail: true
263
+ })];
264
+ var internalExpressions = [expressionPath.value];
265
+ var newFallback = j.templateLiteral(internalQuasis, internalExpressions);
266
+ var newExpression = buildToken(j, tokenId, newFallback);
267
+ newQuasis[expressionIndex] = buildTemplateElement(j, newPrecedingQuasiText, {
268
+ fromNode: newQuasis[expressionIndex]
269
+ });
270
+ newExpressions[expressionIndex] = newExpression;
271
+ newQuasis[expressionIndex + 1] = buildTemplateElement(j, newFollowingQuasiText, {
272
+ fromNode: newQuasis[expressionIndex]
273
+ });
274
+ }
275
+ mainPath.replace(j.templateLiteral(newQuasis, newExpressions));
276
+ return true;
277
+ };
278
+ replaceStringLiteralIfItConsistsOnlyOfColor = function _replaceStringLiteral(j, path, value) {
279
+ if (isDecendantOfToken(j, path)) {
280
+ return false;
281
+ }
282
+ if (isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
283
+ var parent = path.parent.value;
284
+ var key = '';
285
+ if (parent.type === 'VariableDeclarator') {
286
+ key = parent.id.name;
287
+ }
288
+ var tokenId = getTokenFromNode(j, path, value, key);
289
+ insertTokenImport(j, source);
290
+ j(path).replaceWith(buildToken(j, tokenId, path.value));
291
+ return true;
292
+ }
293
+ return false;
294
+ };
295
+ debug = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : false;
296
+ j = api.jscodeshift;
297
+ source = j(file.source);
298
+ transformed = false; // Objects
299
+ source.find(j.ObjectProperty).forEach(function (path) {
300
+ if (path.value.value.type === 'ObjectExpression') {
301
+ return;
302
+ }
150
303
 
151
- // Objects
152
- source.find(j.ObjectProperty).forEach(function (path) {
153
- if (path.value.value.type === 'ObjectExpression') {
154
- return;
155
- }
304
+ // Avoid transforming objects that are default arguments
305
+ if (path.parent.parent.value.type === 'ArrowFunctionExpression' || path.parent.parent.value.type === 'FunctionDeclaration') {
306
+ return;
307
+ }
308
+ if (isParentOfToken(j, path.value.value)) {
309
+ return;
310
+ }
311
+ var value = getColorFromIdentifier(path.value.value);
312
+ if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
313
+ return;
314
+ }
315
+ var key;
316
+ if (path.value.key.type === 'NumericLiteral' || path.value.key.type === 'StringLiteral') {
317
+ key = path.value.key.value.toString();
318
+ }
319
+ if (path.value.key.type === 'Identifier') {
320
+ key = path.value.key.name;
321
+ }
156
322
 
157
- // Avoid transforming objects that are default arguments
158
- if (path.parent.parent.value.type === 'ArrowFunctionExpression' || path.parent.parent.value.type === 'FunctionDeclaration') {
159
- return;
160
- }
161
- if (isParentOfToken(j, path.value.value)) {
162
- return;
163
- }
164
- var value = getColorFromIdentifier(path.value.value);
165
- if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
166
- return;
167
- }
168
- var key;
169
- if (path.value.key.type === 'NumericLiteral' || path.value.key.type === 'StringLiteral') {
170
- key = path.value.key.value.toString();
171
- }
172
- if (path.value.key.type === 'Identifier') {
173
- key = path.value.key.name;
174
- }
323
+ // Key is a node type we do not support
324
+ if (!key) {
325
+ return;
326
+ }
327
+ var tokenId = getTokenFromNode(j, path, value, key);
328
+ insertTokenImport(j, source);
329
+ j(path).replaceWith(j.objectProperty(path.value.key, buildToken(j, tokenId, path.value.value)));
330
+ transformed = true;
331
+ });
175
332
 
176
- // Key is a node type we do not support
177
- if (!key) {
178
- return;
179
- }
180
- var tokenId = getTokenFromNode(j, path, value, key);
181
- insertTokenImport(j, source);
182
- j(path).replaceWith(j.objectProperty(path.value.key, buildToken(j, tokenId, path.value.value)));
183
- transformed = true;
184
- });
333
+ // JSX props
334
+ source.find(j.JSXAttribute).forEach(function (path) {
335
+ var _path$value;
336
+ 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') {
337
+ return;
338
+ }
339
+ if (isParentOfToken(j, path)) {
340
+ return;
341
+ }
342
+ var expression = path.value.value.expression;
343
+ var value = getColorFromIdentifier(expression);
344
+ if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
345
+ return;
346
+ }
347
+ var tokenId = getTokenFromNode(j, path, value, path.value.name.name);
348
+ insertTokenImport(j, source);
349
+ j(path).find(j.JSXExpressionContainer).forEach(function (path) {
350
+ var tokenNode = buildToken(j, tokenId, path.value.expression);
351
+ j(path).replaceWith(j.jsxExpressionContainer(tokenNode));
352
+ });
353
+ transformed = true;
354
+ });
185
355
 
186
- // Template literals
187
- source.find(j.TemplateLiteral).forEach(function (path) {
188
- function replaceTemplateLiteralExpressions(j, expression, index) {
189
- if (isDecendantOfToken(j, expression)) {
190
- return;
191
- }
192
- if (index >= path.value.quasis.length) {
193
- return;
194
- }
195
- var quasi = path.value.quasis[index];
196
- var value = getColorFromIdentifier(expression.value);
197
- if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
198
- return;
199
- }
200
- var tokenId = getTokenFromNode(j, expression, value, parseCSSPropertyName(quasi.value.cooked || ''));
201
- insertTokenImport(j, source);
202
- expression.replace(buildToken(j, tokenId, expression.value));
203
- }
204
- j(path).find(j.Identifier).filter(function (expression) {
205
- return !isDecendantOfType(j, expression, j.MemberExpression);
206
- }).forEach(function (expression, i) {
207
- return replaceTemplateLiteralExpressions(j, expression, i);
208
- });
209
- j(path).find(j.MemberExpression).forEach(function (expression, i) {
210
- return replaceTemplateLiteralExpressions(j, expression, i);
211
- });
212
- transformed = true;
213
- });
356
+ // Strings
357
+ source.find(j.StringLiteral).forEach(function (path) {
358
+ j(path).filter(function (expression) {
359
+ return !isDecendantOfType(j, expression, j.ObjectExpression);
360
+ }).forEach(function (path) {
361
+ var value = path.value.value;
362
+ if (replaceStringLiteralIfItConsistsOnlyOfColor(j, path, value)) {
363
+ transformed = true;
364
+ }
365
+ });
366
+ });
367
+ templateLiteralPaths = source.find(j.TemplateLiteral).paths();
368
+ _iterator = _createForOfIteratorHelper(templateLiteralPaths);
369
+ _context2.prev = 11;
370
+ _loop = /*#__PURE__*/_regeneratorRuntime.mark(function _loop() {
371
+ var path, text, quasiPaths, _iterator2, _step2, quasiPath, _text, newCSS;
372
+ return _regeneratorRuntime.wrap(function _loop$(_context) {
373
+ while (1) switch (_context.prev = _context.next) {
374
+ case 0:
375
+ path = _step.value;
376
+ // Background: a 'type: TemplateLiteral' Node has quasis and expressions
377
+ // (see ast-types/src/gen/namedTypes.ts), and invariant holds that
378
+ // quasis.length === expression.length + 1.
379
+ //
380
+ // eg `${foo}bar` has quasis [Node(''), Node('bar')] and expressions
381
+ // [Node('foo')]. Each quasi has type: 'TemplateElement'; expressions are
382
+ // probably safe to treat as subtypes of Expression, though ast-types
383
+ // codebase has a more involved definition.
384
+ if (path.value.expressions.length === 0) {
385
+ // A single-quasi (equivalently, no-expression) template literal is
386
+ // basically just a string literal, possibly multi-line. We handle the
387
+ // simple `#ababab` case here, and the multi-line case after.
388
+ text = path.value.quasis[0].value.raw;
389
+ if (replaceStringLiteralIfItConsistsOnlyOfColor(j, path, text)) {
390
+ transformed = true;
391
+ }
392
+ } else {
393
+ j(path).find(j.Expression).filter(function (expressionPath) {
394
+ // jscodeshift walks over the whole tree; we are interested only in
395
+ // the direct children: i.e. top-level expressions appearing in ${}.
396
+ return expressionPath.parent === path;
397
+ }).forEach(function (expressionPath, expressionIndex) {
398
+ if (replaceTemplateLiteralExpression(j, path, expressionPath, expressionIndex)) {
399
+ transformed = true;
400
+ }
401
+ });
402
+ }
214
403
 
215
- // JSX props
216
- source.find(j.JSXAttribute).forEach(function (path) {
217
- var _path$value, _path$value$value;
218
- 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') {
219
- return;
220
- }
221
- if (isParentOfToken(j, path)) {
222
- return;
223
- }
224
- var expression = path.value.value.expression;
225
- var value = getColorFromIdentifier(expression);
226
- if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
227
- return;
228
- }
229
- var tokenId = getTokenFromNode(j, path, value, path.value.name.name);
230
- insertTokenImport(j, source);
231
- j(path).find(j.JSXExpressionContainer).forEach(function (path) {
232
- var tokenNode = buildToken(j, tokenId, path.value.expression);
233
- j(path).replaceWith(j.jsxExpressionContainer(tokenNode));
234
- });
235
- transformed = true;
236
- });
237
- return transformed ? source.toSource() : file.source;
404
+ // No matter if we have one big quasi or many small chunks between
405
+ // expressions (which potentially have been transformed), try to pass them
406
+ // through the CSS transformer; it's robust enough to understand malformed
407
+ // CSS that would result if we split e.g. this template:
408
+ //
409
+ // `${gridSize}px; color: red;`, giving `px; color: red;` as input; or
410
+ // `@media ${mobile} { color: red }`, giving `{ color: red }`.
411
+ quasiPaths = j(path).find(j.TemplateElement).filter(function (quasiPath) {
412
+ return quasiPath.parent === path;
413
+ }).paths();
414
+ _iterator2 = _createForOfIteratorHelper(quasiPaths);
415
+ _context.prev = 4;
416
+ _iterator2.s();
417
+ case 6:
418
+ if ((_step2 = _iterator2.n()).done) {
419
+ _context.next = 17;
420
+ break;
421
+ }
422
+ quasiPath = _step2.value;
423
+ _text = quasiPath.value.value.raw;
424
+ if (!(includesHardCodedColor(_text) && containsReplaceableCSSDeclarations(_text))) {
425
+ _context.next = 15;
426
+ break;
427
+ }
428
+ _context.next = 12;
429
+ return CSSTransformer(_text);
430
+ case 12:
431
+ newCSS = _context.sent;
432
+ j(quasiPath).replaceWith(buildTemplateElement(j, newCSS));
433
+ transformed = true;
434
+ case 15:
435
+ _context.next = 6;
436
+ break;
437
+ case 17:
438
+ _context.next = 22;
439
+ break;
440
+ case 19:
441
+ _context.prev = 19;
442
+ _context.t0 = _context["catch"](4);
443
+ _iterator2.e(_context.t0);
444
+ case 22:
445
+ _context.prev = 22;
446
+ _iterator2.f();
447
+ return _context.finish(22);
448
+ case 25:
449
+ case "end":
450
+ return _context.stop();
451
+ }
452
+ }, _loop, null, [[4, 19, 22, 25]]);
453
+ });
454
+ _iterator.s();
455
+ case 14:
456
+ if ((_step = _iterator.n()).done) {
457
+ _context2.next = 18;
458
+ break;
459
+ }
460
+ return _context2.delegateYield(_loop(), "t0", 16);
461
+ case 16:
462
+ _context2.next = 14;
463
+ break;
464
+ case 18:
465
+ _context2.next = 23;
466
+ break;
467
+ case 20:
468
+ _context2.prev = 20;
469
+ _context2.t1 = _context2["catch"](11);
470
+ _iterator.e(_context2.t1);
471
+ case 23:
472
+ _context2.prev = 23;
473
+ _iterator.f();
474
+ return _context2.finish(23);
475
+ case 26:
476
+ return _context2.abrupt("return", transformed ? source.toSource() : file.source);
477
+ case 27:
478
+ case "end":
479
+ return _context2.stop();
480
+ }
481
+ }, _callee, null, [[11, 20, 23, 26]]);
482
+ }));
483
+ return _transformer.apply(this, arguments);
238
484
  }
@@ -1,6 +1,6 @@
1
1
  import { isDecendantOfType } from '@codeshift/utils';
2
2
  export function isDecendantOfToken(j, path) {
3
- if (path.type === 'CallExpression' && path.callee.type === 'Identifier' && path.callee.name === 'token') {
3
+ if ('type' in path && path.type === 'CallExpression' && path.callee.type === 'Identifier' && path.callee.name === 'token') {
4
4
  return true;
5
5
  }
6
6
  return j(path).closest(j.CallExpression, {
@@ -6,9 +6,10 @@ export var isLegacyColor = function isLegacyColor(value) {
6
6
  export var isLegacyNamedColor = function isLegacyNamedColor(value) {
7
7
  return legacyColorMixins.includes(value);
8
8
  };
9
+ var colorRegexp = /#(?:[a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|rgba|hsl|hsla|lch|lab|color)\([^\)]*\)/;
9
10
  export var includesHardCodedColor = function includesHardCodedColor(raw) {
10
11
  var value = raw.toLowerCase();
11
- if (/#(?:[a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|hsl)a?\([^\)]*\)/.exec(value.toLowerCase())) {
12
+ if (colorRegexp.exec(value)) {
12
13
  return true;
13
14
  }
14
15
  for (var i = 0; i < namedColors.length; i++) {
@@ -18,17 +19,18 @@ export var includesHardCodedColor = function includesHardCodedColor(raw) {
18
19
  }
19
20
  return false;
20
21
  };
21
- export var isHardCodedColor = function isHardCodedColor(value) {
22
- if (namedColors.includes(value.toLowerCase())) {
23
- return true;
24
- }
25
- if (value.startsWith('rgb(') || value.startsWith('rgba(') || value.startsWith('hsl(') || value.startsWith('hsla(') || value.startsWith('lch(') || value.startsWith('lab(') || value.startsWith('color(')) {
22
+ export var isHardCodedColor = function isHardCodedColor(raw) {
23
+ var value = raw.toLowerCase();
24
+ if (namedColors.includes(value)) {
26
25
  return true;
27
26
  }
28
- if (value.startsWith('#') && (
29
- // short hex, hex, or hex with alpha
30
- value.length === 4 || value.length === 7 || value.length === 9)) {
27
+ var match = value.toLowerCase().match(colorRegexp);
28
+ if (match && match[0] === value) {
31
29
  return true;
32
30
  }
33
31
  return false;
34
- };
32
+ };
33
+ export function isBoldColor(color) {
34
+ var number = parseInt(color.replace(/^./, ''), 10);
35
+ return number > 300;
36
+ }
@@ -0,0 +1,31 @@
1
+ import { isColorRelatedProperty } from '../../css-to-design-tokens/lib/declaration';
2
+ export function containsReplaceableCSSDeclarations(input) {
3
+ var cssPattern = /(\S+)\s*:/g;
4
+ var match;
5
+ while ((match = cssPattern.exec(input)) !== null) {
6
+ if (isColorRelatedProperty(match[1])) {
7
+ return true;
8
+ }
9
+ }
10
+ return false;
11
+ }
12
+ export function findEndIndexOfCSSExpression(text, isAtEndOfInput) {
13
+ // CSS expression can end *on* a semicolon or *before* a brace. In either
14
+ // case we treat the remaining part of the value to cover one character
15
+ // before that symbol.
16
+ var semicolonIndex = text.indexOf(';');
17
+ var braceIndex = text.indexOf('}');
18
+ if (semicolonIndex === -1 && braceIndex === -1) {
19
+ if (isAtEndOfInput) {
20
+ return text.length;
21
+ } else {
22
+ return null;
23
+ }
24
+ } else if (semicolonIndex === -1) {
25
+ return braceIndex - 1;
26
+ } else if (braceIndex === -1) {
27
+ return semicolonIndex - 1;
28
+ } else {
29
+ return Math.min(semicolonIndex, braceIndex) - 1;
30
+ }
31
+ }
@@ -0,0 +1,17 @@
1
+ export var kebabize = function kebabize(str) {
2
+ return str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, function ($, ofs) {
3
+ return (ofs ? '-' : '') + $.toLowerCase();
4
+ });
5
+ };
6
+ export function findFirstNonspaceIndexAfter(text, index) {
7
+ var rest = text.slice(index + 1);
8
+ var indexInRest = rest.search(/\S/);
9
+ if (indexInRest === -1) {
10
+ return text.length;
11
+ } else {
12
+ return index + 1 + indexInRest;
13
+ }
14
+ }
15
+ export function splitAtIndex(text, index) {
16
+ return [text.slice(0, index), text.slice(index)];
17
+ }
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Flags, Default } from './types';
3
2
  declare const defaultFlags: {
4
3
  parser: "babel";
@@ -1,2 +1,2 @@
1
1
  import { FileInfo } from 'jscodeshift';
2
- export default function transformer(file: FileInfo): Promise<string>;
2
+ export default function transformer(file: FileInfo | string): Promise<string>;
@@ -0,0 +1,6 @@
1
+ export declare function isKnownCssVariable(value: string): boolean;
2
+ export declare function isRawColor(value: string): boolean;
3
+ export declare function isNamedColor(value: string): boolean;
4
+ export declare function isGradient(value: string): boolean;
5
+ export declare function extractBetweenParentheses(value: string): string;
6
+ export declare function isLessFunction(value: string): boolean;
@@ -0,0 +1,5 @@
1
+ export declare function isColorRelatedProperty(prop: string): boolean;
2
+ export declare function isCssDeclaration(prop: string): boolean;
3
+ export declare function extractCssVarName(prop: string): string;
4
+ export declare function extractLessVarName(prop: string): string;
5
+ export declare function splitCssValue(value: string): RegExpMatchArray | null;
@@ -1,3 +1,3 @@
1
1
  export declare const knownVariables: Record<string, string[]>;
2
- export declare const knownColors: Record<string, string[]>;
2
+ export declare const knownNamedColors: Record<string, string[]>;
3
3
  export declare const knownRawColors: Record<string, string[]>;
@@ -0,0 +1,4 @@
1
+ export declare const logger: {
2
+ warn(message: string): void;
3
+ error(message: string): void;
4
+ };
@@ -0,0 +1,6 @@
1
+ import { Declaration } from 'postcss';
2
+ export declare function cleanMeta(meta: string[]): string[];
3
+ export declare function getBaseDeclarationMeta(decl: Declaration): string[];
4
+ export declare function getCssVarMeta(cssVariable: string): string[];
5
+ export declare function getRawColorMeta(rawColor: string): string[];
6
+ export declare function getNamedColorMeta(namedColor: string): string[];
@@ -0,0 +1,7 @@
1
+ import designTokens from '@atlaskit/tokens/token-names';
2
+ type DesignTokensMap = typeof designTokens;
3
+ type DesignTokenJs = keyof DesignTokensMap;
4
+ type DesignTokenCss = DesignTokensMap[DesignTokenJs];
5
+ declare const MISSING_TOKEN_NAME = "MISSING_TOKEN";
6
+ export default function findToken(meta: string[]): DesignTokenCss | typeof MISSING_TOKEN_NAME;
7
+ export {};
@@ -0,0 +1,6 @@
1
+ interface Value {
2
+ getReplacement: (additionalMeta?: string[]) => string;
3
+ getMeta: () => string[];
4
+ }
5
+ export default function parseValue(value: string): Value | null;
6
+ export {};
@@ -1,2 +1,2 @@
1
1
  import { API, FileInfo } from 'jscodeshift';
2
- export default function transformer(file: FileInfo, api: API, debug?: boolean): string;
2
+ export default function transformer(file: FileInfo, api: API, debug?: boolean): Promise<string>;