template-syncer 1.1.3 → 1.2.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.
@@ -1,48 +1,16 @@
1
1
  import type { FileChange, Recommendation } from '../types';
2
- /**
3
- * 交互式提示工具
4
- */
5
2
  export declare const prompts: {
6
- /**
7
- * 输入模板仓库 URL
8
- */
9
3
  inputRepo(): Promise<string>;
10
- /**
11
- * 选择分支
12
- */
13
4
  selectBranch(branches: string[]): Promise<string>;
14
- /**
15
- * 选择处理方式
16
- */
17
5
  selectAction(): Promise<"category" | "individual" | "all" | "cancel">;
18
- /**
19
- * 按分类选择文件
20
- */
21
6
  selectByCategory(changes: FileChange[]): Promise<FileChange[]>;
22
- /**
23
- * 逐一选择文件
24
- */
25
7
  selectIndividually(changes: FileChange[]): Promise<FileChange[]>;
26
- /**
27
- * 确认操作
28
- */
29
8
  confirm(message: string, defaultValue?: boolean): Promise<boolean>;
30
- /**
31
- * 选择推荐操作
32
- */
33
9
  selectRecommendations(recommendations: Recommendation[]): Promise<Recommendation[]>;
34
- /**
35
- * 初始化配置向导
36
- */
37
10
  initConfig(): Promise<{
38
11
  repo: string;
39
12
  branch: string;
40
13
  ignore: string[];
41
- verbose: boolean;
42
14
  }>;
43
- /**
44
- * 显示变更统计
45
- */
46
15
  showChangeSummary(changes: FileChange[]): void;
47
16
  };
48
- //# sourceMappingURL=prompts.d.ts.map
package/lib/ui/prompts.js CHANGED
@@ -7,13 +7,12 @@ exports.prompts = void 0;
7
7
  const inquirer_1 = __importDefault(require("inquirer"));
8
8
  const tree_1 = require("./tree");
9
9
  const chalk = require('chalk');
10
- /**
11
- * 交互式提示工具
12
- */
10
+ const STATUS_TEXT = {
11
+ new: '新增',
12
+ modified: '修改',
13
+ deleted: '删除'
14
+ };
13
15
  exports.prompts = {
14
- /**
15
- * 输入模板仓库 URL
16
- */
17
16
  async inputRepo() {
18
17
  const { repo } = await inquirer_1.default.prompt([{
19
18
  type: 'input',
@@ -23,9 +22,6 @@ exports.prompts = {
23
22
  }]);
24
23
  return repo;
25
24
  },
26
- /**
27
- * 选择分支
28
- */
29
25
  async selectBranch(branches) {
30
26
  if (branches.length === 0)
31
27
  return 'main';
@@ -39,13 +35,10 @@ exports.prompts = {
39
35
  name: b === 'main' || b === 'master' ? `${b} (默认)` : b,
40
36
  value: b
41
37
  })),
42
- default: branches.find(b => b === 'main') || branches.find(b => b === 'master') || branches[0]
38
+ default: branches.find(b => b === 'main') ?? branches.find(b => b === 'master') ?? branches[0]
43
39
  }]);
44
40
  return branch;
45
41
  },
46
- /**
47
- * 选择处理方式
48
- */
49
42
  async selectAction() {
50
43
  const { action } = await inquirer_1.default.prompt([{
51
44
  type: 'list',
@@ -60,73 +53,61 @@ exports.prompts = {
60
53
  }]);
61
54
  return action;
62
55
  },
63
- /**
64
- * 按分类选择文件
65
- */
56
+ // 一次 checkbox 选择所有分类,而不是逐个 confirm
66
57
  async selectByCategory(changes) {
67
- // 按分类分组
68
58
  const categories = new Map();
69
59
  for (const file of changes) {
70
- const list = categories.get(file.category) || [];
60
+ const list = categories.get(file.category) ?? [];
71
61
  list.push(file);
72
62
  categories.set(file.category, list);
73
63
  }
74
- const selected = [];
75
- for (const [category, files] of categories) {
64
+ const choices = Array.from(categories.entries()).map(([category, files]) => {
76
65
  const icon = files[0].icon;
66
+ const parts = [];
77
67
  const newCount = files.filter(f => f.status === 'new').length;
78
68
  const modCount = files.filter(f => f.status === 'modified').length;
79
69
  const delCount = files.filter(f => f.status === 'deleted').length;
80
- let stats = `${files.length} 个文件`;
81
- const parts = [];
82
70
  if (newCount > 0)
83
- parts.push(`新增: ${newCount}`);
71
+ parts.push(chalk.green(`新增 ${newCount}`));
84
72
  if (modCount > 0)
85
- parts.push(`修改: ${modCount}`);
73
+ parts.push(chalk.yellow(`修改 ${modCount}`));
86
74
  if (delCount > 0)
87
- parts.push(`删除: ${delCount}`);
88
- if (parts.length > 0)
89
- stats += `, ${parts.join(', ')}`;
90
- const { include } = await inquirer_1.default.prompt([{
91
- type: 'confirm',
92
- name: 'include',
93
- message: `${icon} ${category} (${stats})`,
94
- default: delCount === 0 // 有删除操作时默认不选中
95
- }]);
96
- if (include) {
97
- selected.push(...files);
98
- }
99
- }
100
- return selected;
75
+ parts.push(chalk.red(`删除 ${delCount}`));
76
+ return {
77
+ name: `${icon} ${category} ${parts.join(' ')}`,
78
+ value: category,
79
+ checked: delCount === 0
80
+ };
81
+ });
82
+ const { selected } = await inquirer_1.default.prompt([{
83
+ type: 'checkbox',
84
+ name: 'selected',
85
+ message: '选择要处理的分类:',
86
+ choices,
87
+ pageSize: 15
88
+ }]);
89
+ return changes.filter(f => selected.includes(f.category));
101
90
  },
102
- /**
103
- * 逐一选择文件
104
- */
105
91
  async selectIndividually(changes) {
106
- const statusText = (status) => {
107
- switch (status) {
108
- case 'new': return '新增';
109
- case 'modified': return '修改';
110
- case 'deleted': return '删除';
111
- default: return status;
112
- }
113
- };
114
92
  const { selected } = await inquirer_1.default.prompt([{
115
93
  type: 'checkbox',
116
94
  name: 'selected',
117
95
  message: '选择要处理的文件:',
118
- choices: changes.map(file => ({
119
- name: `${file.icon} ${file.path} (${statusText(file.status)})`,
120
- value: file,
121
- checked: file.status !== 'deleted' // 删除操作默认不选中
122
- })),
123
- pageSize: 15
96
+ choices: changes.map(file => {
97
+ const statusLabel = STATUS_TEXT[file.status] ?? file.status;
98
+ const colorFn = file.status === 'new' ? chalk.green
99
+ : file.status === 'deleted' ? chalk.red
100
+ : chalk.yellow;
101
+ return {
102
+ name: `${file.icon} ${file.path} ${colorFn(statusLabel)}`,
103
+ value: file,
104
+ checked: file.status !== 'deleted'
105
+ };
106
+ }),
107
+ pageSize: 20
124
108
  }]);
125
109
  return selected;
126
110
  },
127
- /**
128
- * 确认操作
129
- */
130
111
  async confirm(message, defaultValue = true) {
131
112
  const { confirmed } = await inquirer_1.default.prompt([{
132
113
  type: 'confirm',
@@ -136,28 +117,21 @@ exports.prompts = {
136
117
  }]);
137
118
  return confirmed;
138
119
  },
139
- /**
140
- * 选择推荐操作
141
- */
120
+ // batch/smart 模式:一次选择推荐组
142
121
  async selectRecommendations(recommendations) {
122
+ const PRIORITY_ICON = { high: '🔴', medium: '🟡', low: '🟢' };
143
123
  const { selected } = await inquirer_1.default.prompt([{
144
124
  type: 'checkbox',
145
125
  name: 'selected',
146
- message: '选择要执行的操作:',
147
- choices: recommendations.map(rec => {
148
- const icon = rec.priority === 'high' ? '🔴' : rec.priority === 'medium' ? '🟡' : '🟢';
149
- return {
150
- name: `${icon} ${rec.title} (${rec.files.length} 个文件)`,
151
- value: rec,
152
- checked: rec.priority === 'high'
153
- };
154
- })
126
+ message: '选择要执行的更新:',
127
+ choices: recommendations.map(rec => ({
128
+ name: `${PRIORITY_ICON[rec.priority]} ${rec.title} ${chalk.gray(rec.description)} (${rec.files.length} 个文件)`,
129
+ value: rec,
130
+ checked: rec.priority === 'high'
131
+ }))
155
132
  }]);
156
133
  return selected;
157
134
  },
158
- /**
159
- * 初始化配置向导
160
- */
161
135
  async initConfig() {
162
136
  return inquirer_1.default.prompt([
163
137
  {
@@ -177,26 +151,26 @@ exports.prompts = {
177
151
  name: 'ignore',
178
152
  message: '额外忽略的文件:',
179
153
  choices: [
180
- { name: '.env.local', value: '.env.local', checked: false },
181
- { name: 'README.md', value: 'README.md', checked: false },
182
- { name: '.vscode/', value: '.vscode/**', checked: false }
154
+ { name: '.env.local', value: '.env.local' },
155
+ { name: 'README.md', value: 'README.md' },
156
+ { name: '.vscode/', value: '.vscode/**' }
183
157
  ]
184
- },
185
- {
186
- type: 'confirm',
187
- name: 'verbose',
188
- message: '默认启用详细输出?',
189
- default: false
190
158
  }
191
159
  ]);
192
160
  },
193
- /**
194
- * 显示变更统计
195
- */
196
161
  showChangeSummary(changes) {
197
- console.log(`\n发现 ${chalk.bold(changes.length)} 个文件需要处理:\n`);
162
+ const newCount = changes.filter(f => f.status === 'new').length;
163
+ const modCount = changes.filter(f => f.status === 'modified').length;
164
+ const delCount = changes.filter(f => f.status === 'deleted').length;
165
+ const parts = [];
166
+ if (newCount > 0)
167
+ parts.push(chalk.green(`新增 ${newCount}`));
168
+ if (modCount > 0)
169
+ parts.push(chalk.yellow(`修改 ${modCount}`));
170
+ if (delCount > 0)
171
+ parts.push(chalk.red(`删除 ${delCount}`));
172
+ console.log(`\n发现 ${chalk.bold(changes.length)} 个变更 ${parts.join(' ')}\n`);
198
173
  console.log((0, tree_1.formatGroupedTree)(changes));
199
174
  console.log('');
200
175
  }
201
176
  };
202
- //# sourceMappingURL=prompts.js.map
package/lib/ui/tree.d.ts CHANGED
@@ -7,4 +7,3 @@ export declare function formatFileTree(files: FileChange[]): string;
7
7
  * 按分类分组并生成树
8
8
  */
9
9
  export declare function formatGroupedTree(files: FileChange[]): string;
10
- //# sourceMappingURL=tree.d.ts.map
package/lib/ui/tree.js CHANGED
@@ -127,4 +127,3 @@ function formatGroupedTree(files) {
127
127
  });
128
128
  return lines.join('\n');
129
129
  }
130
- //# sourceMappingURL=tree.js.map
@@ -21,4 +21,3 @@ export declare class Categorizer {
21
21
  */
22
22
  addRule(rule: CategoryRule): void;
23
23
  }
24
- //# sourceMappingURL=categorizer.d.ts.map
@@ -198,4 +198,3 @@ class Categorizer {
198
198
  }
199
199
  }
200
200
  exports.Categorizer = Categorizer;
201
- //# sourceMappingURL=categorizer.js.map
@@ -34,4 +34,3 @@ export declare class Git {
34
34
  */
35
35
  removeGitDir(dir: string): void;
36
36
  }
37
- //# sourceMappingURL=git.d.ts.map
package/lib/utils/git.js CHANGED
@@ -95,4 +95,3 @@ class Git {
95
95
  }
96
96
  }
97
97
  exports.Git = Git;
98
- //# sourceMappingURL=git.js.map
@@ -3,4 +3,3 @@ export { Categorizer } from './categorizer';
3
3
  export { Merger } from './merger';
4
4
  export { Git } from './git';
5
5
  export { Scanner } from './scanner';
6
- //# sourceMappingURL=index.d.ts.map
@@ -11,4 +11,3 @@ var git_1 = require("./git");
11
11
  Object.defineProperty(exports, "Git", { enumerable: true, get: function () { return git_1.Git; } });
12
12
  var scanner_1 = require("./scanner");
13
13
  Object.defineProperty(exports, "Scanner", { enumerable: true, get: function () { return scanner_1.Scanner; } });
14
- //# sourceMappingURL=index.js.map
@@ -1,40 +1,15 @@
1
1
  import type { MergeStrategy } from '../types';
2
- /**
3
- * 文件合并器
4
- */
5
2
  export declare class Merger {
6
3
  private strategies;
7
4
  constructor(customStrategies?: Record<string, MergeStrategy>);
8
- /**
9
- * 获取文件的合并策略
10
- */
11
5
  getStrategy(filePath: string): MergeStrategy;
12
- /**
13
- * 合并文件
14
- */
15
- merge(templatePath: string, currentPath: string, targetPath: string): {
6
+ merge(templatePath: string, currentPath: string, targetPath: string): Promise<{
16
7
  success: boolean;
17
8
  message: string;
18
- };
19
- /**
20
- * 智能合并
21
- */
9
+ }>;
22
10
  private smartMerge;
23
- /**
24
- * 合并 package.json
25
- */
26
11
  private mergePackageJson;
27
- /**
28
- * 合并普通 JSON 文件
29
- */
30
12
  private mergeJson;
31
- /**
32
- * 深度合并对象
33
- */
34
13
  private deepMerge;
35
- /**
36
- * 设置合并策略
37
- */
38
14
  setStrategy(pattern: string, strategy: MergeStrategy): void;
39
15
  }
40
- //# sourceMappingURL=merger.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"merger.d.ts","sourceRoot":"","sources":["../../src/utils/merger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;GAEG;AACH,qBAAa,MAAM;IACjB,OAAO,CAAC,UAAU,CAAgC;gBAEtC,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM;IAUhE;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAK5C;;OAEG;IACH,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAkB3G;;OAEG;IACH,OAAO,CAAC,UAAU;IA0BlB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAqFxB;;OAEG;IACH,OAAO,CAAC,SAAS;IAwBjB;;OAEG;IACH,OAAO,CAAC,SAAS;IA2BjB;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;CAG5D"}
1
+ {"version":3,"file":"merger.d.ts","sourceRoot":"","sources":["../../src/utils/merger.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C,qBAAa,MAAM;IACjB,OAAO,CAAC,UAAU,CAAgC;gBAEtC,gBAAgB,GAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAM;IAShE,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa;IAKtC,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;YAY5G,UAAU;YAcV,gBAAgB;YAyDhB,SAAS;IAoBvB,OAAO,CAAC,SAAS;IAajB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,GAAG,IAAI;CAG5D"}
@@ -34,155 +34,110 @@ var __importStar = (this && this.__importStar) || (function () {
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.Merger = void 0;
37
+ const fs = __importStar(require("fs"));
37
38
  const path = __importStar(require("path"));
38
39
  const platform_1 = require("./platform");
39
- /**
40
- * 文件合并器
41
- */
42
40
  class Merger {
43
41
  constructor(customStrategies = {}) {
44
42
  this.strategies = {
45
- // 默认智能合并的文件
46
43
  'package.json': 'smart',
47
44
  'tsconfig.json': 'smart',
48
45
  'jsconfig.json': 'smart',
49
46
  ...customStrategies
50
47
  };
51
48
  }
52
- /**
53
- * 获取文件的合并策略
54
- */
55
49
  getStrategy(filePath) {
56
50
  const fileName = path.basename(filePath);
57
- return this.strategies[fileName] || this.strategies[filePath] || 'overwrite';
51
+ return this.strategies[fileName] ?? this.strategies[filePath] ?? 'overwrite';
58
52
  }
59
- /**
60
- * 合并文件
61
- */
62
- merge(templatePath, currentPath, targetPath) {
53
+ async merge(templatePath, currentPath, targetPath) {
63
54
  const strategy = this.getStrategy(targetPath);
64
55
  const fileName = path.basename(targetPath);
65
- switch (strategy) {
66
- case 'skip':
67
- return { success: false, message: '已跳过' };
68
- case 'smart':
69
- return this.smartMerge(templatePath, currentPath, targetPath, fileName);
70
- case 'overwrite':
71
- default:
72
- platform_1.platform.copyFile(templatePath, targetPath);
73
- return { success: true, message: '已覆盖' };
74
- }
56
+ if (strategy === 'skip')
57
+ return { success: false, message: '已跳过' };
58
+ if (strategy === 'smart')
59
+ return this.smartMerge(templatePath, currentPath, targetPath, fileName);
60
+ // overwrite
61
+ platform_1.platform.copyFile(templatePath, targetPath);
62
+ return { success: true, message: '已覆盖' };
75
63
  }
76
- /**
77
- * 智能合并
78
- */
79
- smartMerge(templatePath, currentPath, targetPath, fileName) {
80
- // 如果当前文件不存在,直接复制
81
- if (!require('fs').existsSync(currentPath)) {
64
+ async smartMerge(templatePath, currentPath, targetPath, fileName) {
65
+ const exists = await fs.promises.access(currentPath).then(() => true).catch(() => false);
66
+ if (!exists) {
82
67
  platform_1.platform.copyFile(templatePath, targetPath);
83
68
  return { success: true, message: '已创建' };
84
69
  }
85
- // 根据文件类型选择合并方式
86
- if (fileName === 'package.json') {
70
+ if (fileName === 'package.json')
87
71
  return this.mergePackageJson(templatePath, currentPath, targetPath);
88
- }
89
- if (fileName.endsWith('.json')) {
72
+ if (fileName.endsWith('.json'))
90
73
  return this.mergeJson(templatePath, currentPath, targetPath);
91
- }
92
- // 默认覆盖
93
74
  platform_1.platform.copyFile(templatePath, targetPath);
94
75
  return { success: true, message: '已覆盖' };
95
76
  }
96
- /**
97
- * 合并 package.json
98
- */
99
- mergePackageJson(templatePath, currentPath, targetPath) {
77
+ async mergePackageJson(templatePath, currentPath, targetPath) {
100
78
  try {
101
- const template = platform_1.platform.readJson(templatePath);
102
- const current = platform_1.platform.readJson(currentPath);
79
+ const [template, current] = await Promise.all([
80
+ platform_1.platform.readJsonAsync(templatePath),
81
+ platform_1.platform.readJsonAsync(currentPath)
82
+ ]);
103
83
  if (!template || !current) {
104
84
  platform_1.platform.copyFile(templatePath, targetPath);
105
85
  return { success: true, message: '已覆盖 (无法解析)' };
106
86
  }
107
- // 智能合并
108
87
  const merged = {
109
- // 保留当前项目的基本信息
110
- name: current.name || template.name,
111
- version: current.version || template.version,
112
- description: current.description || template.description,
113
- author: current.author || template.author,
114
- license: current.license || template.license,
115
- repository: current.repository || template.repository,
116
- homepage: current.homepage || template.homepage,
117
- bugs: current.bugs || template.bugs,
118
- keywords: current.keywords || template.keywords,
119
- // 使用模板的配置
120
- type: template.type || current.type,
121
- main: template.main || current.main,
122
- module: template.module || current.module,
123
- types: template.types || current.types,
124
- exports: template.exports || current.exports,
125
- bin: template.bin || current.bin,
126
- files: template.files || current.files,
127
- engines: template.engines || current.engines,
128
- // 合并脚本 (模板优先)
129
- scripts: {
130
- ...(current.scripts || {}),
131
- ...(template.scripts || {})
132
- },
133
- // 合并依赖 (模板版本优先)
134
- dependencies: {
135
- ...(current.dependencies || {}),
136
- ...(template.dependencies || {})
137
- },
138
- devDependencies: {
139
- ...(current.devDependencies || {}),
140
- ...(template.devDependencies || {})
141
- },
142
- peerDependencies: {
143
- ...(current.peerDependencies || {}),
144
- ...(template.peerDependencies || {})
145
- },
146
- optionalDependencies: {
147
- ...(current.optionalDependencies || {}),
148
- ...(template.optionalDependencies || {})
149
- }
88
+ name: current.name ?? template.name,
89
+ version: current.version ?? template.version,
90
+ description: current.description ?? template.description,
91
+ author: current.author ?? template.author,
92
+ license: current.license ?? template.license,
93
+ repository: current.repository ?? template.repository,
94
+ homepage: current.homepage ?? template.homepage,
95
+ bugs: current.bugs ?? template.bugs,
96
+ keywords: current.keywords ?? template.keywords,
97
+ type: template.type ?? current.type,
98
+ main: template.main ?? current.main,
99
+ module: template.module ?? current.module,
100
+ types: template.types ?? current.types,
101
+ exports: template.exports ?? current.exports,
102
+ bin: template.bin ?? current.bin,
103
+ files: template.files ?? current.files,
104
+ engines: template.engines ?? current.engines,
105
+ scripts: { ...(current.scripts ?? {}), ...(template.scripts ?? {}) },
106
+ dependencies: { ...(current.dependencies ?? {}), ...(template.dependencies ?? {}) },
107
+ devDependencies: { ...(current.devDependencies ?? {}), ...(template.devDependencies ?? {}) },
108
+ peerDependencies: { ...(current.peerDependencies ?? {}), ...(template.peerDependencies ?? {}) },
109
+ optionalDependencies: { ...(current.optionalDependencies ?? {}), ...(template.optionalDependencies ?? {}) }
150
110
  };
151
- // 复制其他字段
152
111
  for (const key of Object.keys(template)) {
153
- if (!(key in merged)) {
112
+ if (!(key in merged))
154
113
  merged[key] = template[key];
155
- }
156
114
  }
157
115
  // 清理空对象
158
116
  for (const key of Object.keys(merged)) {
159
- const value = merged[key];
160
- if (value && typeof value === 'object' && Object.keys(value).length === 0) {
117
+ const v = merged[key];
118
+ if (v && typeof v === 'object' && !Array.isArray(v) && Object.keys(v).length === 0) {
161
119
  delete merged[key];
162
120
  }
163
121
  }
164
122
  platform_1.platform.writeJson(targetPath, merged);
165
123
  return { success: true, message: '已智能合并' };
166
124
  }
167
- catch (error) {
125
+ catch {
168
126
  platform_1.platform.copyFile(templatePath, targetPath);
169
127
  return { success: true, message: '已覆盖 (合并失败)' };
170
128
  }
171
129
  }
172
- /**
173
- * 合并普通 JSON 文件
174
- */
175
- mergeJson(templatePath, currentPath, targetPath) {
130
+ async mergeJson(templatePath, currentPath, targetPath) {
176
131
  try {
177
- const template = platform_1.platform.readJson(templatePath);
178
- const current = platform_1.platform.readJson(currentPath);
132
+ const [template, current] = await Promise.all([
133
+ platform_1.platform.readJsonAsync(templatePath),
134
+ platform_1.platform.readJsonAsync(currentPath)
135
+ ]);
179
136
  if (!template || !current) {
180
137
  platform_1.platform.copyFile(templatePath, targetPath);
181
138
  return { success: true, message: '已覆盖' };
182
139
  }
183
- // 深度合并
184
- const merged = this.deepMerge(current, template);
185
- platform_1.platform.writeJson(targetPath, merged);
140
+ platform_1.platform.writeJson(targetPath, this.deepMerge(current, template));
186
141
  return { success: true, message: '已合并' };
187
142
  }
188
143
  catch {
@@ -190,34 +145,21 @@ class Merger {
190
145
  return { success: true, message: '已覆盖' };
191
146
  }
192
147
  }
193
- /**
194
- * 深度合并对象
195
- */
196
148
  deepMerge(target, source) {
197
149
  const result = { ...target };
198
150
  for (const key of Object.keys(source)) {
199
- const sourceValue = source[key];
200
- const targetValue = target[key];
201
- if (sourceValue &&
202
- typeof sourceValue === 'object' &&
203
- !Array.isArray(sourceValue) &&
204
- targetValue &&
205
- typeof targetValue === 'object' &&
206
- !Array.isArray(targetValue)) {
207
- result[key] = this.deepMerge(targetValue, sourceValue);
151
+ const s = source[key], t = target[key];
152
+ if (s && typeof s === 'object' && !Array.isArray(s) && t && typeof t === 'object' && !Array.isArray(t)) {
153
+ result[key] = this.deepMerge(t, s);
208
154
  }
209
155
  else {
210
- result[key] = sourceValue;
156
+ result[key] = s;
211
157
  }
212
158
  }
213
159
  return result;
214
160
  }
215
- /**
216
- * 设置合并策略
217
- */
218
161
  setStrategy(pattern, strategy) {
219
162
  this.strategies[pattern] = strategy;
220
163
  }
221
164
  }
222
165
  exports.Merger = Merger;
223
- //# sourceMappingURL=merger.js.map