dsh-api-runner 0.2.0 → 0.2.1
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/README.md +14 -2
- package/client/client.js +18 -2
- package/package.json +1 -1
- package/src/ops.js +1268 -1257
- package/src/project-store.js +350 -334
- package/test/smoke.mjs +114 -0
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ DSH 插件:把「后端接口清单」「本地服务启停」「日志增量
|
|
|
44
44
|
dsh plugin --profile web add dsh-api-runner
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
-
npm 上已发布 `dsh-api-runner@0.2.
|
|
47
|
+
npm 上已发布 `dsh-api-runner@0.2.1`,这条是推荐路径,也是 DSH「插件中心」里一键安装的形式。
|
|
48
48
|
|
|
49
49
|
### 从 GitHub 源码安装
|
|
50
50
|
|
|
@@ -67,6 +67,16 @@ DSH 会把仓库 clone 到 profile 的 `node_modules` 下。写成带包名的
|
|
|
67
67
|
|
|
68
68
|
配置文件、面板数据、已保存的服务配方、日志目录都沿用原路径,升级不需要迁移。
|
|
69
69
|
|
|
70
|
+
### 从 0.2.0 升级
|
|
71
|
+
|
|
72
|
+
0.2.1 修了三个面板数据问题,**同样需要硬刷新页面**:
|
|
73
|
+
|
|
74
|
+
1. **示例参数能回显了**。以前填完保存,再点「编辑」输入框一定是空的(面板只存了解析后的对象,没存原文,回显时又只读原文)。
|
|
75
|
+
2. **保存不再丢 query**。以前面板接口按 id 整体覆盖,只要点一次「保存」,YAML 里配的 `query` 就被抹掉。现在表单里没有的字段会沿用原值。
|
|
76
|
+
3. **新增 query 编辑栏**。以前只能把 `?a=b` 塞进「路径」输入框,但没人会想到这么做。现在有独立的 query(JSON)栏,支持 `{占位}`,清空即删除。
|
|
77
|
+
|
|
78
|
+
数据本身不用迁移:之前被抹掉的 `query` 需要你重新填一次(或从 YAML 恢复)。
|
|
79
|
+
|
|
70
80
|
### 本地开发:link 安装
|
|
71
81
|
|
|
72
82
|
```bash
|
|
@@ -245,7 +255,9 @@ flowchart LR
|
|
|
245
255
|
- 每条接口显示方法徽章、名称、地址(host 弱化、路径强化)、来源徽章(`YAML` = 来自配置文件,无徽章 = 面板新建)、占位参数列表。
|
|
246
256
|
- 行内操作:「测试」(用示例参数调用一次)、「登录并保存」(仅登录接口)、复制地址、清除 token、编辑、删除(只允许删面板自己建的)。
|
|
247
257
|
- 调用结果是一张卡片:状态码、耗时、响应大小,可在「响应 / 响应头 / 请求」之间切换,带复制与关闭。
|
|
248
|
-
- **编辑表单**:id / 名称 / 方法 /
|
|
258
|
+
- **编辑表单**:id / 名称 / 方法 / 路径 / baseUrl / 说明 / **query(JSON)** / 请求头(JSON)/ body(JSON)/ 示例参数(JSON)/ 用哪个 token;勾「是登录接口」后展开 tokenPath(如 `data.token`)、注入头(默认 `Authorization`)、前缀(默认 `Bearer `)。
|
|
259
|
+
- **query 单独一栏**,别把 `?a=b` 塞进「路径」。query 支持 `{占位}`,如 `{"matterCd":"{matterCd}"}`,调用时按参数展开;只写在 query 里的占位符也会出现在下方的「占位参数」提示行。
|
|
260
|
+
- 面板保存时,表单里没有的字段(如 YAML 里的 `query`)会沿用原值,不会被抹掉。
|
|
249
261
|
|
|
250
262
|
**服务页签**
|
|
251
263
|
- 每 5 秒刷新。服务页顶部还有一排**二级页签**(**已接管** / **运行中** / **已保存** / **已忽略**)。这一排样式和顶部「接口 / 服务 / 设置」不同:没有灰底容器,选中项是品牌色实心块,用来区分"页面级"和"分组级"两层导航。一次只看一组,不再纵向堆四块。
|
package/client/client.js
CHANGED
|
@@ -326,7 +326,7 @@ window.__ModuleLoader__.load({
|
|
|
326
326
|
function emptyForm(baseUrl) {
|
|
327
327
|
return {
|
|
328
328
|
id: '', name: '', method: 'GET', url: '', baseUrl: baseUrl || '', description: '',
|
|
329
|
-
headersText: '', bodyText: '', sampleText: '', useToken: '',
|
|
329
|
+
headersText: '', queryText: '', bodyText: '', sampleText: '', useToken: '',
|
|
330
330
|
isLogin: false, tokenPath: 'token', authHeader: 'Authorization', prefix: 'Bearer ',
|
|
331
331
|
timeoutMs: 30000,
|
|
332
332
|
};
|
|
@@ -341,6 +341,7 @@ window.__ModuleLoader__.load({
|
|
|
341
341
|
baseUrl: api.baseUrl || '',
|
|
342
342
|
description: api.description || '',
|
|
343
343
|
headersText: api.headersText || '',
|
|
344
|
+
queryText: api.queryText || '',
|
|
344
345
|
bodyText: api.bodyText || '',
|
|
345
346
|
sampleText: api.sampleText || '',
|
|
346
347
|
useToken: api.useToken || '',
|
|
@@ -372,6 +373,9 @@ window.__ModuleLoader__.load({
|
|
|
372
373
|
else if (value && typeof value === 'object') Object.values(value).forEach(scan);
|
|
373
374
|
};
|
|
374
375
|
scan(api.url);
|
|
376
|
+
// query 里的占位符也要算:只写在 query 里的键,提示行不显示的话用户会以为漏了
|
|
377
|
+
scan(api.queryText);
|
|
378
|
+
if (api.query && typeof api.query === 'object') scan(api.query);
|
|
375
379
|
scan(api.bodyText);
|
|
376
380
|
return [...out];
|
|
377
381
|
}
|
|
@@ -471,9 +475,15 @@ window.__ModuleLoader__.load({
|
|
|
471
475
|
h(Field, { label: '名称' }, h('input', { className: 'ar-in', value: value.name, placeholder: '显示名,留空则用 id', onChange: (e) => set('name', e.target.value) })),
|
|
472
476
|
h(Field, { label: '方法' }, h('select', { className: 'ar-sel', value: value.method, onChange: (e) => set('method', e.target.value) },
|
|
473
477
|
METHODS.map((m) => h('option', { key: m, value: m }, m)))),
|
|
474
|
-
h(Field, { label: '路径' }, h('input', { className: 'ar-in', value: value.url, placeholder: '/
|
|
478
|
+
h(Field, { label: '路径' }, h('input', { className: 'ar-in', value: value.url, placeholder: '/system/library/matter/billList,支持 {id}', onChange: (e) => set('url', e.target.value) })),
|
|
475
479
|
h(Field, { label: 'baseUrl' }, h('input', { className: 'ar-in', value: value.baseUrl, placeholder: '留空则用「设置」里的 baseUrl', onChange: (e) => set('baseUrl', e.target.value) })),
|
|
476
480
|
h(Field, { label: '说明' }, h('input', { className: 'ar-in', value: value.description, onChange: (e) => set('description', e.target.value) })),
|
|
481
|
+
h(Field, { label: 'query', top: true }, h('textarea', {
|
|
482
|
+
className: 'ar-ta',
|
|
483
|
+
value: value.queryText,
|
|
484
|
+
placeholder: '查询参数(JSON),如 {"matterCd":"{matterCd}"};不用把 ?a=b 写进「路径」',
|
|
485
|
+
onChange: (e) => set('queryText', e.target.value),
|
|
486
|
+
})),
|
|
477
487
|
h(Field, { label: '请求头', top: true }, h('textarea', { className: 'ar-ta', value: value.headersText, placeholder: '{"X-Token":"${DEMO_TOKEN}"}', onChange: (e) => set('headersText', e.target.value) })),
|
|
478
488
|
h(Field, { label: 'body', top: true }, h('textarea', { className: 'ar-ta', value: value.bodyText, placeholder: '{"username":"{user}","password":"{pwd}"}', onChange: (e) => set('bodyText', e.target.value) })),
|
|
479
489
|
h(Field, { label: '示例参数', top: true }, h('textarea', { className: 'ar-ta', value: value.sampleText, placeholder: '「测试」按钮用它填 {占位},如 {"user":"alice"}', onChange: (e) => set('sampleText', e.target.value) })),
|
|
@@ -1003,6 +1013,12 @@ window.__ModuleLoader__.load({
|
|
|
1003
1013
|
baseUrl: value.baseUrl.trim(),
|
|
1004
1014
|
description: value.description.trim(),
|
|
1005
1015
|
headers: parseJsonField(value.headersText, '请求头') || {},
|
|
1016
|
+
/**
|
|
1017
|
+
* query / sampleParams 用 `|| {}` 兜底:表单里清空时 parseJsonField 返回
|
|
1018
|
+
* undefined,这里显式给 {},表示「用户明确清空了」,后端才会覆盖旧值;
|
|
1019
|
+
* 若传 undefined 会被当成「本次没提交」,旧值又会被沿用回来。
|
|
1020
|
+
*/
|
|
1021
|
+
query: parseJsonField(value.queryText, 'query') || {},
|
|
1006
1022
|
body: parseJsonField(value.bodyText, 'body'),
|
|
1007
1023
|
sampleParams: parseJsonField(value.sampleText, '示例参数') || {},
|
|
1008
1024
|
useToken: value.useToken,
|