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/.env.example ADDED
@@ -0,0 +1,11 @@
1
+ # 示例 .env 配置文件
2
+ # 复制此文件为 .env 并填入你的蓝湖 Cookie 信息
3
+
4
+ # 蓝湖 Session Cookie
5
+ SESSION=your_session_cookie_here
6
+
7
+ # 蓝湖 User Token
8
+ USER_TOKEN=your_user_token_here
9
+
10
+ # 默认团队 ID(可选)
11
+ TID=your_default_team_id
package/README.md ADDED
@@ -0,0 +1,317 @@
1
+ # lanhu-layer-tree
2
+
3
+ 蓝湖设计图图层树提取工具 - 从蓝湖获取设计图列表、图层信息、切图资源等。
4
+
5
+ ## 特性
6
+
7
+ ✅ **完整功能**
8
+ - 获取项目设计图列表
9
+ - 提取图层信息(含文本样式、smartObject、描边、阴影等完整属性)
10
+ - 树形结构输出(支持 Unity/Cocos 坐标系转换)
11
+ - 资源 UUID/GUID 自动解析(Unity .meta / Cocos .meta)
12
+ - 切图列表获取和批量下载
13
+ - 设计图截图下载
14
+
15
+ ✅ **多 URL 合并**
16
+ - 支持逗号分隔多个 URL
17
+ - 自动计算图层相似度(< 80% 终止)
18
+ - 智能合并图层并标注来源
19
+
20
+ ✅ **Cookie 自动管理**
21
+ - 从 Chrome 自动读取蓝湖 cookie(跨平台支持 macOS/Windows/Linux)
22
+ - 认证失败自动刷新重试
23
+ - 支持手动刷新命令
24
+
25
+ ## 安装
26
+
27
+ ### 全局安装(推荐)
28
+
29
+ ```bash
30
+ npm install -g lanhu-layer-tree
31
+ ```
32
+
33
+ ### 本地开发
34
+
35
+ ```bash
36
+ git clone <repo>
37
+ cd lanhu-layer-tree
38
+ npm install
39
+ npm run build
40
+ npm link
41
+ ```
42
+
43
+ ## 配置
44
+
45
+ ### Cookie 缓存机制
46
+
47
+ 工具采用智能缓存策略,**避免每次都访问 Chrome Keychain**:
48
+
49
+ 1. **首次使用**:从 Chrome 读取 cookie → 自动创建/更新 `.env` 文件
50
+ 2. **后续使用**:直接从 `.env` 读取,无需访问 Chrome
51
+ 3. **认证失败**:自动刷新一次并更新 `.env`
52
+
53
+ ### 方式 1:自动从 Chrome 读取(推荐)
54
+
55
+ 确保 Chrome 已登录 lanhuapp.com,首次运行时会自动读取并保存:
56
+
57
+ ```bash
58
+ # 首次使用或 cookie 过期时,手动刷新
59
+ lanhu refresh-cookie
60
+
61
+ # 或指定 .env 文件路径
62
+ lanhu refresh-cookie /path/to/.env
63
+ ```
64
+
65
+ **首次运行后会自动创建 `.env` 文件,后续无需再访问 Chrome Keychain。**
66
+
67
+ ### 方式 2:手动配置 .env
68
+
69
+ 在项目根目录创建 `.env` 文件:
70
+
71
+ ```env
72
+ SESSION=your_session_cookie
73
+ USER_TOKEN=your_user_token
74
+ TID=your_default_team_id
75
+ ```
76
+
77
+ **如何获取 cookie:**
78
+ 1. Chrome 登录 lanhuapp.com
79
+ 2. 打开开发者工具(F12)→ Application → Cookies → https://lanhuapp.com
80
+ 3. 复制 `session` 和 `user_token` 的值
81
+
82
+ ## 使用
83
+
84
+ ### 1. 列出项目设计图
85
+
86
+ ```bash
87
+ # 基本用法
88
+ lanhu list "https://lanhuapp.com/web/#/item/project/product?pid=xxx&tid=xxx"
89
+
90
+ # 保存到文件
91
+ lanhu list "https://lanhuapp.com/web/#/item/project/product?pid=xxx&tid=xxx" -o designs.json
92
+ ```
93
+
94
+ ### 2. 获取图层信息
95
+
96
+ #### 基本用法
97
+
98
+ ```bash
99
+ # 从完整 URL 获取(自动提取 image_id)
100
+ lanhu layers "https://lanhuapp.com/web/#/item/project/detailDetach?tid=xxx&pid=xxx&image_id=xxx"
101
+
102
+ # 手动指定设计图 ID
103
+ lanhu layers "https://lanhuapp.com/web/#/item/project/product?pid=xxx" design_id_123
104
+ ```
105
+
106
+ #### 树形结构输出
107
+
108
+ ```bash
109
+ # 树形格式
110
+ lanhu layers "https://lanhuapp.com/...&image_id=xxx" --tree
111
+
112
+ # 保存到文件
113
+ lanhu layers "https://lanhuapp.com/...&image_id=xxx" --tree -o layers.txt
114
+ ```
115
+
116
+ #### 引擎坐标系转换
117
+
118
+ ```bash
119
+ # Unity 坐标系(中心原点,Y 向上,锚点 0.5)
120
+ lanhu layers "https://lanhuapp.com/...&image_id=xxx" --tree --engine unity
121
+
122
+ # Cocos 坐标系
123
+ lanhu layers "https://lanhuapp.com/...&image_id=xxx" --tree --engine cocos
124
+ ```
125
+
126
+ #### 资源 UUID 解析
127
+
128
+ ```bash
129
+ # Unity 项目(解析 .meta 中的 guid 和 spriteBorder)
130
+ lanhu layers "https://lanhuapp.com/...&image_id=xxx" \
131
+ --tree \
132
+ --engine unity \
133
+ --assets-dir /path/to/unity/Assets
134
+
135
+ # Cocos 项目(读取或生成 .meta 中的 uuid)
136
+ lanhu layers "https://lanhuapp.com/...&image_id=xxx" \
137
+ --tree \
138
+ --engine cocos \
139
+ --assets-dir /path/to/cocos/assets
140
+ ```
141
+
142
+ **输出示例:**
143
+ ```
144
+ Root
145
+ ├── sp Background uuid[a1b2c3d4] pos[0,0] size[750,1334]
146
+ ├── gp Container pos[0,100] size[700,500]
147
+ │ ├── sp Img_Button uuid[e5f6g7h8] s9[10,10] pos[-200,50] size[200,80]
148
+ │ └── txt T1 Title pos[0,150] size[300,40] style[#333333,28,PingFang SC]
149
+ └── sp Img_Icon uuid[i9j0k1l2] pos[100,-200] size[64,64]
150
+ ```
151
+
152
+ #### 多 URL 合并
153
+
154
+ ```bash
155
+ # 逗号分隔多个 URL
156
+ lanhu layers "url1,url2,url3" --tree -o merged.txt
157
+
158
+ # 从文件读取 URL
159
+ echo "https://lanhuapp.com/...&image_id=xxx" > urls.txt
160
+ lanhu layers @urls.txt --tree
161
+ ```
162
+
163
+ **合并规则:**
164
+ - 自动计算相似度(路径 + 类型 + 名称 + 尺寸)
165
+ - 相似度 < 80% 时终止并提示
166
+ - 以第一个为基准,独有图层标注 `(from <设计名>)`
167
+
168
+ ### 3. 获取切图列表
169
+
170
+ ```bash
171
+ # 查看切图列表(JSON)
172
+ lanhu slices "https://lanhuapp.com/...&image_id=xxx"
173
+
174
+ # 保存列表到文件
175
+ lanhu slices "https://lanhuapp.com/...&image_id=xxx" -o slices.json
176
+
177
+ # 批量下载切图
178
+ lanhu slices "https://lanhuapp.com/...&image_id=xxx" -d ./output
179
+ ```
180
+
181
+ ### 4. 下载设计图截图
182
+
183
+ ```bash
184
+ # 下载到当前目录
185
+ lanhu download "https://lanhuapp.com/...&image_id=xxx"
186
+
187
+ # 指定输出目录
188
+ lanhu download "https://lanhuapp.com/...&image_id=xxx" -d ./screenshots
189
+
190
+ # 指定文件名
191
+ lanhu download "https://lanhuapp.com/...&image_id=xxx" design_id_123 "MyDesign"
192
+ ```
193
+
194
+ ### 5. 刷新 Cookie
195
+
196
+ ```bash
197
+ # 从 Chrome 刷新 cookie 到当前目录 .env
198
+ lanhu refresh-cookie
199
+
200
+ # 指定 .env 文件路径
201
+ lanhu refresh-cookie /path/to/.env
202
+ ```
203
+
204
+ ## 图层命名规范
205
+
206
+ 工具会自动处理以下命名规则:
207
+
208
+ ### 资源图层
209
+ - `Img_ButtonNormal` → 提取资源名 `ButtonNormal.png`
210
+ - `ImgIcon` → 提取资源名 `Icon.png`
211
+ - `Img_Button 拷贝 2` → 自动去除 "拷贝" 后缀
212
+ - `Img_Panel s9-10-10` → 九宫格参数 `s9[10,10]`
213
+
214
+ ### 过滤规则
215
+ - `参考图xxx` → 不导出
216
+ - `fexxx` → 不导出
217
+ - 中文命名资源 → 不解析 UUID
218
+ - `background` → 不解析 UUID
219
+
220
+ ### 输出格式
221
+
222
+ **文本图层:**
223
+ ```
224
+ txt T1 Title pos[x,y] size[w,h] style[#333333,28,PingFang SC,#FF0000,2]
225
+ ↑颜色 ↑字号 ↑字体 ↑描边色 ↑描边宽度
226
+ ```
227
+
228
+ **组图层:**
229
+ ```
230
+ gp Container pos[x,y] size[w,h]
231
+ ```
232
+
233
+ **普通图层:**
234
+ ```
235
+ sp ButtonNormal uuid[a1b2c3d4] s9[10,10] pos[x,y] size[w,h]
236
+ ↑资源UUID/GUID ↑九宫格 ↑位置 ↑尺寸
237
+ ```
238
+
239
+ ## API 使用
240
+
241
+ 也可以作为 Node.js 库使用:
242
+
243
+ ```typescript
244
+ import { LanhuClient, formatLayersTree } from 'lanhu-layer-tree';
245
+
246
+ const client = new LanhuClient({
247
+ cookie: 'your_cookie_here' // 可选,默认从环境变量读取
248
+ });
249
+
250
+ // 获取设计图列表
251
+ const designs = await client.getDesigns(url);
252
+
253
+ // 获取图层信息
254
+ const layers = await client.getDesignLayers(url, designId);
255
+
256
+ // 格式化为树形结构
257
+ const tree = formatLayersTree(
258
+ layers.layers,
259
+ layers.design_name,
260
+ layers.canvas_size.width,
261
+ layers.canvas_size.height,
262
+ {
263
+ engine: 'unity',
264
+ assetsDir: '/path/to/Assets'
265
+ }
266
+ );
267
+
268
+ console.log(tree);
269
+ ```
270
+
271
+ ## 常见问题
272
+
273
+ ### Q: 提示 "未找到蓝湖 cookie"
274
+
275
+ **A:** 两种解决方案:
276
+ 1. 确保 Chrome 已登录 lanhuapp.com,运行 `lanhu refresh-cookie`
277
+ 2. 手动配置 `.env` 文件(参考配置章节)
278
+
279
+ ### Q: 提示 "chrome-cookies-secure 未安装"
280
+
281
+ **A:** 运行 `npm install chrome-cookies-secure`
282
+
283
+ ### Q: macOS 提示 Keychain 权限
284
+
285
+ **A:** 首次使用时 macOS 会弹窗请求访问 Keychain,点击"始终允许"
286
+
287
+ ### Q: 资源 UUID 解析失败
288
+
289
+ **A:** 检查:
290
+ 1. `--assets-dir` 路径是否正确
291
+ 2. 资源文件是否存在(文件名需与图层名匹配)
292
+ 3. Unity 项目需要 `.meta` 文件存在
293
+
294
+ ### Q: 多 URL 合并提示相似度过低
295
+
296
+ **A:** 确保所有设计图具有相似的图层结构(路径、类型、名称)
297
+
298
+ ## 开发
299
+
300
+ ```bash
301
+ # 安装依赖
302
+ npm install
303
+
304
+ # 编译
305
+ npm run build
306
+
307
+ # 开发模式(监听文件变化)
308
+ npm run dev
309
+
310
+ # 本地测试
311
+ npm link
312
+ lanhu --help
313
+ ```
314
+
315
+ ## License
316
+
317
+ MIT
@@ -0,0 +1,38 @@
1
+ /**
2
+ * 资源处理:图片尺寸读取、Cocos/Unity meta 文件处理
3
+ */
4
+ /**
5
+ * 读取 PNG 图片尺寸
6
+ */
7
+ export declare function readPngSize(filePath: string): [number, number];
8
+ /**
9
+ * 读取 JPEG 图片尺寸
10
+ */
11
+ export declare function readJpegSize(filePath: string): [number, number];
12
+ /**
13
+ * 获取图片尺寸(支持 PNG/JPEG/WEBP)
14
+ */
15
+ export declare function getImageSize(filePath: string): [number, number];
16
+ /**
17
+ * 生成 Cocos Creator .meta 文件内容
18
+ */
19
+ export declare function makeCocosMeta(imgPath: string): any;
20
+ /**
21
+ * 从 Cocos .meta 文件中读取 spriteFrame UUID
22
+ */
23
+ export declare function readCocosSpriteUuid(metaPath: string): string | null;
24
+ export interface UnityMetaInfo {
25
+ guid: string;
26
+ sliced: boolean;
27
+ border: [number, number, number, number] | null;
28
+ }
29
+ /**
30
+ * 从 Unity YAML .meta 文件中读取 guid 和 spriteBorder
31
+ * Unity spriteBorder 格式: x=left, y=bottom, z=right, w=top
32
+ */
33
+ export declare function readUnityMeta(metaPath: string): UnityMetaInfo | null;
34
+ /**
35
+ * 在 assetsDir 下递归搜索同名文件
36
+ */
37
+ export declare function findLocalAsset(filename: string, assetsDir: string): string | null;
38
+ //# sourceMappingURL=assets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"AAAA;;GAEG;AAaH;;GAEG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAY9D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAe/D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAyB/D;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CA0ClD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAanE;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACjD;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAmCpE;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAuBjF"}
package/dist/assets.js ADDED
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ /**
3
+ * 资源处理:图片尺寸读取、Cocos/Unity meta 文件处理
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.readPngSize = readPngSize;
40
+ exports.readJpegSize = readJpegSize;
41
+ exports.getImageSize = getImageSize;
42
+ exports.makeCocosMeta = makeCocosMeta;
43
+ exports.readCocosSpriteUuid = readCocosSpriteUuid;
44
+ exports.readUnityMeta = readUnityMeta;
45
+ exports.findLocalAsset = findLocalAsset;
46
+ const fs = __importStar(require("fs"));
47
+ const path = __importStar(require("path"));
48
+ const crypto = __importStar(require("crypto"));
49
+ /**
50
+ * 生成 UUID v4
51
+ */
52
+ function generateUuid() {
53
+ return crypto.randomUUID();
54
+ }
55
+ /**
56
+ * 读取 PNG 图片尺寸
57
+ */
58
+ function readPngSize(filePath) {
59
+ const fd = fs.openSync(filePath, 'r');
60
+ try {
61
+ const buffer = Buffer.alloc(24);
62
+ fs.readSync(fd, buffer, 0, 24, 0);
63
+ // PNG: 8 字节签名 + 4 字节长度 + 4 字节类型 + 4 字节宽 + 4 字节高
64
+ const width = buffer.readUInt32BE(16);
65
+ const height = buffer.readUInt32BE(20);
66
+ return [width, height];
67
+ }
68
+ finally {
69
+ fs.closeSync(fd);
70
+ }
71
+ }
72
+ /**
73
+ * 读取 JPEG 图片尺寸
74
+ */
75
+ function readJpegSize(filePath) {
76
+ const data = fs.readFileSync(filePath);
77
+ let i = 2;
78
+ while (i < data.length) {
79
+ if (data[i] !== 0xff)
80
+ break;
81
+ const marker = data[i + 1];
82
+ const length = data.readUInt16BE(i + 2);
83
+ if (marker === 0xc0 || marker === 0xc1 || marker === 0xc2) {
84
+ const height = data.readUInt16BE(i + 5);
85
+ const width = data.readUInt16BE(i + 7);
86
+ return [width, height];
87
+ }
88
+ i += 2 + length;
89
+ }
90
+ throw new Error(`无法读取 JPEG 尺寸: ${filePath}`);
91
+ }
92
+ /**
93
+ * 获取图片尺寸(支持 PNG/JPEG/WEBP)
94
+ */
95
+ function getImageSize(filePath) {
96
+ const ext = path.extname(filePath).toLowerCase();
97
+ if (ext === '.png')
98
+ return readPngSize(filePath);
99
+ if (ext === '.jpg' || ext === '.jpeg')
100
+ return readJpegSize(filePath);
101
+ // WEBP (VP8)
102
+ const data = Buffer.alloc(30);
103
+ const fd = fs.openSync(filePath, 'r');
104
+ try {
105
+ fs.readSync(fd, data, 0, 30, 0);
106
+ }
107
+ finally {
108
+ fs.closeSync(fd);
109
+ }
110
+ if (data.slice(0, 4).toString() === 'RIFF' &&
111
+ data.slice(8, 12).toString() === 'WEBP' &&
112
+ data.slice(12, 16).toString() === 'VP8 ') {
113
+ const width = data.readUInt16LE(26) & 0x3fff;
114
+ const height = data.readUInt16LE(28) & 0x3fff;
115
+ return [width, height];
116
+ }
117
+ throw new Error(`不支持的图片格式: ${filePath}`);
118
+ }
119
+ /**
120
+ * 生成 Cocos Creator .meta 文件内容
121
+ */
122
+ function makeCocosMeta(imgPath) {
123
+ const [w, h] = getImageSize(imgPath);
124
+ const textureUuid = generateUuid();
125
+ const spriteUuid = generateUuid();
126
+ const stem = path.basename(imgPath, path.extname(imgPath));
127
+ return {
128
+ ver: '2.3.5',
129
+ uuid: textureUuid,
130
+ type: 'sprite',
131
+ wrapMode: 'clamp',
132
+ filterMode: 'bilinear',
133
+ premultiplyAlpha: false,
134
+ genMipmaps: false,
135
+ packable: true,
136
+ width: w,
137
+ height: h,
138
+ platformSettings: {},
139
+ subMetas: {
140
+ [stem]: {
141
+ ver: '1.0.4',
142
+ uuid: spriteUuid,
143
+ rawTextureUuid: textureUuid,
144
+ trimType: 'auto',
145
+ trimThreshold: 1,
146
+ rotated: false,
147
+ offsetX: 0,
148
+ offsetY: 0,
149
+ trimX: 0,
150
+ trimY: 0,
151
+ width: w,
152
+ height: h,
153
+ rawWidth: w,
154
+ rawHeight: h,
155
+ borderTop: 0,
156
+ borderBottom: 0,
157
+ borderLeft: 0,
158
+ borderRight: 0,
159
+ subMetas: {}
160
+ }
161
+ }
162
+ };
163
+ }
164
+ /**
165
+ * 从 Cocos .meta 文件中读取 spriteFrame UUID
166
+ */
167
+ function readCocosSpriteUuid(metaPath) {
168
+ try {
169
+ const text = fs.readFileSync(metaPath, 'utf-8');
170
+ const data = JSON.parse(text);
171
+ const sub = data.subMetas || {};
172
+ const keys = Object.keys(sub);
173
+ if (keys.length > 0) {
174
+ return sub[keys[0]].uuid || null;
175
+ }
176
+ }
177
+ catch {
178
+ // ignore
179
+ }
180
+ return null;
181
+ }
182
+ /**
183
+ * 从 Unity YAML .meta 文件中读取 guid 和 spriteBorder
184
+ * Unity spriteBorder 格式: x=left, y=bottom, z=right, w=top
185
+ */
186
+ function readUnityMeta(metaPath) {
187
+ try {
188
+ const text = fs.readFileSync(metaPath, 'utf-8');
189
+ const guidMatch = text.match(/^guid:\s*([0-9a-f]+)/m);
190
+ if (!guidMatch)
191
+ return null;
192
+ const guid = guidMatch[1];
193
+ let sliced = false;
194
+ let border = null;
195
+ const borderMatch = text.match(/spriteBorder:\s*\{x:\s*([\d.]+),\s*y:\s*([\d.]+),\s*z:\s*([\d.]+),\s*w:\s*([\d.]+)\}/);
196
+ if (borderMatch) {
197
+ const values = [
198
+ parseFloat(borderMatch[1]),
199
+ parseFloat(borderMatch[2]),
200
+ parseFloat(borderMatch[3]),
201
+ parseFloat(borderMatch[4])
202
+ ];
203
+ sliced = values.some(v => v !== 0);
204
+ if (sliced) {
205
+ border = [
206
+ Math.round(values[0]),
207
+ Math.round(values[1]),
208
+ Math.round(values[2]),
209
+ Math.round(values[3])
210
+ ];
211
+ }
212
+ }
213
+ return { guid, sliced, border };
214
+ }
215
+ catch {
216
+ return null;
217
+ }
218
+ }
219
+ /**
220
+ * 在 assetsDir 下递归搜索同名文件
221
+ */
222
+ function findLocalAsset(filename, assetsDir) {
223
+ if (!fs.existsSync(assetsDir))
224
+ return null;
225
+ const stack = [assetsDir];
226
+ while (stack.length > 0) {
227
+ const current = stack.pop();
228
+ let entries;
229
+ try {
230
+ entries = fs.readdirSync(current, { withFileTypes: true });
231
+ }
232
+ catch {
233
+ continue;
234
+ }
235
+ for (const entry of entries) {
236
+ const fullPath = path.join(current, entry.name);
237
+ if (entry.isDirectory()) {
238
+ stack.push(fullPath);
239
+ }
240
+ else if (entry.isFile() && entry.name === filename) {
241
+ return fullPath;
242
+ }
243
+ }
244
+ }
245
+ return null;
246
+ }
247
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../src/assets.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}