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 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.0`,这条是推荐路径,也是 DSH「插件中心」里一键安装的形式。
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 / 名称 / 方法 / URL / baseUrl / 说明 / 请求头(JSON)/ body(JSON)/ 示例参数(JSON)/ 用哪个 token;勾「是登录接口」后展开 tokenPath(如 `data.token`)、注入头(默认 `Authorization`)、前缀(默认 `Bearer `)。
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: '/auth/login 或完整地址,支持 {id}', onChange: (e) => set('url', e.target.value) })),
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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-api-runner",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "DSH 插件:按配置调用后端 HTTP 接口、启停/重启本地开发服务、增量读取日志并等待日志特征,让模型能\"改完自己验\"。",
5
5
  "type": "module",
6
6
  "license": "MIT",