@alemonjs/qq-bot 2.1.40 → 2.1.42
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 +1 -1
- package/lib/format.js +2 -2
- package/lib/framework-actions.js +25 -11
- package/lib/index.d.ts +2 -1
- package/lib/index.js +2 -1
- package/lib/markdown.d.ts +25 -0
- package/lib/markdown.js +47 -0
- package/lib/sdk/non-channel-types.d.ts +2 -2
- package/lib/sends.js +5 -5
- package/package.json +11 -4
package/README.md
CHANGED
|
@@ -79,7 +79,7 @@ qq-bot:
|
|
|
79
79
|
| `base_url_gateway` | string | — | 网关域名代理 |
|
|
80
80
|
| `base_url_app_access_token` | string | — | 获取 access_token 的域名代理 |
|
|
81
81
|
| `is_private` | boolean | `false` | 私域机器人,影响默认事件订阅 |
|
|
82
|
-
| `sandbox` | boolean | `false` |
|
|
82
|
+
| `sandbox` | boolean | `false` | 显式使用旧版沙盒域名;默认正式环境使用 api.bot.qq.com |
|
|
83
83
|
| `shard` | number[] | `[0, 1]` | WebSocket 分片 |
|
|
84
84
|
| `intents` | string[] | 自动组装 | 自定义事件订阅,覆盖默认值,见 [intents.ts](./src/sdk/intents.ts);通常省略,不要填空数组 |
|
|
85
85
|
| `autoInteractionAck` | boolean | `true` | 自动确认按钮、快捷菜单事件;关闭后由应用调用 `useInteraction().ack()` |
|
package/lib/format.js
CHANGED
|
@@ -129,10 +129,10 @@ const mdFormatters = {
|
|
|
129
129
|
return `[🔗${value?.text}](${value?.url}) `;
|
|
130
130
|
},
|
|
131
131
|
"MD.image": (value, options) => `\n\n`,
|
|
132
|
-
"MD.mention": (value, options) => {
|
|
132
|
+
"MD.mention": (value, options, context) => {
|
|
133
133
|
const { belong } = options || {};
|
|
134
134
|
if (belong === "channel") return "";
|
|
135
|
-
if (value === "everyone") return "<qqbot-at-everyone />";
|
|
135
|
+
if (value === "everyone") return context === "c2c" ? "" : "<qqbot-at-everyone />";
|
|
136
136
|
if (belong === "user") return `<qqbot-at-user id="${value}" />`;
|
|
137
137
|
return `<qqbot-at-user id="${value}" />`;
|
|
138
138
|
},
|
package/lib/framework-actions.js
CHANGED
|
@@ -21,10 +21,15 @@ const nonEmptyIds = (ids, maximum, name) => {
|
|
|
21
21
|
if (!Array.isArray(ids) || ids.length < 1 || ids.length > maximum || ids.some((id) => typeof id !== "string" || !id)) throw new Error(`Expected 1 to ${maximum} non-empty ${name}`);
|
|
22
22
|
return ids;
|
|
23
23
|
};
|
|
24
|
-
const textLength = (value) =>
|
|
24
|
+
const textLength = (value) => Array.from(value).reduce((length, character) => length + (character.codePointAt(0) <= 127 ? 1 : 2), 0);
|
|
25
|
+
const panelScope = (scope) => {
|
|
26
|
+
if (scope === "direct") return "dm";
|
|
27
|
+
if (scope === "group" || scope === "c2c" || scope === "channel") return scope;
|
|
28
|
+
throw new Error("QQ panel scope must be group, c2c, channel or direct");
|
|
29
|
+
};
|
|
25
30
|
const menuItem = (item, child = false) => {
|
|
26
31
|
const maximum = child ? 14 : 10;
|
|
27
|
-
if (!item.name || textLength(item.name) > maximum) throw new Error(`Menu item name must be at most ${maximum}
|
|
32
|
+
if (!item.name || textLength(item.name) > maximum) throw new Error(`Menu item name must be at most ${maximum} weighted characters`);
|
|
28
33
|
if (child && item.type === "menu") throw new Error("Menu sub-items cannot contain another menu");
|
|
29
34
|
if (item.type === "link" && !item.url.startsWith("https://")) throw new Error("Menu links must use https");
|
|
30
35
|
if (item.type === "menu" && (item.items.length < 1 || item.items.length > 5)) throw new Error("A menu must contain 1 to 5 sub-items");
|
|
@@ -41,14 +46,18 @@ const menuItem = (item, child = false) => {
|
|
|
41
46
|
};
|
|
42
47
|
};
|
|
43
48
|
const validatePanel = (panel) => {
|
|
44
|
-
if (panel.items.length > 20 || panel.remark &&
|
|
49
|
+
if (panel.items.length > 20 || panel.remark && Array.from(panel.remark).length > 255) throw new Error("Panel supports at most 20 items and a 255-character remark");
|
|
45
50
|
for (const item of panel.items) {
|
|
46
51
|
if (!item.name || textLength(item.name) > 14 || item.description && textLength(item.description) > 30) throw new Error("Panel item name/description exceeds its limit");
|
|
47
52
|
if (item.type === "link" && (!item.url || !item.url.startsWith("https://"))) throw new Error("Panel link items require an https URL");
|
|
48
53
|
}
|
|
49
54
|
};
|
|
50
55
|
const validatePanelAudience = (scope, audience, userIds, guildIds) => {
|
|
51
|
-
if (
|
|
56
|
+
if (audience !== void 0 && audience !== "all" && audience !== "specific") throw new Error("QQ panel audience must be all or specific");
|
|
57
|
+
if (scope === "channel" || scope === "dm") {
|
|
58
|
+
if (audience !== void 0 && audience !== "all" || userIds?.length || guildIds?.length) throw new Error("QQ channel/direct panels only support audience: all without audience IDs");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
52
61
|
if (Boolean(userIds?.length) && Boolean(guildIds?.length)) throw new Error("A panel audience cannot mix users and groups");
|
|
53
62
|
if (audience === "specific") nonEmptyIds(scope === "group" ? guildIds : userIds, 20, scope === "group" ? "group IDs" : "user IDs");
|
|
54
63
|
else if (userIds?.length || guildIds?.length) throw new Error("Panel audience IDs require audience: specific");
|
|
@@ -125,10 +134,15 @@ const panelBody = (panel) => ({
|
|
|
125
134
|
version: panel.version
|
|
126
135
|
});
|
|
127
136
|
const fromPanel = (r) => {
|
|
128
|
-
if (![
|
|
137
|
+
if (![
|
|
138
|
+
"group",
|
|
139
|
+
"c2c",
|
|
140
|
+
"channel",
|
|
141
|
+
"dm"
|
|
142
|
+
].includes(r.scope)) throw new Error(`QQ panel scope ${r.scope || "unknown"} is not supported`);
|
|
129
143
|
return {
|
|
130
144
|
id: r.panel_id,
|
|
131
|
-
scope: r.scope,
|
|
145
|
+
scope: r.scope === "dm" ? "direct" : r.scope,
|
|
132
146
|
audience: r.target_type,
|
|
133
147
|
userIds: r.user_openids,
|
|
134
148
|
guildIds: r.group_openids,
|
|
@@ -293,19 +307,19 @@ const handleFrameworkAction = async (client, data, botId) => {
|
|
|
293
307
|
return client.menuPut({ menu: { items: p.menu.items.map(menuItem) } });
|
|
294
308
|
},
|
|
295
309
|
"panel.list": async () => {
|
|
296
|
-
if (!["group", "c2c"].includes(p.scope)) throw new Error("QQ panel scope must be group or c2c");
|
|
297
310
|
const r = await client.panelsList({
|
|
298
|
-
scope: p.scope,
|
|
311
|
+
scope: panelScope(p.scope),
|
|
299
312
|
...pagination(p.pagination)
|
|
300
313
|
});
|
|
301
314
|
return page(r.records.map(fromPanel), r);
|
|
302
315
|
},
|
|
303
316
|
"panel.create": async () => {
|
|
304
317
|
validatePanel(p.panel);
|
|
305
|
-
|
|
318
|
+
const scope = panelScope(p.scope);
|
|
319
|
+
validatePanelAudience(scope, p.audience, p.userIds, p.guildIds);
|
|
306
320
|
return { id: (await client.panelsCreate({
|
|
307
|
-
scope
|
|
308
|
-
target_type: p.audience,
|
|
321
|
+
scope,
|
|
322
|
+
target_type: p.audience ?? "all",
|
|
309
323
|
user_openids: p.userIds,
|
|
310
324
|
group_openids: p.guildIds,
|
|
311
325
|
panel: panelBody(p.panel)
|
package/lib/index.d.ts
CHANGED
|
@@ -6,7 +6,8 @@ import { QQBotAPI } from "./sdk/api.js";
|
|
|
6
6
|
import { useClient, useMode, useValue } from "./hook.js";
|
|
7
7
|
import { QQBotGroupEventMap } from "./sdk/message.group.js";
|
|
8
8
|
import { QQBotPublicEventMap } from "./sdk/message.public.js";
|
|
9
|
+
import { QQMarkdown, QQMarkdownMathOptions, QQMarkdownTask } from "./markdown.js";
|
|
9
10
|
//#region src/index.d.ts
|
|
10
11
|
declare const _default: () => any;
|
|
11
12
|
//#endregion
|
|
12
|
-
export { QQBotAPI as API, type ApiRequestData, type ButtonType, type FileType, type GlobalMuteRule, type GroupAction, type JoinApprovalStrategy, type JoinRequest, type KeyboardType, type MarkdownType, type MemberMuteState, type MessageType, type Options, type QQBotArkData, type QQBotAttachment, type QQBotBlacklistUser, type QQBotGroupEventMap, type QQBotGroupMember, type QQBotInteractionResolved, type QQBotMenu, type QQBotMenuItem, type QQBotMessageContent, type QQBotMessageElement, type QQBotMessageResult, type QQBotMessageUser, type QQBotPage, type QQBotPanel, type QQBotPanelCreate, type QQBotPanelRecord, type QQBotPanelScope, type QQBotPublicEventMap, type QQTextSanitizerOptions, type SetMemberMuteState, type StreamMessageData, type StreamMessageResult, type UploadConfig, type UploadPart, type UploadPartFinishData, type UploadPrepareData, type UploadPrepareResult, type VerifyInfo, _default as default, platform, sanitizeQQText, useClient, useMode, useValue };
|
|
13
|
+
export { QQBotAPI as API, type ApiRequestData, type ButtonType, type FileType, type GlobalMuteRule, type GroupAction, type JoinApprovalStrategy, type JoinRequest, type KeyboardType, type MarkdownType, type MemberMuteState, type MessageType, type Options, type QQBotArkData, type QQBotAttachment, type QQBotBlacklistUser, type QQBotGroupEventMap, type QQBotGroupMember, type QQBotInteractionResolved, type QQBotMenu, type QQBotMenuItem, type QQBotMessageContent, type QQBotMessageElement, type QQBotMessageResult, type QQBotMessageUser, type QQBotPage, type QQBotPanel, type QQBotPanelCreate, type QQBotPanelRecord, type QQBotPanelScope, type QQBotPublicEventMap, QQMarkdown, type QQMarkdownMathOptions, type QQMarkdownTask, type QQTextSanitizerOptions, type SetMemberMuteState, type StreamMessageData, type StreamMessageResult, type UploadConfig, type UploadPart, type UploadPartFinishData, type UploadPrepareData, type UploadPrepareResult, type VerifyInfo, _default as default, platform, sanitizeQQText, useClient, useMode, useValue };
|
package/lib/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import { QQBotAPI } from "./sdk/api.js";
|
|
|
4
4
|
import { start } from "./index.websoket.js";
|
|
5
5
|
import { useClient, useMode, useValue } from "./hook.js";
|
|
6
6
|
import { start as start$1 } from "./index.webhook.js";
|
|
7
|
+
import { QQMarkdown } from "./markdown.js";
|
|
7
8
|
import { definePlatform } from "alemonjs";
|
|
8
9
|
|
|
9
10
|
//#region src/index.ts
|
|
@@ -15,4 +16,4 @@ const main = () => {
|
|
|
15
16
|
var src_default = definePlatform({ main });
|
|
16
17
|
|
|
17
18
|
//#endregion
|
|
18
|
-
export { QQBotAPI as API, src_default as default, platform, sanitizeQQText, useClient, useMode, useValue };
|
|
19
|
+
export { QQBotAPI as API, QQMarkdown, src_default as default, platform, sanitizeQQText, useClient, useMode, useValue };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
//#region src/markdown.d.ts
|
|
2
|
+
/** QQ Markdown 专用扩展。仅生成字符串,不扩展 alemonjs 的通用节点或渲染协议。 */
|
|
3
|
+
type QQMarkdownMathOptions = {
|
|
4
|
+
block?: boolean;
|
|
5
|
+
};
|
|
6
|
+
type QQMarkdownTask = {
|
|
7
|
+
text: string;
|
|
8
|
+
checked?: boolean;
|
|
9
|
+
};
|
|
10
|
+
declare const math: (latex: string, options?: QQMarkdownMathOptions) => string;
|
|
11
|
+
/**
|
|
12
|
+
* 仅用于支持这些扩展的 QQ Markdown 消息;通过 addContent() 或原始 Markdown 发送。
|
|
13
|
+
* 不提供跨平台渲染或自动降级,调用方应根据发送平台选择内容。
|
|
14
|
+
*/
|
|
15
|
+
declare const QQMarkdown: {
|
|
16
|
+
math: typeof math;
|
|
17
|
+
taskList(...items: QQMarkdownTask[]): string;
|
|
18
|
+
underline(text: string): string;
|
|
19
|
+
color(text: string, color: string): string;
|
|
20
|
+
ruby(text: string, annotation: string): string;
|
|
21
|
+
boxed(text: string): string;
|
|
22
|
+
cancel(text: string): string;
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { QQMarkdown, QQMarkdownMathOptions, QQMarkdownTask };
|
package/lib/markdown.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
//#region src/markdown.ts
|
|
2
|
+
const latexText = (text) => {
|
|
3
|
+
const escapes = {
|
|
4
|
+
"\\": "\\textbackslash{}",
|
|
5
|
+
"{": "\\{",
|
|
6
|
+
"}": "\\}",
|
|
7
|
+
$: "\\$",
|
|
8
|
+
"&": "\\&",
|
|
9
|
+
"#": "\\#",
|
|
10
|
+
"%": "\\%",
|
|
11
|
+
_: "\\_",
|
|
12
|
+
"^": "\\textasciicircum{}",
|
|
13
|
+
"~": "\\textasciitilde{}"
|
|
14
|
+
};
|
|
15
|
+
return `\\text{${text.replace(/[\\{}$&#%_^~]/g, (character) => escapes[character]).replace(/\r\n?|\n/g, " ")}}`;
|
|
16
|
+
};
|
|
17
|
+
const math = (latex, options) => options?.block ? `\n\n$$\n${latex}\n$$\n\n` : `$${latex}$`;
|
|
18
|
+
/**
|
|
19
|
+
* 仅用于支持这些扩展的 QQ Markdown 消息;通过 addContent() 或原始 Markdown 发送。
|
|
20
|
+
* 不提供跨平台渲染或自动降级,调用方应根据发送平台选择内容。
|
|
21
|
+
*/
|
|
22
|
+
const QQMarkdown = {
|
|
23
|
+
math,
|
|
24
|
+
taskList(...items) {
|
|
25
|
+
if (items.length === 0) return "";
|
|
26
|
+
return "\n\n" + items.map((item) => `- [${item.checked ? "x" : " "}] ${item.text.replace(/\r\n?|\n/g, " ")}`).join("\n") + "\n\n";
|
|
27
|
+
},
|
|
28
|
+
underline(text) {
|
|
29
|
+
return math(`\\underline{${latexText(text)}}`);
|
|
30
|
+
},
|
|
31
|
+
color(text, color) {
|
|
32
|
+
if (!/^(?:[a-zA-Z]+|#[0-9a-fA-F]{3}(?:[0-9a-fA-F]{3})?)$/.test(color)) throw new TypeError("QQ Markdown color must be a color name or #RGB / #RRGGBB");
|
|
33
|
+
return math(`\\color{${color}}{${latexText(text)}}`);
|
|
34
|
+
},
|
|
35
|
+
ruby(text, annotation) {
|
|
36
|
+
return math(`\\overset{${latexText(annotation)}}{${latexText(text)}}`);
|
|
37
|
+
},
|
|
38
|
+
boxed(text) {
|
|
39
|
+
return math(`\\boxed{${latexText(text)}}`);
|
|
40
|
+
},
|
|
41
|
+
cancel(text) {
|
|
42
|
+
return math(`\\cancel{${latexText(text)}}`);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
//#endregion
|
|
47
|
+
export { QQMarkdown };
|
|
@@ -34,8 +34,8 @@ type QQBotPanel = {
|
|
|
34
34
|
remark?: string;
|
|
35
35
|
version?: number;
|
|
36
36
|
};
|
|
37
|
-
/**
|
|
38
|
-
type QQBotPanelScope = 'c2c' | 'group';
|
|
37
|
+
/** QQ 原生面板场景;框架 direct 对应 dm。 */
|
|
38
|
+
type QQBotPanelScope = 'c2c' | 'group' | 'channel' | 'dm';
|
|
39
39
|
type QQBotPanelCreate = {
|
|
40
40
|
scope: QQBotPanelScope;
|
|
41
41
|
target_type?: 'all' | 'specific';
|
package/lib/sends.js
CHANGED
|
@@ -182,7 +182,7 @@ const formatMention = (item, mode) => {
|
|
|
182
182
|
if (item.options?.belong === "channel") return `<#${value}>`;
|
|
183
183
|
return "";
|
|
184
184
|
}
|
|
185
|
-
if (isEmptyMention) return "";
|
|
185
|
+
if (isEmptyMention) return mode === "group" ? "<qqbot-at-everyone />" : "";
|
|
186
186
|
if (item.options?.belong === "user") return `<qqbot-at-user id="${value}" />`;
|
|
187
187
|
return "";
|
|
188
188
|
};
|
|
@@ -352,7 +352,7 @@ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMes
|
|
|
352
352
|
const fileInfo = await resolveMediaUrl(media, uploadMedia);
|
|
353
353
|
if (!fileInfo) return [createResult(ResultCode.Fail, "媒体上传失败", null)];
|
|
354
354
|
const res = await sendMessage({
|
|
355
|
-
content: stripMediaPlaceholders(formatQQContent(val, (item) => extractContent([item], "group"), true, config.hideUnsupported)),
|
|
355
|
+
content: stripMediaPlaceholders(formatQQContent(val, (item) => extractContent([item], context === "group" ? "group-media" : context), true, config.hideUnsupported)),
|
|
356
356
|
media: { file_info: fileInfo },
|
|
357
357
|
msg_type: 7,
|
|
358
358
|
...baseParams
|
|
@@ -368,7 +368,7 @@ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMes
|
|
|
368
368
|
return [];
|
|
369
369
|
}
|
|
370
370
|
if (mdToText) {
|
|
371
|
-
const textContent = formatQQContent(val, (item) => extractContent([item],
|
|
371
|
+
const textContent = formatQQContent(val, (item) => extractContent([item], context), true, config.hideUnsupported);
|
|
372
372
|
if (textContent) {
|
|
373
373
|
const res = await sendMessage({
|
|
374
374
|
content: textContent,
|
|
@@ -385,7 +385,7 @@ const sendOpenApiMessage = async (content, val, baseParams, uploadMedia, sendMes
|
|
|
385
385
|
}
|
|
386
386
|
const mdParams = buildMdAndButtonsParams(val, context);
|
|
387
387
|
if (mdParams) {
|
|
388
|
-
if (mdParams.markdown?.content) mdParams.markdown.content = formatQQContent(val, (item) => extractContent([item],
|
|
388
|
+
if (mdParams.markdown?.content) mdParams.markdown.content = formatQQContent(val, (item) => extractContent([item], context), false, void 0, context);
|
|
389
389
|
if (mdParams.markdown && options?.forceVerifyImageResource !== void 0) mdParams.markdown.force_verify_image_resource = options.forceVerifyImageResource;
|
|
390
390
|
const res = await sendMessage({
|
|
391
391
|
msg_type: 2,
|
|
@@ -522,7 +522,7 @@ const GROUP_AT_MESSAGE_CREATE = async (client, event, val, options) => {
|
|
|
522
522
|
*/
|
|
523
523
|
const C2C_MESSAGE_CREATE = async (client, event, val, options) => {
|
|
524
524
|
const baseParams = buildBaseParams(event._tag, event.MessageId, "INTERACTION_CREATE_C2C");
|
|
525
|
-
const content = extractContent(val, "
|
|
525
|
+
const content = extractContent(val, "c2c");
|
|
526
526
|
try {
|
|
527
527
|
return await sendOpenApiMessage(content, val, baseParams, (data) => client.postRichMediaByUser(event.UserId, data), (data) => client.usersOpenMessages(event.UserId, data), "client.usersOpenMessages", "c2c", options);
|
|
528
528
|
} catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alemonjs/qq-bot",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.42",
|
|
4
4
|
"description": "QQ官方平台",
|
|
5
5
|
"author": "lemonade",
|
|
6
6
|
"license": "MIT",
|
|
@@ -12,13 +12,15 @@
|
|
|
12
12
|
"test:send": "yarn build && node tests/use-send.notice.mjs",
|
|
13
13
|
"test:channel": "yarn --cwd ../alemonjs build && yarn build && node tests/channel.contract.mjs",
|
|
14
14
|
"test:qr": "yarn build && node tests/qr-auth.mjs",
|
|
15
|
-
"test:non-channel": "yarn build && node tests/markdown-buttons.contract.mjs && node tests/non-channel.contract.mjs && node tests/framework.contract.mjs && node tests/non-channel.transport.mjs && node tests/media-upload.contract.mjs && node tests/routing.contract.mjs && node tests/lifecycle.contract.mjs && node tests/http-diagnostics.contract.mjs && node tests/webhook-ingress.contract.mjs && node tests/text-sanitizer.contract.mjs && tsc -p tests/tsconfig.non-channel.json",
|
|
15
|
+
"test:non-channel": "yarn build && node tests/markdown-buttons.contract.mjs && node tests/markdown-extension.contract.mjs && node tests/non-channel.contract.mjs && node tests/framework.contract.mjs && node tests/changelog.contract.mjs && node tests/everyone.contract.mjs && node tests/non-channel.transport.mjs && node tests/media-upload.contract.mjs && node tests/routing.contract.mjs && node tests/lifecycle.contract.mjs && node tests/http-diagnostics.contract.mjs && node tests/webhook-ingress.contract.mjs && node tests/text-sanitizer.contract.mjs && tsc -p tests/tsconfig.non-channel.json",
|
|
16
16
|
"docs:snapshot": "python3 scripts/snapshot-official.py",
|
|
17
17
|
"test:http": "yarn build && node tests/http-diagnostics.contract.mjs && node tests/webhook-ingress.contract.mjs",
|
|
18
18
|
"test:text": "yarn build && node tests/text-sanitizer.contract.mjs",
|
|
19
19
|
"test:materials": "yarn build && node tests/materials.contract.mjs",
|
|
20
20
|
"test:mention": "yarn build && node tests/everyone.contract.mjs",
|
|
21
|
-
"test:buttons": "yarn build && node tests/markdown-buttons.contract.mjs"
|
|
21
|
+
"test:buttons": "yarn build && node tests/markdown-buttons.contract.mjs",
|
|
22
|
+
"test:markdown-extension": "yarn build && node tests/markdown-extension.contract.mjs && node ../../node_modules/typescript/bin/tsc --noEmit --strict --skipLibCheck --module ESNext --moduleResolution Bundler --target ES2022 tests/markdown-extension.types.ts",
|
|
23
|
+
"test:changelog": "yarn --cwd ../alemonjs build && yarn build && node tests/changelog.contract.mjs && node tests/everyone.contract.mjs"
|
|
22
24
|
},
|
|
23
25
|
"dependencies": {
|
|
24
26
|
"@noble/curves": "^1.7.0",
|
|
@@ -45,7 +47,12 @@
|
|
|
45
47
|
"require": "./lib/index.js"
|
|
46
48
|
},
|
|
47
49
|
"./package": "./package.json",
|
|
48
|
-
"./desktop": "./lib/desktop.js"
|
|
50
|
+
"./desktop": "./lib/desktop.js",
|
|
51
|
+
"./markdown": {
|
|
52
|
+
"types": "./lib/markdown.d.ts",
|
|
53
|
+
"import": "./lib/markdown.js",
|
|
54
|
+
"require": "./lib/markdown.js"
|
|
55
|
+
}
|
|
49
56
|
},
|
|
50
57
|
"alemonjs": {
|
|
51
58
|
"config": [
|