@zjex/git-workflow 0.2.24 → 0.3.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.
- package/.github/workflows/deploy-docs.yml +68 -0
- package/.github/workflows/test.yml +24 -4
- package/.husky/pre-commit +14 -0
- package/README.md +72 -1066
- package/dist/index.js +103 -13
- package/docs/.vitepress/cache/deps/_metadata.json +52 -0
- package/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js +9719 -0
- package/docs/.vitepress/cache/deps/chunk-2CLQ7TTZ.js.map +7 -0
- package/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js +12824 -0
- package/docs/.vitepress/cache/deps/chunk-LE5NDSFD.js.map +7 -0
- package/docs/.vitepress/cache/deps/package.json +3 -0
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js +4505 -0
- package/docs/.vitepress/cache/deps/vitepress___@vue_devtools-api.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js +583 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_core.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js +1352 -0
- package/docs/.vitepress/cache/deps/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js +1665 -0
- package/docs/.vitepress/cache/deps/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js +1813 -0
- package/docs/.vitepress/cache/deps/vitepress___minisearch.js.map +7 -0
- package/docs/.vitepress/cache/deps/vue.js +347 -0
- package/docs/.vitepress/cache/deps/vue.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-2CLQ7TTZ.js +9719 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-2CLQ7TTZ.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-LE5NDSFD.js +12824 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/chunk-LE5NDSFD.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/package.json +3 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vue_devtools-api.js +4505 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vue_devtools-api.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_core.js +583 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_core.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_integrations_useFocusTrap.js +1352 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___@vueuse_integrations_useFocusTrap.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___mark__js_src_vanilla__js.js +1665 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___mark__js_src_vanilla__js.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___minisearch.js +1813 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vitepress___minisearch.js.map +7 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vue.js +347 -0
- package/docs/.vitepress/cache/deps_temp_44e2fb0f/vue.js.map +7 -0
- package/docs/.vitepress/config.ts +167 -0
- package/docs/.vitepress/theme/custom.css +39 -0
- package/docs/.vitepress/theme/index.ts +4 -0
- package/docs/README.md +82 -0
- package/docs/commands/branch.md +468 -0
- package/docs/commands/commit.md +554 -0
- package/docs/commands/config.md +346 -0
- package/docs/commands/index.md +312 -0
- package/docs/commands/interactive.md +384 -0
- package/docs/commands/release.md +300 -0
- package/docs/commands/stash.md +309 -0
- package/docs/commands/tag.md +278 -0
- package/docs/commands/update.md +347 -0
- package/docs/config/ai-config.md +160 -0
- package/docs/config/branch-config.md +133 -0
- package/docs/config/commit-config.md +185 -0
- package/docs/config/config-file.md +776 -0
- package/docs/config/examples.md +279 -0
- package/docs/config/index.md +478 -0
- package/docs/guide/ai-commit.md +576 -0
- package/docs/guide/basic-usage.md +522 -0
- package/docs/guide/best-practices.md +426 -0
- package/docs/guide/branch-management.md +712 -0
- package/docs/guide/getting-started.md +294 -0
- package/docs/guide/index.md +168 -0
- package/docs/guide/installation.md +449 -0
- package/docs/guide/release-management.md +744 -0
- package/docs/guide/stash-management.md +608 -0
- package/docs/guide/tag-management.md +614 -0
- package/docs/index.md +205 -0
- package/docs/public/favicon.svg +21 -0
- package/docs/public/hero-logo.svg +43 -0
- package/docs/public/logo.svg +20 -0
- package/package.json +11 -2
- package/scripts/publish.js +55 -8
- package/scripts/publish.sh +20 -2
- package/scripts/release.sh +20 -2
- package/scripts/update-test-count.js +55 -0
- package/src/ai-service.ts +101 -15
- package/src/commands/init.ts +18 -0
- package/src/config.ts +1 -0
- package/tests/ai-service.test.ts +237 -2
- package/tests/help.test.ts +134 -0
- package/tests/init.test.ts +582 -0
- package/tests/release.test.ts +333 -0
- package/tests/setup.ts +21 -0
- package/tests/stash.test.ts +376 -0
- package/tests/update.test.ts +402 -0
- package/vitest.config.ts +3 -0
- package/zjex-logo.svg +22 -0
- package/zjex-optimized.svg +34 -0
- package/zjex.svg +1 -0
|
@@ -0,0 +1,402 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { existsSync, unlinkSync } from "fs";
|
|
4
|
+
import { homedir } from "os";
|
|
5
|
+
import { join } from "path";
|
|
6
|
+
|
|
7
|
+
// Mock 所有外部依赖
|
|
8
|
+
vi.mock("child_process", () => ({
|
|
9
|
+
execSync: vi.fn(),
|
|
10
|
+
}));
|
|
11
|
+
|
|
12
|
+
vi.mock("fs", () => ({
|
|
13
|
+
existsSync: vi.fn(),
|
|
14
|
+
unlinkSync: vi.fn(),
|
|
15
|
+
}));
|
|
16
|
+
|
|
17
|
+
vi.mock("os", () => ({
|
|
18
|
+
homedir: vi.fn(),
|
|
19
|
+
}));
|
|
20
|
+
|
|
21
|
+
vi.mock("path", () => ({
|
|
22
|
+
join: vi.fn(),
|
|
23
|
+
}));
|
|
24
|
+
|
|
25
|
+
vi.mock("ora", () => ({
|
|
26
|
+
default: vi.fn(() => ({
|
|
27
|
+
start: vi.fn().mockReturnThis(),
|
|
28
|
+
stop: vi.fn().mockReturnThis(),
|
|
29
|
+
succeed: vi.fn().mockReturnThis(),
|
|
30
|
+
fail: vi.fn().mockReturnThis(),
|
|
31
|
+
})),
|
|
32
|
+
}));
|
|
33
|
+
|
|
34
|
+
vi.mock("boxen", () => ({
|
|
35
|
+
default: vi.fn((content: string) => content),
|
|
36
|
+
}));
|
|
37
|
+
|
|
38
|
+
vi.mock("semver", () => ({
|
|
39
|
+
default: {
|
|
40
|
+
gte: vi.fn(),
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
vi.mock("../src/utils.js", () => ({
|
|
45
|
+
colors: {
|
|
46
|
+
bold: (text: string) => text,
|
|
47
|
+
green: (text: string) => text,
|
|
48
|
+
yellow: (text: string) => text,
|
|
49
|
+
red: (text: string) => text,
|
|
50
|
+
dim: (text: string) => text,
|
|
51
|
+
cyan: (text: string) => text,
|
|
52
|
+
},
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
describe("Update 模块测试", () => {
|
|
56
|
+
const mockExecSync = vi.mocked(execSync);
|
|
57
|
+
const mockExistsSync = vi.mocked(existsSync);
|
|
58
|
+
const mockUnlinkSync = vi.mocked(unlinkSync);
|
|
59
|
+
const mockHomedir = vi.mocked(homedir);
|
|
60
|
+
const mockJoin = vi.mocked(join);
|
|
61
|
+
|
|
62
|
+
beforeEach(() => {
|
|
63
|
+
vi.clearAllMocks();
|
|
64
|
+
// Mock console methods
|
|
65
|
+
vi.spyOn(console, "log").mockImplementation(() => {});
|
|
66
|
+
vi.spyOn(process, "exit").mockImplementation(() => {
|
|
67
|
+
throw new Error("process.exit called");
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
// Default mocks
|
|
71
|
+
mockHomedir.mockReturnValue("/home/user");
|
|
72
|
+
mockJoin.mockReturnValue("/home/user/.gw-update-check");
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
afterEach(() => {
|
|
76
|
+
vi.restoreAllMocks();
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe("版本检查", () => {
|
|
80
|
+
it("应该正确获取最新版本", async () => {
|
|
81
|
+
mockExecSync.mockReturnValueOnce("1.2.4\n");
|
|
82
|
+
|
|
83
|
+
const semver = await import("semver");
|
|
84
|
+
vi.mocked(semver.default.gte).mockReturnValue(true);
|
|
85
|
+
|
|
86
|
+
const { update } = await import("../src/commands/update.js");
|
|
87
|
+
|
|
88
|
+
await update("1.2.3");
|
|
89
|
+
|
|
90
|
+
expect(mockExecSync).toHaveBeenCalledWith(
|
|
91
|
+
"npm view @zjex/git-workflow version",
|
|
92
|
+
expect.objectContaining({
|
|
93
|
+
encoding: "utf-8",
|
|
94
|
+
timeout: 3000,
|
|
95
|
+
stdio: ["pipe", "pipe", "ignore"],
|
|
96
|
+
})
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
it("应该处理网络错误", async () => {
|
|
101
|
+
mockExecSync.mockImplementation(() => {
|
|
102
|
+
throw new Error("Network error");
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
const { update } = await import("../src/commands/update.js");
|
|
106
|
+
|
|
107
|
+
await update("1.2.3");
|
|
108
|
+
|
|
109
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("请检查网络连接后重试"));
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it("应该正确比较版本号", async () => {
|
|
113
|
+
mockExecSync
|
|
114
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw (isUsingVolta)
|
|
115
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
116
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
117
|
+
|
|
118
|
+
const semver = await import("semver");
|
|
119
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
120
|
+
|
|
121
|
+
const { update } = await import("../src/commands/update.js");
|
|
122
|
+
|
|
123
|
+
try {
|
|
124
|
+
await update("1.2.3");
|
|
125
|
+
} catch (error) {
|
|
126
|
+
// 期望 process.exit 被调用
|
|
127
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
expect(semver.default.gte).toHaveBeenCalledWith("1.2.3", "1.2.4");
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
describe("Volta 检测", () => {
|
|
135
|
+
it("应该正确检测 Volta 环境", async () => {
|
|
136
|
+
mockExecSync
|
|
137
|
+
.mockReturnValueOnce("/home/user/.volta/bin/gw\n") // which gw (isUsingVolta)
|
|
138
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
139
|
+
.mockReturnValueOnce("update success"); // volta install
|
|
140
|
+
|
|
141
|
+
const semver = await import("semver");
|
|
142
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
143
|
+
|
|
144
|
+
const { update } = await import("../src/commands/update.js");
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
await update("1.2.3");
|
|
148
|
+
} catch (error) {
|
|
149
|
+
// 期望 process.exit 被调用
|
|
150
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
expect(mockExecSync).toHaveBeenCalledWith(
|
|
154
|
+
"volta install @zjex/git-workflow@latest",
|
|
155
|
+
expect.any(Object)
|
|
156
|
+
);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
it("应该正确检测非 Volta 环境", async () => {
|
|
160
|
+
mockExecSync
|
|
161
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
162
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n"); // which gw
|
|
163
|
+
|
|
164
|
+
const semver = await import("semver");
|
|
165
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
166
|
+
|
|
167
|
+
// Mock 更新命令
|
|
168
|
+
mockExecSync.mockReturnValueOnce("update success");
|
|
169
|
+
|
|
170
|
+
const { update } = await import("../src/commands/update.js");
|
|
171
|
+
|
|
172
|
+
try {
|
|
173
|
+
await update("1.2.3");
|
|
174
|
+
} catch (error) {
|
|
175
|
+
// 期望 process.exit 被调用
|
|
176
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
expect(mockExecSync).toHaveBeenCalledWith(
|
|
180
|
+
"npm install -g @zjex/git-workflow@latest",
|
|
181
|
+
expect.any(Object)
|
|
182
|
+
);
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
it("应该处理 which 命令失败", async () => {
|
|
186
|
+
mockExecSync
|
|
187
|
+
.mockImplementationOnce(() => { // which gw (isUsingVolta)
|
|
188
|
+
throw new Error("Command not found");
|
|
189
|
+
})
|
|
190
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
191
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
192
|
+
|
|
193
|
+
const semver = await import("semver");
|
|
194
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
195
|
+
|
|
196
|
+
const { update } = await import("../src/commands/update.js");
|
|
197
|
+
|
|
198
|
+
try {
|
|
199
|
+
await update("1.2.3");
|
|
200
|
+
} catch (error) {
|
|
201
|
+
// 期望 process.exit 被调用
|
|
202
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 应该使用 npm 命令(默认)
|
|
206
|
+
expect(mockExecSync).toHaveBeenCalledWith(
|
|
207
|
+
"npm install -g @zjex/git-workflow@latest",
|
|
208
|
+
expect.any(Object)
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe("更新流程", () => {
|
|
214
|
+
it("应该在已是最新版本时显示提示", async () => {
|
|
215
|
+
mockExecSync
|
|
216
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw (isUsingVolta)
|
|
217
|
+
.mockReturnValueOnce("1.2.3\n"); // npm view (same version)
|
|
218
|
+
|
|
219
|
+
const semver = await import("semver");
|
|
220
|
+
vi.mocked(semver.default.gte).mockReturnValue(true);
|
|
221
|
+
|
|
222
|
+
const { update } = await import("../src/commands/update.js");
|
|
223
|
+
|
|
224
|
+
await update("1.2.3");
|
|
225
|
+
|
|
226
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("✅ 已是最新版本"));
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
it("应该成功执行更新", async () => {
|
|
230
|
+
mockExecSync
|
|
231
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
232
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw
|
|
233
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
234
|
+
|
|
235
|
+
const semver = await import("semver");
|
|
236
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
237
|
+
|
|
238
|
+
const { update } = await import("../src/commands/update.js");
|
|
239
|
+
|
|
240
|
+
try {
|
|
241
|
+
await update("1.2.3");
|
|
242
|
+
} catch (error) {
|
|
243
|
+
// 期望 process.exit 被调用
|
|
244
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("🎉 发现新版本!"));
|
|
248
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("✨ 更新完成!"));
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
it("应该处理更新失败", async () => {
|
|
252
|
+
mockExecSync
|
|
253
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
254
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw
|
|
255
|
+
.mockImplementationOnce(() => { // npm install
|
|
256
|
+
throw new Error("Update failed");
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const semver = await import("semver");
|
|
260
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
261
|
+
|
|
262
|
+
const { update } = await import("../src/commands/update.js");
|
|
263
|
+
|
|
264
|
+
try {
|
|
265
|
+
await update("1.2.3");
|
|
266
|
+
} catch (error) {
|
|
267
|
+
// 期望 process.exit 被调用
|
|
268
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("你可以手动运行以下命令更新"));
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
describe("缓存管理", () => {
|
|
276
|
+
it("应该在更新成功后清理缓存", async () => {
|
|
277
|
+
mockExistsSync.mockReturnValue(true);
|
|
278
|
+
mockExecSync
|
|
279
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
280
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw
|
|
281
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
282
|
+
|
|
283
|
+
const semver = await import("semver");
|
|
284
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
285
|
+
|
|
286
|
+
const { update } = await import("../src/commands/update.js");
|
|
287
|
+
|
|
288
|
+
try {
|
|
289
|
+
await update("1.2.3");
|
|
290
|
+
} catch (error) {
|
|
291
|
+
// 期望 process.exit 被调用
|
|
292
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
expect(mockUnlinkSync).toHaveBeenCalledWith("/home/user/.gw-update-check");
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
it("应该处理缓存文件不存在的情况", async () => {
|
|
299
|
+
mockExistsSync.mockReturnValue(false);
|
|
300
|
+
mockExecSync
|
|
301
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
302
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw
|
|
303
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
304
|
+
|
|
305
|
+
const semver = await import("semver");
|
|
306
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
307
|
+
|
|
308
|
+
const { update } = await import("../src/commands/update.js");
|
|
309
|
+
|
|
310
|
+
try {
|
|
311
|
+
await update("1.2.3");
|
|
312
|
+
} catch (error) {
|
|
313
|
+
// 期望 process.exit 被调用
|
|
314
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
expect(mockUnlinkSync).not.toHaveBeenCalled();
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
it("应该静默处理缓存清理错误", async () => {
|
|
321
|
+
mockExistsSync.mockReturnValue(true);
|
|
322
|
+
mockUnlinkSync.mockImplementation(() => {
|
|
323
|
+
throw new Error("Permission denied");
|
|
324
|
+
});
|
|
325
|
+
|
|
326
|
+
mockExecSync
|
|
327
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
328
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw
|
|
329
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
330
|
+
|
|
331
|
+
const semver = await import("semver");
|
|
332
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
333
|
+
|
|
334
|
+
const { update } = await import("../src/commands/update.js");
|
|
335
|
+
|
|
336
|
+
try {
|
|
337
|
+
await update("1.2.3");
|
|
338
|
+
} catch (error) {
|
|
339
|
+
// 期望 process.exit 被调用,而不是缓存清理错误
|
|
340
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
341
|
+
}
|
|
342
|
+
});
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
describe("用户界面", () => {
|
|
346
|
+
it("应该显示检查更新的提示", async () => {
|
|
347
|
+
mockExecSync.mockReturnValueOnce("1.2.3\n");
|
|
348
|
+
|
|
349
|
+
const semver = await import("semver");
|
|
350
|
+
vi.mocked(semver.default.gte).mockReturnValue(true);
|
|
351
|
+
|
|
352
|
+
const { update } = await import("../src/commands/update.js");
|
|
353
|
+
|
|
354
|
+
await update("1.2.3");
|
|
355
|
+
|
|
356
|
+
expect(console.log).toHaveBeenCalledWith("🔍 检查更新...");
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
it("应该显示版本比较信息", async () => {
|
|
360
|
+
mockExecSync
|
|
361
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw (isUsingVolta)
|
|
362
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
363
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
364
|
+
|
|
365
|
+
const semver = await import("semver");
|
|
366
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
367
|
+
|
|
368
|
+
const { update } = await import("../src/commands/update.js");
|
|
369
|
+
|
|
370
|
+
try {
|
|
371
|
+
await update("1.2.3");
|
|
372
|
+
} catch (error) {
|
|
373
|
+
// 期望 process.exit 被调用
|
|
374
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("1.2.3"));
|
|
378
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("1.2.4"));
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it("应该显示验证命令提示", async () => {
|
|
382
|
+
mockExecSync
|
|
383
|
+
.mockReturnValueOnce("1.2.4\n") // npm view
|
|
384
|
+
.mockReturnValueOnce("/usr/local/bin/gw\n") // which gw
|
|
385
|
+
.mockReturnValueOnce("update success"); // npm install
|
|
386
|
+
|
|
387
|
+
const semver = await import("semver");
|
|
388
|
+
vi.mocked(semver.default.gte).mockReturnValue(false);
|
|
389
|
+
|
|
390
|
+
const { update } = await import("../src/commands/update.js");
|
|
391
|
+
|
|
392
|
+
try {
|
|
393
|
+
await update("1.2.3");
|
|
394
|
+
} catch (error) {
|
|
395
|
+
// 期望 process.exit 被调用
|
|
396
|
+
expect(error).toEqual(new Error("process.exit called"));
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
expect(console.log).toHaveBeenCalledWith(expect.stringContaining("hash -r && gw --version"));
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
});
|
package/vitest.config.ts
CHANGED
package/zjex-logo.svg
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 120 120" width="100" height="100">
|
|
2
|
+
<!-- ZJEX 纯图标版本 - 修复裁切问题,确保内容居中 -->
|
|
3
|
+
|
|
4
|
+
<!-- 交叉图案 - 完美居中,适当缩小 -->
|
|
5
|
+
<g transform="translate(60, 60) scale(0.8) translate(-51, -50)">
|
|
6
|
+
<!-- 蓝色条纹 -->
|
|
7
|
+
<path d="M69.3 59.41l-9.89 9.89L51 77.73 30.46 98.26A6 6 0 0 1 22 89.83L42.56 69.3 51 60.88l9.9-9.9z" fill="#0059cc"/>
|
|
8
|
+
<path d="M102 24.28a6 6 0 0 1-1.75 4.21L77.72 51l-8.42-8.44 22.5-22.5a6 6 0 0 1 10.2 4.22z" fill="#0059cc"/>
|
|
9
|
+
|
|
10
|
+
<!-- 青色条纹 -->
|
|
11
|
+
<path d="M83.64 6a5.94 5.94 0 0 1-1.74 4.21L41.08 51l-8.42-8.42 9.9-9.89L51 24.24 73.48 1.75A6 6 0 0 1 83.64 6z" fill="#00dac7"/>
|
|
12
|
+
<path d="M32.66 59.41L12.13 79.93a6 6 0 0 1-8.42-8.42L24.24 51z" fill="#00dac7"/>
|
|
13
|
+
|
|
14
|
+
<!-- 浅蓝色条纹 -->
|
|
15
|
+
<path d="M51 24.24l-8.42 8.43-22.5-22.5A6 6 0 0 1 24.28 0a5.89 5.89 0 0 1 4.2 1.75z" fill="#00baec"/>
|
|
16
|
+
<path d="M98.25 79.93a5.94 5.94 0 0 1-8.42 0L51 41.09l8.42-8.42 9.9 9.89 8.4 8.44 20.53 20.51a6 6 0 0 1 0 8.42z" fill="#00baec"/>
|
|
17
|
+
|
|
18
|
+
<!-- 深蓝色条纹 -->
|
|
19
|
+
<path d="M51 60.88l-8.44 8.42L1.74 28.49a6 6 0 0 1 8.43-8.43l22.49 22.5L41.08 51z" fill="#00abd8"/>
|
|
20
|
+
<path d="M79.93 98.26a6 6 0 0 1-8.42 0L51 77.73l8.42-8.43 20.51 20.53a6 6 0 0 1 0 8.43z" fill="#00abd8"/>
|
|
21
|
+
</g>
|
|
22
|
+
</svg>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 350 100" width="350" height="100">
|
|
2
|
+
<!-- 修正版本:确保垂直居中对齐 -->
|
|
3
|
+
|
|
4
|
+
<!-- 交叉图案 - 精确垂直居中 -->
|
|
5
|
+
<g transform="translate(50, 50) scale(0.9) translate(-51, -50)">
|
|
6
|
+
<!-- 蓝色条纹 -->
|
|
7
|
+
<path d="M69.3 59.41l-9.89 9.89L51 77.73 30.46 98.26A6 6 0 0 1 22 89.83L42.56 69.3 51 60.88l9.9-9.9z" fill="#0059cc"/>
|
|
8
|
+
<path d="M102 24.28a6 6 0 0 1-1.75 4.21L77.72 51l-8.42-8.44 22.5-22.5a6 6 0 0 1 10.2 4.22z" fill="#0059cc"/>
|
|
9
|
+
|
|
10
|
+
<!-- 青色条纹 -->
|
|
11
|
+
<path d="M83.64 6a5.94 5.94 0 0 1-1.74 4.21L41.08 51l-8.42-8.42 9.9-9.89L51 24.24 73.48 1.75A6 6 0 0 1 83.64 6z" fill="#00dac7"/>
|
|
12
|
+
<path d="M32.66 59.41L12.13 79.93a6 6 0 0 1-8.42-8.42L24.24 51z" fill="#00dac7"/>
|
|
13
|
+
|
|
14
|
+
<!-- 浅蓝色条纹 -->
|
|
15
|
+
<path d="M51 24.24l-8.42 8.43-22.5-22.5A6 6 0 0 1 24.28 0a5.89 5.89 0 0 1 4.2 1.75z" fill="#00baec"/>
|
|
16
|
+
<path d="M98.25 79.93a5.94 5.94 0 0 1-8.42 0L51 41.09l8.42-8.42 9.9 9.89 8.4 8.44 20.53 20.51a6 6 0 0 1 0 8.42z" fill="#00baec"/>
|
|
17
|
+
|
|
18
|
+
<!-- 深蓝色条纹 -->
|
|
19
|
+
<path d="M51 60.88l-8.44 8.42L1.74 28.49a6 6 0 0 1 8.43-8.43l22.49 22.5L41.08 51z" fill="#00abd8"/>
|
|
20
|
+
<path d="M79.93 98.26a6 6 0 0 1-8.42 0L51 77.73l8.42-8.43 20.51 20.53a6 6 0 0 1 0 8.43z" fill="#00abd8"/>
|
|
21
|
+
</g>
|
|
22
|
+
|
|
23
|
+
<!-- ZJEX 文字 - 放大文字,保持垂直居中对齐 -->
|
|
24
|
+
<g transform="translate(120, 78) scale(1.3)" fill="#2d3748">
|
|
25
|
+
<path d="M36.2-46.02L36.2-46.02 36.2-44.72 13.97-1.5 20.73-1.5Q22.95-1.5 25.19-2.21 27.43-2.93 29.35-4.55 31.27-6.17 32.63-8.87 34-11.57 34.45-15.6L34.45-15.6 35.95-15.6Q35.75-13.39 35.75-9.88L35.75-9.88Q35.75-8.38 35.81-5.66 35.88-2.93 36.2 0L36.2 0Q32.63-0.13 28.11-0.16 23.6-0.2 20.02-0.2L20.02-0.2Q15.79-0.2 11.18-0.16 6.57-0.13 2.54 0L2.54 0 2.54-1.3 24.83-44.52 17.81-44.52Q14.56-44.52 11.83-43.32 9.1-42.12 7.28-39.23 5.46-36.34 4.81-31.2L4.81-31.2 3.31-31.2Q3.45-32.11 3.48-33.41 3.51-34.71 3.51-36.14L3.51-36.14Q3.51-37.63 3.41-40.37 3.31-43.09 3.06-46.02L3.06-46.02Q6.31-45.89 10.37-45.86 14.43-45.83 17.68-45.83L17.68-45.83Q22.04-45.83 26.98-45.86 31.92-45.89 36.2-46.02Z"/>
|
|
26
|
+
<path d="M37.64 12.22L37.64 12.22 37.64 10.92Q40.23 10.66 42.05 9.39 43.88 8.13 44.85 5.07 45.83 2.02 45.83-3.51L45.83-3.51 45.83-39.13Q45.83-41.54 45.47-42.67 45.11-43.81 44.07-44.23 43.03-44.66 40.95-44.72L40.95-44.72 40.95-46.02Q42.58-45.95 45.21-45.89 47.84-45.83 50.77-45.83L50.77-45.83Q53.69-45.83 56.45-45.89 59.22-45.95 61.04-46.02L61.04-46.02 61.04-44.72Q59.02-44.66 57.95-44.23 56.88-43.81 56.52-42.67 56.16-41.54 56.16-39.13L56.16-39.13 56.16-15.34Q56.16-12.68 56.16-9.59 56.16-6.5 55.93-3.58 55.7-0.65 55.06 1.63L55.06 1.63Q53.76 6.11 49.43 9.17 45.11 12.22 37.64 12.22Z"/>
|
|
27
|
+
<path d="M99.78-46.02L99.78-46.02Q99.52-43.16 99.42-40.5 99.32-37.83 99.32-36.4L99.32-36.4Q99.32-35.1 99.39-33.93 99.45-32.76 99.52-31.98L99.52-31.98 98.02-31.98Q97.37-36.73 96.01-39.49 94.64-42.25 92.46-43.39 90.29-44.52 87.36-44.52L87.36-44.52 84.7-44.52Q82.75-44.52 81.8-44.2 80.86-43.88 80.54-42.93 80.21-41.99 80.21-39.91L80.21-39.91 80.21-6.11Q80.21-4.09 80.54-3.12 80.86-2.15 81.8-1.82 82.75-1.5 84.7-1.5L84.7-1.5 87.88-1.5Q90.81-1.5 93.05-2.76 95.29-4.03 96.88-7.08 98.48-10.14 99.32-15.34L99.32-15.34 100.81-15.34Q100.62-13.26 100.62-9.88L100.62-9.88Q100.62-8.38 100.69-5.66 100.75-2.93 101.08 0L101.08 0Q97.76-0.13 93.6-0.16 89.44-0.2 86.19-0.2L86.19-0.2Q83.98-0.2 80.34-0.2 76.7-0.2 72.61-0.16 68.51-0.13 65 0L65 0 65-1.3Q67.08-1.43 68.12-1.82 69.16-2.21 69.52-3.38 69.88-4.55 69.88-6.89L69.88-6.89 69.88-39.13Q69.88-41.54 69.52-42.67 69.16-43.81 68.09-44.23 67.02-44.66 65-44.72L65-44.72 65-46.02Q68.51-45.95 72.61-45.89 76.7-45.83 80.34-45.83 83.98-45.83 86.19-45.83L86.19-45.83Q89.18-45.83 92.98-45.86 96.79-45.89 99.78-46.02Z"/>
|
|
28
|
+
<path d="M78.26-23.79L89.64-23.79Q89.64-23.79 89.64-23.14 89.64-22.49 89.64-22.49L89.64-22.49 78.26-22.49Q78.26-22.49 78.26-23.14 78.26-23.79 78.26-23.79L78.26-23.79Z"/>
|
|
29
|
+
<path d="M90.03-32.37L91.52-32.37Q91.26-28.67 91.29-26.71 91.33-24.77 91.33-23.14L91.33-23.14Q91.33-21.52 91.39-19.57 91.46-17.62 91.72-13.91L91.72-13.91 90.22-13.91Q89.9-16.19 89.02-18.14 88.14-20.09 86.52-21.29 84.89-22.49 82.29-22.49L82.29-22.49 82.29-23.79Q84.89-23.79 86.45-25.22 88.01-26.65 88.86-28.63 89.7-30.62 90.03-32.37L90.03-32.37Z"/>
|
|
30
|
+
<path d="M123.44-46.09L123.44-46.09 123.44-44.72Q120.51-44.72 119.7-44.17 118.89-43.62 119.8-42.25L119.8-42.25 145.53-4.62Q146.84-2.79 147.62-2.15 148.4-1.5 149.69-1.36L149.69-1.36 149.69 0Q148.4-0.07 145.93-0.16 143.45-0.26 140.79-0.26L140.79-0.26Q137.87-0.26 134.84-0.16 131.82-0.07 130.32 0L130.32 0 130.32-1.36Q133.31-1.36 134.19-1.79 135.07-2.21 134.16-3.58L134.16-3.58 108.36-41.47Q107.12-43.36 106.34-44.01 105.56-44.66 104.19-44.72L104.19-44.72 104.19-46.09Q105.56-46.02 108.19-45.92 110.83-45.83 113.49-45.83L113.49-45.83Q116.42-45.83 119.11-45.92 121.81-46.02 123.44-46.09Z"/>
|
|
31
|
+
<path d="M113.75-9.23L124.02-23.14Q124.02-23.14 124.28-22.3 124.54-21.45 124.54-21.45L124.54-21.45 118.04-12.54Q115.44-9.04 115.11-6.6 114.79-4.16 116.25-2.83 117.72-1.5 120.58-1.3L120.58-1.3 120.58 0Q119.34-0.07 117.33-0.1 115.31-0.13 113.36-0.16 111.41-0.2 110.31-0.2L110.31-0.2Q106.41-0.2 104.33 0L104.33 0 104.33-1.3Q106.6-2.08 108.94-4.06 111.28-6.04 113.75-9.23L113.75-9.23Z"/>
|
|
32
|
+
<path d="M146.77-46.02L146.77-46.02 146.77-44.72Q144.63-44.13 142.51-42.25 140.4-40.37 138.58-37.9L138.58-37.9 128.05-23.86Q128.05-23.86 127.82-24.7 127.59-25.55 127.59-25.55L127.59-25.55 134.29-34.58Q138-39.33 137.28-41.93 136.56-44.52 132.6-44.72L132.6-44.72 132.6-46.02Q134.49-45.95 136.82-45.89 139.16-45.83 140.79-45.83L140.79-45.83Q144.69-45.83 146.77-46.02Z"/>
|
|
33
|
+
</g>
|
|
34
|
+
</svg>
|
package/zjex.svg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg data-v-0dd9719b="" version="1.0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="100%" height="100%" viewBox="0 0 340.000000 250.000000" preserveAspectRatio="xMidYMid meet" color-interpolation-filters="sRGB" style="margin: auto;"> <rect data-v-0dd9719b="" x="0" y="0" width="100%" height="100%" fill="#fff" fill-opacity="1" class="background"></rect> <rect data-v-0dd9719b="" x="0" y="0" width="100%" height="100%" fill="url(#watermark)" fill-opacity="1" class="watermarklayer"></rect> <g data-v-0dd9719b="" fill="#333" class="icon-text-wrapper icon-svg-group iconsvg" transform="translate(62.92499542236328,95.46575355529785)"><g class="iconsvg-imagesvg" transform="translate(0,0)"><g><rect fill="#333" fill-opacity="0" stroke-width="2" x="0" y="0" width="60" height="59.06848991405534" class="image-rect"></rect> <svg x="0" y="0" width="60" height="59.06848991405534" filtersec="colorsb2691092612" class="image-svg-svg primary" style="overflow: visible;"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0.4385022521018982 -0.000009216904800268821 101.5615005493164 99.98497772216797"><path d="M69.3 59.41l-9.89 9.89L51 77.73 30.46 98.26A6 6 0 0 1 22 89.83L42.56 69.3 51 60.88l9.9-9.9zM102 24.28a6 6 0 0 1-1.75 4.21L77.72 51l-8.42-8.44 22.5-22.5a6 6 0 0 1 10.2 4.22z" fill="#0059cc"></path><path d="M83.64 6a5.94 5.94 0 0 1-1.74 4.21L41.08 51l-8.42-8.42 9.9-9.89L51 24.24 73.48 1.75A6 6 0 0 1 83.64 6zM32.66 59.41L12.13 79.93a6 6 0 0 1-8.42-8.42L24.24 51z" fill="#00dac7"></path><path d="M51 24.24l-8.42 8.43-22.5-22.5A6 6 0 0 1 24.28 0a5.89 5.89 0 0 1 4.2 1.75zM98.25 79.93a5.94 5.94 0 0 1-8.42 0L51 41.09l8.42-8.42 9.9 9.89 8.4 8.44 20.53 20.51a6 6 0 0 1 0 8.42z" fill="#00baec"></path><path d="M51 60.88l-8.44 8.42L1.74 28.49a6 6 0 0 1 8.43-8.43l22.49 22.5L41.08 51zM79.93 98.26a6 6 0 0 1-8.42 0L51 77.73l8.42-8.43 20.51 20.53a6 6 0 0 1 0 8.43z" fill="#00abd8"></path></svg></svg> <!----></g></g> <g transform="translate(67,0.3792438507080078)"><g data-gra="path-name" fill-rule="" class="tp-name iconsvg-namesvg"><g transform="scale(1)"><g><path d="M36.2-46.02L36.2-46.02 36.2-44.72 13.97-1.5 20.73-1.5Q22.95-1.5 25.19-2.21 27.43-2.93 29.35-4.55 31.27-6.17 32.63-8.87 34-11.57 34.45-15.6L34.45-15.6 35.95-15.6Q35.75-13.39 35.75-9.88L35.75-9.88Q35.75-8.38 35.81-5.66 35.88-2.93 36.2 0L36.2 0Q32.63-0.13 28.11-0.16 23.6-0.2 20.02-0.2L20.02-0.2Q15.79-0.2 11.18-0.16 6.57-0.13 2.54 0L2.54 0 2.54-1.3 24.83-44.52 17.81-44.52Q14.56-44.52 11.83-43.32 9.1-42.12 7.28-39.23 5.46-36.34 4.81-31.2L4.81-31.2 3.31-31.2Q3.45-32.11 3.48-33.41 3.51-34.71 3.51-36.14L3.51-36.14Q3.51-37.63 3.41-40.37 3.31-43.09 3.06-46.02L3.06-46.02Q6.31-45.89 10.37-45.86 14.43-45.83 17.68-45.83L17.68-45.83Q22.04-45.83 26.98-45.86 31.92-45.89 36.2-46.02ZM37.64 12.22L37.64 12.22 37.64 10.92Q40.23 10.66 42.05 9.39 43.88 8.13 44.85 5.07 45.83 2.02 45.83-3.51L45.83-3.51 45.83-39.13Q45.83-41.54 45.47-42.67 45.11-43.81 44.07-44.23 43.03-44.66 40.95-44.72L40.95-44.72 40.95-46.02Q42.58-45.95 45.21-45.89 47.84-45.83 50.77-45.83L50.77-45.83Q53.69-45.83 56.45-45.89 59.22-45.95 61.04-46.02L61.04-46.02 61.04-44.72Q59.02-44.66 57.95-44.23 56.88-43.81 56.52-42.67 56.16-41.54 56.16-39.13L56.16-39.13 56.16-15.34Q56.16-12.68 56.16-9.59 56.16-6.5 55.93-3.58 55.7-0.65 55.06 1.63L55.06 1.63Q53.76 6.11 49.43 9.17 45.11 12.22 37.64 12.22ZM99.78-46.02L99.78-46.02Q99.52-43.16 99.42-40.5 99.32-37.83 99.32-36.4L99.32-36.4Q99.32-35.1 99.39-33.93 99.45-32.76 99.52-31.98L99.52-31.98 98.02-31.98Q97.37-36.73 96.01-39.49 94.64-42.25 92.46-43.39 90.29-44.52 87.36-44.52L87.36-44.52 84.7-44.52Q82.75-44.52 81.8-44.2 80.86-43.88 80.54-42.93 80.21-41.99 80.21-39.91L80.21-39.91 80.21-6.11Q80.21-4.09 80.54-3.12 80.86-2.15 81.8-1.82 82.75-1.5 84.7-1.5L84.7-1.5 87.88-1.5Q90.81-1.5 93.05-2.76 95.29-4.03 96.88-7.08 98.48-10.14 99.32-15.34L99.32-15.34 100.81-15.34Q100.62-13.26 100.62-9.88L100.62-9.88Q100.62-8.38 100.69-5.66 100.75-2.93 101.08 0L101.08 0Q97.76-0.13 93.6-0.16 89.44-0.2 86.19-0.2L86.19-0.2Q83.98-0.2 80.34-0.2 76.7-0.2 72.61-0.16 68.51-0.13 65 0L65 0 65-1.3Q67.08-1.43 68.12-1.82 69.16-2.21 69.52-3.38 69.88-4.55 69.88-6.89L69.88-6.89 69.88-39.13Q69.88-41.54 69.52-42.67 69.16-43.81 68.09-44.23 67.02-44.66 65-44.72L65-44.72 65-46.02Q68.51-45.95 72.61-45.89 76.7-45.83 80.34-45.83 83.98-45.83 86.19-45.83L86.19-45.83Q89.18-45.83 92.98-45.86 96.79-45.89 99.78-46.02ZM78.26-23.79L89.64-23.79Q89.64-23.79 89.64-23.14 89.64-22.49 89.64-22.49L89.64-22.49 78.26-22.49Q78.26-22.49 78.26-23.14 78.26-23.79 78.26-23.79L78.26-23.79ZM90.03-32.37L91.52-32.37Q91.26-28.67 91.29-26.71 91.33-24.77 91.33-23.14L91.33-23.14Q91.33-21.52 91.39-19.57 91.46-17.62 91.72-13.91L91.72-13.91 90.22-13.91Q89.9-16.19 89.02-18.14 88.14-20.09 86.52-21.29 84.89-22.49 82.29-22.49L82.29-22.49 82.29-23.79Q84.89-23.79 86.45-25.22 88.01-26.65 88.86-28.63 89.7-30.62 90.03-32.37L90.03-32.37ZM123.44-46.09L123.44-46.09 123.44-44.72Q120.51-44.72 119.7-44.17 118.89-43.62 119.8-42.25L119.8-42.25 145.53-4.62Q146.84-2.79 147.62-2.15 148.4-1.5 149.69-1.36L149.69-1.36 149.69 0Q148.4-0.07 145.93-0.16 143.45-0.26 140.79-0.26L140.79-0.26Q137.87-0.26 134.84-0.16 131.82-0.07 130.32 0L130.32 0 130.32-1.36Q133.31-1.36 134.19-1.79 135.07-2.21 134.16-3.58L134.16-3.58 108.36-41.47Q107.12-43.36 106.34-44.01 105.56-44.66 104.19-44.72L104.19-44.72 104.19-46.09Q105.56-46.02 108.19-45.92 110.83-45.83 113.49-45.83L113.49-45.83Q116.42-45.83 119.11-45.92 121.81-46.02 123.44-46.09ZM113.75-9.23L124.02-23.14Q124.02-23.14 124.28-22.3 124.54-21.45 124.54-21.45L124.54-21.45 118.04-12.54Q115.44-9.04 115.11-6.6 114.79-4.16 116.25-2.83 117.72-1.5 120.58-1.3L120.58-1.3 120.58 0Q119.34-0.07 117.33-0.1 115.31-0.13 113.36-0.16 111.41-0.2 110.31-0.2L110.31-0.2Q106.41-0.2 104.33 0L104.33 0 104.33-1.3Q106.6-2.08 108.94-4.06 111.28-6.04 113.75-9.23L113.75-9.23ZM146.77-46.02L146.77-46.02 146.77-44.72Q144.63-44.13 142.51-42.25 140.4-40.37 138.58-37.9L138.58-37.9 128.05-23.86Q128.05-23.86 127.82-24.7 127.59-25.55 127.59-25.55L127.59-25.55 134.29-34.58Q138-39.33 137.28-41.93 136.56-44.52 132.6-44.72L132.6-44.72 132.6-46.02Q134.49-45.95 136.82-45.89 139.16-45.83 140.79-45.83L140.79-45.83Q144.69-45.83 146.77-46.02Z" transform="translate(-2.5399999618530273, 46.09000015258789)"></path></g> <!----> <!----> <!----> <!----> <!----> <!----> <!----></g></g> <!----></g></g><defs v-gra="od"></defs></svg>
|