lanhu-layer-tree 1.0.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 (54) hide show
  1. package/.env.example +11 -0
  2. package/README.md +317 -0
  3. package/dist/assets.d.ts +38 -0
  4. package/dist/assets.d.ts.map +1 -0
  5. package/dist/assets.js +247 -0
  6. package/dist/assets.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +322 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/client.d.ts +44 -0
  12. package/dist/client.d.ts.map +1 -0
  13. package/dist/client.js +441 -0
  14. package/dist/client.js.map +1 -0
  15. package/dist/cookie.d.ts +32 -0
  16. package/dist/cookie.d.ts.map +1 -0
  17. package/dist/cookie.js +177 -0
  18. package/dist/cookie.js.map +1 -0
  19. package/dist/formatter.d.ts +6 -0
  20. package/dist/formatter.d.ts.map +1 -0
  21. package/dist/formatter.js +225 -0
  22. package/dist/formatter.js.map +1 -0
  23. package/dist/index.d.ts +5 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +27 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/merger.d.ts +27 -0
  28. package/dist/merger.d.ts.map +1 -0
  29. package/dist/merger.js +141 -0
  30. package/dist/merger.js.map +1 -0
  31. package/dist/resolver.d.ts +27 -0
  32. package/dist/resolver.d.ts.map +1 -0
  33. package/dist/resolver.js +196 -0
  34. package/dist/resolver.js.map +1 -0
  35. package/dist/types.d.ts +85 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +6 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/utils.d.ts +23 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/dist/utils.js +106 -0
  42. package/dist/utils.js.map +1 -0
  43. package/package.json +38 -0
  44. package/src/assets.ts +221 -0
  45. package/src/cli.ts +333 -0
  46. package/src/client.ts +490 -0
  47. package/src/cookie.ts +156 -0
  48. package/src/formatter.ts +251 -0
  49. package/src/index.ts +4 -0
  50. package/src/merger.ts +154 -0
  51. package/src/resolver.ts +195 -0
  52. package/src/types.ts +94 -0
  53. package/src/utils.ts +120 -0
  54. package/tsconfig.json +20 -0
package/dist/cookie.js ADDED
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ /**
3
+ * Cookie 管理:从 Chrome 自动读取蓝湖 cookie,并维护 .env 配置
4
+ */
5
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ var desc = Object.getOwnPropertyDescriptor(m, k);
8
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
9
+ desc = { enumerable: true, get: function() { return m[k]; } };
10
+ }
11
+ Object.defineProperty(o, k2, desc);
12
+ }) : (function(o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ o[k2] = m[k];
15
+ }));
16
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
17
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
18
+ }) : function(o, v) {
19
+ o["default"] = v;
20
+ });
21
+ var __importStar = (this && this.__importStar) || (function () {
22
+ var ownKeys = function(o) {
23
+ ownKeys = Object.getOwnPropertyNames || function (o) {
24
+ var ar = [];
25
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
26
+ return ar;
27
+ };
28
+ return ownKeys(o);
29
+ };
30
+ return function (mod) {
31
+ if (mod && mod.__esModule) return mod;
32
+ var result = {};
33
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
34
+ __setModuleDefault(result, mod);
35
+ return result;
36
+ };
37
+ })();
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.AUTH_ERROR_CODES = void 0;
40
+ exports.buildCookie = buildCookie;
41
+ exports.getLanhuCookiesFromChrome = getLanhuCookiesFromChrome;
42
+ exports.refreshCookieFromChrome = refreshCookieFromChrome;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ /**
46
+ * 从 SESSION/USER_TOKEN/HM_LVT 等环境变量拼装 Cookie 字符串
47
+ *
48
+ * 兼容两种格式:
49
+ * - SESSION 已是完整 cookie(包含 user_token=)→ 直接使用
50
+ * - 否则按字段拼装
51
+ */
52
+ function buildCookie() {
53
+ const sessionValue = process.env.SESSION || '';
54
+ if (sessionValue.includes('user_token=')) {
55
+ return sessionValue;
56
+ }
57
+ const parts = [];
58
+ if (sessionValue)
59
+ parts.push(`session=${sessionValue}`);
60
+ if (process.env.USER_TOKEN)
61
+ parts.push(`user_token=${process.env.USER_TOKEN}`);
62
+ const hmKey = process.env.HM_LVT_KEY || '';
63
+ const hmVal = process.env.HM_LVT_VALUE || '';
64
+ if (hmKey && hmVal)
65
+ parts.push(`${hmKey}=${hmVal}`);
66
+ return parts.join(';');
67
+ }
68
+ /**
69
+ * 从 Chrome 浏览器读取 lanhuapp.com 的 cookie
70
+ *
71
+ * 使用 chrome-cookies-secure 跨平台读取(macOS Keychain / Windows DPAPI / Linux GNOME Keyring)
72
+ */
73
+ async function getLanhuCookiesFromChrome() {
74
+ let chromeCookies;
75
+ try {
76
+ chromeCookies = require('chrome-cookies-secure');
77
+ }
78
+ catch {
79
+ console.warn('⚠️ chrome-cookies-secure 未安装,无法自动刷新 cookie。请运行: npm install chrome-cookies-secure');
80
+ return null;
81
+ }
82
+ const cookies = await new Promise((resolve, reject) => {
83
+ chromeCookies.getCookies('https://lanhuapp.com/', 'object', (err, result) => {
84
+ if (err)
85
+ reject(err);
86
+ else
87
+ resolve(result || {});
88
+ });
89
+ }).catch((err) => {
90
+ console.warn(`⚠️ 从 Chrome 读取 cookie 失败: ${err?.message || err}`);
91
+ return {};
92
+ });
93
+ const session = cookies['session'] || '';
94
+ const userToken = cookies['user_token'] || '';
95
+ if (!session && !userToken) {
96
+ console.warn('⚠️ Chrome 中未找到蓝湖 cookie,请确认 Chrome 中已登录 lanhuapp.com');
97
+ return null;
98
+ }
99
+ let hmKey = '';
100
+ let hmVal = '';
101
+ for (const [name, value] of Object.entries(cookies)) {
102
+ if (name.startsWith('Hm_lvt_')) {
103
+ hmKey = name;
104
+ hmVal = value;
105
+ break;
106
+ }
107
+ }
108
+ return {
109
+ SESSION: session,
110
+ USER_TOKEN: userToken,
111
+ HM_LVT_KEY: hmKey,
112
+ HM_LVT_VALUE: hmVal
113
+ };
114
+ }
115
+ /**
116
+ * 将 cookie 字段写入 .env 文件
117
+ */
118
+ function updateEnvFile(fields, envFile) {
119
+ if (!fs.existsSync(envFile))
120
+ return;
121
+ let content = fs.readFileSync(envFile, 'utf-8');
122
+ for (const [key, val] of Object.entries(fields)) {
123
+ if (!val)
124
+ continue;
125
+ const newLine = `${key}="${val}"`;
126
+ const re = new RegExp(`^${key}=.*$`, 'm');
127
+ if (re.test(content)) {
128
+ content = content.replace(re, newLine);
129
+ }
130
+ else {
131
+ content += `\n${newLine}\n`;
132
+ }
133
+ }
134
+ fs.writeFileSync(envFile, content, 'utf-8');
135
+ }
136
+ /**
137
+ * 从 Chrome 读取蓝湖 cookie,更新 .env 文件,返回拼装好的 cookie 字符串
138
+ */
139
+ async function refreshCookieFromChrome(envPath) {
140
+ const fields = await getLanhuCookiesFromChrome();
141
+ if (!fields)
142
+ return '';
143
+ // 同步到当前进程环境变量,让 buildCookie 后续调用也能读到
144
+ process.env.SESSION = fields.SESSION;
145
+ process.env.USER_TOKEN = fields.USER_TOKEN;
146
+ if (fields.HM_LVT_KEY) {
147
+ process.env.HM_LVT_KEY = fields.HM_LVT_KEY;
148
+ process.env.HM_LVT_VALUE = fields.HM_LVT_VALUE;
149
+ }
150
+ const envFile = envPath || path.resolve(process.cwd(), '.env');
151
+ // 如果 .env 不存在,创建它
152
+ if (!fs.existsSync(envFile)) {
153
+ const content = [
154
+ '# 蓝湖 Cookie 配置(自动生成)',
155
+ `SESSION="${fields.SESSION}"`,
156
+ `USER_TOKEN="${fields.USER_TOKEN}"`,
157
+ fields.HM_LVT_KEY ? `${fields.HM_LVT_KEY}="${fields.HM_LVT_VALUE}"` : '',
158
+ '# TID=your_default_team_id',
159
+ ''
160
+ ].filter(Boolean).join('\n');
161
+ fs.writeFileSync(envFile, content, 'utf-8');
162
+ console.log(`✅ 已从 Chrome 读取蓝湖 cookie 并创建 ${envFile}`);
163
+ }
164
+ else {
165
+ updateEnvFile(fields, envFile);
166
+ console.log(`✅ 已从 Chrome 刷新蓝湖 cookie → ${envFile}`);
167
+ }
168
+ const parts = [`session=${fields.SESSION}`, `user_token=${fields.USER_TOKEN}`];
169
+ if (fields.HM_LVT_KEY)
170
+ parts.push(`${fields.HM_LVT_KEY}=${fields.HM_LVT_VALUE}`);
171
+ return parts.join(';');
172
+ }
173
+ /**
174
+ * 蓝湖认证错误码
175
+ */
176
+ exports.AUTH_ERROR_CODES = new Set(['10000', '10001', '10002', '99999', 'A0001']);
177
+ //# sourceMappingURL=cookie.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cookie.js","sourceRoot":"","sources":["../src/cookie.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { Layer, TreeFormatOptions } from './types';
2
+ /**
3
+ * 将图层列表格式化为树形结构
4
+ */
5
+ export declare function formatLayersTree(layers: Layer[], designName?: string, canvasWidth?: number, canvasHeight?: number, options?: TreeFormatOptions): string;
6
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAqDnD;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,KAAK,EAAE,EACf,UAAU,GAAE,MAAe,EAC3B,WAAW,GAAE,MAAU,EACvB,YAAY,GAAE,MAAU,EACxB,OAAO,GAAE,iBAAsB,GAC9B,MAAM,CA4LR"}
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatLayersTree = formatLayersTree;
4
+ const utils_1 = require("./utils");
5
+ const resolver_1 = require("./resolver");
6
+ /**
7
+ * 翻转同级节点的顺序(保持父子关系不变)
8
+ * 游戏引擎中节点展示逻辑跟 PS 中是相反的,位于树下方的在展示时靠前
9
+ */
10
+ function reverseSiblingOrder(layers) {
11
+ if (!layers || layers.length === 0)
12
+ return [];
13
+ // 分组:按父路径分组同级节点
14
+ const siblingsMap = {};
15
+ layers.forEach(layer => {
16
+ const path = layer.path;
17
+ const parentPath = path.includes('/') ? path.split('/').slice(0, -1).join('/') : '';
18
+ if (!siblingsMap[parentPath]) {
19
+ siblingsMap[parentPath] = [];
20
+ }
21
+ siblingsMap[parentPath].push(layer);
22
+ });
23
+ // 翻转每组同级节点
24
+ Object.keys(siblingsMap).forEach(parentPath => {
25
+ siblingsMap[parentPath].reverse();
26
+ });
27
+ // 重新构建列表(深度优先遍历)
28
+ const result = [];
29
+ const visited = new Set();
30
+ function dfs(parentPath) {
31
+ if (!siblingsMap[parentPath])
32
+ return;
33
+ siblingsMap[parentPath].forEach(layer => {
34
+ const path = layer.path;
35
+ if (visited.has(path))
36
+ return;
37
+ visited.add(path);
38
+ result.push(layer);
39
+ dfs(path);
40
+ });
41
+ }
42
+ dfs('');
43
+ return result;
44
+ }
45
+ const GROUP_TYPES = new Set(['group', 'layerGroup', 'artboard', 'layerSection']);
46
+ /**
47
+ * 将图层列表格式化为树形结构
48
+ */
49
+ function formatLayersTree(layers, designName = 'Root', canvasWidth = 0, canvasHeight = 0, options = {}) {
50
+ if (!layers || layers.length === 0)
51
+ return '';
52
+ // 解析资源 UUID(如果指定了引擎和资源目录)
53
+ let uuidMap = {};
54
+ if (options.engine && options.assetsDir) {
55
+ console.log(`\n🔍 开始解析 ${options.engine.toUpperCase()} 资源 UUID...`);
56
+ if (options.engine === 'unity') {
57
+ uuidMap = (0, resolver_1.resolveLayerAssetsUnity)(layers, options.assetsDir);
58
+ }
59
+ else if (options.engine === 'cocos') {
60
+ uuidMap = (0, resolver_1.resolveLayerAssetsCocos)(layers, options.assetsDir);
61
+ }
62
+ console.log(`✅ 解析完成,共找到 ${Object.keys(uuidMap).length} 个资源\n`);
63
+ }
64
+ const lines = [];
65
+ let textLayerIndex = 1;
66
+ // 过滤掉不需要导出的图层
67
+ const filteredLayers = layers.filter(layer => {
68
+ const name = layer.name.trim();
69
+ return !name.startsWith('参考图') && !name.startsWith('fe');
70
+ });
71
+ // 翻转同级节点顺序
72
+ const reversedLayers = reverseSiblingOrder(filteredLayers);
73
+ // 添加树根
74
+ lines.push(designName);
75
+ // 父节点栈:[(depth, abs_x, abs_y, width, height), ...]
76
+ const parentStack = [];
77
+ reversedLayers.forEach((layer, idx) => {
78
+ const depth = layer.depth;
79
+ let name = layer.name;
80
+ // 过滤掉名称中的"拷贝"及其后面的数字部分
81
+ name = name.replace(/\s*拷贝\s*\d*/g, '').trim();
82
+ // 提取九宫格参数(如 " s9-3-3" → [3,3])
83
+ let s9Params = null;
84
+ const s9Match = name.match(/\s+s9-(\d+)-(\d+)/);
85
+ if (s9Match) {
86
+ s9Params = [parseInt(s9Match[1]), parseInt(s9Match[2])];
87
+ }
88
+ // 过滤掉九宫格标记
89
+ name = name.replace(/\s+s9-\d+-\d+/g, '').trim();
90
+ const ltype = layer.type;
91
+ const width = layer.width;
92
+ const height = layer.height;
93
+ const absX = layer.x;
94
+ const absY = layer.y;
95
+ // 维护父节点栈
96
+ while (parentStack.length > 0 && parentStack[parentStack.length - 1][0] >= depth) {
97
+ parentStack.pop();
98
+ }
99
+ // 计算相对于父节点的坐标
100
+ let relX, relY;
101
+ let parentW, parentH;
102
+ if (parentStack.length > 0) {
103
+ const [, parentAbsX, parentAbsY, pW, pH] = parentStack[parentStack.length - 1];
104
+ relX = absX - parentAbsX;
105
+ relY = absY - parentAbsY;
106
+ parentW = pW;
107
+ parentH = pH;
108
+ }
109
+ else {
110
+ parentW = canvasWidth;
111
+ parentH = canvasHeight;
112
+ relX = absX;
113
+ relY = absY;
114
+ }
115
+ // 坐标系转换
116
+ let x, y;
117
+ if (options.engine && canvasWidth && canvasHeight) {
118
+ [x, y] = (0, utils_1.convertToEnginePos)(relX, relY, width, height, parentW, parentH);
119
+ }
120
+ else {
121
+ x = relX;
122
+ y = relY;
123
+ }
124
+ // 将当前节点加入父节点栈
125
+ parentStack.push([depth, absX, absY, width, height]);
126
+ // 查找资源 UUID(仅对非文本、非组图层)
127
+ let assetInfo = null;
128
+ if (ltype !== 'textLayer' && !GROUP_TYPES.has(ltype)) {
129
+ assetInfo = (0, resolver_1.getAssetInfoForLayer)(layer.name, uuidMap);
130
+ }
131
+ // 构建图层描述
132
+ let desc;
133
+ if (ltype === 'textLayer') {
134
+ // 文本图层
135
+ const textStyle = layer.text_style || {};
136
+ const styleParts = [];
137
+ if (textStyle.fill_color)
138
+ styleParts.push(textStyle.fill_color);
139
+ if (textStyle.font_size)
140
+ styleParts.push(String(Math.round(textStyle.font_size)));
141
+ if (textStyle.font_name)
142
+ styleParts.push(textStyle.font_name);
143
+ if (textStyle.stroke_color)
144
+ styleParts.push(textStyle.stroke_color);
145
+ if (textStyle.stroke_width)
146
+ styleParts.push(String(Math.round(textStyle.stroke_width)));
147
+ desc = `txt T${textLayerIndex} ${name} pos[${x},${y}] size[${width},${height}]`;
148
+ if (styleParts.length > 0) {
149
+ desc += ` style[${styleParts.join(',')}]`;
150
+ }
151
+ textLayerIndex++;
152
+ }
153
+ else if (GROUP_TYPES.has(ltype)) {
154
+ // 组图层
155
+ desc = `gp ${name} pos[${x},${y}] size[${width},${height}]`;
156
+ }
157
+ else {
158
+ // 普通图层
159
+ desc = `sp ${name}`;
160
+ if (assetInfo?.guid) {
161
+ desc += ` uuid[${assetInfo.guid}]`;
162
+ }
163
+ else if (assetInfo?.uuid) {
164
+ desc += ` uuid[${assetInfo.uuid}]`;
165
+ }
166
+ if (assetInfo?.sliced) {
167
+ // 优先使用图层名称中的 s9 参数
168
+ if (s9Params) {
169
+ desc += ` s9[${s9Params[0]},${s9Params[1]}]`;
170
+ }
171
+ else if (assetInfo.border) {
172
+ // border 格式: [left, bottom, right, top]
173
+ const [left, bottom] = assetInfo.border;
174
+ desc += ` s9[${left},${bottom}]`;
175
+ }
176
+ }
177
+ desc += ` pos[${x},${y}] size[${width},${height}]`;
178
+ }
179
+ // 检查是否是最后一个子节点
180
+ let isLastChild = true;
181
+ for (let nextIdx = idx + 1; nextIdx < reversedLayers.length; nextIdx++) {
182
+ const nextDepth = reversedLayers[nextIdx].depth;
183
+ if (nextDepth <= depth) {
184
+ if (nextDepth === depth) {
185
+ isLastChild = false;
186
+ }
187
+ break;
188
+ }
189
+ }
190
+ // 构建前缀
191
+ const prefixParts = [];
192
+ for (let d = 0; d <= depth; d++) {
193
+ if (d === depth) {
194
+ prefixParts.push(isLastChild ? '└── ' : '├── ');
195
+ }
196
+ else {
197
+ // 找到深度为 d 的最近祖先节点
198
+ let ancestorIdx = null;
199
+ for (let prevIdx = idx - 1; prevIdx >= 0; prevIdx--) {
200
+ if (reversedLayers[prevIdx].depth === d) {
201
+ ancestorIdx = prevIdx;
202
+ break;
203
+ }
204
+ }
205
+ // 检查该祖先节点是否还有后续同级兄弟
206
+ let hasSibling = false;
207
+ if (ancestorIdx !== null) {
208
+ for (let checkIdx = ancestorIdx + 1; checkIdx < reversedLayers.length; checkIdx++) {
209
+ const checkDepth = reversedLayers[checkIdx].depth;
210
+ if (checkDepth <= d) {
211
+ if (checkDepth === d) {
212
+ hasSibling = true;
213
+ }
214
+ break;
215
+ }
216
+ }
217
+ }
218
+ prefixParts.push(hasSibling ? '│ ' : ' ');
219
+ }
220
+ }
221
+ lines.push(prefixParts.join('') + desc);
222
+ });
223
+ return lines.join('\n');
224
+ }
225
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../src/formatter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { LanhuClient } from './client';
2
+ export { formatLayersTree } from './formatter';
3
+ export { parseUrl, normalizeColor, convertToEnginePos } from './utils';
4
+ export * from './types';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AACvE,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.convertToEnginePos = exports.normalizeColor = exports.parseUrl = exports.formatLayersTree = exports.LanhuClient = void 0;
18
+ var client_1 = require("./client");
19
+ Object.defineProperty(exports, "LanhuClient", { enumerable: true, get: function () { return client_1.LanhuClient; } });
20
+ var formatter_1 = require("./formatter");
21
+ Object.defineProperty(exports, "formatLayersTree", { enumerable: true, get: function () { return formatter_1.formatLayersTree; } });
22
+ var utils_1 = require("./utils");
23
+ Object.defineProperty(exports, "parseUrl", { enumerable: true, get: function () { return utils_1.parseUrl; } });
24
+ Object.defineProperty(exports, "normalizeColor", { enumerable: true, get: function () { return utils_1.normalizeColor; } });
25
+ Object.defineProperty(exports, "convertToEnginePos", { enumerable: true, get: function () { return utils_1.convertToEnginePos; } });
26
+ __exportStar(require("./types"), exports);
27
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AACpB,yCAA+C;AAAtC,6GAAA,gBAAgB,OAAA;AACzB,iCAAuE;AAA9D,iGAAA,QAAQ,OAAA;AAAE,uGAAA,cAAc,OAAA;AAAE,2GAAA,kBAAkB,OAAA;AACrD,0CAAwB"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * 多 URL 图层合并 - 相似度计算 + 合并
3
+ */
4
+ import { Layer } from './types';
5
+ /**
6
+ * 计算两个图层列表的相似度(0-100)
7
+ *
8
+ * 计算依据:
9
+ * 1. 路径匹配(去除 #ID 后缀的标准化路径)
10
+ * 2. 类型一致性(权重 40%)
11
+ * 3. 名称相似度(权重 30%,完全相等或字符重合度)
12
+ * 4. 尺寸接近度(权重 30%)
13
+ */
14
+ export declare function calculateLayerSimilarity(layers1: Layer[], layers2: Layer[]): number;
15
+ /**
16
+ * 合并多个图层列表
17
+ *
18
+ * 策略:
19
+ * 1. 以第一个图层列表为基准
20
+ * 2. 后续列表中已存在路径的图层跳过(保留第一个版本)
21
+ * 3. 后续列表中独有的图层附加,并在名称后追加 (from <设计名>) 标记来源
22
+ */
23
+ export declare function mergeLayers(layersList: Layer[][], designNames: string[]): {
24
+ layers: Layer[];
25
+ name: string;
26
+ };
27
+ //# sourceMappingURL=merger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merger.d.ts","sourceRoot":"","sources":["../src/merger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAahC;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,MAAM,CA6EnF;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,UAAU,EAAE,KAAK,EAAE,EAAE,EACrB,WAAW,EAAE,MAAM,EAAE,GACpB;IAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAqCnC"}
package/dist/merger.js ADDED
@@ -0,0 +1,141 @@
1
+ "use strict";
2
+ /**
3
+ * 多 URL 图层合并 - 相似度计算 + 合并
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.calculateLayerSimilarity = calculateLayerSimilarity;
7
+ exports.mergeLayers = mergeLayers;
8
+ /**
9
+ * 标准化路径:移除 #ID 后缀
10
+ * 用于支持同名图层匹配
11
+ */
12
+ function normalizePath(path) {
13
+ return path
14
+ .split('/')
15
+ .map(part => (part.includes('#') ? part.split('#')[0] : part))
16
+ .join('/');
17
+ }
18
+ /**
19
+ * 计算两个图层列表的相似度(0-100)
20
+ *
21
+ * 计算依据:
22
+ * 1. 路径匹配(去除 #ID 后缀的标准化路径)
23
+ * 2. 类型一致性(权重 40%)
24
+ * 3. 名称相似度(权重 30%,完全相等或字符重合度)
25
+ * 4. 尺寸接近度(权重 30%)
26
+ */
27
+ function calculateLayerSimilarity(layers1, layers2) {
28
+ if (!layers1 || !layers2 || layers1.length === 0 || layers2.length === 0) {
29
+ return 0;
30
+ }
31
+ const map1 = new Map();
32
+ for (const layer of layers1) {
33
+ const key = normalizePath(layer.path || '');
34
+ if (!map1.has(key))
35
+ map1.set(key, []);
36
+ map1.get(key).push(layer);
37
+ }
38
+ const map2 = new Map();
39
+ for (const layer of layers2) {
40
+ const key = normalizePath(layer.path || '');
41
+ if (!map2.has(key))
42
+ map2.set(key, []);
43
+ map2.get(key).push(layer);
44
+ }
45
+ let matchedCount = 0;
46
+ let totalScore = 0;
47
+ for (const [normPath, list1] of map1) {
48
+ const list2 = map2.get(normPath);
49
+ if (!list2)
50
+ continue;
51
+ for (const layer1 of list1) {
52
+ let bestScore = 0;
53
+ for (const layer2 of list2) {
54
+ let score = 0;
55
+ // 类型匹配(权重 40%)
56
+ if ((layer1.type || '') === (layer2.type || '')) {
57
+ score += 0.4;
58
+ }
59
+ // 名称匹配(权重 30%)
60
+ const name1 = layer1.name || '';
61
+ const name2 = layer2.name || '';
62
+ if (name1 && name1 === name2) {
63
+ score += 0.3;
64
+ }
65
+ else if (name1 && name2) {
66
+ let common = 0;
67
+ for (const c of name1) {
68
+ if (name2.includes(c))
69
+ common++;
70
+ }
71
+ score += 0.3 * (common / Math.max(name1.length, name2.length));
72
+ }
73
+ // 尺寸接近度(权重 30%)
74
+ const w1 = layer1.width || 0;
75
+ const h1 = layer1.height || 0;
76
+ const w2 = layer2.width || 0;
77
+ const h2 = layer2.height || 0;
78
+ if (w1 > 0 && h1 > 0 && w2 > 0 && h2 > 0) {
79
+ const wRatio = Math.min(w1, w2) / Math.max(w1, w2);
80
+ const hRatio = Math.min(h1, h2) / Math.max(h1, h2);
81
+ score += 0.3 * ((wRatio + hRatio) / 2);
82
+ }
83
+ if (score > bestScore)
84
+ bestScore = score;
85
+ }
86
+ if (bestScore > 0.5) {
87
+ matchedCount++;
88
+ totalScore += bestScore;
89
+ }
90
+ }
91
+ }
92
+ const totalLayers = Math.max(layers1.length, layers2.length);
93
+ if (totalLayers === 0)
94
+ return 0;
95
+ const matchRate = matchedCount / totalLayers;
96
+ const avgQuality = matchedCount > 0 ? totalScore / matchedCount : 0;
97
+ return Math.round(matchRate * avgQuality * 100 * 100) / 100;
98
+ }
99
+ /**
100
+ * 合并多个图层列表
101
+ *
102
+ * 策略:
103
+ * 1. 以第一个图层列表为基准
104
+ * 2. 后续列表中已存在路径的图层跳过(保留第一个版本)
105
+ * 3. 后续列表中独有的图层附加,并在名称后追加 (from <设计名>) 标记来源
106
+ */
107
+ function mergeLayers(layersList, designNames) {
108
+ if (!layersList || layersList.length === 0) {
109
+ return { layers: [], name: '' };
110
+ }
111
+ if (layersList.length === 1) {
112
+ return {
113
+ layers: layersList[0],
114
+ name: designNames[0] || 'Root'
115
+ };
116
+ }
117
+ const baseLayers = layersList[0];
118
+ const merged = [...baseLayers];
119
+ const baseMap = new Set();
120
+ for (const layer of baseLayers) {
121
+ baseMap.add(normalizePath(layer.path || ''));
122
+ }
123
+ for (let idx = 1; idx < layersList.length; idx++) {
124
+ const layers = layersList[idx];
125
+ const sourceName = designNames[idx] || `Source${idx + 1}`;
126
+ for (const layer of layers) {
127
+ const key = normalizePath(layer.path || '');
128
+ if (baseMap.has(key))
129
+ continue;
130
+ const newLayer = {
131
+ ...layer,
132
+ name: `${layer.name || ''} (from ${sourceName})`
133
+ };
134
+ merged.push(newLayer);
135
+ baseMap.add(key);
136
+ }
137
+ }
138
+ const mergedName = designNames.length > 0 ? designNames.join(' + ') : 'Merged';
139
+ return { layers: merged, name: mergedName };
140
+ }
141
+ //# sourceMappingURL=merger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"merger.js","sourceRoot":"","sources":["../src/merger.ts"],"names":[],"mappings":"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"}