@atlaskit/codemod-cli 0.17.10 → 0.19.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 (108) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/cjs/filepath.js +1 -1
  3. package/dist/cjs/main.js +1 -1
  4. package/dist/cjs/presets/index.js +2 -4
  5. package/dist/cjs/transforms.js +3 -3
  6. package/dist/es2019/filepath.js +2 -2
  7. package/dist/es2019/presets/index.js +2 -4
  8. package/dist/es2019/transforms.js +3 -3
  9. package/dist/esm/filepath.js +2 -2
  10. package/dist/esm/main.js +1 -1
  11. package/dist/esm/presets/index.js +2 -4
  12. package/dist/esm/transforms.js +3 -3
  13. package/dist/types/presets/index.d.ts +1 -3
  14. package/dist/types-ts4.5/presets/index.d.ts +1 -3
  15. package/package.json +3 -6
  16. package/dist/cjs/presets/css-to-design-tokens/css-to-design-tokens.js +0 -117
  17. package/dist/cjs/presets/css-to-design-tokens/lib/colors.js +0 -49
  18. package/dist/cjs/presets/css-to-design-tokens/lib/declaration.js +0 -29
  19. package/dist/cjs/presets/css-to-design-tokens/lib/legacy-colors.js +0 -338
  20. package/dist/cjs/presets/css-to-design-tokens/lib/logger.js +0 -18
  21. package/dist/cjs/presets/css-to-design-tokens/lib/meta.js +0 -157
  22. package/dist/cjs/presets/css-to-design-tokens/lib/tokens.js +0 -47
  23. package/dist/cjs/presets/css-to-design-tokens/lib/value.js +0 -80
  24. package/dist/cjs/presets/theme-to-design-tokens/theme-to-design-tokens.js +0 -489
  25. package/dist/cjs/presets/theme-to-design-tokens/types.js +0 -5
  26. package/dist/cjs/presets/theme-to-design-tokens/utils/ast-meta.js +0 -82
  27. package/dist/cjs/presets/theme-to-design-tokens/utils/ast.js +0 -35
  28. package/dist/cjs/presets/theme-to-design-tokens/utils/color.js +0 -44
  29. package/dist/cjs/presets/theme-to-design-tokens/utils/css-utils.js +0 -38
  30. package/dist/cjs/presets/theme-to-design-tokens/utils/fuzzy-search.js +0 -289
  31. package/dist/cjs/presets/theme-to-design-tokens/utils/legacy-colors.js +0 -96
  32. package/dist/cjs/presets/theme-to-design-tokens/utils/named-colors.js +0 -7
  33. package/dist/cjs/presets/theme-to-design-tokens/utils/string-utils.js +0 -25
  34. package/dist/cjs/presets/theme-to-design-tokens/utils/tokens.js +0 -28
  35. package/dist/es2019/presets/css-to-design-tokens/css-to-design-tokens.js +0 -89
  36. package/dist/es2019/presets/css-to-design-tokens/lib/colors.js +0 -34
  37. package/dist/es2019/presets/css-to-design-tokens/lib/declaration.js +0 -17
  38. package/dist/es2019/presets/css-to-design-tokens/lib/legacy-colors.js +0 -332
  39. package/dist/es2019/presets/css-to-design-tokens/lib/logger.js +0 -11
  40. package/dist/es2019/presets/css-to-design-tokens/lib/meta.js +0 -133
  41. package/dist/es2019/presets/css-to-design-tokens/lib/tokens.js +0 -24
  42. package/dist/es2019/presets/css-to-design-tokens/lib/value.js +0 -68
  43. package/dist/es2019/presets/theme-to-design-tokens/theme-to-design-tokens.js +0 -377
  44. package/dist/es2019/presets/theme-to-design-tokens/types.js +0 -1
  45. package/dist/es2019/presets/theme-to-design-tokens/utils/ast-meta.js +0 -60
  46. package/dist/es2019/presets/theme-to-design-tokens/utils/ast.js +0 -27
  47. package/dist/es2019/presets/theme-to-design-tokens/utils/color.js +0 -32
  48. package/dist/es2019/presets/theme-to-design-tokens/utils/css-utils.js +0 -31
  49. package/dist/es2019/presets/theme-to-design-tokens/utils/fuzzy-search.js +0 -279
  50. package/dist/es2019/presets/theme-to-design-tokens/utils/legacy-colors.js +0 -90
  51. package/dist/es2019/presets/theme-to-design-tokens/utils/named-colors.js +0 -1
  52. package/dist/es2019/presets/theme-to-design-tokens/utils/string-utils.js +0 -13
  53. package/dist/es2019/presets/theme-to-design-tokens/utils/tokens.js +0 -8
  54. package/dist/esm/presets/css-to-design-tokens/css-to-design-tokens.js +0 -109
  55. package/dist/esm/presets/css-to-design-tokens/lib/colors.js +0 -38
  56. package/dist/esm/presets/css-to-design-tokens/lib/declaration.js +0 -19
  57. package/dist/esm/presets/css-to-design-tokens/lib/legacy-colors.js +0 -332
  58. package/dist/esm/presets/css-to-design-tokens/lib/logger.js +0 -11
  59. package/dist/esm/presets/css-to-design-tokens/lib/meta.js +0 -146
  60. package/dist/esm/presets/css-to-design-tokens/lib/tokens.js +0 -40
  61. package/dist/esm/presets/css-to-design-tokens/lib/value.js +0 -73
  62. package/dist/esm/presets/theme-to-design-tokens/theme-to-design-tokens.js +0 -484
  63. package/dist/esm/presets/theme-to-design-tokens/types.js +0 -1
  64. package/dist/esm/presets/theme-to-design-tokens/utils/ast-meta.js +0 -74
  65. package/dist/esm/presets/theme-to-design-tokens/utils/ast.js +0 -27
  66. package/dist/esm/presets/theme-to-design-tokens/utils/color.js +0 -36
  67. package/dist/esm/presets/theme-to-design-tokens/utils/css-utils.js +0 -31
  68. package/dist/esm/presets/theme-to-design-tokens/utils/fuzzy-search.js +0 -283
  69. package/dist/esm/presets/theme-to-design-tokens/utils/legacy-colors.js +0 -90
  70. package/dist/esm/presets/theme-to-design-tokens/utils/named-colors.js +0 -1
  71. package/dist/esm/presets/theme-to-design-tokens/utils/string-utils.js +0 -17
  72. package/dist/esm/presets/theme-to-design-tokens/utils/tokens.js +0 -21
  73. package/dist/types/presets/css-to-design-tokens/css-to-design-tokens.d.ts +0 -2
  74. package/dist/types/presets/css-to-design-tokens/lib/colors.d.ts +0 -6
  75. package/dist/types/presets/css-to-design-tokens/lib/declaration.d.ts +0 -5
  76. package/dist/types/presets/css-to-design-tokens/lib/legacy-colors.d.ts +0 -3
  77. package/dist/types/presets/css-to-design-tokens/lib/logger.d.ts +0 -4
  78. package/dist/types/presets/css-to-design-tokens/lib/meta.d.ts +0 -6
  79. package/dist/types/presets/css-to-design-tokens/lib/tokens.d.ts +0 -7
  80. package/dist/types/presets/css-to-design-tokens/lib/value.d.ts +0 -6
  81. package/dist/types/presets/theme-to-design-tokens/theme-to-design-tokens.d.ts +0 -2
  82. package/dist/types/presets/theme-to-design-tokens/utils/ast-meta.d.ts +0 -3
  83. package/dist/types/presets/theme-to-design-tokens/utils/ast.d.ts +0 -4
  84. package/dist/types/presets/theme-to-design-tokens/utils/color.d.ts +0 -5
  85. package/dist/types/presets/theme-to-design-tokens/utils/css-utils.d.ts +0 -2
  86. package/dist/types/presets/theme-to-design-tokens/utils/fuzzy-search.d.ts +0 -5
  87. package/dist/types/presets/theme-to-design-tokens/utils/legacy-colors.d.ts +0 -3
  88. package/dist/types/presets/theme-to-design-tokens/utils/named-colors.d.ts +0 -1
  89. package/dist/types/presets/theme-to-design-tokens/utils/string-utils.d.ts +0 -3
  90. package/dist/types/presets/theme-to-design-tokens/utils/tokens.d.ts +0 -2
  91. package/dist/types-ts4.5/presets/css-to-design-tokens/css-to-design-tokens.d.ts +0 -2
  92. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/colors.d.ts +0 -6
  93. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/declaration.d.ts +0 -5
  94. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/legacy-colors.d.ts +0 -3
  95. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/logger.d.ts +0 -4
  96. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/meta.d.ts +0 -6
  97. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/tokens.d.ts +0 -7
  98. package/dist/types-ts4.5/presets/css-to-design-tokens/lib/value.d.ts +0 -6
  99. package/dist/types-ts4.5/presets/theme-to-design-tokens/theme-to-design-tokens.d.ts +0 -2
  100. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/ast-meta.d.ts +0 -3
  101. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/ast.d.ts +0 -4
  102. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/color.d.ts +0 -5
  103. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/css-utils.d.ts +0 -2
  104. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/fuzzy-search.d.ts +0 -5
  105. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/legacy-colors.d.ts +0 -3
  106. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/named-colors.d.ts +0 -1
  107. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/string-utils.d.ts +0 -6
  108. package/dist/types-ts4.5/presets/theme-to-design-tokens/utils/tokens.d.ts +0 -2
@@ -1,377 +0,0 @@
1
- /* eslint-disable no-console */
2
-
3
- import { isDecendantOfType, hasImportDeclaration } from '@codeshift/utils';
4
- import { isDecendantOfToken, isParentOfToken } from './utils/ast';
5
- import { cleanMeta, getMetaFromAncestors } from './utils/ast-meta';
6
- import { includesHardCodedColor, isHardCodedColor, isLegacyColor, isLegacyNamedColor, isBoldColor } from './utils/color';
7
- import Search from './utils/fuzzy-search';
8
- import { legacyColorMetaMap } from './utils/legacy-colors';
9
- import { tokens } from './utils/tokens';
10
- import { kebabize, findFirstNonspaceIndexAfter, splitAtIndex } from './utils/string-utils';
11
- import { containsReplaceableCSSDeclarations, findEndIndexOfCSSExpression } from './utils/css-utils';
12
- import CSSTransformer from '../css-to-design-tokens/css-to-design-tokens';
13
- function insertTokenImport(j, source) {
14
- if (hasImportDeclaration(j, source, '@atlaskit/tokens')) {
15
- return;
16
- }
17
- const newImport = j.importDeclaration([j.importSpecifier(j.identifier('token'))], j.stringLiteral('@atlaskit/tokens'));
18
- source.get().node.program.body.unshift(newImport);
19
- }
20
- function buildToken(j, tokenId, node) {
21
- const callExpr = j.callExpression(j.identifier('token'), [j.stringLiteral(tokenId), node].filter(Boolean));
22
- return callExpr;
23
- }
24
-
25
- // Wrap over the j.templateElement builder to provide a more convenient API.
26
- function buildTemplateElement(j, text, options = {
27
- tail: false,
28
- fromNode: null
29
- }) {
30
- let tail;
31
- if (options.fromNode) {
32
- tail = options.fromNode.tail;
33
- } else {
34
- tail = !!options.tail;
35
- }
36
- return j.templateElement({
37
- raw: text,
38
- cooked: null
39
- }, tail);
40
- }
41
- function getColorFromIdentifier(expression) {
42
- let value = '';
43
- if (expression.type === 'Identifier') {
44
- value = expression.name;
45
- }
46
- if (expression.type === 'StringLiteral') {
47
- value = expression.value;
48
- }
49
- if (expression.type === 'MemberExpression' && expression.object.name === 'colors' && isLegacyColor(expression.property.name)) {
50
- value = expression.property.name;
51
- }
52
- return value;
53
- }
54
- function getTokenFromNode(j, path, value, propertyName) {
55
- const valueMeta = cleanMeta(legacyColorMetaMap[value] || []);
56
- const ancestorMeta = cleanMeta([...getMetaFromAncestors(j, path), ...kebabize(propertyName).split('-')] || []);
57
- let property = cleanMeta([kebabize(propertyName)])[0];
58
-
59
- // Attempt to find a property from ancestors if one is not found
60
- if (!property || !['border', 'icon', 'background', 'text'].includes(property)) {
61
- if (ancestorMeta.includes('border')) {
62
- property = 'border';
63
- }
64
- if (ancestorMeta.includes('icon')) {
65
- property = 'icon';
66
- }
67
- if (ancestorMeta.includes('background')) {
68
- property = 'background';
69
- }
70
- if (ancestorMeta.includes('color')) {
71
- property = 'text';
72
- }
73
- }
74
- let meta = [];
75
- let possibleTokens = tokens;
76
- if (property === 'text') {
77
- possibleTokens = tokens.filter(token => token.includes('.text'));
78
- if (valueMeta.includes('neutral')) {
79
- meta.push('color', 'text');
80
- }
81
- if (valueMeta.includes('neutral') && (value === 'N400' || value === 'N500')) {
82
- meta.push('color', 'text', 'subtle');
83
- }
84
- if (valueMeta.includes('neutral') && (value === 'N80' || value === 'N100' || value === 'N200' || value === 'N300' || value === 'N400')) {
85
- meta.push('color', 'text', 'subtlest');
86
- }
87
-
88
- // handle non-neutrals
89
- if (!valueMeta.includes('neutral')) {
90
- meta.push('color', ...ancestorMeta, ...valueMeta);
91
- }
92
- }
93
- if (property === 'background' || property === 'background-color') {
94
- if (ancestorMeta.includes('disabled')) {
95
- // disabled backgrounds
96
- meta.push(property, ...ancestorMeta);
97
- } else if (
98
- // Surfaces
99
- valueMeta.includes('neutral') && value !== 'N100' && value !== 'N200' && value !== 'N300' && value !== 'N400' && value !== 'N500' && value !== 'N600' && value !== 'N700' && value !== 'N800') {
100
- meta.push('surface', ...ancestorMeta);
101
- } else if (value.includes('N0')) {
102
- // default surface
103
- meta.push('elevation', 'surface');
104
- } else if (valueMeta.includes('neutral') && isBoldColor(value)) {
105
- // bold netural backgrounds
106
- meta.push('background', 'neutral', 'bold');
107
- } else if (valueMeta.includes('neutral')) {
108
- // netural backgrounds
109
- meta.push('background', 'neutral');
110
- }
111
- }
112
- if (property === 'border' || property === 'border-color' || property === 'border-left' || property === 'border-right' || property === 'border-top' || property === 'border-bottom' || property === 'outline' || property === 'outline-color') {
113
- possibleTokens = tokens.filter(token => token.includes('.border') || token.includes('.focus'));
114
- if (valueMeta.includes('neutral')) {
115
- // standard netural boarder
116
- meta.push('color', 'border', ...ancestorMeta);
117
- } else {
118
- meta.push('border', ...valueMeta, ...ancestorMeta);
119
- }
120
- }
121
- if (ancestorMeta.includes('icon')) {
122
- possibleTokens = tokens.filter(token => token.includes('.icon'));
123
- if (ancestorMeta.includes('disabled')) {
124
- // disabled backgrounds
125
- meta.push('disabled');
126
- }
127
- meta.push('color', 'icon', ...valueMeta);
128
- }
129
-
130
- // Fallback if guided behavior yields nothing
131
- if (meta.length === 0) {
132
- meta.push(property, ...valueMeta, ...ancestorMeta);
133
- }
134
- const search = Search(possibleTokens, false);
135
- const results = search.get(meta.join(' '));
136
- let tokenId = ['MISSING_TOKEN'];
137
- if (results) {
138
- tokenId = results.map(result => result[1]);
139
- }
140
- return tokenId[0];
141
- }
142
- function parseCSSPropertyName(cssString) {
143
- const lastColonIndex = cssString.lastIndexOf(':');
144
- if (lastColonIndex === -1) {
145
- return {
146
- colonIndex: null,
147
- cssPropertyName: null
148
- };
149
- }
150
- const propertyNameEndIndex = Math.max(cssString.lastIndexOf(';', lastColonIndex), cssString.lastIndexOf(' ', lastColonIndex), -1);
151
- const startIndex = propertyNameEndIndex + 1;
152
- return {
153
- cssPropertyName: cssString.slice(startIndex, lastColonIndex).trim(),
154
- colonIndex: lastColonIndex
155
- };
156
- }
157
- export default async function transformer(file, api, debug = false) {
158
- const j = api.jscodeshift;
159
- const source = j(file.source);
160
- let transformed = false;
161
-
162
- // Objects
163
- source.find(j.ObjectProperty).forEach(path => {
164
- if (path.value.value.type === 'ObjectExpression') {
165
- return;
166
- }
167
-
168
- // Avoid transforming objects that are default arguments
169
- if (path.parent.parent.value.type === 'ArrowFunctionExpression' || path.parent.parent.value.type === 'FunctionDeclaration') {
170
- return;
171
- }
172
- if (isParentOfToken(j, path.value.value)) {
173
- return;
174
- }
175
- const value = getColorFromIdentifier(path.value.value);
176
- if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
177
- return;
178
- }
179
- let key;
180
- if (path.value.key.type === 'NumericLiteral' || path.value.key.type === 'StringLiteral') {
181
- key = path.value.key.value.toString();
182
- }
183
- if (path.value.key.type === 'Identifier') {
184
- key = path.value.key.name;
185
- }
186
-
187
- // Key is a node type we do not support
188
- if (!key) {
189
- return;
190
- }
191
- const tokenId = getTokenFromNode(j, path, value, key);
192
- insertTokenImport(j, source);
193
- j(path).replaceWith(j.objectProperty(path.value.key, buildToken(j, tokenId, path.value.value)));
194
- transformed = true;
195
- });
196
-
197
- // JSX props
198
- source.find(j.JSXAttribute).forEach(path => {
199
- var _path$value, _path$value$value;
200
- 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') {
201
- return;
202
- }
203
- if (isParentOfToken(j, path)) {
204
- return;
205
- }
206
- const expression = path.value.value.expression;
207
- const value = getColorFromIdentifier(expression);
208
- if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
209
- return;
210
- }
211
- const tokenId = getTokenFromNode(j, path, value, path.value.name.name);
212
- insertTokenImport(j, source);
213
- j(path).find(j.JSXExpressionContainer).forEach(path => {
214
- const tokenNode = buildToken(j, tokenId, path.value.expression);
215
- j(path).replaceWith(j.jsxExpressionContainer(tokenNode));
216
- });
217
- transformed = true;
218
- });
219
-
220
- // Strings
221
- source.find(j.StringLiteral).forEach(path => {
222
- j(path).filter(expression => !isDecendantOfType(j, expression, j.ObjectExpression)).forEach(path => {
223
- const value = path.value.value;
224
- if (replaceStringLiteralIfItConsistsOnlyOfColor(j, path, value)) {
225
- transformed = true;
226
- }
227
- });
228
- });
229
- const templateLiteralPaths = source.find(j.TemplateLiteral).paths();
230
- for (const path of templateLiteralPaths) {
231
- // Background: a 'type: TemplateLiteral' Node has quasis and expressions
232
- // (see ast-types/src/gen/namedTypes.ts), and invariant holds that
233
- // quasis.length === expression.length + 1.
234
- //
235
- // eg `${foo}bar` has quasis [Node(''), Node('bar')] and expressions
236
- // [Node('foo')]. Each quasi has type: 'TemplateElement'; expressions are
237
- // probably safe to treat as subtypes of Expression, though ast-types
238
- // codebase has a more involved definition.
239
- if (path.value.expressions.length === 0) {
240
- // A single-quasi (equivalently, no-expression) template literal is
241
- // basically just a string literal, possibly multi-line. We handle the
242
- // simple `#ababab` case here, and the multi-line case after.
243
- const text = path.value.quasis[0].value.raw;
244
- if (replaceStringLiteralIfItConsistsOnlyOfColor(j, path, text)) {
245
- transformed = true;
246
- }
247
- } else {
248
- j(path).find(j.Expression).filter(expressionPath => {
249
- // jscodeshift walks over the whole tree; we are interested only in
250
- // the direct children: i.e. top-level expressions appearing in ${}.
251
- return expressionPath.parent === path;
252
- }).forEach((expressionPath, expressionIndex) => {
253
- if (replaceTemplateLiteralExpression(j, path, expressionPath, expressionIndex)) {
254
- transformed = true;
255
- }
256
- });
257
- }
258
-
259
- // No matter if we have one big quasi or many small chunks between
260
- // expressions (which potentially have been transformed), try to pass them
261
- // through the CSS transformer; it's robust enough to understand malformed
262
- // CSS that would result if we split e.g. this template:
263
- //
264
- // `${gridSize}px; color: red;`, giving `px; color: red;` as input; or
265
- // `@media ${mobile} { color: red }`, giving `{ color: red }`.
266
- const quasiPaths = j(path).find(j.TemplateElement).filter(quasiPath => {
267
- return quasiPath.parent === path;
268
- }).paths();
269
- for (const quasiPath of quasiPaths) {
270
- const text = quasiPath.value.value.raw;
271
- if (includesHardCodedColor(text) && containsReplaceableCSSDeclarations(text)) {
272
- const newCSS = await CSSTransformer(text);
273
- j(quasiPath).replaceWith(buildTemplateElement(j, newCSS));
274
- transformed = true;
275
- }
276
- }
277
- }
278
- function replaceStringLiteralIfItConsistsOnlyOfColor(j, path, value) {
279
- if (isDecendantOfToken(j, path)) {
280
- return false;
281
- }
282
- if (isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
283
- const parent = path.parent.value;
284
- let key = '';
285
- if (parent.type === 'VariableDeclarator') {
286
- key = parent.id.name;
287
- }
288
- const 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
- function replaceTemplateLiteralExpression(j, mainPath, expressionPath, expressionIndex) {
296
- const expression = expressionPath.value;
297
- if (!(expression.type === 'MemberExpression' || expression.type === 'Identifier')) {
298
- return false;
299
- }
300
- if (isDecendantOfToken(j, expressionPath)) {
301
- return false;
302
- }
303
- const value = getColorFromIdentifier(expression);
304
- if (!value || !includesHardCodedColor(value) && !isHardCodedColor(value) && !isLegacyColor(value) && !isLegacyNamedColor(value)) {
305
- return false;
306
- }
307
- const precedingQuasi = mainPath.value.quasis[expressionIndex];
308
- const precedingQuasiText = precedingQuasi.value.raw;
309
- const {
310
- cssPropertyName,
311
- colonIndex
312
- } = parseCSSPropertyName(precedingQuasiText);
313
- if (!cssPropertyName) {
314
- return false;
315
- }
316
- const tokenId = getTokenFromNode(j, expressionPath, value, cssPropertyName);
317
- insertTokenImport(j, source);
318
- const newQuasis = [...mainPath.value.quasis];
319
- const newExpressions = [...mainPath.value.expressions];
320
- if (cssPropertyName !== 'box-shadow') {
321
- const tokenExpression = buildToken(j, tokenId, expressionPath.value);
322
- newExpressions[expressionIndex] = tokenExpression;
323
- } else {
324
- // box-shadow is a multi-part property where the color can appear at any
325
- // part position (even though the standard suggests that color comes
326
- // last, browsers' CSS parsers are more lax). If we get here, then the
327
- // color part is replaceable. Textually, it's something like:
328
- //
329
- // <rules before>; box-shadow: 0 1px ${colors.N50} 2rem; <rules after>
330
- //
331
- // the fallback value will be multipart, i.e. the token call is
332
- //
333
- // token(<replacedValue>, `0 1px ${colors.N50} 2rem`)
334
- //
335
- // and it's wrapped in a substitution like this:
336
- //
337
- // <rules before>; box-shadow: ${token(<...>)}; <rules after>
338
- //
339
- // We stich the fallback from the last part of preceding quasi (after
340
- // colon) and the first part of the following quasi (before ';' or '}').
341
- //
342
- // If multiple box-shadows are comma-separated but only one of them has a
343
- // replaceable color and others are hard-coded, this logic would still
344
- // work. When multiple shadows have expressions, it's unfortunately not
345
- // possible to proceed because we cannot find where the value ends from a
346
- // single following quasi.
347
- const valueStartIndex = findFirstNonspaceIndexAfter(precedingQuasiText, colonIndex);
348
- const [newPrecedingQuasiText, partialValueBeginning] = splitAtIndex(precedingQuasiText, valueStartIndex);
349
- const followingQuasi = mainPath.value.quasis[expressionIndex + 1];
350
- const followingQuasiText = followingQuasi.value.raw;
351
- const valueEndIndex = findEndIndexOfCSSExpression(followingQuasiText, followingQuasi.tail);
352
- if (!valueEndIndex) {
353
- console.warn('cannot find end of box-shadow value, please check manually');
354
- return false;
355
- }
356
- const [partialValueEnd, newFollowingQuasiText] = splitAtIndex(followingQuasiText, valueEndIndex + 1);
357
- const internalQuasis = [buildTemplateElement(j, partialValueBeginning, {
358
- tail: false
359
- }), buildTemplateElement(j, partialValueEnd, {
360
- tail: true
361
- })];
362
- const internalExpressions = [expressionPath.value];
363
- const newFallback = j.templateLiteral(internalQuasis, internalExpressions);
364
- const newExpression = buildToken(j, tokenId, newFallback);
365
- newQuasis[expressionIndex] = buildTemplateElement(j, newPrecedingQuasiText, {
366
- fromNode: newQuasis[expressionIndex]
367
- });
368
- newExpressions[expressionIndex] = newExpression;
369
- newQuasis[expressionIndex + 1] = buildTemplateElement(j, newFollowingQuasiText, {
370
- fromNode: newQuasis[expressionIndex]
371
- });
372
- }
373
- mainPath.replace(j.templateLiteral(newQuasis, newExpressions));
374
- return true;
375
- }
376
- return transformed ? source.toSource() : file.source;
377
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,60 +0,0 @@
1
- import { getClosestDecendantOfType } from './ast';
2
- import { getUniqueWordsFromTokens } from './tokens';
3
- export function getMetaFromAncestors(j, path, meta = []) {
4
- const parent = path.parentPath;
5
- const grandParent = parent && parent.parentPath;
6
- if (parent && parent.value.type === 'ObjectProperty') {
7
- let value = '';
8
- if (parent.value.key.type === 'Literal' || parent.value.key.type === 'StringLiteral' || parent.value.key.type === 'NumericLiteral') {
9
- value = parent.value.key.value.toString();
10
- } else {
11
- value = parent.value.key.name;
12
- }
13
- meta.push(value);
14
- }
15
- if (parent && grandParent && grandParent.value.type === 'TemplateLiteral') {
16
- const expressionIndex = grandParent.value.expressions.findIndex(exp => exp.name === path.value.name);
17
- const quasi = grandParent.value.quasis[expressionIndex];
18
- const propertyName = (quasi.value.cooked || quasi.value.raw || '').replace(/\n/g, '').split(/;|{|}/).filter(el => !el.match(/\.|\@|\(|\)/)).pop().split(/:/g)[0].trim();
19
- grandParent.value.quasis.slice(0, expressionIndex + 1).map(q => q.value.cooked)
20
- // We reverse so the most nested one is first which we're more likely than not interested in
21
- .reverse().some(str => {
22
- const result = /(hover|active|disabled|focus)/.exec(str.toLowerCase());
23
- if (result) {
24
- meta.push(result[0]);
25
- return true;
26
- }
27
- });
28
- meta.push(propertyName);
29
- }
30
- if (parent && parent.value.type === 'JSXAttribute') {
31
- if (!['css', 'styles', 'style', 'fill', 'stopColor', 'startColor'].includes(parent.value.name.name)) {
32
- meta.push(parent.value.name.name);
33
- }
34
- }
35
- const closestJSXElement = getClosestDecendantOfType(j, path, j.JSXOpeningElement);
36
- if (closestJSXElement) {
37
- const jsxElementName = closestJSXElement.value.name.name;
38
- const nameComponents = jsxElementName.replace(/([a-z])([A-Z])/g, '$1 $2').split(' ');
39
- meta.push(...nameComponents);
40
- }
41
- if (parent && parent.value.type === 'VariableDeclarator') {
42
- meta.push(parent.value.id.name);
43
- }
44
- if (parent) {
45
- return getMetaFromAncestors(j, parent, meta);
46
- }
47
- return meta;
48
- }
49
- export function cleanMeta(meta) {
50
- return meta.reduce((accum, val) => [...accum, ...(typeof val === 'string' ? val.split(/(?=[A-Z])/g).map(e => e.toLowerCase()) : [])], []).reduce((accum, val) => {
51
- const cleanVal = val.replace(/:/g, '').replace(/,/g, '').replace('grey', 'neutral').replace('skeleton', 'neutral').replace('texts', 'text').replace('red', 'danger').replace('error', 'danger').replace('invalid', 'danger').replace('removed', 'danger').replace('removal', 'danger').replace('remove', 'danger').replace('focus', 'focused').replace('valid', 'success').replace('successful', 'success').replace('risk', 'warning').replace('caution', 'warning').replace('primary', 'bold').replace('secondary', 'subtle').replace('hyperlink', 'link').replace('anchor', 'link').replace('active', 'pressed').replace('hover', 'hovered').replace('card', 'raised').replace('dragged', 'surface overlay').replace('dragging', 'surface overlay').replace('drag', 'surface overlay').replace('background-color', 'background').replace('color', 'text').replace('icons', 'icon').replace('glyph', 'icon').replace('stroke', 'border').replace('border-left', 'border').replace('border-right', 'border').replace('border-top', 'border').replace('border-bottom', 'border').replace('box-shadow', 'shadow');
52
- accum.push(...cleanVal.split(' '));
53
- return accum;
54
- }, []).filter(val => getUniqueWordsFromTokens.includes(val)).reduce((accum, val) => {
55
- if (!accum.includes(val)) {
56
- accum.push(val);
57
- }
58
- return accum;
59
- }, []);
60
- }
@@ -1,27 +0,0 @@
1
- import { isDecendantOfType } from '@codeshift/utils';
2
- export function isDecendantOfToken(j, path) {
3
- if ('type' in path && path.type === 'CallExpression' && path.callee.type === 'Identifier' && path.callee.name === 'token') {
4
- return true;
5
- }
6
- return j(path).closest(j.CallExpression, {
7
- callee: {
8
- name: 'token'
9
- }
10
- }).length > 0;
11
- }
12
- export function isParentOfToken(j, path) {
13
- if (path.type === 'CallExpression' && path.callee.type === 'Identifier' && path.callee.name === 'token') {
14
- return true;
15
- }
16
- return j(path).find(j.CallExpression, {
17
- callee: {
18
- name: 'token'
19
- }
20
- }).length > 0;
21
- }
22
- export function getClosestDecendantOfType(j, path, type) {
23
- if (!isDecendantOfType(j, path, type)) {
24
- return;
25
- }
26
- return j(path).closest(type).get();
27
- }
@@ -1,32 +0,0 @@
1
- import { legacyColorMixins, legacyColors } from './legacy-colors';
2
- import { namedColors } from './named-colors';
3
- export const isLegacyColor = value => legacyColors.includes(value);
4
- export const isLegacyNamedColor = value => legacyColorMixins.includes(value);
5
- const colorRegexp = /#(?:[a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|rgba|hsl|hsla|lch|lab|color)\([^\)]*\)/;
6
- export const includesHardCodedColor = raw => {
7
- const value = raw.toLowerCase();
8
- if (colorRegexp.exec(value)) {
9
- return true;
10
- }
11
- for (let i = 0; i < namedColors.length; i++) {
12
- if (value.includes(`${namedColors[i]};`)) {
13
- return true;
14
- }
15
- }
16
- return false;
17
- };
18
- export const isHardCodedColor = raw => {
19
- const value = raw.toLowerCase();
20
- if (namedColors.includes(value)) {
21
- return true;
22
- }
23
- const match = value.toLowerCase().match(colorRegexp);
24
- if (match && match[0] === value) {
25
- return true;
26
- }
27
- return false;
28
- };
29
- export function isBoldColor(color) {
30
- const number = parseInt(color.replace(/^./, ''), 10);
31
- return number > 300;
32
- }
@@ -1,31 +0,0 @@
1
- import { isColorRelatedProperty } from '../../css-to-design-tokens/lib/declaration';
2
- export function containsReplaceableCSSDeclarations(input) {
3
- const cssPattern = /(\S+)\s*:/g;
4
- let 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
- const semicolonIndex = text.indexOf(';');
17
- const 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
- }