@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
package/README.md CHANGED
@@ -316,3 +316,161 @@ transform fixed less style to antd v5 design token.
316
316
  }
317
317
  }
318
318
  ```
319
+
320
+ ### `less-to-cssvar`
321
+
322
+ Transform Less variables to CSS variables. This transformer must be explicitly specified via `--transformer` option.
323
+
324
+ ```shell
325
+ # Basic usage (auto-detect: CSS Module import → .module.css, global import → .css)
326
+ npx -p @oceanbase/codemod codemod src --transformer=less-to-cssvar
327
+
328
+ # Output as .scss instead of .css
329
+ npx -p @oceanbase/codemod codemod src --transformer=less-to-cssvar --rename-to=scss
330
+
331
+ # With custom prefix (default: ant)
332
+ npx -p @oceanbase/codemod codemod src --transformer=less-to-cssvar --prefix=ob
333
+
334
+ # Never add .module suffix (skip auto-detection)
335
+ npx -p @oceanbase/codemod codemod src --transformer=less-to-cssvar --add-module=false
336
+
337
+ # Keep .less extension (disable renaming)
338
+ npx -p @oceanbase/codemod codemod src --transformer=less-to-cssvar --rename-to=false
339
+
340
+ # Combine options: output as .scss with custom prefix
341
+ npx -p @oceanbase/codemod codemod src --transformer=less-to-cssvar --rename-to=scss --prefix=ob
342
+ ```
343
+
344
+ **Options:**
345
+
346
+ | Option | Description | Default |
347
+ | -------------- | -------------------------------------------------------- | ------- |
348
+ | `--prefix` | CSS variable prefix, e.g. `var(--ant-color-primary)` | `ant` |
349
+ | `--rename-to` | Target format: `css`, `scss`, or `false` to keep `.less` | `css` |
350
+ | `--add-module` | Add `.module` suffix when renaming | `true` |
351
+
352
+ **`--rename-to` 说明:**
353
+
354
+ | 值 | 行为 | 示例 |
355
+ | ------- | ----------------------------- | --------------------------- |
356
+ | `css` | 输出为 `.css` 文件(默认) | `style.less` → `style.css` |
357
+ | `scss` | 输出为 `.scss` 文件 | `style.less` → `style.scss` |
358
+ | `false` | 保持 `.less` 扩展名,不重命名 | `style.less` → `style.less` |
359
+
360
+ **`--add-module` 说明:**
361
+
362
+ | 值 | 行为 |
363
+ | ------- | -------------------------------------------- |
364
+ | `true` | 自动检测:根据导入方式判断是否添加 `.module` |
365
+ | `false` | 跳过检测:统一不添加 `.module` |
366
+
367
+ **注意**:当 `--rename-to=false` 时,如果用户没有显式指定 `--add-module`,则 `--add-module` 会自动设置为 `false`(因为不重命名文件时,添加 `.module` 后缀没有意义)。如果用户显式指定了 `--add-module`,则使用用户指定的值。
368
+
369
+ **自动检测规则:**
370
+
371
+ | 导入方式 | 结果(CSS) | 结果(SCSS) |
372
+ | ---------------------------------------------- | ---------------- | ----------------- |
373
+ | `import styles from './xxx.less'` (CSS Module) | `xxx.module.css` | `xxx.module.scss` |
374
+ | `import './xxx.less'` (全局样式) | `xxx.css` | `xxx.scss` |
375
+ | `global.less` / `reset.less` 等常见全局文件名 | `xxx.css` | `xxx.scss` |
376
+
377
+ **Important Notes:**
378
+
379
+ When `--rename-to` is set to `css` or `scss` (default: `css`):
380
+
381
+ 1. **Comment conversion**:
382
+ - For `.css` output: Less single-line comments (`//`) will be automatically converted to CSS block comments (`/* */`).
383
+ - For `.scss` output: Comments are kept as `//` (SCSS supports single-line comments).
384
+ 2. **`:global` syntax**: CSS Modules `:global` syntax will continue to work in `.module.css` or `.module.scss` files.
385
+ 3. **Import references**: Import references in JS/TS/JSX/TSX files will be **automatically updated**:
386
+
387
+ ```diff
388
+ - import './style.less';
389
+ + import './style.css'; // or './style.scss' if --rename-to=scss
390
+ ```
391
+
392
+ **Example:**
393
+
394
+ ```diff
395
+ - @import '~@oceanbase/design/es/theme/index.less';
396
+ .container {
397
+ - color: @colorPrimary;
398
+ - background: @colorBgContainer;
399
+ - border-color: @colorBorder;
400
+ - font-size: @fontSize;
401
+ + color: var(--ant-color-primary);
402
+ + background: var(--ant-color-bg-container);
403
+ + border-color: var(--ant-color-border);
404
+ + font-size: var(--ant-font-size);
405
+ }
406
+
407
+ .status {
408
+ &.success {
409
+ - color: @colorSuccess;
410
+ - background: @colorSuccessBg;
411
+ + color: var(--ant-color-success);
412
+ + background: var(--ant-color-success-bg);
413
+ }
414
+ &.error {
415
+ - color: @colorError;
416
+ - background: @colorErrorBg;
417
+ + color: var(--ant-color-error);
418
+ + background: var(--ant-color-error-bg);
419
+ }
420
+ }
421
+ ```
422
+
423
+ ### `sass-to-cssvar`
424
+
425
+ Transform SASS/SCSS variables to CSS variables. This transformer must be explicitly specified via `--transformer` option.
426
+
427
+ ```shell
428
+ # Basic usage
429
+ npx -p @oceanbase/codemod codemod src --transformer=sass-to-cssvar
430
+
431
+ # With custom prefix (default: ant)
432
+ npx -p @oceanbase/codemod codemod src --transformer=sass-to-cssvar --prefix=ob
433
+ ```
434
+
435
+ **Options:**
436
+
437
+ | Option | Description | Default |
438
+ | ---------- | ---------------------------------------------------- | ------- |
439
+ | `--prefix` | CSS variable prefix, e.g. `var(--ant-color-primary)` | `ant` |
440
+
441
+ **Important Notes:**
442
+
443
+ 1. **File format**: Supports both `.sass` and `.scss` files.
444
+ 2. **Variable syntax**: Converts SASS variables (`$variableName`) to CSS variables (`var(--prefix-variable-name)`).
445
+ 3. **Token matching**: Only converts variables that match tokens from `@oceanbase/design` theme.
446
+ 4. **No file renaming**: Files keep their original `.sass` or `.scss` extension.
447
+
448
+ **Example:**
449
+
450
+ ```diff
451
+ .container {
452
+ - color: $colorPrimary;
453
+ - background: $colorBgContainer;
454
+ - border-color: $colorBorder;
455
+ - font-size: $fontSize;
456
+ + color: var(--ant-color-primary);
457
+ + background: var(--ant-color-bg-container);
458
+ + border-color: var(--ant-color-border);
459
+ + font-size: var(--ant-font-size);
460
+ }
461
+
462
+ .status {
463
+ &.success {
464
+ - color: $colorSuccess;
465
+ - background: $colorSuccessBg;
466
+ + color: var(--ant-color-success);
467
+ + background: var(--ant-color-success-bg);
468
+ }
469
+ &.error {
470
+ - color: $colorError;
471
+ - background: $colorErrorBg;
472
+ + color: var(--ant-color-error);
473
+ + background: var(--ant-color-error-bg);
474
+ }
475
+ }
476
+ ```
package/bin/cli.js CHANGED
@@ -13,11 +13,14 @@ const { run: jscodeshift } = require('jscodeshift/src/Runner');
13
13
  const execa = require('execa');
14
14
  const isDirectory = require('is-directory');
15
15
  const commandExistsSync = require('command-exists').sync;
16
+ const { readPackageUp } = require('read-pkg-up');
16
17
 
17
18
  const pkg = require('../package.json');
18
19
  const pkgUpgradeList = require('./upgrade-list');
19
20
  const { getDependencies } = require('../transforms/utils/marker');
20
21
  const { lessToToken } = require('../transforms/less-to-token');
22
+ const { lessToCssvar } = require('../transforms/less-to-cssvar');
23
+ const { sassToCssvar } = require('../transforms/sass-to-cssvar');
21
24
 
22
25
  // jscodeshift codemod scripts dir
23
26
  const transformersDir = path.join(__dirname, '../transforms');
@@ -35,6 +38,13 @@ const transformers = [
35
38
  'less-to-token',
36
39
  ];
37
40
 
41
+ // Transformers that must be explicitly specified via --transformer option
42
+ // These are not run by default
43
+ const explicitTransformers = ['less-to-cssvar', 'sass-to-cssvar'];
44
+
45
+ // All available transformers
46
+ const allTransformers = [...transformers, ...explicitTransformers];
47
+
38
48
  const dependencyProperties = [
39
49
  'dependencies',
40
50
  'devDependencies',
@@ -101,12 +111,16 @@ function getRunnerArgs(transformerPath, parser = 'babylon', options = {}) {
101
111
  }
102
112
 
103
113
  async function run(filePath, args = {}) {
104
- const targetTransformers =
105
- args.transformer?.split(',')?.filter(transformer => transformers.includes(transformer)) ||
106
- transformers;
114
+ // When --transformer is specified, filter against all available transformers
115
+ // Otherwise, use default transformers only (excluding explicit-only ones like less-to-cssvar)
116
+ const targetTransformers = args.transformer
117
+ ? args.transformer.split(',').filter(transformer => allTransformers.includes(transformer))
118
+ : transformers;
107
119
  for (const transformer of targetTransformers) {
108
120
  await transform(transformer, 'babylon', filePath, args);
109
121
  }
122
+ // Return executed transformers for checking if we should skip dependency detection
123
+ return targetTransformers;
110
124
  }
111
125
 
112
126
  async function transform(transformer, parser, filePath, options) {
@@ -120,6 +134,58 @@ async function transform(transformer, parser, filePath, options) {
120
134
  try {
121
135
  if (transformer === 'less-to-token') {
122
136
  await lessToToken(filePath);
137
+ } else if (transformer === 'less-to-cssvar') {
138
+ // less-to-cssvar options:
139
+ // --prefix: CSS variable prefix (default: 'ant')
140
+ // --rename-to: Target format: 'css', 'scss', or false to keep .less (default: 'css')
141
+ // --add-module: Whether to add .module suffix when renaming (default: true)
142
+ // - true (default): auto-detect based on import style (CSS Module vs global)
143
+ // - false: skip detection, never add .module
144
+
145
+ // Check if user explicitly specified --add-module
146
+ const hasExplicitAddModule =
147
+ options['add-module'] !== undefined || options.addModule !== undefined;
148
+ const addModuleValue = options['add-module'] ?? options.addModule;
149
+ // Default is true (auto-detect), false means skip detection
150
+ let addModuleOption = addModuleValue !== false && addModuleValue !== 'false';
151
+
152
+ // Parse --rename-to option: 'css', 'scss', or false
153
+ let renameToOption = 'css'; // default
154
+ const renameToValue = options['rename-to'] ?? options.renameTo;
155
+ if (renameToValue === false || renameToValue === 'false') {
156
+ renameToOption = false;
157
+ // When renameTo is false, disable addModule by default (only if not explicitly specified)
158
+ if (!hasExplicitAddModule && addModuleOption === true) {
159
+ addModuleOption = false;
160
+ }
161
+ } else if (renameToValue === 'scss' || renameToValue === true) {
162
+ renameToOption = renameToValue === 'scss' ? 'scss' : 'css';
163
+ } else if (typeof renameToValue === 'string') {
164
+ renameToOption = renameToValue.toLowerCase() === 'scss' ? 'scss' : 'css';
165
+ }
166
+ // Backward compatibility: support --rename-to-css=false
167
+ else if (options['rename-to-css'] === false || options.renameToCss === false) {
168
+ renameToOption = false;
169
+ // When renameTo is false, disable addModule by default (only if not explicitly specified)
170
+ if (!hasExplicitAddModule && addModuleOption === true) {
171
+ addModuleOption = false;
172
+ }
173
+ }
174
+
175
+ const lessToCssvarOptions = {
176
+ prefix: options.prefix || 'ant',
177
+ renameTo: renameToOption,
178
+ addModule: addModuleOption,
179
+ _explicitAddModule: hasExplicitAddModule, // Pass flag to indicate explicit user choice
180
+ };
181
+ await lessToCssvar(filePath, lessToCssvarOptions);
182
+ } else if (transformer === 'sass-to-cssvar') {
183
+ // sass-to-cssvar options:
184
+ // --prefix: CSS variable prefix (default: 'ant')
185
+ const sassToCssvarOptions = {
186
+ prefix: options.prefix || 'ant',
187
+ };
188
+ await sassToCssvar(filePath, sassToCssvarOptions);
123
189
  } else {
124
190
  if (process.env.NODE_ENV === 'local') {
125
191
  console.log(`Running jscodeshift with: ${JSON.stringify(args)}`);
@@ -138,18 +204,79 @@ async function transform(transformer, parser, filePath, options) {
138
204
  }
139
205
  }
140
206
 
207
+ /**
208
+ * Detect which package manager to use
209
+ * Priority:
210
+ * 1. Check lockfile files (pnpm-lock.yaml, yarn.lock, package-lock.json)
211
+ * 2. Check package.json packageManager field
212
+ * 3. Check if commands exist (pnpm > yarn > tnpm > npm)
213
+ * @param {string} cwd - Current working directory
214
+ * @returns {Promise<string>} - Package manager command name
215
+ */
216
+ async function detectPackageManager(cwd) {
217
+ // 1. Check for lockfiles
218
+ const lockfiles = {
219
+ 'pnpm-lock.yaml': 'pnpm',
220
+ 'yarn.lock': 'yarn',
221
+ 'package-lock.json': 'npm',
222
+ };
223
+
224
+ for (const [lockfile, manager] of Object.entries(lockfiles)) {
225
+ const lockfilePath = path.join(cwd, lockfile);
226
+ if (fs.existsSync(lockfilePath)) {
227
+ if (commandExistsSync(manager)) {
228
+ return manager;
229
+ }
230
+ }
231
+ }
232
+
233
+ // 2. Check package.json for packageManager field
234
+ try {
235
+ const { readPackageUp } = await import('read-pkg-up');
236
+ const pkgResult = await readPackageUp({ cwd });
237
+ if (pkgResult?.packageJson?.packageManager) {
238
+ const packageManager = pkgResult.packageJson.packageManager;
239
+ // Format: "pnpm@8.6.0" or "yarn@3.0.0"
240
+ const manager = packageManager.split('@')[0];
241
+ if (commandExistsSync(manager)) {
242
+ return manager;
243
+ }
244
+ }
245
+ } catch (e) {
246
+ // Ignore errors
247
+ }
248
+
249
+ // 3. Check if commands exist in priority order
250
+ const managers = ['pnpm', 'yarn', 'tnpm', 'npm'];
251
+ for (const manager of managers) {
252
+ if (commandExistsSync(manager)) {
253
+ return manager;
254
+ }
255
+ }
256
+
257
+ // Fallback to npm
258
+ return 'npm';
259
+ }
260
+
141
261
  async function upgradeDetect(targetDir, needOBCharts, needObUtil) {
142
262
  const result = [];
143
263
  const cwd = path.join(process.cwd(), targetDir);
144
264
  const { readPackageUp } = await import('read-pkg-up');
145
- const closetPkgJson = await readPackageUp({ cwd });
265
+ let closetPkgJson;
266
+ try {
267
+ closetPkgJson = await readPackageUp({ cwd });
268
+ } catch (err) {
269
+ // 处理无效的 package.json 文件(如版本格式错误)
270
+ console.log(chalk.yellow(`Warning: Failed to read package.json: ${err.message}`));
271
+ closetPkgJson = null;
272
+ }
146
273
 
147
274
  let pkgJsonPath;
148
275
  if (!closetPkgJson) {
149
276
  pkgJsonPath = "we didn't find your package.json";
150
277
  // unknown dependency property
151
- result.push(['install', '@oceanbase/design', pkgUpgradeList['@oceanbase/design']]);
152
- result.push(['install', '@oceanbase/ui', pkgUpgradeList['@oceanbase/ui']]);
278
+ result.push(['install', '@oceanbase/design', pkgUpgradeList['@oceanbase/design'].version]);
279
+ result.push(['install', '@oceanbase/ui', pkgUpgradeList['@oceanbase/ui'].version]);
153
280
  if (needOBCharts) {
154
281
  result.push(['install', '@oceanbase/charts', pkgUpgradeList['@oceanbase/charts'].version]);
155
282
  }
@@ -219,7 +346,7 @@ async function upgradeDetect(targetDir, needOBCharts, needObUtil) {
219
346
  )
220
347
  );
221
348
  console.log(`> Update package.json file: ${pkgJsonPath} \n`);
222
- const npmCommand = commandExistsSync('tnpm') ? 'tnpm' : 'npm';
349
+ const npmCommand = await detectPackageManager(cwd);
223
350
 
224
351
  // install dependencies
225
352
  console.log(`New package installing...\n`);
@@ -241,23 +368,50 @@ async function upgradeDetect(targetDir, needOBCharts, needObUtil) {
241
368
  console.log(`\nNew package installed!\n`);
242
369
 
243
370
  // uninstall dependencies
244
- console.log(`Deprecated package uninstalling...\n`);
245
- const uninstallDependencies = ['@alipay/ob-ui', '@alipay/ob-util', '@alipay/ob-charts'];
246
- console.log(uninstallDependencies.map(n => `* ${n}`).join('\n'));
247
- console.log('\n');
248
- await execa(npmCommand, ['uninstall', ...uninstallDependencies, '--save'], {
249
- stdio: 'inherit',
250
- });
251
- console.log(`\nDeprecated package uninstalled!\n`);
371
+ const deprecatedPackages = ['@alipay/ob-ui', '@alipay/ob-util', '@alipay/ob-charts'];
372
+ const uninstallDependencies = [];
373
+
374
+ if (closetPkgJson) {
375
+ const { packageJson } = closetPkgJson;
376
+ deprecatedPackages.forEach(depName => {
377
+ dependencyProperties.forEach(property => {
378
+ const versionRange = _.get(packageJson, `${property}.${depName}`);
379
+ if (versionRange && !uninstallDependencies.includes(depName)) {
380
+ uninstallDependencies.push(depName);
381
+ }
382
+ });
383
+ });
384
+ }
385
+ // 如果没有找到 package.json,跳过卸载操作(无法确定包是否存在)
386
+
387
+ if (uninstallDependencies.length > 0) {
388
+ console.log(`Deprecated package uninstalling...\n`);
389
+ console.log(uninstallDependencies.map(n => `* ${n}`).join('\n'));
390
+ console.log('\n');
391
+ await execa(npmCommand, ['uninstall', ...uninstallDependencies, '--save'], {
392
+ stdio: 'inherit',
393
+ });
394
+ console.log(`\nDeprecated package uninstalled!\n`);
395
+ }
252
396
  }
253
397
 
254
398
  /**
255
399
  * options
256
400
  * --force // force skip git checking (dangerously)
257
401
  * --cpus=1 // specify cpus cores to use
258
- * --disablePrettier // disable prettier
402
+ * --disablePrettier // disable prettier (default: true, use --disablePrettier=false to enable)
259
403
  * --transformer=t1,t2 // specify target transformer
260
404
  * --ignore-config // ignore config file
405
+ *
406
+ * less-to-cssvar specific options:
407
+ * --prefix=ant // CSS variable prefix (default: 'ant'), e.g. var(--ant-color-primary)
408
+ * --rename-to // target format: 'css' (default), 'scss', or false to keep .less
409
+ * --add-module // add .module suffix when renaming (default: true)
410
+ * // true: auto-detect based on import style (CSS Module vs global)
411
+ * // false: skip detection, never add .module
412
+ *
413
+ * sass-to-cssvar specific options:
414
+ * --prefix=ant // CSS variable prefix (default: 'ant'), e.g. var(--ant-color-primary)
261
415
  */
262
416
 
263
417
  async function bootstrap() {
@@ -289,9 +443,12 @@ async function bootstrap() {
289
443
  process.exit(1);
290
444
  }
291
445
 
292
- await run(dir, args);
446
+ const executedTransformers = await run(dir, args);
293
447
 
294
- if (!args.disablePrettier) {
448
+ // Default: disablePrettier is true (don't run prettier by default)
449
+ // User can enable prettier by passing --disablePrettier=false
450
+ const shouldRunPrettier = args.disablePrettier === false || args.disablePrettier === 'false';
451
+ if (shouldRunPrettier) {
295
452
  console.log('----------- Prettier Format -----------\n');
296
453
  console.log('[Prettier] format files running...');
297
454
  try {
@@ -305,19 +462,28 @@ async function bootstrap() {
305
462
  }
306
463
  }
307
464
 
308
- try {
309
- console.log('----------- Dependencies Alert -----------\n');
310
- const depsList = await getDependencies();
311
- await upgradeDetect(
312
- dir,
313
- depsList.includes('@oceanbase/charts'),
314
- depsList.includes('@oceanbase/util')
315
- );
316
- } catch (err) {
317
- console.log('skip summary due to', err);
318
- } finally {
319
- console.log(`\n----------- Thanks for using @oceanbase/codemod ${pkg.version} -----------`);
465
+ // Skip dependency detection if only explicit transformers are executed
466
+ // Explicit transformers (less-to-cssvar, sass-to-cssvar) only do code transformation
467
+ // and don't require dependency installation
468
+ const onlyExplicitTransformers =
469
+ executedTransformers.length > 0 &&
470
+ executedTransformers.every(t => explicitTransformers.includes(t));
471
+
472
+ if (!onlyExplicitTransformers) {
473
+ try {
474
+ console.log('----------- Dependencies Alert -----------\n');
475
+ const depsList = await getDependencies();
476
+ await upgradeDetect(
477
+ dir,
478
+ depsList.includes('@oceanbase/charts'),
479
+ depsList.includes('@oceanbase/util')
480
+ );
481
+ } catch (err) {
482
+ console.log('skip summary due to', err);
483
+ }
320
484
  }
485
+
486
+ console.log(`\n----------- Thanks for using @oceanbase/codemod ${pkg.version} -----------`);
321
487
  }
322
488
 
323
489
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oceanbase/codemod",
3
- "version": "1.0.0-alpha.1",
3
+ "version": "1.0.0-alpha.10",
4
4
  "description": "Codemod for OceanBase Design upgrade",
5
5
  "keywords": [
6
6
  "oceanbase",
@@ -23,21 +23,22 @@
23
23
  "build": "father build"
24
24
  },
25
25
  "dependencies": {
26
- "@oceanbase/design": "^1.0.0-alpha.1",
26
+ "@oceanbase/design": "^1.0.0-alpha.10",
27
27
  "chalk": "^3.0.0",
28
28
  "command-exists": "^1.2.9",
29
29
  "execa": "^5.1.1",
30
30
  "find-up": "^7.0.0",
31
- "glob": "^11.0.3",
31
+ "glob": "^11.1.0",
32
32
  "is-directory": "^0.3.1",
33
33
  "is-git-clean": "^1.1.0",
34
34
  "jscodeshift": "^0.16.1",
35
35
  "lodash": "^4.17.21",
36
36
  "postcss": "^8.5.6",
37
37
  "postcss-less": "^6.0.0",
38
- "prettier": "^3.6.2",
38
+ "postcss-scss": "^4.0.9",
39
+ "prettier": "^3.7.4",
39
40
  "read-pkg-up": "^10.1.0",
40
- "semver": "^7.7.2",
41
+ "semver": "^7.7.3",
41
42
  "update-check": "^1.5.4",
42
43
  "yargs-parser": "^21.1.1"
43
44
  },
@@ -47,5 +48,5 @@
47
48
  "enzyme": "^3.11.0",
48
49
  "enzyme-to-json": "^3.6.2"
49
50
  },
50
- "gitHead": "47b1ebfa75581585b83252085dddd33fc2c072a5"
51
+ "gitHead": "06757770d5ede2d3bc2ea0409e45d2e6dea5012c"
51
52
  }
@@ -0,0 +1,16 @@
1
+ @import '~@oceanbase/design/es/theme/index.less';
2
+
3
+ .container {
4
+ color: @colorPrimary;
5
+ background: @colorBgContainer;
6
+ border-color: @colorBorder;
7
+ font-size: @fontSize;
8
+ }
9
+
10
+ .content {
11
+ color: @colorText;
12
+ background-color: @colorBgLayout;
13
+ border-radius: @borderRadius;
14
+ padding: @padding;
15
+ }
16
+
@@ -0,0 +1,14 @@
1
+ .container {
2
+ color: var(--ant-color-primary);
3
+ background: var(--ant-color-bg-container);
4
+ border-color: var(--ant-color-border);
5
+ font-size: var(--ant-font-size);
6
+ }
7
+
8
+ .content {
9
+ color: var(--ant-color-text);
10
+ background-color: var(--ant-color-bg-layout);
11
+ border-radius: var(--ant-border-radius);
12
+ padding: var(--ant-padding);
13
+ }
14
+
@@ -0,0 +1,23 @@
1
+ @import '~@oceanbase/design/es/theme/index.less';
2
+
3
+ .palette {
4
+ // Gray scale
5
+ --gray-1: @gray1;
6
+ --gray-5: @gray5;
7
+ --gray-9: @gray9;
8
+
9
+ // Blue scale
10
+ --blue-1: @blue1;
11
+ --blue-4: @blue4;
12
+ --blue-6: @blue6;
13
+
14
+ // Status colors
15
+ --success: @green4;
16
+ --warning: @orange4;
17
+ --error: @red4;
18
+
19
+ // Special colors
20
+ --white: @white;
21
+ --black: @black;
22
+ }
23
+
@@ -0,0 +1,21 @@
1
+ .palette {
2
+ // Gray scale
3
+ --gray-1: var(--ant-gray1);
4
+ --gray-5: var(--ant-gray5);
5
+ --gray-9: var(--ant-gray9);
6
+
7
+ // Blue scale
8
+ --blue-1: var(--ant-blue1);
9
+ --blue-4: var(--ant-blue4);
10
+ --blue-6: var(--ant-blue6);
11
+
12
+ // Status colors
13
+ --success: var(--ant-green4);
14
+ --warning: var(--ant-orange4);
15
+ --error: var(--ant-red4);
16
+
17
+ // Special colors
18
+ --white: var(--ant-white);
19
+ --black: var(--ant-black);
20
+ }
21
+
@@ -0,0 +1,22 @@
1
+ @import '~@oceanbase/design/es/theme/index.less';
2
+
3
+ .card {
4
+ padding: @paddingSM @paddingLG;
5
+ border: 1px solid @colorBorder;
6
+ border-radius: @borderRadiusLG;
7
+ box-shadow: @boxShadow;
8
+ font-size: @fontSizeLG;
9
+ line-height: @lineHeight;
10
+ }
11
+
12
+ .text {
13
+ color: @colorTextSecondary;
14
+ font-weight: @fontWeightStrong;
15
+ }
16
+
17
+ @media (max-width: @screenMD) {
18
+ .card {
19
+ padding: @paddingXS;
20
+ }
21
+ }
22
+
@@ -0,0 +1,20 @@
1
+ .card {
2
+ padding: var(--ant-padding-sm) var(--ant-padding-lg);
3
+ border: 1px solid var(--ant-color-border);
4
+ border-radius: var(--ant-border-radius-lg);
5
+ box-shadow: var(--ant-box-shadow);
6
+ font-size: var(--ant-font-size-lg);
7
+ line-height: var(--ant-line-height);
8
+ }
9
+
10
+ .text {
11
+ color: var(--ant-color-text-secondary);
12
+ font-weight: var(--ant-font-weight-strong);
13
+ }
14
+
15
+ @media (max-width: var(--ant-screen-md)) {
16
+ .card {
17
+ padding: var(--ant-padding-xs);
18
+ }
19
+ }
20
+
@@ -0,0 +1,29 @@
1
+ @import '~@oceanbase/design/es/theme/index.less';
2
+
3
+ .button {
4
+ height: @controlHeight;
5
+ background: @colorBgContainer;
6
+
7
+ &:hover {
8
+ background: @controlItemBgHover;
9
+ }
10
+
11
+ &:active {
12
+ background: @controlItemBgActive;
13
+ }
14
+
15
+ &.disabled {
16
+ background: @controlItemBgActiveDisabled;
17
+ }
18
+ }
19
+
20
+ .input {
21
+ height: @controlHeightSM;
22
+ padding: 0 @controlPaddingHorizontal;
23
+ }
24
+
25
+ .select {
26
+ height: @controlHeightLG;
27
+ padding: 0 @controlPaddingHorizontalSM;
28
+ }
29
+