koishi-plugin-dew-bot 1.0.244 → 1.0.246
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 +30 -0
- package/lib/index.js +110 -9
- package/lib/shared/face/index.d.ts +5 -0
- package/package.json +5 -1
- package/src/plugin/serverHandel/qqPageMessage.ts +86 -8
- package/src/shared/bot/serviceProto.ts +28 -1
- package/src/shared/face/index.ts +2 -0
package/README.md
CHANGED
|
@@ -21,3 +21,33 @@ plugins:
|
|
|
21
21
|
| 服务器地址 | 游戏服 WebSocket 地址 | `ws://dew-v7-test:3021` |
|
|
22
22
|
|
|
23
23
|
插件会忽略机器人自己发出的消息,避免回显再次上传形成循环。
|
|
24
|
+
|
|
25
|
+
## 发布到 npm
|
|
26
|
+
|
|
27
|
+
在 `bot/external/dew-bot` 目录执行:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm run release
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
脚本会先从 `bot` 工作区执行 `npm run build -- dew-bot`,构建成功后运行 `npm version patch --no-git-tag-version --workspaces=false`,再以 `public` 权限和 `latest` 标签发布到 `https://registry.npmjs.org`。例如 `1.0.245` 会提升为 `1.0.246`,不会创建 Git 提交或标签。发布前需已安装工作区依赖,并登录有该包发布权限的 npm 账号:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm login --registry=https://registry.npmjs.org
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
仅构建并检查包内容,执行:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
npm run release:check
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
这相当于 `npm run release -- --dry-run`,会真实构建并执行 `npm pack --dry-run`,不会提升版本号、生成压缩包或发布到 npm。
|
|
46
|
+
|
|
47
|
+
构建失败时脚本会停止,版本不递增。若递增后发布失败,本地保留新版本,脚本会以非零退出码结束并打印当前版本及重试命令;在插件目录确认该版本的发布状态后,可重试同一版本:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm publish --workspaces=false --access=public --tag=latest --registry=https://registry.npmjs.org
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
重试发布时不要再次运行 `npm run release`,否则会再次递增版本。
|
package/lib/index.js
CHANGED
|
@@ -721,6 +721,11 @@ function pageCommand(command) {
|
|
|
721
721
|
return command.startsWith("/") ? command : `/${command}`;
|
|
722
722
|
}
|
|
723
723
|
__name(pageCommand, "pageCommand");
|
|
724
|
+
function inlineCommandUrl(command) {
|
|
725
|
+
const encoded = encodeURIComponent(pageCommand(command)).replace(/[!'()*]/g, (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
726
|
+
return `mqqapi://aio/inlinecmd?command=${encoded}&enter=true&reply=false`;
|
|
727
|
+
}
|
|
728
|
+
__name(inlineCommandUrl, "inlineCommandUrl");
|
|
724
729
|
function pageCommandLines(nav) {
|
|
725
730
|
return [
|
|
726
731
|
...nav.previousCommand ? [`上一页:${pageCommand(nav.previousCommand)}`] : [],
|
|
@@ -729,23 +734,90 @@ function pageCommandLines(nav) {
|
|
|
729
734
|
}
|
|
730
735
|
__name(pageCommandLines, "pageCommandLines");
|
|
731
736
|
function renderQQPageMarkdown(data, showGreeting, showCommands) {
|
|
737
|
+
const nav = data.pageNav;
|
|
738
|
+
const entryCommands = new Map(nav?.entries?.map((entry) => [entry.lineIndex, entry.viewCommand]) ?? []);
|
|
739
|
+
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/;
|
|
740
|
+
const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/;
|
|
741
|
+
const title = data.line.find((item) => item.type === 0 /* title */);
|
|
742
|
+
const summaryLine = data.line.find((item) => item.type === 1 /* line */ && pagePattern.test(item.content));
|
|
743
|
+
const summary = summaryLine && pagePattern.exec(summaryLine.content);
|
|
744
|
+
const listCount = data.line.filter((item) => item.type === 1 /* line */ && listPattern.test(item.content)).length;
|
|
745
|
+
const count = summary?.[1] ?? (nav?.total === 1 ? String(listCount) : void 0);
|
|
746
|
+
const countUnit = summary?.[2] ?? "项";
|
|
747
|
+
const isLeaderboardDirectory = !!nav?.entries?.length && nav.entries.every((entry) => /^排行榜查看\s/.test(entry.viewCommand));
|
|
732
748
|
const sections = [];
|
|
749
|
+
const bodyLines = [];
|
|
750
|
+
const listLines = [];
|
|
751
|
+
const flushBody = /* @__PURE__ */ __name(() => {
|
|
752
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(" \n"));
|
|
753
|
+
}, "flushBody");
|
|
754
|
+
const flushList = /* @__PURE__ */ __name(() => {
|
|
755
|
+
if (listLines.length) sections.push(listLines.splice(0).join(" \n"));
|
|
756
|
+
}, "flushList");
|
|
757
|
+
const flush = /* @__PURE__ */ __name(() => {
|
|
758
|
+
flushList();
|
|
759
|
+
flushBody();
|
|
760
|
+
}, "flush");
|
|
761
|
+
let hasPageSummary = false;
|
|
762
|
+
let hasHelp = false;
|
|
763
|
+
let pageFooter;
|
|
733
764
|
if (showGreeting) sections.push(escapeMarkdown("Ciallo~(∠・ω< )"));
|
|
734
|
-
for (const item of data.line) {
|
|
765
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
735
766
|
switch (item.type) {
|
|
736
767
|
case 0 /* title */:
|
|
737
|
-
|
|
768
|
+
flush();
|
|
769
|
+
if (isLeaderboardDirectory) {
|
|
770
|
+
sections.push(`## ${item.content.includes("🏆") ? "" : "🏆 "}${escapeMarkdown(item.content)}`);
|
|
771
|
+
sections.push(`> 共 ${nav.entries.length} 个榜单 · 点击榜名查看`);
|
|
772
|
+
} else {
|
|
773
|
+
sections.push(`**${escapeMarkdown(item.content)}${count !== void 0 ? ` · ${count} ${countUnit}` : ""}**`);
|
|
774
|
+
}
|
|
738
775
|
break;
|
|
739
|
-
case 1 /* line */:
|
|
740
|
-
|
|
776
|
+
case 1 /* line */: {
|
|
777
|
+
const listEntry = listPattern.exec(item.content);
|
|
778
|
+
if (listEntry) {
|
|
779
|
+
flushBody();
|
|
780
|
+
const command = entryCommands.get(lineIndex);
|
|
781
|
+
const label = escapeMarkdown(listEntry[2]);
|
|
782
|
+
const name2 = command ? `[${label}](${inlineCommandUrl(command)})` : label;
|
|
783
|
+
listLines.push(`${escapeMarkdown(`[${listEntry[1]}]`)} ${name2}`);
|
|
784
|
+
break;
|
|
785
|
+
}
|
|
786
|
+
flushList();
|
|
787
|
+
if (/^\[指令\]相关指令$/.test(item.content)) {
|
|
788
|
+
flushBody();
|
|
789
|
+
hasHelp = true;
|
|
790
|
+
break;
|
|
791
|
+
}
|
|
792
|
+
const page = pagePattern.exec(item.content);
|
|
793
|
+
if (page && nav) {
|
|
794
|
+
flushBody();
|
|
795
|
+
pageFooter = `**第 ${nav.current} / ${nav.total} 页${!title && page[1] ? ` · 共 ${page[1]} ${page[2]}` : ""}**`;
|
|
796
|
+
hasPageSummary = true;
|
|
797
|
+
break;
|
|
798
|
+
}
|
|
799
|
+
bodyLines.push(escapeMarkdown(item.content));
|
|
741
800
|
break;
|
|
801
|
+
}
|
|
742
802
|
case 2 /* error */:
|
|
803
|
+
flush();
|
|
743
804
|
sections.push(`❌ 出错了!错误原因:${escapeMarkdown(item.content)},请反馈至联系开发者`);
|
|
744
805
|
break;
|
|
745
806
|
}
|
|
746
807
|
}
|
|
747
|
-
|
|
748
|
-
|
|
808
|
+
flush();
|
|
809
|
+
if (nav && !hasPageSummary && (nav.total > 1 || nav.previousCommand || nav.nextCommand))
|
|
810
|
+
pageFooter = `**第 ${nav.current} / ${nav.total} 页**`;
|
|
811
|
+
const helpLink = hasHelp ? `[指令](${inlineCommandUrl("指令")})` : void 0;
|
|
812
|
+
const footer = pageFooter ? [pageFooter, helpLink].filter(Boolean).join(" · ") : helpLink ? `更多操作:${helpLink}` : void 0;
|
|
813
|
+
if (footer) {
|
|
814
|
+
if (isLeaderboardDirectory) sections.push("***");
|
|
815
|
+
sections.push(footer);
|
|
816
|
+
}
|
|
817
|
+
if (showCommands && nav) {
|
|
818
|
+
const commands = pageCommandLines(nav);
|
|
819
|
+
if (commands.length) sections.push(`**翻页指令**
|
|
820
|
+
${commands.map(escapeMarkdown).join(" \n")}`);
|
|
749
821
|
}
|
|
750
822
|
return sections.join("\n\n") || " ";
|
|
751
823
|
}
|
|
@@ -783,14 +855,16 @@ async function sendQQPage(session, data, withKeyboard) {
|
|
|
783
855
|
const nav = data.pageNav;
|
|
784
856
|
const buttons = withKeyboard ? buttonsFor(nav, data.userId, session.isDirect) : [];
|
|
785
857
|
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0, buttons.length === 0);
|
|
858
|
+
const hasEntries = !!nav.entries?.length;
|
|
859
|
+
const hasInlineHelp = data.line.some((item) => item.type === 1 /* line */ && item.content === "[指令]相关指令");
|
|
786
860
|
const request = {
|
|
787
861
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
788
862
|
content: "",
|
|
789
863
|
msg_type: 2,
|
|
790
864
|
markdown: {
|
|
791
|
-
content:
|
|
865
|
+
content: !session.isDirect && (buttons.length || hasEntries || hasInlineHelp) ? `${markdown}
|
|
792
866
|
|
|
793
|
-
|
|
867
|
+
点击后如未自动发送,请点发送。` : markdown
|
|
794
868
|
},
|
|
795
869
|
...buttons.length ? { keyboard: { content: { rows: [{ buttons }] } } } : {}
|
|
796
870
|
};
|
|
@@ -912,7 +986,7 @@ var import_tsrpc = require("tsrpc");
|
|
|
912
986
|
|
|
913
987
|
// src/shared/bot/serviceProto.ts
|
|
914
988
|
var serviceProto = {
|
|
915
|
-
"version":
|
|
989
|
+
"version": 10,
|
|
916
990
|
"services": [
|
|
917
991
|
{
|
|
918
992
|
"id": 0,
|
|
@@ -1665,6 +1739,33 @@ var serviceProto = {
|
|
|
1665
1739
|
"type": "String"
|
|
1666
1740
|
},
|
|
1667
1741
|
"optional": true
|
|
1742
|
+
},
|
|
1743
|
+
{
|
|
1744
|
+
"id": 4,
|
|
1745
|
+
"name": "entries",
|
|
1746
|
+
"type": {
|
|
1747
|
+
"type": "Array",
|
|
1748
|
+
"elementType": {
|
|
1749
|
+
"type": "Interface",
|
|
1750
|
+
"properties": [
|
|
1751
|
+
{
|
|
1752
|
+
"id": 0,
|
|
1753
|
+
"name": "lineIndex",
|
|
1754
|
+
"type": {
|
|
1755
|
+
"type": "Number"
|
|
1756
|
+
}
|
|
1757
|
+
},
|
|
1758
|
+
{
|
|
1759
|
+
"id": 1,
|
|
1760
|
+
"name": "viewCommand",
|
|
1761
|
+
"type": {
|
|
1762
|
+
"type": "String"
|
|
1763
|
+
}
|
|
1764
|
+
}
|
|
1765
|
+
]
|
|
1766
|
+
}
|
|
1767
|
+
},
|
|
1768
|
+
"optional": true
|
|
1668
1769
|
}
|
|
1669
1770
|
]
|
|
1670
1771
|
},
|
|
@@ -114,6 +114,11 @@ export interface PageNavData {
|
|
|
114
114
|
total: number;
|
|
115
115
|
previousCommand?: string;
|
|
116
116
|
nextCommand?: string;
|
|
117
|
+
/** 可点击的列表行;lineIndex 是 IMessage.line 的零起始位置。 */
|
|
118
|
+
entries?: Array<{
|
|
119
|
+
lineIndex: number;
|
|
120
|
+
viewCommand: string;
|
|
121
|
+
}>;
|
|
117
122
|
}
|
|
118
123
|
/** 下发给客户端的消息主体 **/
|
|
119
124
|
export interface IMessage {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "koishi-plugin-dew-bot",
|
|
3
3
|
"description": "连游戏服,把聊天消息交给服务器处理",
|
|
4
|
-
"version": "1.0.
|
|
4
|
+
"version": "1.0.246",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"typings": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"src",
|
|
10
10
|
"assets"
|
|
11
11
|
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"release": "node scripts/release.cjs",
|
|
14
|
+
"release:check": "node scripts/release.cjs --dry-run"
|
|
15
|
+
},
|
|
12
16
|
"license": "MIT",
|
|
13
17
|
"keywords": [
|
|
14
18
|
"chatbot",
|
|
@@ -44,6 +44,14 @@ export function pageCommand(command: string): string {
|
|
|
44
44
|
return command.startsWith('/') ? command : `/${command}`
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
function inlineCommandUrl(command: string): string {
|
|
48
|
+
// encodeURIComponent leaves parentheses unescaped, which would close the
|
|
49
|
+
// surrounding Markdown link if an item ID ever contained one.
|
|
50
|
+
const encoded = encodeURIComponent(pageCommand(command)).replace(/[!'()*]/g, character =>
|
|
51
|
+
`%${character.charCodeAt(0).toString(16).toUpperCase()}`)
|
|
52
|
+
return `mqqapi://aio/inlinecmd?command=${encoded}&enter=true&reply=false`
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
export function pageCommandLines(nav: PageNavData): string[] {
|
|
48
56
|
return [
|
|
49
57
|
...(nav.previousCommand ? [`上一页:${pageCommand(nav.previousCommand)}`] : []),
|
|
@@ -52,23 +60,91 @@ export function pageCommandLines(nav: PageNavData): string[] {
|
|
|
52
60
|
}
|
|
53
61
|
|
|
54
62
|
export function renderQQPageMarkdown(data: MsgMessage, showGreeting: boolean, showCommands: boolean): string {
|
|
63
|
+
const nav = data.pageNav
|
|
64
|
+
const entryCommands = new Map(nav?.entries?.map(entry => [entry.lineIndex, entry.viewCommand]) ?? [])
|
|
65
|
+
const listPattern = /^\[(\d+)\]\s*([^\r\n]+)$/
|
|
66
|
+
const pagePattern = /^第\s*\d+\s*\/\s*\d+\s*页(?:\s*[||]\s*共\s*(\d+)\s*([项条]))?$/
|
|
67
|
+
const title = data.line.find(item => item.type === MessageType.title)
|
|
68
|
+
const summaryLine = data.line.find(item => item.type === MessageType.line && pagePattern.test(item.content))
|
|
69
|
+
const summary = summaryLine && pagePattern.exec(summaryLine.content)
|
|
70
|
+
const listCount = data.line.filter(item => item.type === MessageType.line && listPattern.test(item.content)).length
|
|
71
|
+
const count = summary?.[1] ?? (nav?.total === 1 ? String(listCount) : undefined)
|
|
72
|
+
const countUnit = summary?.[2] ?? '项'
|
|
73
|
+
const isLeaderboardDirectory = !!nav?.entries?.length
|
|
74
|
+
&& nav.entries.every(entry => /^排行榜查看\s/.test(entry.viewCommand))
|
|
55
75
|
const sections: string[] = []
|
|
76
|
+
const bodyLines: string[] = []
|
|
77
|
+
const listLines: string[] = []
|
|
78
|
+
const flushBody = () => {
|
|
79
|
+
if (bodyLines.length) sections.push(bodyLines.splice(0).join(' \n'))
|
|
80
|
+
}
|
|
81
|
+
const flushList = () => {
|
|
82
|
+
if (listLines.length) sections.push(listLines.splice(0).join(' \n'))
|
|
83
|
+
}
|
|
84
|
+
const flush = () => { flushList(); flushBody() }
|
|
85
|
+
let hasPageSummary = false
|
|
86
|
+
let hasHelp = false
|
|
87
|
+
let pageFooter: string | undefined
|
|
56
88
|
if (showGreeting) sections.push(escapeMarkdown('Ciallo~(∠・ω< )'))
|
|
57
|
-
for (const item of data.line) {
|
|
89
|
+
for (const [lineIndex, item] of data.line.entries()) {
|
|
58
90
|
switch (item.type) {
|
|
59
91
|
case MessageType.title:
|
|
60
|
-
|
|
92
|
+
flush()
|
|
93
|
+
if (isLeaderboardDirectory) {
|
|
94
|
+
sections.push(`## ${item.content.includes('🏆') ? '' : '🏆 '}${escapeMarkdown(item.content)}`)
|
|
95
|
+
sections.push(`> 共 ${nav!.entries!.length} 个榜单 · 点击榜名查看`)
|
|
96
|
+
} else {
|
|
97
|
+
sections.push(`**${escapeMarkdown(item.content)}${count !== undefined ? ` · ${count} ${countUnit}` : ''}**`)
|
|
98
|
+
}
|
|
61
99
|
break
|
|
62
|
-
case MessageType.line:
|
|
63
|
-
|
|
100
|
+
case MessageType.line: {
|
|
101
|
+
const listEntry = listPattern.exec(item.content)
|
|
102
|
+
if (listEntry) {
|
|
103
|
+
flushBody()
|
|
104
|
+
const command = entryCommands.get(lineIndex)
|
|
105
|
+
const label = escapeMarkdown(listEntry[2])
|
|
106
|
+
const name = command
|
|
107
|
+
? `[${label}](${inlineCommandUrl(command)})`
|
|
108
|
+
: label
|
|
109
|
+
listLines.push(`${escapeMarkdown(`[${listEntry[1]}]`)} ${name}`)
|
|
110
|
+
break
|
|
111
|
+
}
|
|
112
|
+
flushList()
|
|
113
|
+
if (/^\[指令\]相关指令$/.test(item.content)) {
|
|
114
|
+
flushBody()
|
|
115
|
+
hasHelp = true
|
|
116
|
+
break
|
|
117
|
+
}
|
|
118
|
+
const page = pagePattern.exec(item.content)
|
|
119
|
+
if (page && nav) {
|
|
120
|
+
flushBody()
|
|
121
|
+
pageFooter = `**第 ${nav.current} / ${nav.total} 页${!title && page[1] ? ` · 共 ${page[1]} ${page[2]}` : ''}**`
|
|
122
|
+
hasPageSummary = true
|
|
123
|
+
break
|
|
124
|
+
}
|
|
125
|
+
bodyLines.push(escapeMarkdown(item.content))
|
|
64
126
|
break
|
|
127
|
+
}
|
|
65
128
|
case MessageType.error:
|
|
129
|
+
flush()
|
|
66
130
|
sections.push(`❌ 出错了!错误原因:${escapeMarkdown(item.content)},请反馈至联系开发者`)
|
|
67
131
|
break
|
|
68
132
|
}
|
|
69
133
|
}
|
|
70
|
-
|
|
71
|
-
|
|
134
|
+
flush()
|
|
135
|
+
if (nav && !hasPageSummary && (nav.total > 1 || nav.previousCommand || nav.nextCommand))
|
|
136
|
+
pageFooter = `**第 ${nav.current} / ${nav.total} 页**`
|
|
137
|
+
const helpLink = hasHelp ? `[指令](${inlineCommandUrl('指令')})` : undefined
|
|
138
|
+
const footer = pageFooter
|
|
139
|
+
? [pageFooter, helpLink].filter(Boolean).join(' · ')
|
|
140
|
+
: helpLink ? `更多操作:${helpLink}` : undefined
|
|
141
|
+
if (footer) {
|
|
142
|
+
if (isLeaderboardDirectory) sections.push('***')
|
|
143
|
+
sections.push(footer)
|
|
144
|
+
}
|
|
145
|
+
if (showCommands && nav) {
|
|
146
|
+
const commands = pageCommandLines(nav)
|
|
147
|
+
if (commands.length) sections.push(`**翻页指令** \n${commands.map(escapeMarkdown).join(' \n')}`)
|
|
72
148
|
}
|
|
73
149
|
return sections.join('\n\n') || ' '
|
|
74
150
|
}
|
|
@@ -108,13 +184,15 @@ export async function sendQQPage(session: Session, data: MsgMessage, withKeyboar
|
|
|
108
184
|
const nav = data.pageNav!
|
|
109
185
|
const buttons = withKeyboard ? buttonsFor(nav, data.userId, session.isDirect) : []
|
|
110
186
|
const markdown = renderQQPageMarkdown(data, session.event?.channel?.type === 0, buttons.length === 0)
|
|
187
|
+
const hasEntries = !!nav.entries?.length
|
|
188
|
+
const hasInlineHelp = data.line.some(item => item.type === MessageType.line && item.content === '[指令]相关指令')
|
|
111
189
|
const request: QQRequest = {
|
|
112
190
|
// With msg_type=2, QQ requires the ordinary content field to be empty.
|
|
113
191
|
content: '',
|
|
114
192
|
msg_type: 2,
|
|
115
193
|
markdown: {
|
|
116
|
-
content: buttons.length
|
|
117
|
-
? `${markdown}\n\n
|
|
194
|
+
content: !session.isDirect && (buttons.length || hasEntries || hasInlineHelp)
|
|
195
|
+
? `${markdown}\n\n点击后如未自动发送,请点发送。`
|
|
118
196
|
: markdown,
|
|
119
197
|
},
|
|
120
198
|
...(buttons.length ? { keyboard: { content: { rows: [{ buttons }] } } } : {}),
|
|
@@ -20,7 +20,7 @@ export interface ServiceType {
|
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
export const serviceProto: ServiceProto<ServiceType> = {
|
|
23
|
-
"version":
|
|
23
|
+
"version": 10,
|
|
24
24
|
"services": [
|
|
25
25
|
{
|
|
26
26
|
"id": 0,
|
|
@@ -773,6 +773,33 @@ export const serviceProto: ServiceProto<ServiceType> = {
|
|
|
773
773
|
"type": "String"
|
|
774
774
|
},
|
|
775
775
|
"optional": true
|
|
776
|
+
},
|
|
777
|
+
{
|
|
778
|
+
"id": 4,
|
|
779
|
+
"name": "entries",
|
|
780
|
+
"type": {
|
|
781
|
+
"type": "Array",
|
|
782
|
+
"elementType": {
|
|
783
|
+
"type": "Interface",
|
|
784
|
+
"properties": [
|
|
785
|
+
{
|
|
786
|
+
"id": 0,
|
|
787
|
+
"name": "lineIndex",
|
|
788
|
+
"type": {
|
|
789
|
+
"type": "Number"
|
|
790
|
+
}
|
|
791
|
+
},
|
|
792
|
+
{
|
|
793
|
+
"id": 1,
|
|
794
|
+
"name": "viewCommand",
|
|
795
|
+
"type": {
|
|
796
|
+
"type": "String"
|
|
797
|
+
}
|
|
798
|
+
}
|
|
799
|
+
]
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
"optional": true
|
|
776
803
|
}
|
|
777
804
|
]
|
|
778
805
|
},
|
package/src/shared/face/index.ts
CHANGED