@zhin.js/adapter-icqq 1.1.17 → 1.1.19

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.
Files changed (59) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +55 -10
  3. package/adapters/icqq/index.js +3 -19
  4. package/adapters/icqq/index.ts +2 -25
  5. package/commands/icqq/endpoint/definition.js +3 -25
  6. package/commands/icqq/endpoint/definition.ts +3 -24
  7. package/commands/icqq/login/code/index.js +28 -0
  8. package/commands/icqq/login/code/index.ts +30 -0
  9. package/commands/icqq/login/confirm/index.js +20 -0
  10. package/commands/icqq/login/confirm/index.ts +21 -0
  11. package/commands/icqq/login/definition.js +65 -0
  12. package/commands/icqq/login/definition.ts +72 -0
  13. package/commands/icqq/login/qr/index.js +53 -0
  14. package/commands/icqq/login/qr/index.ts +55 -0
  15. package/commands/icqq/login/retry/index.js +21 -0
  16. package/commands/icqq/login/retry/index.ts +23 -0
  17. package/commands/icqq/login/status/index.js +31 -0
  18. package/commands/icqq/login/status/index.ts +34 -0
  19. package/lib/adapter.d.ts +13 -0
  20. package/lib/adapter.js +27 -0
  21. package/lib/client.d.ts +6 -9
  22. package/lib/client.js +1 -3
  23. package/lib/console-spec.d.ts +17 -0
  24. package/lib/console-spec.js +21 -0
  25. package/lib/console.d.ts +2 -0
  26. package/lib/console.js +13 -0
  27. package/lib/endpoint.d.ts +12 -15
  28. package/lib/endpoint.js +373 -164
  29. package/lib/group-moderation.d.ts +6 -3
  30. package/lib/group-moderation.js +9 -8
  31. package/lib/group-scene.d.ts +3 -3
  32. package/lib/group-scene.js +8 -7
  33. package/lib/icqq-login-assist.d.ts +3 -1
  34. package/lib/icqq-login-assist.js +3 -1
  35. package/lib/icqq-login-control.d.ts +24 -0
  36. package/lib/icqq-login-control.js +25 -0
  37. package/lib/index.d.ts +3 -2
  38. package/lib/index.js +2 -2
  39. package/lib/protocol.d.ts +13 -0
  40. package/lib/protocol.js +24 -9
  41. package/package.json +25 -17
  42. package/pages/index/index.js +15 -0
  43. package/pages/index/index.ts +16 -0
  44. package/plugin.js +3 -5
  45. package/schema.json +174 -0
  46. package/src/adapter.ts +29 -0
  47. package/src/client.ts +6 -11
  48. package/src/console-spec.ts +26 -0
  49. package/src/console.ts +17 -0
  50. package/src/endpoint.ts +381 -178
  51. package/src/group-moderation.ts +10 -10
  52. package/src/group-scene.ts +8 -8
  53. package/src/icqq-login-assist.ts +6 -2
  54. package/src/icqq-login-control.ts +42 -0
  55. package/src/index.ts +4 -1
  56. package/src/protocol.ts +35 -8
  57. package/lib/icqq-runtime-state.d.ts +0 -1
  58. package/lib/icqq-runtime-state.js +0 -6
  59. package/src/icqq-runtime-state.ts +0 -7
@@ -0,0 +1,53 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineCommand } from 'zhin.js/command';
3
+ import { icqqLoginControls, icqqLoginForbidden, isIcqqLoginOperator, pickIcqqLoginControl, } from '../definition.js';
4
+ const QR_IMAGE = /^data:image\/[a-z0-9.+-]+;base64,(.+)$/iu;
5
+ export default defineCommand({
6
+ description: '获取 ICQQ 登录二维码(发给当前会话)',
7
+ descriptionI18n: { en: 'Fetch the ICQQ login QR code into this conversation' },
8
+ async execute({ args, config, input, project, owner }) {
9
+ if (!isIcqqLoginOperator(config, input))
10
+ return icqqLoginForbidden();
11
+ const picked = pickIcqqLoginControl(icqqLoginControls({ project, owner }), args[0]);
12
+ if (!picked.control)
13
+ return picked.text ?? 'ICQQ 适配器还没有启动';
14
+ const control = picked.control;
15
+ const findQr = () => control.pending().find((task) => task.type === 'qrcode' || task.type === 'auth');
16
+ let task = findQr();
17
+ if (!task) {
18
+ const other = control.pending().find((item) => item.type !== 'qrcode' && item.type !== 'auth');
19
+ if (other) {
20
+ const url = typeof other.payload.url === 'string' ? other.payload.url : '';
21
+ return `ICQQ ${other.endpointKey} 当前是${other.type === 'slider' ? '滑块验证' : '登录验证'},请打开 ${url || '验证页面'},`
22
+ + '完成后回复 `icqq login code <内容>`。';
23
+ }
24
+ try {
25
+ await control.relogin();
26
+ }
27
+ catch {
28
+ // The SDK may still deliver a QR challenge asynchronously.
29
+ }
30
+ task = findQr();
31
+ if (!task)
32
+ return '已触发重新登录,请 5 秒后再发送 `icqq login qr` 获取二维码。';
33
+ }
34
+ const raw = typeof task.payload.image === 'string' ? task.payload.image : '';
35
+ const base64 = QR_IMAGE.exec(raw)?.[1];
36
+ if (!base64) {
37
+ return `ICQQ ${task.endpointKey} 当前是 ${task.type === 'qrcode' ? '二维码' : '登录确认'}待办,但没有可发送的图片;请打开 Console 的 ICQQ 页面完成。`;
38
+ }
39
+ return [
40
+ {
41
+ type: 'text',
42
+ data: {
43
+ text: `ICQQ ${task.endpointKey} 登录二维码(约 3 分钟有效)。\n`
44
+ + '用手机 QQ 扫码,完成后回复 `icqq login confirm`。',
45
+ },
46
+ },
47
+ {
48
+ type: 'image',
49
+ data: { media: { kind: 'base64', value: base64, mime_type: 'image/png' } },
50
+ },
51
+ ];
52
+ },
53
+ });
@@ -0,0 +1,55 @@
1
+ import { defineCommand } from 'zhin.js/command';
2
+ import {
3
+ icqqLoginControls,
4
+ icqqLoginForbidden,
5
+ isIcqqLoginOperator,
6
+ pickIcqqLoginControl,
7
+ } from '../definition.js';
8
+
9
+ const QR_IMAGE = /^data:image\/[a-z0-9.+-]+;base64,(.+)$/iu;
10
+
11
+ export default defineCommand({
12
+ description: '获取 ICQQ 登录二维码(发给当前会话)',
13
+ descriptionI18n: { en: 'Fetch the ICQQ login QR code into this conversation' },
14
+ async execute({ args, config, input, project, owner }) {
15
+ if (!isIcqqLoginOperator(config, input)) return icqqLoginForbidden();
16
+ const picked = pickIcqqLoginControl(icqqLoginControls({ project, owner }), args[0]);
17
+ if (!picked.control) return picked.text ?? 'ICQQ 适配器还没有启动';
18
+ const control = picked.control;
19
+ const findQr = () => control.pending().find((task) => task.type === 'qrcode' || task.type === 'auth');
20
+ let task = findQr();
21
+ if (!task) {
22
+ const other = control.pending().find((item) => item.type !== 'qrcode' && item.type !== 'auth');
23
+ if (other) {
24
+ const url = typeof other.payload.url === 'string' ? other.payload.url : '';
25
+ return `ICQQ ${other.endpointKey} 当前是${other.type === 'slider' ? '滑块验证' : '登录验证'},请打开 ${url || '验证页面'},`
26
+ + '完成后回复 `icqq login code <内容>`。';
27
+ }
28
+ try {
29
+ await control.relogin();
30
+ } catch {
31
+ // The SDK may still deliver a QR challenge asynchronously.
32
+ }
33
+ task = findQr();
34
+ if (!task) return '已触发重新登录,请 5 秒后再发送 `icqq login qr` 获取二维码。';
35
+ }
36
+ const raw = typeof task.payload.image === 'string' ? task.payload.image : '';
37
+ const base64 = QR_IMAGE.exec(raw)?.[1];
38
+ if (!base64) {
39
+ return `ICQQ ${task.endpointKey} 当前是 ${task.type === 'qrcode' ? '二维码' : '登录确认'}待办,但没有可发送的图片;请打开 Console 的 ICQQ 页面完成。`;
40
+ }
41
+ return [
42
+ {
43
+ type: 'text',
44
+ data: {
45
+ text: `ICQQ ${task.endpointKey} 登录二维码(约 3 分钟有效)。\n`
46
+ + '用手机 QQ 扫码,完成后回复 `icqq login confirm`。',
47
+ },
48
+ },
49
+ {
50
+ type: 'image',
51
+ data: { media: { kind: 'base64', value: base64, mime_type: 'image/png' } },
52
+ },
53
+ ];
54
+ },
55
+ });
@@ -0,0 +1,21 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineCommand } from 'zhin.js/command';
3
+ import { icqqLoginControls, icqqLoginForbidden, isIcqqLoginOperator, pickIcqqLoginControl, } from '../definition.js';
4
+ export default defineCommand({
5
+ description: '重新触发 ICQQ 登录',
6
+ descriptionI18n: { en: 'Trigger an ICQQ login attempt again' },
7
+ async execute({ args, config, input, project, owner }) {
8
+ if (!isIcqqLoginOperator(config, input))
9
+ return icqqLoginForbidden();
10
+ const picked = pickIcqqLoginControl(icqqLoginControls({ project, owner }), args[0]);
11
+ if (!picked.control)
12
+ return picked.text ?? 'ICQQ 适配器还没有启动';
13
+ try {
14
+ await picked.control.relogin();
15
+ return `已触发 ICQQ ${picked.control.endpointId} 重新登录;需要扫码时发送 \`icqq login qr\`。`;
16
+ }
17
+ catch {
18
+ return `ICQQ ${picked.control.endpointId} 重新登录失败,请稍后重试或查看日志。`;
19
+ }
20
+ },
21
+ });
@@ -0,0 +1,23 @@
1
+ import { defineCommand } from 'zhin.js/command';
2
+ import {
3
+ icqqLoginControls,
4
+ icqqLoginForbidden,
5
+ isIcqqLoginOperator,
6
+ pickIcqqLoginControl,
7
+ } from '../definition.js';
8
+
9
+ export default defineCommand({
10
+ description: '重新触发 ICQQ 登录',
11
+ descriptionI18n: { en: 'Trigger an ICQQ login attempt again' },
12
+ async execute({ args, config, input, project, owner }) {
13
+ if (!isIcqqLoginOperator(config, input)) return icqqLoginForbidden();
14
+ const picked = pickIcqqLoginControl(icqqLoginControls({ project, owner }), args[0]);
15
+ if (!picked.control) return picked.text ?? 'ICQQ 适配器还没有启动';
16
+ try {
17
+ await picked.control.relogin();
18
+ return `已触发 ICQQ ${picked.control.endpointId} 重新登录;需要扫码时发送 \`icqq login qr\`。`;
19
+ } catch {
20
+ return `ICQQ ${picked.control.endpointId} 重新登录失败,请稍后重试或查看日志。`;
21
+ }
22
+ },
23
+ });
@@ -0,0 +1,31 @@
1
+ // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
+ import { defineCommand } from 'zhin.js/command';
3
+ import { icqqLoginControls, icqqLoginForbidden, isIcqqLoginOperator, pendingTaskLabel, pickIcqqLoginControl, } from '../definition.js';
4
+ export default defineCommand({
5
+ description: '查看 ICQQ 掉线状态与登录待办',
6
+ descriptionI18n: { en: 'Show ICQQ offline status and pending login tasks' },
7
+ async execute({ args, config, input, project, owner }) {
8
+ if (!isIcqqLoginOperator(config, input))
9
+ return icqqLoginForbidden();
10
+ const picked = pickIcqqLoginControl(icqqLoginControls({ project, owner }), args[0]);
11
+ if (!picked.control)
12
+ return picked.text ?? 'ICQQ 适配器还没有启动';
13
+ const state = picked.control.state();
14
+ const lines = [
15
+ `ICQQ ${state.endpointId}: ${state.online ? '在线' : '离线'}(${state.transportState})`,
16
+ ];
17
+ if (state.pending.length === 0) {
18
+ lines.push('没有待处理的登录验证。');
19
+ }
20
+ else {
21
+ lines.push('待处理:');
22
+ for (const task of state.pending) {
23
+ const url = typeof task.payload.url === 'string' ? task.payload.url : undefined;
24
+ lines.push(`- ${pendingTaskLabel(task.type)}(${task.id},endpoint ${task.endpointKey})`
25
+ + (url ? `:${url}` : ''));
26
+ }
27
+ lines.push('二维码:`icqq login qr`;完成扫码后:`icqq login confirm`;滑块/短信:`icqq login code <内容>`。');
28
+ }
29
+ return lines.join('\n');
30
+ },
31
+ });
@@ -0,0 +1,34 @@
1
+ import { defineCommand } from 'zhin.js/command';
2
+ import {
3
+ icqqLoginControls,
4
+ icqqLoginForbidden,
5
+ isIcqqLoginOperator,
6
+ pendingTaskLabel,
7
+ pickIcqqLoginControl,
8
+ } from '../definition.js';
9
+
10
+ export default defineCommand({
11
+ description: '查看 ICQQ 掉线状态与登录待办',
12
+ descriptionI18n: { en: 'Show ICQQ offline status and pending login tasks' },
13
+ async execute({ args, config, input, project, owner }) {
14
+ if (!isIcqqLoginOperator(config, input)) return icqqLoginForbidden();
15
+ const picked = pickIcqqLoginControl(icqqLoginControls({ project, owner }), args[0]);
16
+ if (!picked.control) return picked.text ?? 'ICQQ 适配器还没有启动';
17
+ const state = picked.control.state();
18
+ const lines = [
19
+ `ICQQ ${state.endpointId}: ${state.online ? '在线' : '离线'}(${state.transportState})`,
20
+ ];
21
+ if (state.pending.length === 0) {
22
+ lines.push('没有待处理的登录验证。');
23
+ } else {
24
+ lines.push('待处理:');
25
+ for (const task of state.pending) {
26
+ const url = typeof task.payload.url === 'string' ? task.payload.url : undefined;
27
+ lines.push(`- ${pendingTaskLabel(task.type)}(${task.id},endpoint ${task.endpointKey})`
28
+ + (url ? `:${url}` : ''));
29
+ }
30
+ lines.push('二维码:`icqq login qr`;完成扫码后:`icqq login confirm`;滑块/短信:`icqq login code <内容>`。');
31
+ }
32
+ return lines.join('\n');
33
+ },
34
+ });
@@ -0,0 +1,13 @@
1
+ import { Adapter, type AdapterContext, type EndpointCreationContext } from 'zhin.js/adapter';
2
+ import { IcqqEndpoint } from './endpoint.js';
3
+ import { type IcqqEndpointConfig } from './protocol.js';
4
+ import type { IcqqClientEventMap } from './client.js';
5
+ /** ICQQ account construction and actual SDK ownership belong to this Adapter. */
6
+ export declare class IcqqAdapter extends Adapter<IcqqEndpoint, IcqqEndpointConfig, IcqqClientEventMap> {
7
+ #private;
8
+ get configurationIdentityFields(): readonly string[];
9
+ get configurationUpdateFields(): readonly string[];
10
+ constructor(context: AdapterContext<IcqqEndpointConfig>);
11
+ protected validateConfiguration(config: IcqqEndpointConfig): void;
12
+ protected createEndpoint(input: IcqqEndpointConfig, execution: EndpointCreationContext): IcqqEndpoint;
13
+ }
package/lib/adapter.js ADDED
@@ -0,0 +1,27 @@
1
+ import { Adapter, createAdapterOutageNotifier } from 'zhin.js/adapter';
2
+ import { projectLocaleToken } from 'zhin.js/i18n';
3
+ import { loginAssistToken } from '@zhin.js/core/runtime';
4
+ import { outboundHostToken } from 'zhin.js';
5
+ import { IcqqEndpoint } from './endpoint.js';
6
+ import { resolveIcqqConfig } from './protocol.js';
7
+ /** ICQQ account construction and actual SDK ownership belong to this Adapter. */
8
+ export class IcqqAdapter extends Adapter {
9
+ get configurationIdentityFields() { return ['id']; }
10
+ get configurationUpdateFields() {
11
+ return ['password', 'platform', 'ver', 'dataDir', 'signApiAddr', 'autoReconnect', 'autoServer', 'qqnt', 'ntLogin'];
12
+ }
13
+ #context;
14
+ constructor(context) { super(); this.#context = context; }
15
+ validateConfiguration(config) { resolveIcqqConfig(config); }
16
+ createEndpoint(input, execution) {
17
+ const context = this.#context;
18
+ const config = resolveIcqqConfig(input);
19
+ const outbound = context.has?.(outboundHostToken) ? context.use(outboundHostToken) : undefined;
20
+ const endpoint = new IcqqEndpoint({ id: execution.canonicalId, config,
21
+ signal: execution.signal, endpointIdentity: { canonicalId: execution.canonicalId, instanceId: execution.instanceId, epoch: execution.epoch, incarnationId: execution.incarnationId },
22
+ loginAssist: context.use(loginAssistToken), locale: context.use(projectLocaleToken),
23
+ notifier: createAdapterOutageNotifier(outbound, config.notify),
24
+ });
25
+ return endpoint;
26
+ }
27
+ }
package/lib/client.d.ts CHANGED
@@ -1,19 +1,16 @@
1
- import type { Client, EventMap } from '@icqqjs/icqq';
1
+ import type { IcqqAdapter } from './adapter.js';
2
+ import type { IcqqEndpoint } from './endpoint.js';
3
+ import type { EventMap } from '@icqqjs/icqq';
2
4
  type EventPayload<TListener> = TListener extends (event: infer TEvent, ...rest: readonly unknown[]) => unknown ? TEvent : never;
3
5
  /** The actual ICQQ SDK instance exposed by every ICQQ Endpoint event. */
4
- export type IcqqClient = Client;
6
+ export type IcqqClient = IcqqEndpoint;
5
7
  /** Native ICQQ event-name → first public event payload, derived from the SDK SSOT. */
6
8
  export type IcqqClientEventMap = {
7
9
  readonly [TName in keyof EventMap]: EventPayload<EventMap[TName]>;
8
10
  };
9
11
  declare module '@zhin.js/feature-kit' {
10
- interface AdapterClientRegistry {
11
- readonly icqq: {
12
- readonly client: IcqqClient;
13
- readonly events: IcqqClientEventMap;
14
- };
12
+ interface AdapterRegistry {
13
+ readonly icqq: IcqqAdapter;
15
14
  }
16
15
  }
17
- /** Typed, generation-checked identity used by handlers, commands, tools and schedules. */
18
- export declare const icqqClient: import("@zhin.js/adapter").EndpointClientToken<Client, IcqqClientEventMap>;
19
16
  export {};
package/lib/client.js CHANGED
@@ -1,3 +1 @@
1
- import { defineEndpointClient } from 'zhin.js/adapter';
2
- /** Typed, generation-checked identity used by handlers, commands, tools and schedules. */
3
- export const icqqClient = defineEndpointClient('icqq');
1
+ export {};
@@ -0,0 +1,17 @@
1
+ /**
2
+ * ICQQ Console 页面元数据(浏览器与服务端共享;不要在这里 import 服务端代码)。
3
+ */
4
+ import type { AdapterConsoleField } from 'zhin.js/adapter';
5
+ export declare const icqqConsoleSpec: {
6
+ readonly adapterKey: "icqq";
7
+ readonly adapterDisplayName: "ICQQ";
8
+ readonly fields: readonly AdapterConsoleField[];
9
+ readonly docsUrl: "https://zhin.js.org/adapters/icqq";
10
+ readonly readPermission: "icqq:read";
11
+ readonly writePermission: "icqq:write";
12
+ readonly idPattern: RegExp;
13
+ readonly idHint: "ICQQ endpoint id 是 QQ 号(纯数字)";
14
+ readonly idHintI18n: {
15
+ readonly en: "ICQQ endpoint ID is the QQ number (digits only)";
16
+ };
17
+ };
@@ -0,0 +1,21 @@
1
+ export const icqqConsoleSpec = {
2
+ adapterKey: 'icqq',
3
+ adapterDisplayName: 'ICQQ',
4
+ fields: [
5
+ { key: 'password', env: true, description: 'QQ password; leave blank to retain the saved credential' },
6
+ { key: 'platform', type: 'number', description: 'ICQQ platform number' },
7
+ { key: 'ver', description: 'ICQQ protocol version' },
8
+ { key: 'dataDir', description: 'ICQQ device and session directory' },
9
+ { key: 'signApiAddr', description: 'ICQQ signing service URL' },
10
+ { key: 'autoReconnect', type: 'boolean', description: 'ICQQ reconnect setting' },
11
+ { key: 'autoServer', type: 'boolean', description: 'ICQQ automatic server selection' },
12
+ { key: 'qqnt', type: 'boolean', description: 'QQNT protocol' },
13
+ { key: 'ntLogin', type: 'boolean', description: 'QQNT login' },
14
+ ],
15
+ docsUrl: 'https://zhin.js.org/adapters/icqq',
16
+ readPermission: 'icqq:read',
17
+ writePermission: 'icqq:write',
18
+ idPattern: /^\d+$/,
19
+ idHint: 'ICQQ endpoint id 是 QQ 号(纯数字)',
20
+ idHintI18n: { en: 'ICQQ endpoint ID is the QQ number (digits only)' },
21
+ };
@@ -0,0 +1,2 @@
1
+ import type { PluginConsoleRpc } from 'zhin.js';
2
+ export declare function createIcqqConsoleRpc(getConfig: () => unknown): PluginConsoleRpc;
package/lib/console.js ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * ICQQ Console RPC:运行状态 + endpoint 增删(原 `icqq endpoint` 聊天命令)。
3
+ *
4
+ * 页面绑定 `pages/index`,读取 / 写入分别要求 `<adapter>:read` / `<adapter>:write`。
5
+ */
6
+ import { createAdapterConsoleRpc } from 'zhin.js/adapter';
7
+ import { icqqConsoleSpec } from './console-spec.js';
8
+ export function createIcqqConsoleRpc(getConfig) {
9
+ return createAdapterConsoleRpc({
10
+ ...icqqConsoleSpec,
11
+ getConfig,
12
+ });
13
+ }
package/lib/endpoint.d.ts CHANGED
@@ -1,29 +1,26 @@
1
- import { Client } from '@icqqjs/icqq';
2
- import { Endpoint, type EndpointControl, type EndpointManagement, type EndpointSendRequest, type EndpointTransportState } from 'zhin.js/adapter';
3
- import type { EndpointContentPort } from '@zhin.js/adapter';
4
- import { type LoginAssist } from '@zhin.js/core';
1
+ import { endpointSpec, type Endpoint, type EndpointSpecification, type AdapterOutageNotifier } from 'zhin.js/adapter';
2
+ import { type LoginAssist, type LoginAssistEndpointIdentity } from '@zhin.js/core';
5
3
  import type { CapabilityId } from 'zhin.js';
4
+ import type { IcqqLoginControl } from './icqq-login-control.js';
6
5
  import { type IcqqInboundMessage, type ResolvedIcqqConfig } from './protocol.js';
7
6
  import { ManagedIcqqClient } from './managed-client.js';
8
7
  export interface IcqqEndpointOptions {
9
8
  readonly id: CapabilityId;
10
9
  readonly config: ResolvedIcqqConfig;
10
+ readonly signal?: AbortSignal;
11
+ readonly endpointIdentity?: LoginAssistEndpointIdentity;
11
12
  readonly loginAssist: LoginAssist;
12
13
  readonly locale?: import('zhin.js/i18n').Locale;
14
+ /** Out-of-band outage notifier; absent in tests/hosts without outbound. */
15
+ readonly notifier?: AdapterOutageNotifier;
13
16
  }
14
- export declare class IcqqEndpoint extends Endpoint<Client> {
17
+ export declare class IcqqEndpoint extends ManagedIcqqClient implements Endpoint {
15
18
  #private;
16
- readonly client: ManagedIcqqClient;
19
+ readonly [endpointSpec]: EndpointSpecification;
17
20
  readonly endpointName: string;
18
- readonly content: EndpointContentPort;
19
- readonly management: EndpointManagement;
20
- readonly control: EndpointControl;
21
+ readonly loginControl: IcqqLoginControl;
21
22
  constructor(options: IcqqEndpointOptions);
22
- get transportState(): EndpointTransportState;
23
- start(signal: AbortSignal): Promise<void>;
24
- open(): void;
25
- close(): Promise<void>;
26
- stop(): Promise<void>;
27
- send({ conversation, payload }: EndpointSendRequest): Promise<string>;
23
+ /** Force a login attempt (manual recovery command). */
24
+ relogin(): Promise<void>;
28
25
  admit(msg: IcqqInboundMessage): Promise<void>;
29
26
  }