@oceanbase/codemod 1.0.0-alpha.1 → 1.0.0-alpha.10

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 (63) hide show
  1. package/README.md +158 -0
  2. package/bin/cli.js +196 -30
  3. package/package.json +7 -6
  4. package/transforms/__testfixtures__/less-to-cssvar/basic.input.less +16 -0
  5. package/transforms/__testfixtures__/less-to-cssvar/basic.output.less +14 -0
  6. package/transforms/__testfixtures__/less-to-cssvar/color-scales.input.less +23 -0
  7. package/transforms/__testfixtures__/less-to-cssvar/color-scales.output.less +21 -0
  8. package/transforms/__testfixtures__/less-to-cssvar/complex-values.input.less +22 -0
  9. package/transforms/__testfixtures__/less-to-cssvar/complex-values.output.less +20 -0
  10. package/transforms/__testfixtures__/less-to-cssvar/control-tokens.input.less +29 -0
  11. package/transforms/__testfixtures__/less-to-cssvar/control-tokens.output.less +27 -0
  12. package/transforms/__testfixtures__/less-to-cssvar/css-modules-global.input.less +21 -0
  13. package/transforms/__testfixtures__/less-to-cssvar/css-modules-global.output.less +19 -0
  14. package/transforms/__testfixtures__/less-to-cssvar/custom-prefix.input.less +9 -0
  15. package/transforms/__testfixtures__/less-to-cssvar/custom-prefix.output.less +7 -0
  16. package/transforms/__testfixtures__/less-to-cssvar/fill-tokens.input.less +36 -0
  17. package/transforms/__testfixtures__/less-to-cssvar/fill-tokens.output.less +34 -0
  18. package/transforms/__testfixtures__/less-to-cssvar/mixed-values.input.less +21 -0
  19. package/transforms/__testfixtures__/less-to-cssvar/mixed-values.output.less +19 -0
  20. package/transforms/__testfixtures__/less-to-cssvar/multiple-imports.input.less +9 -0
  21. package/transforms/__testfixtures__/less-to-cssvar/multiple-imports.output.less +8 -0
  22. package/transforms/__testfixtures__/less-to-cssvar/nested-selectors.input.less +24 -0
  23. package/transforms/__testfixtures__/less-to-cssvar/nested-selectors.output.less +22 -0
  24. package/transforms/__testfixtures__/less-to-cssvar/no-transform.input.less +8 -0
  25. package/transforms/__testfixtures__/less-to-cssvar/no-transform.output.less +8 -0
  26. package/transforms/__testfixtures__/less-to-cssvar/obui-import.input.less +7 -0
  27. package/transforms/__testfixtures__/less-to-cssvar/obui-import.output.less +5 -0
  28. package/transforms/__testfixtures__/less-to-cssvar/status-colors.input.less +25 -0
  29. package/transforms/__testfixtures__/less-to-cssvar/status-colors.output.less +23 -0
  30. package/transforms/__testfixtures__/less-to-token/antd-v4-less-to-token.input.less +2 -0
  31. package/transforms/__testfixtures__/less-to-token/antd-v4-less-to-token.output.less +2 -0
  32. package/transforms/__testfixtures__/less-to-token/case-insensitive.input.less +4 -0
  33. package/transforms/__testfixtures__/less-to-token/case-insensitive.output.less +4 -0
  34. package/transforms/__testfixtures__/less-to-token/exist-import-url.input.less +10 -0
  35. package/transforms/__testfixtures__/less-to-token/exist-import-url.output.less +10 -0
  36. package/transforms/__testfixtures__/less-to-token/exist-import.input.less +10 -0
  37. package/transforms/__testfixtures__/less-to-token/exist-import.output.less +10 -0
  38. package/transforms/__testfixtures__/sass-to-cssvar/basic.input.scss +18 -0
  39. package/transforms/__testfixtures__/sass-to-cssvar/basic.output.scss +18 -0
  40. package/transforms/__testfixtures__/sass-to-cssvar/custom-prefix.input.scss +5 -0
  41. package/transforms/__testfixtures__/sass-to-cssvar/custom-prefix.output.scss +5 -0
  42. package/transforms/__testfixtures__/sass-to-cssvar/no-transform.input.scss +6 -0
  43. package/transforms/__testfixtures__/sass-to-cssvar/no-transform.output.scss +6 -0
  44. package/transforms/__testfixtures__/style-to-token/antd-style.input.js +1 -0
  45. package/transforms/__testfixtures__/style-to-token/antd-style.output.js +1 -0
  46. package/transforms/__testfixtures__/style-to-token/function-component.input.js +2 -2
  47. package/transforms/__testfixtures__/style-to-token/function-component.output.js +2 -2
  48. package/transforms/__testfixtures__/style-to-token/nested-object.input.js +12 -0
  49. package/transforms/__testfixtures__/style-to-token/nested-object.output.js +13 -0
  50. package/transforms/__testfixtures__/style-to-token/single-function.output.js +1 -2
  51. package/transforms/__testfixtures__/style-to-token/template-string.input.js +23 -0
  52. package/transforms/__testfixtures__/style-to-token/template-string.output.js +25 -0
  53. package/transforms/__tests__/less-to-cssvar.test.ts +180 -0
  54. package/transforms/__tests__/less-to-token.test.ts +2 -0
  55. package/transforms/__tests__/sass-to-cssvar.test.ts +67 -0
  56. package/transforms/__tests__/style-to-token.test.ts +2 -0
  57. package/transforms/less-to-cssvar.js +505 -0
  58. package/transforms/less-to-token.js +47 -7
  59. package/transforms/obui-to-oceanbase-design-and-ui.js +0 -4
  60. package/transforms/sass-to-cssvar.js +194 -0
  61. package/transforms/style-to-token.js +183 -12
  62. package/transforms/utils/path-utils.js +40 -0
  63. package/transforms/utils/token.js +24 -2
@@ -0,0 +1,194 @@
1
+ const path = require('path');
2
+ const fs = require('fs');
3
+ const postcss = require('postcss');
4
+ const postcssScss = require('postcss-scss');
5
+ const isDirectory = require('is-directory');
6
+ const { shouldExcludePath } = require('./utils/path-utils');
7
+
8
+ /**
9
+ * Get SASS/SCSS tokens from @oceanbase/design theme Less file
10
+ * Since we're converting SASS variables to CSS variables based on the same design tokens,
11
+ * we can reuse the Less token list
12
+ */
13
+ function getSassTokensFromTheme() {
14
+ try {
15
+ // Try to find the Less theme file from @oceanbase/design
16
+ const themeLessPath = require.resolve('@oceanbase/design/es/theme/style/default.less');
17
+ const content = fs.readFileSync(themeLessPath, 'utf-8');
18
+
19
+ // Extract all @variableName: definitions
20
+ const tokenRegex = /@([a-zA-Z][a-zA-Z0-9]*):/g;
21
+ const tokens = new Set();
22
+ let match;
23
+ while ((match = tokenRegex.exec(content)) !== null) {
24
+ tokens.add(match[1]);
25
+ }
26
+ return Array.from(tokens);
27
+ } catch (e) {
28
+ // Fallback: try lib path
29
+ try {
30
+ const themeLessPath = require.resolve('@oceanbase/design/lib/theme/style/default.less');
31
+ const content = fs.readFileSync(themeLessPath, 'utf-8');
32
+
33
+ const tokenRegex = /@([a-zA-Z][a-zA-Z0-9]*):/g;
34
+ const tokens = new Set();
35
+ let match;
36
+ while ((match = tokenRegex.exec(content)) !== null) {
37
+ tokens.add(match[1]);
38
+ }
39
+ return Array.from(tokens);
40
+ } catch (e2) {
41
+ // Final fallback: use theme token object
42
+ try {
43
+ const { default: defaultTheme } = require('@oceanbase/design/lib/theme/default');
44
+ return Object.keys(defaultTheme.token || {});
45
+ } catch (e3) {
46
+ console.warn('Warning: Could not load tokens from @oceanbase/design, using empty list');
47
+ return [];
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ // Get SASS variable tokens dynamically from @oceanbase/design theme
54
+ const SASS_TOKENS = getSassTokensFromTheme();
55
+
56
+ /**
57
+ * Convert camelCase to kebab-case
58
+ * @param {string} str - camelCase string
59
+ * @returns {string} - kebab-case string
60
+ */
61
+ function camelToKebab(str) {
62
+ return str.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();
63
+ }
64
+
65
+ /**
66
+ * Find all sass/scss files in the directory
67
+ * @param {string} dir - Directory or file path
68
+ * @returns {string[]} - Array of file paths
69
+ */
70
+ const findAllSassFiles = dir => {
71
+ const sassFiles = [];
72
+ const isDir = isDirectory.sync(dir);
73
+ if (isDir) {
74
+ const files = fs.readdirSync(dir);
75
+ files.forEach(file => {
76
+ const filePath = path.join(dir, file);
77
+ if (isDirectory.sync(filePath)) {
78
+ if (shouldExcludePath(filePath)) {
79
+ return;
80
+ }
81
+ sassFiles.push(...findAllSassFiles(filePath));
82
+ } else if (file.endsWith('.sass') || file.endsWith('.scss')) {
83
+ sassFiles.push(filePath);
84
+ }
85
+ });
86
+ } else if (dir.endsWith('.sass') || dir.endsWith('.scss')) {
87
+ sassFiles.push(dir);
88
+ }
89
+ return sassFiles;
90
+ };
91
+
92
+ /**
93
+ * Transform SASS variable to CSS variable
94
+ * @param {string} value - CSS value that may contain SASS variables
95
+ * @param {string} prefix - CSS variable prefix (default: 'ant')
96
+ * @returns {string} - Transformed value with CSS variables
97
+ */
98
+ function transformSassVarToCssVar(value, prefix = 'ant') {
99
+ if (!value || typeof value !== 'string') {
100
+ return value;
101
+ }
102
+
103
+ let result = value;
104
+
105
+ // Match SASS variables like $colorPrimary, $fontSize, etc.
106
+ // Support both $tokenName and #{tokenName} syntax
107
+ const sassVarRegex = /\$([a-zA-Z][a-zA-Z0-9]*)/g;
108
+
109
+ result = result.replace(sassVarRegex, (match, varName) => {
110
+ // Check if this is a known token
111
+ if (SASS_TOKENS.includes(varName)) {
112
+ const kebabName = camelToKebab(varName);
113
+ return `var(--${prefix}-${kebabName})`;
114
+ }
115
+ // Return original if not a known token
116
+ return match;
117
+ });
118
+
119
+ return result;
120
+ }
121
+
122
+ /**
123
+ * Transform a single SASS/SCSS file to use CSS variables
124
+ * @param {string} file - File path
125
+ * @param {object} options - Transform options
126
+ * @param {string} options.prefix - CSS variable prefix (default: 'ant')
127
+ * @returns {Promise<{content: string, hasTransformations: boolean}>} - Transformed content
128
+ */
129
+ async function transform(file, options = {}) {
130
+ const { prefix = 'ant' } = options;
131
+ const content = fs.readFileSync(file, 'utf-8');
132
+ const { root: ast } = await postcss([]).process(content, {
133
+ syntax: postcssScss,
134
+ from: file,
135
+ });
136
+
137
+ // Track whether any transformations were made
138
+ let hasTransformations = false;
139
+
140
+ // Traverse AST
141
+ ast.walk(node => {
142
+ if (node.type === 'decl') {
143
+ // Transform property values that contain SASS variables
144
+ const newValue = transformSassVarToCssVar(node.value, prefix);
145
+ if (newValue !== node.value) {
146
+ node.value = newValue;
147
+ hasTransformations = true;
148
+ }
149
+ } else if (node.type === 'atrule') {
150
+ // Transform SASS variables in at-rule params (e.g., media queries)
151
+ if (node.params) {
152
+ const newParams = transformSassVarToCssVar(node.params, prefix);
153
+ if (newParams !== node.params) {
154
+ node.params = newParams;
155
+ hasTransformations = true;
156
+ }
157
+ }
158
+ }
159
+ });
160
+
161
+ return {
162
+ content: ast.toString(postcssScss.stringify),
163
+ hasTransformations,
164
+ };
165
+ }
166
+
167
+ /**
168
+ * Run the sass-to-cssvar transformation
169
+ * @param {string} file - File or directory path
170
+ * @param {object} options - Transform options
171
+ * @param {string} options.prefix - CSS variable prefix (default: 'ant')
172
+ */
173
+ async function sassToCssvar(file, options = {}) {
174
+ const { prefix = 'ant' } = options;
175
+ const allSassFiles = findAllSassFiles(file);
176
+
177
+ for (const item of allSassFiles) {
178
+ const { content, hasTransformations } = await transform(item, { prefix });
179
+
180
+ if (hasTransformations) {
181
+ fs.writeFileSync(item, content);
182
+ console.log(` Transformed: ${item}`);
183
+ }
184
+ }
185
+ }
186
+
187
+ module.exports = {
188
+ transform,
189
+ sassToCssvar,
190
+ transformSassVarToCssVar,
191
+ getSassTokensFromTheme,
192
+ camelToKebab,
193
+ SASS_TOKENS,
194
+ };
@@ -65,8 +65,8 @@ function isReactComponentOrHook(functionName, path) {
65
65
  // 检查 BlockStatement 中是否包含 token 使用
66
66
  function hasTokenUsage(j, path) {
67
67
  return (
68
- j(path).find(j.Identifier, {
69
- name: name => name?.includes('token.'),
68
+ j(path).find(j.MemberExpression, {
69
+ object: { name: 'token' },
70
70
  }).length > 0
71
71
  );
72
72
  }
@@ -156,7 +156,6 @@ function addTokenImportToBlockStatement(j, root, path) {
156
156
  moduleName: '@oceanbase/design',
157
157
  importedName: 'token',
158
158
  importKind: 'value',
159
- after: 'react',
160
159
  });
161
160
  }
162
161
  }
@@ -261,12 +260,130 @@ function processStringLiterals(j, root) {
261
260
  return hasChanged;
262
261
  }
263
262
 
263
+ // 处理模板字符串中的颜色值
264
+ function processTemplateLiterals(j, root) {
265
+ let hasChanged = false;
266
+
267
+ const templateList = root.find(j.TemplateLiteral);
268
+
269
+ if (templateList.length > 0) {
270
+ templateList.forEach(path => {
271
+ const templateLiteral = path.value;
272
+ const quasis = templateLiteral.quasis;
273
+ const expressions = templateLiteral.expressions || [];
274
+
275
+ // 检查每个模板字符串片段是否包含需要转换的颜色值
276
+ let needsReconstruction = false;
277
+ const newQuasis = [];
278
+ const newExpressions = [];
279
+
280
+ for (let i = 0; i < quasis.length; i++) {
281
+ const quasi = quasis[i];
282
+ let value = quasi.value.raw;
283
+
284
+ // 查找需要转换的颜色值
285
+ const colorMatch = value.match(
286
+ /rgba?\([^)]+\)|#[0-9a-fA-F]{3,8}|rgb\([^)]+\)|hsl\([^)]+\)|hsla?\([^)]+\)/g
287
+ );
288
+ if (colorMatch) {
289
+ hasChanged = true;
290
+ needsReconstruction = true;
291
+
292
+ // 收集所有需要替换的匹配项及其 token
293
+ const replacements = [];
294
+ colorMatch.forEach(match => {
295
+ const { token } = tokenParse(match);
296
+ if (token) {
297
+ const index = value.indexOf(match);
298
+ replacements.push({ index, match, token });
299
+ }
300
+ });
301
+
302
+ // 按位置排序,从后往前处理以避免位置偏移
303
+ replacements.sort((a, b) => b.index - a.index);
304
+
305
+ let processedValue = value;
306
+ replacements.forEach(({ index, match, token }) => {
307
+ const before = processedValue.substring(0, index);
308
+ const after = processedValue.substring(index + match.length);
309
+
310
+ // 如果前面有内容,创建一个 quasi
311
+ if (before) {
312
+ newQuasis.push(j.templateElement({ raw: before, cooked: before }, false));
313
+ }
314
+
315
+ // 创建 token 表达式
316
+ newExpressions.push(j.memberExpression(j.identifier('token'), j.identifier(token)));
317
+
318
+ // 剩余部分继续处理
319
+ processedValue = after;
320
+ });
321
+
322
+ // 如果有剩余部分,添加到 quasis
323
+ if (processedValue || newQuasis.length === 0) {
324
+ const isTail = i === quasis.length - 1 && expressions.length === 0;
325
+ newQuasis.push(
326
+ j.templateElement({ raw: processedValue || '', cooked: processedValue || '' }, isTail)
327
+ );
328
+ } else if (newQuasis.length > 0) {
329
+ // 确保最后一个 quasi 标记为 tail(如果这是最后一个 quasi 且没有更多表达式)
330
+ const isTail = i === quasis.length - 1 && expressions.length === 0;
331
+ if (isTail) {
332
+ const lastQuasi = newQuasis[newQuasis.length - 1];
333
+ lastQuasi.tail = true;
334
+ }
335
+ }
336
+ } else {
337
+ // 如果没有颜色值需要转换,保持原样
338
+ newQuasis.push(quasi);
339
+ if (i < expressions.length) {
340
+ newExpressions.push(expressions[i]);
341
+ }
342
+ }
343
+ }
344
+
345
+ // 如果需要重构,替换整个模板字符串
346
+ if (needsReconstruction) {
347
+ // 确保最后一个 quasi 标记为 tail
348
+ if (newQuasis.length > 0) {
349
+ const lastQuasi = newQuasis[newQuasis.length - 1];
350
+ lastQuasi.tail = true;
351
+ }
352
+
353
+ // 合并原有的表达式(如果有)
354
+ const allExpressions = [...newExpressions];
355
+ // 添加原有的表达式(在 quasis 之后)
356
+ for (let i = 0; i < expressions.length; i++) {
357
+ allExpressions.push(expressions[i]);
358
+ }
359
+
360
+ path.replace(j.templateLiteral(newQuasis, allExpressions));
361
+ }
362
+ });
363
+
364
+ // 为包含 token 使用的顶级 BlockStatement 添加导入
365
+ root
366
+ .find(j.BlockStatement)
367
+ .filter(path => isTopBlockStatement(path))
368
+ .forEach(path => {
369
+ if (hasTokenUsage(j, path) && !hasUseTokenStatement(j, path)) {
370
+ addTokenImportToBlockStatement(j, root, path);
371
+ }
372
+ });
373
+ }
374
+
375
+ return hasChanged;
376
+ }
377
+
264
378
  function importComponent(j, root, options) {
265
379
  let hasChanged = false;
266
380
 
267
381
  // 处理字符串字面量
268
382
  hasChanged = processStringLiterals(j, root) || hasChanged;
269
383
 
384
+ // 处理模板字符串中的颜色值
385
+ hasChanged = processTemplateLiterals(j, root) || hasChanged;
386
+
270
387
  // 处理对象属性值(如 fontSize: 14)
271
388
  const objectPropertyChanged = processObjectProperties(j, root);
272
389
  hasChanged = objectPropertyChanged || hasChanged;
@@ -293,8 +410,11 @@ function processObjectProperties(j, root) {
293
410
  if (tokenResult) {
294
411
  hasChanged = true;
295
412
  const isJSXAttribute = path.parentPath.value.type === 'JSXAttribute';
296
- const stringValue = wrapJSXValue(`token.${tokenResult.token}`, isJSXAttribute);
297
- return j.objectProperty(j.identifier(propertyName), j.identifier(stringValue));
413
+ const memberExpression = j.memberExpression(
414
+ j.identifier('token'),
415
+ j.identifier(tokenResult.token)
416
+ );
417
+ return j.objectProperty(j.identifier(propertyName), memberExpression);
298
418
  }
299
419
  return path.value;
300
420
  });
@@ -315,23 +435,22 @@ function processObjectProperties(j, root) {
315
435
  if (tokenResult) {
316
436
  hasChanged = true;
317
437
  const isJSXAttribute = path.parentPath.value.type === 'JSXAttribute';
318
- const stringValue = wrapJSXValue(`token.${tokenResult.token}`, isJSXAttribute);
319
- return j.objectProperty(j.identifier(propertyName), j.identifier(stringValue));
438
+ const memberExpression = j.memberExpression(
439
+ j.identifier('token'),
440
+ j.identifier(tokenResult.token)
441
+ );
442
+ return j.objectProperty(j.identifier(propertyName), memberExpression);
320
443
  }
321
444
  return path.value;
322
445
  });
323
446
  }
324
447
 
325
- // 如果发生了替换,需要添加 token 导入
326
- if (hasChanged) {
327
- addTokenImportsForObjectProperties(j, root);
328
- }
329
-
330
448
  return hasChanged;
331
449
  }
332
450
 
333
451
  // 为对象属性添加 token 导入
334
452
  function addTokenImportsForObjectProperties(j, root) {
453
+ // 处理 BlockStatement 中的 token 使用
335
454
  root
336
455
  .find(j.BlockStatement)
337
456
  .filter(path => isTopBlockStatement(path))
@@ -344,6 +463,31 @@ function addTokenImportsForObjectProperties(j, root) {
344
463
  }
345
464
  }
346
465
  });
466
+
467
+ // 处理顶层导出语句中的 token 使用
468
+ const hasTokenUsageInRoot =
469
+ root.find(j.MemberExpression, {
470
+ object: { name: 'token' },
471
+ }).length > 0;
472
+
473
+ if (hasTokenUsageInRoot) {
474
+ // 检查是否应该添加顶层 token 导入
475
+ if (shouldAddTopLevelTokenImport(j, root)) {
476
+ // 检查是否有 @oceanbase/design 的导入
477
+ const hasOceanbaseImport =
478
+ root.find(j.ImportDeclaration, {
479
+ source: { value: '@oceanbase/design' },
480
+ }).length > 0;
481
+
482
+ if (hasOceanbaseImport) {
483
+ // 如果有 @oceanbase/design 导入,添加到现有导入
484
+ addTokenToExistingImport(j, root);
485
+ } else {
486
+ // 如果没有 @oceanbase/design 导入,添加顶层 token 导入
487
+ addTopLevelTokenImport(j, root);
488
+ }
489
+ }
490
+ }
347
491
  }
348
492
 
349
493
  // 检查是否应该添加顶层 token 导入
@@ -425,6 +569,33 @@ module.exports = (file, api, options) => {
425
569
  processCreateStylesParams(j, root);
426
570
  }
427
571
 
572
+ // 为对象属性添加 token 导入(只在没有其他 token 导入逻辑时调用)
573
+ if (hasChanged) {
574
+ // 检查是否已经有其他 token 导入逻辑在处理
575
+ const hasOtherTokenLogic =
576
+ root.find(j.CallExpression, {
577
+ callee: { name: 'createStyles' },
578
+ }).length > 0 ||
579
+ root.find(j.CallExpression, {
580
+ callee: {
581
+ type: 'MemberExpression',
582
+ object: { name: 'theme' },
583
+ property: { name: 'useToken' },
584
+ },
585
+ }).length > 0 ||
586
+ root
587
+ .find(j.ImportDeclaration, {
588
+ source: { value: '@oceanbase/design' },
589
+ })
590
+ .find(j.ImportSpecifier, {
591
+ imported: { name: 'theme' },
592
+ }).length > 0;
593
+
594
+ if (!hasOtherTokenLogic) {
595
+ addTokenImportsForObjectProperties(j, root);
596
+ }
597
+ }
598
+
428
599
  // 如果有变化,检查是否需要添加 token 导入
429
600
  if (hasChanged) {
430
601
  // 检查是否有 token 使用
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Common directories to exclude when traversing files
3
+ * These are typically build outputs, caches, dependencies, and temporary directories
4
+ */
5
+ const EXCLUDED_DIRS = [
6
+ 'node_modules',
7
+ '.umi',
8
+ '.umi-production',
9
+ '.git',
10
+ 'dist',
11
+ 'build',
12
+ 'coverage',
13
+ '.cache',
14
+ '.next',
15
+ '.turbo',
16
+ '.vite',
17
+ '.nuxt',
18
+ '.output',
19
+ '.temp',
20
+ '.tmp',
21
+ 'temp',
22
+ 'tmp',
23
+ ];
24
+
25
+ /**
26
+ * Check if a path should be excluded
27
+ * @param {string} filePath - File path to check
28
+ * @returns {boolean} - True if should be excluded
29
+ */
30
+ function shouldExcludePath(filePath) {
31
+ const normalizedPath = filePath.replace(/\\/g, '/');
32
+ return EXCLUDED_DIRS.some(
33
+ dir => normalizedPath.includes(`/${dir}/`) || normalizedPath.endsWith(`/${dir}`)
34
+ );
35
+ }
36
+
37
+ module.exports = {
38
+ EXCLUDED_DIRS,
39
+ shouldExcludePath,
40
+ };
@@ -36,17 +36,24 @@ const TOKEN_MAP = {
36
36
  '#1890ff': 'colorInfo',
37
37
  '#40a9ff': 'colorInfo',
38
38
  '#006aff': 'colorInfo',
39
+ '#1843ff': 'colorInfo',
40
+ '#597ef7': 'colorInfo',
39
41
  '#f7f9fb': 'colorInfoBg',
42
+ '#91a9f8': 'colorInfoBg',
40
43
  '#e6f7ff': 'colorInfoBgHover',
41
44
  '#f3f9ff': 'colorInfoBgHover',
42
45
  '#e6f7ff': 'colorInfoBgHover',
43
46
  '#73d13d': 'colorSuccess',
44
47
  '#52c41a': 'colorSuccess',
45
48
  '#faad14': 'colorWarning',
49
+ '#ffa940': 'colorWarning',
46
50
  '#fef6e7': 'colorWarningBg',
51
+ '#fed59c': 'colorWarningBg',
47
52
  '#ff4d4f': 'colorError',
48
53
  '#f5222d': 'colorError',
49
54
  '#f8636b': 'colorError',
55
+ '#f93939': 'colorError',
56
+ '#eb4444': 'colorError',
50
57
  '#d9d9d9': 'colorBorder',
51
58
  '#bfbfbf': 'colorBorder',
52
59
  '#e8e8e8': 'colorBorder',
@@ -67,7 +74,9 @@ const TOKEN_MAP = {
67
74
  'rgba(0,0,0,0.85)': 'colorText',
68
75
  'rgba(0,0,0,0.65)': 'colorTextSecondary',
69
76
  'rgba(0,0,0,0.45)': 'colorTextTertiary',
70
- '#5c6b8a': 'colorTextTertiary',
77
+ '#5c6b8a': 'colorTextSecondary',
78
+ '#5C6B8A': 'colorTextSecondary',
79
+ '#ced5e3': '@colorTextPlaceholder',
71
80
  'rgba(0,0,0,0.25)': 'colorTextQuaternary',
72
81
  'rgba(0,0,0,.85)': 'colorText',
73
82
  'rgba(0,0,0,.65)': 'colorTextSecondary',
@@ -97,6 +106,7 @@ const TOKEN_MAP = {
97
106
  'rgba(0,0,0,0.06)': 'colorFillSecondary',
98
107
  'rgba(0,0,0,0.04)': 'colorFillTertiary',
99
108
  'rgba(0,0,0,0.02)': 'colorFillQuaternary',
109
+ 'rgba(0,0,0,0.03)': 'colorFillQuaternary',
100
110
  '#f5f6fa': 'colorBgLayout',
101
111
  '#edeff2': 'colorBgLayout',
102
112
  // obui legacy style => token
@@ -122,12 +132,12 @@ const TOKEN_MAP = {
122
132
  '#cdd5e4': 'colorBorder',
123
133
  '#f5f8fe': 'colorBgLayout',
124
134
  '#f5f7fa': 'colorBgLayout',
135
+ '#f8fafe': 'colorBgLayout',
125
136
  'rgba(140,140,140,0.1)': 'colorBgLayout',
126
137
  'rgb(240,242,245)': 'colorBgLayout',
127
138
  '#132039': 'colorText',
128
139
  '#364563': 'colorTextSecondary',
129
140
  '#8592ad': 'colorTextTertiary',
130
- '#f8fafe': 'colorFillQuaternary',
131
141
  };
132
142
 
133
143
  const TOKEN_MAP_KEYS = Object.keys(TOKEN_MAP).map(key => formatValue(key));
@@ -170,6 +180,18 @@ const PROPERTY_TOKEN_MAP = {
170
180
  15: 'fontSizeLG',
171
181
  16: 'fontSizeLG',
172
182
  },
183
+ fontWeight: {
184
+ 300: 'fontWeightWeak',
185
+ 400: 'fontWeight',
186
+ 500: 'fontWeightStrong',
187
+ 600: 'fontWeightStrong',
188
+ },
189
+ borderRadius: {
190
+ 2: 'borderRadiusSM',
191
+ 4: 'borderRadius',
192
+ 6: 'borderRadiusMD',
193
+ 8: 'borderRadiusLG',
194
+ },
173
195
  };
174
196
 
175
197
  function propertyTokenParse(propertyName, value) {