Skip to content

Commit 8059efa

Browse files
author
zhaowenhao
committed
chore: release v1.1.8
同步版本号到 1.1.8,补充 1.1.8 发版说明,更新忽略规则并准备 macOS 双架构发布产物。
1 parent ae9999a commit 8059efa

5 files changed

Lines changed: 152 additions & 72 deletions

File tree

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,5 @@ dist-ssr
2525
release
2626
dist-electron
2727
package-lock.json
28+
feature/
29+
CLAUDE.md

RELEASE_NOTES_1.1.8.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Rest Code v1.1.8 发版说明
2+
3+
## 版本概览
4+
5+
v1.1.8 重点增强了 DSL 对标量类型的表达能力,并进一步统一了参数契约语法,降低脚本编写与代码生成时的歧义。
6+
7+
## 主要变更
8+
9+
### 1) 新增标量响应类型表达
10+
11+
新增以下响应契约,支持直接表达标量结果:
12+
13+
- `>#``Result<Long>`
14+
- `>$``Result<String>`
15+
- `>!``Result<Boolean>`
16+
- `>~``Result<BigDecimal>`
17+
18+
同时支持对应 List 变体:
19+
20+
- `>=#``Result<List<Long>>`
21+
- `>=$``Result<List<String>>`
22+
- `>=!``Result<List<Boolean>>`
23+
- `>=~``Result<List<BigDecimal>>`
24+
25+
### 2) RequestBody 标量语法统一
26+
27+
将历史表达迁移并统一为:
28+
29+
- `@# / @$``@=# / @=$`
30+
31+
并复用为单标量 RequestBody 的统一语法入口,减少同类场景下的记忆负担。
32+
33+
### 3) 新增 Query 标量参数与数组表达
34+
35+
新增 Query 标量参数:
36+
37+
- `?!`(Boolean)
38+
- `?~`(BigDecimal)
39+
40+
新增 Query 标量数组:
41+
42+
- `?=# / ?=$ / ?=! / ?=~`
43+
44+
用于更精确表达查询场景下的基础类型与集合类型输入。
45+
46+
### 4) 语法细节修正
47+
48+
- 修复 `@PathVariable` 语法,移除不必要引号,简化参数定义。
49+
- 同步更新文档示例,保证文档与实现一致。
50+
51+
## 兼容性说明
52+
53+
- 本次更新以 DSL 表达能力增强和语法统一为主。
54+
- 建议在升级后优先检查旧脚本中 `@# / @$` 的使用并迁移至 `@=# / @=$`
55+
56+
## 关联提交(节选)
57+
58+
- `bd4f048` 新增标量响应类型、RequestBody 标量统一、Query 标量参数与数组表达
59+
- `ae9999a` 修复 `@PathVariable` 语法并更新示例
60+
61+
---
62+
63+
如在迁移过程中遇到兼容性问题,建议先用最小脚本验证单条契约,再逐步回归到完整业务脚本。

electron/main.ts

Lines changed: 84 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
import { app, ipcMain, dialog, BrowserWindow, Menu, shell } from 'electron';
1+
import { app, ipcMain, dialog, BrowserWindow, Menu, shell } from "electron";
22
import path from "path";
3-
import { fileURLToPath } from 'url';
4-
import https from 'https';
3+
import { fileURLToPath } from "url";
4+
import https from "https";
55

66
// 重建 __dirname
77
const __filename = fileURLToPath(import.meta.url);
88
const __dirname = path.dirname(__filename);
99

1010
// 应用版本和更新相关
11-
const CURRENT_VERSION = '1.1.7';
12-
const UPDATE_CHECK_URL = 'https://api.github.com/repos/dhslegen/rest-code/releases/latest';
11+
const CURRENT_VERSION = "1.1.8";
12+
const UPDATE_CHECK_URL =
13+
"https://api.github.com/repos/dhslegen/rest-code/releases/latest";
1314

1415
let win: BrowserWindow | null;
1516

@@ -19,33 +20,33 @@ if (!gotTheLock) {
1920
app.quit();
2021
} else {
2122
// 当第二个实例启动时
22-
app.on('second-instance', (_event, argv, _workingDirectory) => {
23+
app.on("second-instance", (_event, argv, _workingDirectory) => {
2324
// 当运行第二个实例时,聚焦到主窗口
2425
if (win) {
2526
if (win.isMinimized()) win.restore();
2627
win.focus();
2728

2829
// Windows 平台下,文件路径作为参数传递
29-
if (process.platform === 'win32' && argv.length >= 2) {
30+
if (process.platform === "win32" && argv.length >= 2) {
3031
const filePath = argv[argv.length - 1];
31-
if (filePath && filePath.endsWith('.rcs')) {
32-
win.webContents.send('open-file', filePath);
32+
if (filePath && filePath.endsWith(".rcs")) {
33+
win.webContents.send("open-file", filePath);
3334
}
3435
}
3536
}
3637
});
3738

3839
// macOS 下处理 'open-file' 事件
39-
app.on('open-file', (event, filePath) => {
40+
app.on("open-file", (event, filePath) => {
4041
event.preventDefault();
4142
if (win) {
42-
win.webContents.send('open-file', filePath);
43+
win.webContents.send("open-file", filePath);
4344
} else {
4445
// 如果窗口尚未创建,等待窗口创建后再发送事件
4546
app.whenReady().then(() => {
4647
createWindow();
47-
win!.webContents.once('did-finish-load', () => {
48-
win!.webContents.send('open-file', filePath);
48+
win!.webContents.once("did-finish-load", () => {
49+
win!.webContents.send("open-file", filePath);
4950
});
5051
});
5152
}
@@ -55,11 +56,11 @@ if (!gotTheLock) {
5556
createWindow();
5657

5758
// 应用启动时,处理传入的文件路径(Windows 平台)
58-
if (process.platform === 'win32' && process.argv.length >= 2) {
59+
if (process.platform === "win32" && process.argv.length >= 2) {
5960
const filePath = process.argv[process.argv.length - 1];
60-
if (filePath && filePath.endsWith('.rcs')) {
61-
win!.webContents.once('did-finish-load', () => {
62-
win!.webContents.send('open-file', filePath);
61+
if (filePath && filePath.endsWith(".rcs")) {
62+
win!.webContents.once("did-finish-load", () => {
63+
win!.webContents.send("open-file", filePath);
6364
});
6465
}
6566
}
@@ -75,19 +76,20 @@ function createWindow() {
7576
width: 1250,
7677
height: 925,
7778
frame: false, // 无边框窗口
78-
titleBarStyle: process.platform === 'darwin' ? 'hiddenInset' : undefined, // macOS隐藏标题栏但保留交通灯
79-
trafficLightPosition: process.platform === 'darwin' ? { x: 20, y: 15 } : undefined, // macOS交通灯位置,稍微
79+
titleBarStyle: process.platform === "darwin" ? "hiddenInset" : undefined, // macOS隐藏标题栏但保留交通灯
80+
trafficLightPosition:
81+
process.platform === "darwin" ? { x: 20, y: 15 } : undefined, // macOS交通灯位置,稍微
8082
transparent: false, // 保持不透明,避免性能问题
81-
vibrancy: process.platform === 'darwin' ? 'under-window' : undefined, // macOS毛玻璃效果
82-
backgroundMaterial: process.platform === 'win32' ? 'acrylic' : undefined, // Windows亚克力效果
83+
vibrancy: process.platform === "darwin" ? "under-window" : undefined, // macOS毛玻璃效果
84+
backgroundMaterial: process.platform === "win32" ? "acrylic" : undefined, // Windows亚克力效果
8385
webPreferences: {
8486
preload: path.join(__dirname, "preload.mjs"),
8587
contextIsolation: true,
8688
allowRunningInsecureContent: false,
8789
nodeIntegration: true,
8890
// 禁用开发者工具
89-
devTools: true
90-
}
91+
devTools: true,
92+
},
9193
});
9294

9395
Menu.setApplicationMenu(null);
@@ -103,7 +105,7 @@ function createWindow() {
103105
// 禁用快捷键支持开发者工具
104106
// win.webContents.on('before-input-event', (event, input) => {
105107
// // F12 或 Cmd/Ctrl+Shift+I 打开开发者工具
106-
// if (input.key === 'F12' ||
108+
// if (input.key === 'F12' ||
107109
// (input.control && input.shift && input.key === 'I') ||
108110
// (input.meta && input.alt && input.key === 'I')) {
109111
// win!.webContents.toggleDevTools();
@@ -115,7 +117,7 @@ function createWindow() {
115117
});
116118

117119
// 窗口加载完成后进行自动更新检查
118-
win.webContents.once('did-finish-load', () => {
120+
win.webContents.once("did-finish-load", () => {
119121
// 延迟3秒后检查更新,避免影响启动速度
120122
setTimeout(() => {
121123
autoCheckForUpdates();
@@ -125,67 +127,80 @@ function createWindow() {
125127

126128
ipcMain.handle("showSaveDialog", async () => {
127129
const { filePath } = await dialog.showSaveDialog({
128-
filters: [{ name: "Rcs Files", extensions: ["rcs"] }]
130+
filters: [{ name: "Rcs Files", extensions: ["rcs"] }],
129131
});
130132
return filePath;
131133
});
132134

133135
ipcMain.handle("showOpenDialog", async (_event, options) => {
134136
const { filePaths, canceled } = await dialog.showOpenDialog({
135-
...options
137+
...options,
136138
});
137139
return { filePaths, canceled };
138140
});
139141

140-
ipcMain.handle('appPath', () => {
142+
ipcMain.handle("appPath", () => {
141143
return app.getAppPath();
142144
});
143145

144146
// 更新检查功能
145-
function checkForUpdates(): Promise<{ hasUpdate: boolean; latestVersion?: string; downloadUrl?: string; releaseNotes?: string }> {
147+
function checkForUpdates(): Promise<{
148+
hasUpdate: boolean;
149+
latestVersion?: string;
150+
downloadUrl?: string;
151+
releaseNotes?: string;
152+
}> {
146153
return new Promise((resolve) => {
147-
console.log('开始检查更新,URL:', UPDATE_CHECK_URL);
148-
const req = https.get(UPDATE_CHECK_URL, { headers: { 'User-Agent': 'Rest-Code' } }, (res) => {
149-
let data = '';
150-
res.on('data', (chunk) => data += chunk);
151-
res.on('end', () => {
152-
try {
153-
const release = JSON.parse(data);
154-
console.log('获取到发布信息:', release.tag_name, release.name);
155-
const latestVersion = release.tag_name?.replace('v', '') || release.name;
156-
const hasUpdate = compareVersions(latestVersion, CURRENT_VERSION) > 0;
157-
158-
console.log(`当前版本: ${CURRENT_VERSION}, 最新版本: ${latestVersion}, 需要更新: ${hasUpdate}`);
159-
160-
resolve({
161-
hasUpdate,
162-
latestVersion,
163-
downloadUrl: release.html_url,
164-
releaseNotes: release.body
165-
});
166-
} catch (error) {
167-
console.error('解析更新信息失败:', error);
168-
resolve({ hasUpdate: false });
169-
}
170-
});
171-
});
154+
console.log("开始检查更新,URL:", UPDATE_CHECK_URL);
155+
const req = https.get(
156+
UPDATE_CHECK_URL,
157+
{ headers: { "User-Agent": "Rest-Code" } },
158+
(res) => {
159+
let data = "";
160+
res.on("data", (chunk) => (data += chunk));
161+
res.on("end", () => {
162+
try {
163+
const release = JSON.parse(data);
164+
console.log("获取到发布信息:", release.tag_name, release.name);
165+
const latestVersion =
166+
release.tag_name?.replace("v", "") || release.name;
167+
const hasUpdate =
168+
compareVersions(latestVersion, CURRENT_VERSION) > 0;
169+
170+
console.log(
171+
`当前版本: ${CURRENT_VERSION}, 最新版本: ${latestVersion}, 需要更新: ${hasUpdate}`,
172+
);
173+
174+
resolve({
175+
hasUpdate,
176+
latestVersion,
177+
downloadUrl: release.html_url,
178+
releaseNotes: release.body,
179+
});
180+
} catch (error) {
181+
console.error("解析更新信息失败:", error);
182+
resolve({ hasUpdate: false });
183+
}
184+
});
185+
},
186+
);
172187

173-
req.on('error', (error) => {
174-
console.error('检查更新失败:', error);
188+
req.on("error", (error) => {
189+
console.error("检查更新失败:", error);
175190
resolve({ hasUpdate: false });
176191
});
177192

178193
req.setTimeout(10000, () => {
179-
console.log('更新检查超时');
194+
console.log("更新检查超时");
180195
req.destroy();
181196
resolve({ hasUpdate: false });
182197
});
183198
});
184199
}
185200

186201
function compareVersions(version1: string, version2: string): number {
187-
const v1parts = version1.split('.').map(Number);
188-
const v2parts = version2.split('.').map(Number);
202+
const v1parts = version1.split(".").map(Number);
203+
const v2parts = version2.split(".").map(Number);
189204

190205
for (let i = 0; i < Math.max(v1parts.length, v2parts.length); i++) {
191206
const v1part = v1parts[i] || 0;
@@ -205,24 +220,24 @@ async function autoCheckForUpdates() {
205220
// 添加当前版本号到更新信息中
206221
const updateDataWithCurrentVersion = {
207222
...updateInfo,
208-
currentVersion: CURRENT_VERSION
223+
currentVersion: CURRENT_VERSION,
209224
};
210-
win.webContents.send('update-available', updateDataWithCurrentVersion);
225+
win.webContents.send("update-available", updateDataWithCurrentVersion);
211226
}
212227
} catch (error) {
213228
// 静默失败,不显示错误
214-
console.error('检查更新失败:', error);
229+
console.error("检查更新失败:", error);
215230
}
216231
}
217232

218233
// 窗口控制IPC处理器
219-
ipcMain.handle('minimize-window', () => {
234+
ipcMain.handle("minimize-window", () => {
220235
if (win && !win.isDestroyed()) {
221236
win.minimize();
222237
}
223238
});
224239

225-
ipcMain.handle('maximize-window', () => {
240+
ipcMain.handle("maximize-window", () => {
226241
if (win && !win.isDestroyed()) {
227242
if (win.isMaximized()) {
228243
win.unmaximize();
@@ -232,21 +247,21 @@ ipcMain.handle('maximize-window', () => {
232247
}
233248
});
234249

235-
ipcMain.handle('close-window', () => {
250+
ipcMain.handle("close-window", () => {
236251
if (win && !win.isDestroyed()) {
237252
win.close();
238253
}
239254
});
240255

241256
// 更新检查IPC处理器
242-
ipcMain.handle('check-for-updates', async () => {
257+
ipcMain.handle("check-for-updates", async () => {
243258
return await checkForUpdates();
244259
});
245260

246-
ipcMain.handle('get-current-version', () => {
261+
ipcMain.handle("get-current-version", () => {
247262
return CURRENT_VERSION;
248263
});
249264

250-
ipcMain.handle('open-download-page', (_, url: string) => {
265+
ipcMain.handle("open-download-page", (_, url: string) => {
251266
shell.openExternal(url);
252-
});
267+
});

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "rest-code",
33
"private": true,
4-
"version": "1.1.7",
4+
"version": "1.1.8",
55
"author": "zhaowenhao<https://dahaoshen.com>",
66
"description": "Rest Code 是一款基于 Electron 的自动化工具,用于通过简洁的脚本快速生成 REST API 后端代码。",
77
"license": "Apache-2.0",

src/App.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@
260260
<div class="card-content">
261261
<label>当前版本</label>
262262
<a href="javascript:void(0)"
263-
@click="openLink('https://github.com/dhslegen/rest-code/releases/tag/v1.1.7')" class="link-btn">
264-
v1.1.7
263+
@click="openLink('https://github.com/dhslegen/rest-code/releases/tag/v1.1.8')" class="link-btn">
264+
v1.1.8
265265
</a>
266266
</div>
267267
</div>

0 commit comments

Comments
 (0)