@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.8
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/LICENSE +21 -0
- package/README.md +726 -2
- package/dist/client/abort.d.ts +5 -0
- package/dist/client/abort.d.ts.map +1 -0
- package/dist/client/abort.js +23 -0
- package/dist/client/abort.js.map +1 -0
- package/dist/client/address.d.ts +17 -0
- package/dist/client/address.d.ts.map +1 -0
- package/dist/client/address.js +66 -0
- package/dist/client/address.js.map +1 -0
- package/dist/client/api/voice.d.ts +24 -0
- package/dist/client/api/voice.d.ts.map +1 -0
- package/dist/client/api/voice.js +33 -0
- package/dist/client/api/voice.js.map +1 -0
- package/dist/client/capabilities.d.ts +68 -0
- package/dist/client/capabilities.d.ts.map +1 -0
- package/dist/client/capabilities.js +59 -0
- package/dist/client/capabilities.js.map +1 -0
- package/dist/client/client.d.ts +196 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1523 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/commands.d.ts +66 -0
- package/dist/client/commands.d.ts.map +1 -0
- package/dist/client/commands.js +162 -0
- package/dist/client/commands.js.map +1 -0
- package/dist/client/crypto/crypt-ops.d.ts +7 -0
- package/dist/client/crypto/crypt-ops.d.ts.map +1 -0
- package/dist/client/crypto/crypt-ops.js +2 -0
- package/dist/client/crypto/crypt-ops.js.map +1 -0
- package/dist/client/crypto/crypt.d.ts +37 -0
- package/dist/client/crypto/crypt.d.ts.map +1 -0
- package/dist/client/crypto/crypt.js +203 -0
- package/dist/client/crypto/crypt.js.map +1 -0
- package/dist/client/crypto/eax.d.ts +12 -0
- package/dist/client/crypto/eax.d.ts.map +1 -0
- package/dist/client/crypto/eax.js +118 -0
- package/dist/client/crypto/eax.js.map +1 -0
- package/dist/client/crypto/identity.d.ts +97 -0
- package/dist/client/crypto/identity.d.ts.map +1 -0
- package/dist/client/crypto/identity.js +412 -0
- package/dist/client/crypto/identity.js.map +1 -0
- package/dist/client/crypto/index.d.ts +7 -0
- package/dist/client/crypto/index.d.ts.map +1 -0
- package/dist/client/crypto/index.js +5 -0
- package/dist/client/crypto/index.js.map +1 -0
- package/dist/client/crypto/primitives.d.ts +43 -0
- package/dist/client/crypto/primitives.d.ts.map +1 -0
- package/dist/client/crypto/primitives.js +116 -0
- package/dist/client/crypto/primitives.js.map +1 -0
- package/dist/client/diagnostics.d.ts +45 -0
- package/dist/client/diagnostics.d.ts.map +1 -0
- package/dist/client/diagnostics.js +30 -0
- package/dist/client/diagnostics.js.map +1 -0
- package/dist/client/discovery/index.d.ts +2 -0
- package/dist/client/discovery/index.d.ts.map +1 -0
- package/dist/client/discovery/index.js +2 -0
- package/dist/client/discovery/index.js.map +1 -0
- package/dist/client/discovery/resolver.d.ts +26 -0
- package/dist/client/discovery/resolver.d.ts.map +1 -0
- package/dist/client/discovery/resolver.js +275 -0
- package/dist/client/discovery/resolver.js.map +1 -0
- package/dist/client/errors.d.ts +82 -0
- package/dist/client/errors.d.ts.map +1 -0
- package/dist/client/errors.js +201 -0
- package/dist/client/errors.js.map +1 -0
- package/dist/client/events.d.ts +3 -0
- package/dist/client/events.d.ts.map +1 -0
- package/dist/client/events.js +8 -0
- package/dist/client/events.js.map +1 -0
- package/dist/client/handshake/crypt-handshake.d.ts +17 -0
- package/dist/client/handshake/crypt-handshake.d.ts.map +1 -0
- package/dist/client/handshake/crypt-handshake.js +128 -0
- package/dist/client/handshake/crypt-handshake.js.map +1 -0
- package/dist/client/handshake/crypt-init2.d.ts +7 -0
- package/dist/client/handshake/crypt-init2.d.ts.map +1 -0
- package/dist/client/handshake/crypt-init2.js +37 -0
- package/dist/client/handshake/crypt-init2.js.map +1 -0
- package/dist/client/handshake/index.d.ts +4 -0
- package/dist/client/handshake/index.d.ts.map +1 -0
- package/dist/client/handshake/index.js +4 -0
- package/dist/client/handshake/index.js.map +1 -0
- package/dist/client/handshake/license.d.ts +35 -0
- package/dist/client/handshake/license.d.ts.map +1 -0
- package/dist/client/handshake/license.js +169 -0
- package/dist/client/handshake/license.js.map +1 -0
- package/dist/client/handshake.d.ts +27 -0
- package/dist/client/handshake.d.ts.map +1 -0
- package/dist/client/handshake.js +126 -0
- package/dist/client/handshake.js.map +1 -0
- package/dist/client/helpers.d.ts +6 -0
- package/dist/client/helpers.d.ts.map +1 -0
- package/dist/client/helpers.js +13 -0
- package/dist/client/helpers.js.map +1 -0
- package/dist/client/hooks.d.ts +7 -0
- package/dist/client/hooks.d.ts.map +1 -0
- package/dist/client/hooks.js +28 -0
- package/dist/client/hooks.js.map +1 -0
- package/dist/client/index.d.ts +26 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +28 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/reconnect.d.ts +12 -0
- package/dist/client/reconnect.d.ts.map +1 -0
- package/dist/client/reconnect.js +44 -0
- package/dist/client/reconnect.js.map +1 -0
- package/dist/client/throttle.d.ts +20 -0
- package/dist/client/throttle.d.ts.map +1 -0
- package/dist/client/throttle.js +83 -0
- package/dist/client/throttle.js.map +1 -0
- package/dist/client/trace.d.ts +223 -0
- package/dist/client/trace.d.ts.map +1 -0
- package/dist/client/trace.js +13 -0
- package/dist/client/trace.js.map +1 -0
- package/dist/client/transfer.d.ts +111 -0
- package/dist/client/transfer.d.ts.map +1 -0
- package/dist/client/transfer.js +243 -0
- package/dist/client/transfer.js.map +1 -0
- package/dist/client/transport/generation-window.d.ts +30 -0
- package/dist/client/transport/generation-window.d.ts.map +1 -0
- package/dist/client/transport/generation-window.js +97 -0
- package/dist/client/transport/generation-window.js.map +1 -0
- package/dist/client/transport/handler.d.ts +61 -0
- package/dist/client/transport/handler.d.ts.map +1 -0
- package/dist/client/transport/handler.js +793 -0
- package/dist/client/transport/handler.js.map +1 -0
- package/dist/client/transport/index.d.ts +6 -0
- package/dist/client/transport/index.d.ts.map +1 -0
- package/dist/client/transport/index.js +5 -0
- package/dist/client/transport/index.js.map +1 -0
- package/dist/client/transport/packet.d.ts +36 -0
- package/dist/client/transport/packet.d.ts.map +1 -0
- package/dist/client/transport/packet.js +55 -0
- package/dist/client/transport/packet.js.map +1 -0
- package/dist/client/transport/quicklz.d.ts +24 -0
- package/dist/client/transport/quicklz.d.ts.map +1 -0
- package/dist/client/transport/quicklz.js +179 -0
- package/dist/client/transport/quicklz.js.map +1 -0
- package/dist/client/types.d.ts +226 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +39 -0
- package/dist/client/types.js.map +1 -0
- package/dist/core/api/channels.d.ts +182 -0
- package/dist/core/api/channels.d.ts.map +1 -0
- package/dist/core/api/channels.js +155 -0
- package/dist/core/api/channels.js.map +1 -0
- package/dist/core/api/clients.d.ts +304 -0
- package/dist/core/api/clients.d.ts.map +1 -0
- package/dist/core/api/clients.js +260 -0
- package/dist/core/api/clients.js.map +1 -0
- package/dist/core/api/command.d.ts +305 -0
- package/dist/core/api/command.d.ts.map +1 -0
- package/dist/core/api/command.js +363 -0
- package/dist/core/api/command.js.map +1 -0
- package/dist/core/api/files.d.ts +153 -0
- package/dist/core/api/files.d.ts.map +1 -0
- package/dist/core/api/files.js +181 -0
- package/dist/core/api/files.js.map +1 -0
- package/dist/core/api/groups.d.ts +248 -0
- package/dist/core/api/groups.d.ts.map +1 -0
- package/dist/core/api/groups.js +271 -0
- package/dist/core/api/groups.js.map +1 -0
- package/dist/core/api/moderation.d.ts +205 -0
- package/dist/core/api/moderation.d.ts.map +1 -0
- package/dist/core/api/moderation.js +209 -0
- package/dist/core/api/moderation.js.map +1 -0
- package/dist/core/api/parse.d.ts +16 -0
- package/dist/core/api/parse.d.ts.map +1 -0
- package/dist/core/api/parse.js +40 -0
- package/dist/core/api/parse.js.map +1 -0
- package/dist/core/api/server.d.ts +310 -0
- package/dist/core/api/server.d.ts.map +1 -0
- package/dist/core/api/server.js +290 -0
- package/dist/core/api/server.js.map +1 -0
- package/dist/core/command/command.d.ts +20 -0
- package/dist/core/command/command.d.ts.map +1 -0
- package/dist/core/command/command.js +112 -0
- package/dist/core/command/command.js.map +1 -0
- package/dist/core/command/ids.d.ts +125 -0
- package/dist/core/command/ids.d.ts.map +1 -0
- package/dist/core/command/ids.js +85 -0
- package/dist/core/command/ids.js.map +1 -0
- package/dist/core/command/parser.d.ts +17 -0
- package/dist/core/command/parser.d.ts.map +1 -0
- package/dist/core/command/parser.js +65 -0
- package/dist/core/command/parser.js.map +1 -0
- package/dist/core/command/request.d.ts +61 -0
- package/dist/core/command/request.d.ts.map +1 -0
- package/dist/core/command/request.js +64 -0
- package/dist/core/command/request.js.map +1 -0
- package/dist/core/command/responses.d.ts +59 -0
- package/dist/core/command/responses.d.ts.map +1 -0
- package/dist/core/command/responses.js +74 -0
- package/dist/core/command/responses.js.map +1 -0
- package/dist/core/command-name.d.ts +333 -0
- package/dist/core/command-name.d.ts.map +1 -0
- package/dist/core/command-name.js +331 -0
- package/dist/core/command-name.js.map +1 -0
- package/dist/core/enums.d.ts +146 -0
- package/dist/core/enums.d.ts.map +1 -0
- package/dist/core/enums.js +132 -0
- package/dist/core/enums.js.map +1 -0
- package/dist/core/errorcode.d.ts +413 -0
- package/dist/core/errorcode.d.ts.map +1 -0
- package/dist/core/errorcode.js +410 -0
- package/dist/core/errorcode.js.map +1 -0
- package/dist/core/errors.d.ts +111 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +233 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/events.d.ts +207 -0
- package/dist/core/events.d.ts.map +1 -0
- package/dist/core/events.js +6 -0
- package/dist/core/events.js.map +1 -0
- package/dist/core/helpers.d.ts +42 -0
- package/dist/core/helpers.d.ts.map +1 -0
- package/dist/core/helpers.js +156 -0
- package/dist/core/helpers.js.map +1 -0
- package/dist/core/index.d.ts +35 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +34 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/internal.d.ts +23 -0
- package/dist/core/internal.d.ts.map +1 -0
- package/dist/core/internal.js +20 -0
- package/dist/core/internal.js.map +1 -0
- package/dist/core/middleware.d.ts +14 -0
- package/dist/core/middleware.d.ts.map +1 -0
- package/dist/core/middleware.js +18 -0
- package/dist/core/middleware.js.map +1 -0
- package/dist/core/notification-name.d.ts +154 -0
- package/dist/core/notification-name.d.ts.map +1 -0
- package/dist/core/notification-name.js +152 -0
- package/dist/core/notification-name.js.map +1 -0
- package/dist/core/notifications.d.ts +43 -0
- package/dist/core/notifications.d.ts.map +1 -0
- package/dist/core/notifications.js +116 -0
- package/dist/core/notifications.js.map +1 -0
- package/dist/core/permission-name.d.ts +533 -0
- package/dist/core/permission-name.d.ts.map +1 -0
- package/dist/core/permission-name.js +531 -0
- package/dist/core/permission-name.js.map +1 -0
- package/dist/core/permission.d.ts +31 -0
- package/dist/core/permission.d.ts.map +1 -0
- package/dist/core/permission.js +20 -0
- package/dist/core/permission.js.map +1 -0
- package/dist/core/property-name.d.ts +403 -0
- package/dist/core/property-name.d.ts.map +1 -0
- package/dist/core/property-name.js +405 -0
- package/dist/core/property-name.js.map +1 -0
- package/dist/core/reason.d.ts +39 -0
- package/dist/core/reason.d.ts.map +1 -0
- package/dist/core/reason.js +36 -0
- package/dist/core/reason.js.map +1 -0
- package/dist/core/reconnect.d.ts +59 -0
- package/dist/core/reconnect.d.ts.map +1 -0
- package/dist/core/reconnect.js +55 -0
- package/dist/core/reconnect.js.map +1 -0
- package/dist/core/types.d.ts +110 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +27 -0
- package/dist/core/types.js.map +1 -0
- package/dist/query/client.d.ts +194 -0
- package/dist/query/client.d.ts.map +1 -0
- package/dist/query/client.js +969 -0
- package/dist/query/client.js.map +1 -0
- package/dist/query/errors.d.ts +61 -0
- package/dist/query/errors.d.ts.map +1 -0
- package/dist/query/errors.js +100 -0
- package/dist/query/errors.js.map +1 -0
- package/dist/query/index.d.ts +36 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/index.js +34 -0
- package/dist/query/index.js.map +1 -0
- package/dist/query/knownhosts.d.ts +61 -0
- package/dist/query/knownhosts.d.ts.map +1 -0
- package/dist/query/knownhosts.js +223 -0
- package/dist/query/knownhosts.js.map +1 -0
- package/dist/query/lines.d.ts +14 -0
- package/dist/query/lines.d.ts.map +1 -0
- package/dist/query/lines.js +29 -0
- package/dist/query/lines.js.map +1 -0
- package/dist/query/options.d.ts +187 -0
- package/dist/query/options.d.ts.map +1 -0
- package/dist/query/options.js +213 -0
- package/dist/query/options.js.map +1 -0
- package/dist/query/reconnect.d.ts +29 -0
- package/dist/query/reconnect.d.ts.map +1 -0
- package/dist/query/reconnect.js +87 -0
- package/dist/query/reconnect.js.map +1 -0
- package/dist/query/ssh.d.ts +345 -0
- package/dist/query/ssh.d.ts.map +1 -0
- package/dist/query/ssh.js +241 -0
- package/dist/query/ssh.js.map +1 -0
- package/dist/query/stream.d.ts +38 -0
- package/dist/query/stream.d.ts.map +1 -0
- package/dist/query/stream.js +70 -0
- package/dist/query/stream.js.map +1 -0
- package/dist/query/tcp.d.ts +38 -0
- package/dist/query/tcp.d.ts.map +1 -0
- package/dist/query/tcp.js +53 -0
- package/dist/query/tcp.js.map +1 -0
- package/dist/query/transport.d.ts +36 -0
- package/dist/query/transport.d.ts.map +1 -0
- package/dist/query/transport.js +2 -0
- package/dist/query/transport.js.map +1 -0
- package/dist/query/web.d.ts +54 -0
- package/dist/query/web.d.ts.map +1 -0
- package/dist/query/web.js +146 -0
- package/dist/query/web.js.map +1 -0
- package/dist/versions/index.d.ts +3094 -0
- package/dist/versions/index.d.ts.map +1 -0
- package/dist/versions/index.js +9237 -0
- package/dist/versions/index.js.map +1 -0
- package/package.json +118 -4
- package/src/client/abort.ts +24 -0
- package/src/client/address.ts +74 -0
- package/src/client/api/voice.ts +61 -0
- package/src/client/capabilities.ts +106 -0
- package/src/client/client.ts +1809 -0
- package/src/client/commands.ts +193 -0
- package/src/client/crypto/crypt-ops.ts +6 -0
- package/src/client/crypto/crypt.ts +275 -0
- package/src/client/crypto/eax.ts +152 -0
- package/src/client/crypto/identity.ts +484 -0
- package/src/client/crypto/index.ts +21 -0
- package/src/client/crypto/primitives.ts +141 -0
- package/src/client/diagnostics.ts +58 -0
- package/src/client/discovery/index.ts +1 -0
- package/src/client/discovery/resolver.ts +325 -0
- package/src/client/errors.ts +217 -0
- package/src/client/events.ts +12 -0
- package/src/client/handshake/crypt-handshake.ts +157 -0
- package/src/client/handshake/crypt-init2.ts +48 -0
- package/src/client/handshake/index.ts +3 -0
- package/src/client/handshake/license.ts +208 -0
- package/src/client/handshake.ts +150 -0
- package/src/client/helpers.ts +10 -0
- package/src/client/hooks.ts +30 -0
- package/src/client/index.ts +93 -0
- package/src/client/reconnect.ts +43 -0
- package/src/client/throttle.ts +92 -0
- package/src/client/trace.ts +237 -0
- package/src/client/transfer.ts +436 -0
- package/src/client/transport/generation-window.ts +108 -0
- package/src/client/transport/handler.ts +926 -0
- package/src/client/transport/index.ts +14 -0
- package/src/client/transport/packet.ts +69 -0
- package/src/client/transport/quicklz.ts +209 -0
- package/src/client/types.ts +268 -0
- package/src/core/api/channels.ts +396 -0
- package/src/core/api/clients.ts +654 -0
- package/src/core/api/command.ts +563 -0
- package/src/core/api/files.ts +405 -0
- package/src/core/api/groups.ts +622 -0
- package/src/core/api/moderation.ts +525 -0
- package/src/core/api/parse.ts +52 -0
- package/src/core/api/server.ts +709 -0
- package/src/core/command/command.ts +125 -0
- package/src/core/command/ids.ts +149 -0
- package/src/core/command/parser.ts +68 -0
- package/src/core/command/request.ts +119 -0
- package/src/core/command/responses.ts +114 -0
- package/src/core/command-name.ts +334 -0
- package/src/core/enums.ts +167 -0
- package/src/core/errorcode.ts +412 -0
- package/src/core/errors.ts +258 -0
- package/src/core/events.ts +219 -0
- package/src/core/helpers.ts +161 -0
- package/src/core/index.ts +126 -0
- package/src/core/internal.ts +23 -0
- package/src/core/middleware.ts +24 -0
- package/src/core/notification-name.ts +155 -0
- package/src/core/notifications.ts +157 -0
- package/src/core/permission-name.ts +538 -0
- package/src/core/permission.ts +34 -0
- package/src/core/property-name.ts +411 -0
- package/src/core/reason.ts +38 -0
- package/src/core/reconnect.ts +98 -0
- package/src/core/types.ts +138 -0
- package/src/query/client.ts +1129 -0
- package/src/query/errors.ts +108 -0
- package/src/query/index.ts +65 -0
- package/src/query/knownhosts.ts +257 -0
- package/src/query/lines.ts +28 -0
- package/src/query/options.ts +388 -0
- package/src/query/reconnect.ts +84 -0
- package/src/query/ssh.ts +614 -0
- package/src/query/stream.ts +91 -0
- package/src/query/tcp.ts +85 -0
- package/src/query/transport.ts +35 -0
- package/src/query/web.ts +195 -0
- package/src/versions/index.ts +10774 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed command layer.
|
|
3
|
+
*
|
|
4
|
+
* Every command both the voice protocol and ServerQuery accept is one function
|
|
5
|
+
* here, running on any CommandExecutor. Functions that only send a command
|
|
6
|
+
* return `Promise<void>`; functions that read return a parsed type. Every one
|
|
7
|
+
* takes a last, optional {@link CommandOptions} — a signal to abandon it and a
|
|
8
|
+
* timeoutMs — which is passed to the executor as it is.
|
|
9
|
+
*
|
|
10
|
+
* Nothing here re-encodes ids or field names by hand at the call site: the
|
|
11
|
+
* branded id types, the field tables below and the request encoder
|
|
12
|
+
* turn parameters into wire form in one place.
|
|
13
|
+
*/
|
|
14
|
+
import type { CommandExecutor, CommandOptions, ParamValue } from "../command/request.js";
|
|
15
|
+
import type { ChannelID, ChannelUID, IconID } from "../command/ids.js";
|
|
16
|
+
import type { Permission } from "../permission.js";
|
|
17
|
+
/** Parameters in the order they are sent. */
|
|
18
|
+
export type Params = ReadonlyArray<readonly [string, ParamValue]>;
|
|
19
|
+
/**
|
|
20
|
+
* Send a command that produces no data and wait for the server's answer.
|
|
21
|
+
*
|
|
22
|
+
* `passwords` names the parameters that carry a channel password. Naming them
|
|
23
|
+
* here, rather than encoding them, leaves the encoding to the transport — the
|
|
24
|
+
* voice protocol hashes them, ServerQuery does not — and keeps every call site
|
|
25
|
+
* from having to remember, which is how a raw password once reached the server
|
|
26
|
+
* and failed 781.
|
|
27
|
+
*/
|
|
28
|
+
declare function exec(client: CommandExecutor, command: string, params?: Params, options?: CommandOptions, passwords?: readonly string[]): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* The signal and timeoutMs of a command's options, alone: a command's own
|
|
31
|
+
* options extend CommandOptions, and the executor, and any middleware on it,
|
|
32
|
+
* should see only what is theirs.
|
|
33
|
+
*/
|
|
34
|
+
declare function commandOptions(options: CommandOptions | undefined): CommandOptions | undefined;
|
|
35
|
+
/** Send a command and return its response rows. */
|
|
36
|
+
declare function query(client: CommandExecutor, command: string, params?: Params, options?: CommandOptions, passwords?: readonly string[]): Promise<Array<Record<string, string>>>;
|
|
37
|
+
/**
|
|
38
|
+
* Send a command that lists or finds something and return its rows.
|
|
39
|
+
*
|
|
40
|
+
* The server reports an empty list as error 1281, "database empty result set",
|
|
41
|
+
* rather than as no rows — `banlist` on a server with no bans, `messagelist`
|
|
42
|
+
* with no messages — which made every list function throw where it should
|
|
43
|
+
* have answered `[]`. A search may report finding nothing with an error of its
|
|
44
|
+
* own, `how.noMatch`: `clientfind` answers 512 and `channelfind` 768, which for a
|
|
45
|
+
* command naming no client or channel can mean nothing else. `how.passwords`
|
|
46
|
+
* is as for {@link exec}.
|
|
47
|
+
*/
|
|
48
|
+
declare function list(client: CommandExecutor, command: string, params?: Params, options?: CommandOptions, how?: {
|
|
49
|
+
readonly noMatch?: number;
|
|
50
|
+
readonly passwords?: readonly string[];
|
|
51
|
+
}): Promise<Array<Record<string, string>>>;
|
|
52
|
+
/** How a paged command is walked, as by {@link iterateClientDatabase}. */
|
|
53
|
+
export interface PagingOptions extends CommandOptions {
|
|
54
|
+
/**
|
|
55
|
+
* How many rows to ask for per page; 100 by default. The server may cap a
|
|
56
|
+
* page below this, which the walk allows for.
|
|
57
|
+
*/
|
|
58
|
+
readonly pageSize?: number | undefined;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Walk a command the server pages with `start` and `duration`, a page at a
|
|
62
|
+
* time, as the caller asks for more.
|
|
63
|
+
*
|
|
64
|
+
* The walk ends when the server answers a `start` past the last row with error
|
|
65
|
+
* 1281, "database empty result set", on an empty page, or on a page shorter
|
|
66
|
+
* than an earlier one. A short *first* page does not end it: the server may cap
|
|
67
|
+
* a page below what was asked, so the walk asks once more to find out. It also
|
|
68
|
+
* ends when a page starts at or before the last row already seen
|
|
69
|
+
* (`advanced` says), which is a server ignoring `start` — without that check
|
|
70
|
+
* such a server would be asked for its first page forever.
|
|
71
|
+
*
|
|
72
|
+
* Any other error is thrown from the iteration. Rows added or removed during
|
|
73
|
+
* the walk can be skipped or seen twice, since each page is a separate query.
|
|
74
|
+
*
|
|
75
|
+
* `options` reaches every page's command.
|
|
76
|
+
*/
|
|
77
|
+
declare function pages<T>(client: CommandExecutor, command: string, parse: (row: Record<string, string>) => T, advanced: (previous: T, next: T) => boolean, options?: PagingOptions): AsyncGenerator<T, void, undefined>;
|
|
78
|
+
/**
|
|
79
|
+
* The row a command is defined to answer with, which must hold `key` when one
|
|
80
|
+
* is named. A server that acknowledged the command without it has not
|
|
81
|
+
* answered, which is a NoDataError rather than a row of empty fields.
|
|
82
|
+
*/
|
|
83
|
+
declare function firstRow(rows: ReadonlyArray<Record<string, string>>, command: string, key?: string): Record<string, string>;
|
|
84
|
+
export { exec, query, list, pages, commandOptions, firstRow };
|
|
85
|
+
export type { ParamValue };
|
|
86
|
+
/**
|
|
87
|
+
* How one option field goes on the wire: its parameter name, or its name and a
|
|
88
|
+
* function from the field's value to the parameter's. An encoder may return
|
|
89
|
+
* undefined to omit the parameter.
|
|
90
|
+
*/
|
|
91
|
+
export type WireField<V> = string | readonly [name: string, encode: (value: V) => ParamValue];
|
|
92
|
+
/**
|
|
93
|
+
* A wire name for every field of an options type.
|
|
94
|
+
*
|
|
95
|
+
* Every key is required, so a field added to the options interface without a
|
|
96
|
+
* wire name is a compile error rather than a field silently never sent; the
|
|
97
|
+
* signal and timeoutMs every command's options carry are not parameters. A
|
|
98
|
+
* field whose type is not already a parameter value — a duration in
|
|
99
|
+
* milliseconds sent in seconds, say — must have an encoder.
|
|
100
|
+
*/
|
|
101
|
+
export type WireNames<T> = {
|
|
102
|
+
readonly [K in Exclude<keyof T, keyof CommandOptions>]-?: Exclude<T[K], undefined> extends ParamValue ? WireField<Exclude<T[K], undefined>> : readonly [name: string, encode: (value: Exclude<T[K], undefined>) => ParamValue];
|
|
103
|
+
};
|
|
104
|
+
/**
|
|
105
|
+
* Encode an options object through its field table.
|
|
106
|
+
*
|
|
107
|
+
* The table, not the object, decides what is sent: a key missing from the
|
|
108
|
+
* table — a typo, or anything else a JavaScript caller put there — is ignored
|
|
109
|
+
* rather than forwarded onto the wire. An unset field (undefined, or null from
|
|
110
|
+
* JavaScript) is omitted; any other value is sent, so `""` is sent as an empty
|
|
111
|
+
* parameter, which is how a setting such as a channel password is cleared.
|
|
112
|
+
*/
|
|
113
|
+
export declare function encodeFields<T extends object>(fields: T, names: WireNames<T>): Params;
|
|
114
|
+
/** An encoder that omits an empty string instead of sending it. */
|
|
115
|
+
export declare const nonEmpty: (value: string) => string | undefined;
|
|
116
|
+
/**
|
|
117
|
+
* An encoder that omits an id of 0 instead of sending it: where a command
|
|
118
|
+
* takes an id as a filter or a target, 0 names no channel, client or group,
|
|
119
|
+
* so it can only mean "any" or "none".
|
|
120
|
+
*/
|
|
121
|
+
export declare const nonZero: (value: bigint) => bigint | undefined;
|
|
122
|
+
/** One second, in milliseconds: the unit most durations travel in. */
|
|
123
|
+
export declare const SECOND = 1000;
|
|
124
|
+
/** One millisecond: the unit `client_idle_time` and its like travel in. */
|
|
125
|
+
export declare const MILLISECOND = 1;
|
|
126
|
+
/**
|
|
127
|
+
* A duration in milliseconds, as the count of `unitMs` the wire carries.
|
|
128
|
+
*
|
|
129
|
+
* Rounds to the nearest unit, except that a positive duration never becomes 0:
|
|
130
|
+
* several fields read 0 as "forever" (a ban) or "never" (a temporary
|
|
131
|
+
* password), so half a second sent as 0 seconds would turn a short ban into a
|
|
132
|
+
* permanent one. A negative or non-finite duration is refused.
|
|
133
|
+
*/
|
|
134
|
+
export declare function toWireDuration(ms: number, unitMs: number): number;
|
|
135
|
+
/** An encoder for a millisecond field the wire carries in seconds. */
|
|
136
|
+
export declare const inSeconds: (ms: number) => number;
|
|
137
|
+
/**
|
|
138
|
+
* Read a string field, tolerating absence.
|
|
139
|
+
*
|
|
140
|
+
* The parser has already unescaped it; unescaping again would turn a nickname
|
|
141
|
+
* that really contains `\s` into one with a space.
|
|
142
|
+
*/
|
|
143
|
+
declare const str: (row: Record<string, string>, key: string) => string;
|
|
144
|
+
/**
|
|
145
|
+
* Read an unsigned 64-bit field, tolerating absence. Garbage, and a value
|
|
146
|
+
* outside 0 to 2^64-1, read as 0: every field read this way is an id or a
|
|
147
|
+
* size, and reading one must not throw where the id constructors would.
|
|
148
|
+
*/
|
|
149
|
+
declare const big: (row: Record<string, string>, key: string) => bigint;
|
|
150
|
+
/**
|
|
151
|
+
* Read an id no wider than `max`: an integer from 0 to `max`, or 0 for
|
|
152
|
+
* anything else, so the id constructors never see a value they refuse.
|
|
153
|
+
*/
|
|
154
|
+
declare const uint: (row: Record<string, string>, key: string, max: number) => number;
|
|
155
|
+
/** The widths {@link uint} reads ids at. */
|
|
156
|
+
declare const U16 = 65535;
|
|
157
|
+
declare const U32 = 4294967295;
|
|
158
|
+
/** Read a number field, tolerating absence. Fractions are kept. */
|
|
159
|
+
declare const num: (row: Record<string, string>, key: string) => number;
|
|
160
|
+
/** Read a boolean field: the protocol writes 0/1. */
|
|
161
|
+
declare const bool: (row: Record<string, string>, key: string) => boolean;
|
|
162
|
+
/** Read an icon id, signed or unsigned, as its unsigned value; 0 is no icon. */
|
|
163
|
+
declare const icon: (row: Record<string, string>, key: string) => IconID | undefined;
|
|
164
|
+
/**
|
|
165
|
+
* Read a unix timestamp as a Date.
|
|
166
|
+
*
|
|
167
|
+
* 0, absence and garbage are `undefined`, not 1970: the server sends 0 for
|
|
168
|
+
* "never" (a client that never connected, a key never used).
|
|
169
|
+
*/
|
|
170
|
+
declare const date: (row: Record<string, string>, key: string) => Date | undefined;
|
|
171
|
+
/** Read a duration sent as a count of `unitMs`, in milliseconds. */
|
|
172
|
+
declare const durationMs: (row: Record<string, string>, key: string, unitMs: number) => number;
|
|
173
|
+
export { str, big, num, uint, U16, U32, bool, icon, date, durationMs };
|
|
174
|
+
/**
|
|
175
|
+
* The id of the group a create or copy just made.
|
|
176
|
+
*
|
|
177
|
+
* ServerQuery answers `servergroupadd` with the new id alone. The voice
|
|
178
|
+
* protocol answers with the whole group list instead (`notifyservergrouplist`),
|
|
179
|
+
* so taking the first row returned the first group on the server rather than
|
|
180
|
+
* the new one. The new group is the one with the requested name — the newest,
|
|
181
|
+
* should the name repeat across group types.
|
|
182
|
+
*
|
|
183
|
+
* The difference is a property of the answers, not a choice:
|
|
184
|
+
* `notifychannelcreated` names the client that invoked it, so `channelcreate`
|
|
185
|
+
* keeps only its own row, while the group commands answer with the whole list
|
|
186
|
+
* and name no invoker — `notifyservergrouplist` for `servergroupadd` and
|
|
187
|
+
* `servergroupcopy`, `notifychannelgrouplist` for `channelgroupadd` and
|
|
188
|
+
* `channelgroupcopy` — leaving nothing but the name to match on. A group of
|
|
189
|
+
* the same name created concurrently by another party is therefore
|
|
190
|
+
* indistinguishable from ours, channel groups as much as server groups, and
|
|
191
|
+
* the id returned may be theirs rather than the one we just made. That is a
|
|
192
|
+
* limit of what the notification reports, not of this function.
|
|
193
|
+
*/
|
|
194
|
+
export declare function createdGroupID(rows: ReadonlyArray<Record<string, string>>, idKey: "sgid" | "cgid", name: string, command: string): bigint;
|
|
195
|
+
/**
|
|
196
|
+
* Encode a permission as `permid` or `permsid`, whichever names it.
|
|
197
|
+
*
|
|
198
|
+
* A JavaScript caller can pass an object naming neither, and a command sent
|
|
199
|
+
* with neither parameter fails on the server with a less helpful error, if it
|
|
200
|
+
* fails at all — so that is refused here.
|
|
201
|
+
*/
|
|
202
|
+
export declare function permissionParam(permission: Permission): readonly [string, ParamValue];
|
|
203
|
+
/** A channel as returned by `channellist` or `channelinfo`. */
|
|
204
|
+
export interface Channel {
|
|
205
|
+
/** The channel's id. */
|
|
206
|
+
readonly id: ChannelID;
|
|
207
|
+
/**
|
|
208
|
+
* The channel this one sits under, or 0 at the top level.
|
|
209
|
+
*
|
|
210
|
+
* `channellist` names this `cpid` and `channelinfo` names it `pid` — the same
|
|
211
|
+
* value under two keys, which is why both are read here.
|
|
212
|
+
*/
|
|
213
|
+
readonly parentID: ChannelID;
|
|
214
|
+
/** The channel's name. */
|
|
215
|
+
readonly name: string;
|
|
216
|
+
/** The topic shown under the name (`channel_topic`). */
|
|
217
|
+
readonly topic: string;
|
|
218
|
+
/**
|
|
219
|
+
* The description (`channel_description`). `channellist` does not carry it,
|
|
220
|
+
* so `listChannels` leaves it empty; `getChannelInfo` or the voice client's
|
|
221
|
+
* `getChannelDescription` has it.
|
|
222
|
+
*/
|
|
223
|
+
readonly description: string;
|
|
224
|
+
/**
|
|
225
|
+
* The channel this one is sorted after among its siblings, or 0 for the
|
|
226
|
+
* first: `channel_order` is a channel id, not a position.
|
|
227
|
+
*/
|
|
228
|
+
readonly order: ChannelID;
|
|
229
|
+
/** Whether joining needs a password. */
|
|
230
|
+
readonly hasPassword: boolean;
|
|
231
|
+
/** Whether new clients land here. */
|
|
232
|
+
readonly isDefault: boolean;
|
|
233
|
+
/** Whether the channel survives a server restart (`channel_flag_permanent`). */
|
|
234
|
+
readonly isPermanent: boolean;
|
|
235
|
+
/**
|
|
236
|
+
* Whether the channel is kept until the last client leaves it, but not
|
|
237
|
+
* across a restart (`channel_flag_semi_permanent`).
|
|
238
|
+
*/
|
|
239
|
+
readonly isSemiPermanent: boolean;
|
|
240
|
+
/** The voice codec, one of {@link Codec}. */
|
|
241
|
+
readonly codec: number;
|
|
242
|
+
/** The codec's quality, 0 to 10. */
|
|
243
|
+
readonly codecQuality: number;
|
|
244
|
+
/** How many clients may be in the channel (`channel_maxclients`); -1 for no limit. */
|
|
245
|
+
readonly maxClients: number;
|
|
246
|
+
/**
|
|
247
|
+
* How many clients may be in the channel and its subchannels together
|
|
248
|
+
* (`channel_maxfamilyclients`); -1 for no limit.
|
|
249
|
+
*/
|
|
250
|
+
readonly maxFamilyClients: number;
|
|
251
|
+
/**
|
|
252
|
+
* How many clients are in the channel now (`total_clients`).
|
|
253
|
+
* `listChannels` reports it; `getChannelInfo` leaves it undefined, because
|
|
254
|
+
* `channelinfo` does not carry it.
|
|
255
|
+
*/
|
|
256
|
+
readonly totalClients: number | undefined;
|
|
257
|
+
/**
|
|
258
|
+
* How many clients are in the channel and its subchannels now
|
|
259
|
+
* (`total_clients_family`). `listChannels` reports it; `getChannelInfo`
|
|
260
|
+
* leaves it undefined, because `channelinfo` does not carry it.
|
|
261
|
+
*/
|
|
262
|
+
readonly totalFamilyClients: number | undefined;
|
|
263
|
+
/**
|
|
264
|
+
* The subscribe power a client needs to subscribe to the channel
|
|
265
|
+
* (`channel_needed_subscribe_power`). `listChannels` reports it;
|
|
266
|
+
* `getChannelInfo` leaves it undefined, because `channelinfo` does not
|
|
267
|
+
* carry it.
|
|
268
|
+
*/
|
|
269
|
+
readonly neededSubscribePower: number | undefined;
|
|
270
|
+
/** The talk power a client needs to speak here. */
|
|
271
|
+
readonly neededTalkPower: number;
|
|
272
|
+
/** The channel's icon, or undefined for none. */
|
|
273
|
+
readonly iconID: IconID | undefined;
|
|
274
|
+
/**
|
|
275
|
+
* The unique identifier the server gives the channel
|
|
276
|
+
* (`channel_unique_identifier`): TS6 sends one, TS3 none, which reads as "".
|
|
277
|
+
* `channellist` does not carry it, so `listChannels` leaves it empty.
|
|
278
|
+
*/
|
|
279
|
+
readonly uid: ChannelUID;
|
|
280
|
+
}
|
|
281
|
+
declare function parseChannel(row: Record<string, string>): Channel;
|
|
282
|
+
export { parseChannel };
|
|
283
|
+
/** One entry of a permission list. */
|
|
284
|
+
export interface PermissionEntry {
|
|
285
|
+
/**
|
|
286
|
+
* The permission the entry sets, named the way the server sent it — by id,
|
|
287
|
+
* unless a row carries the name. It can be passed straight back to the
|
|
288
|
+
* matching delete function.
|
|
289
|
+
*/
|
|
290
|
+
readonly permission: Permission;
|
|
291
|
+
/** The permission's value. */
|
|
292
|
+
readonly value: number;
|
|
293
|
+
/** Whether the value is negated, taking the lowest value instead of the highest. */
|
|
294
|
+
readonly negated: boolean;
|
|
295
|
+
/** Whether the permission skips channel and client overrides. */
|
|
296
|
+
readonly skip: boolean;
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* Parse one permission row.
|
|
300
|
+
*
|
|
301
|
+
* A permission is addressable by id or by name, and the server answers in
|
|
302
|
+
* whichever form the request used, so a row carries one or the other.
|
|
303
|
+
*/
|
|
304
|
+
export declare function parsePermission(row: Record<string, string>): PermissionEntry;
|
|
305
|
+
//# sourceMappingURL=command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../../src/core/api/command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed command layer.
|
|
3
|
+
*
|
|
4
|
+
* Every command both the voice protocol and ServerQuery accept is one function
|
|
5
|
+
* here, running on any CommandExecutor. Functions that only send a command
|
|
6
|
+
* return `Promise<void>`; functions that read return a parsed type. Every one
|
|
7
|
+
* takes a last, optional {@link CommandOptions} — a signal to abandon it and a
|
|
8
|
+
* timeoutMs — which is passed to the executor as it is.
|
|
9
|
+
*
|
|
10
|
+
* Nothing here re-encodes ids or field names by hand at the call site: the
|
|
11
|
+
* branded id types, the field tables below and the request encoder
|
|
12
|
+
* turn parameters into wire form in one place.
|
|
13
|
+
*/
|
|
14
|
+
import { ErrorCode } from "../errorcode.js";
|
|
15
|
+
import { NoDataError, ServerError } from "../errors.js";
|
|
16
|
+
import { asChannelID, asChannelUID, asPermissionID, parseIconID } from "../command/ids.js";
|
|
17
|
+
import { permissionByID, permissionByName } from "../permission.js";
|
|
18
|
+
// ---- Sending ----------------------------------------------------------------
|
|
19
|
+
/**
|
|
20
|
+
* Send a command that produces no data and wait for the server's answer.
|
|
21
|
+
*
|
|
22
|
+
* `passwords` names the parameters that carry a channel password. Naming them
|
|
23
|
+
* here, rather than encoding them, leaves the encoding to the transport — the
|
|
24
|
+
* voice protocol hashes them, ServerQuery does not — and keeps every call site
|
|
25
|
+
* from having to remember, which is how a raw password once reached the server
|
|
26
|
+
* and failed 781.
|
|
27
|
+
*/
|
|
28
|
+
async function exec(client, command, params = [], options, passwords = []) {
|
|
29
|
+
await client.send({ command, params, passwords }, commandOptions(options));
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The signal and timeoutMs of a command's options, alone: a command's own
|
|
33
|
+
* options extend CommandOptions, and the executor, and any middleware on it,
|
|
34
|
+
* should see only what is theirs.
|
|
35
|
+
*/
|
|
36
|
+
function commandOptions(options) {
|
|
37
|
+
if (options === undefined)
|
|
38
|
+
return undefined;
|
|
39
|
+
return { signal: options.signal, timeoutMs: options.timeoutMs };
|
|
40
|
+
}
|
|
41
|
+
/** Send a command and return its response rows. */
|
|
42
|
+
async function query(client, command, params = [], options, passwords = []) {
|
|
43
|
+
return client.send({ command, params, passwords }, commandOptions(options));
|
|
44
|
+
}
|
|
45
|
+
/** Whether an error is the server's "database empty result set" (1281). */
|
|
46
|
+
const isEmptyResult = (err) => err instanceof ServerError && err.code === ErrorCode.DatabaseEmptyResult;
|
|
47
|
+
/**
|
|
48
|
+
* Send a command that lists or finds something and return its rows.
|
|
49
|
+
*
|
|
50
|
+
* The server reports an empty list as error 1281, "database empty result set",
|
|
51
|
+
* rather than as no rows — `banlist` on a server with no bans, `messagelist`
|
|
52
|
+
* with no messages — which made every list function throw where it should
|
|
53
|
+
* have answered `[]`. A search may report finding nothing with an error of its
|
|
54
|
+
* own, `how.noMatch`: `clientfind` answers 512 and `channelfind` 768, which for a
|
|
55
|
+
* command naming no client or channel can mean nothing else. `how.passwords`
|
|
56
|
+
* is as for {@link exec}.
|
|
57
|
+
*/
|
|
58
|
+
async function list(client, command, params = [], options, how = {}) {
|
|
59
|
+
const { noMatch, passwords } = how;
|
|
60
|
+
try {
|
|
61
|
+
return await query(client, command, params, options, passwords);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
if (isEmptyResult(err))
|
|
65
|
+
return [];
|
|
66
|
+
if (noMatch !== undefined && err instanceof ServerError && err.code === noMatch)
|
|
67
|
+
return [];
|
|
68
|
+
throw err;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Default page size for a paged walk. */
|
|
72
|
+
const DEFAULT_PAGE_SIZE = 100;
|
|
73
|
+
/**
|
|
74
|
+
* Walk a command the server pages with `start` and `duration`, a page at a
|
|
75
|
+
* time, as the caller asks for more.
|
|
76
|
+
*
|
|
77
|
+
* The walk ends when the server answers a `start` past the last row with error
|
|
78
|
+
* 1281, "database empty result set", on an empty page, or on a page shorter
|
|
79
|
+
* than an earlier one. A short *first* page does not end it: the server may cap
|
|
80
|
+
* a page below what was asked, so the walk asks once more to find out. It also
|
|
81
|
+
* ends when a page starts at or before the last row already seen
|
|
82
|
+
* (`advanced` says), which is a server ignoring `start` — without that check
|
|
83
|
+
* such a server would be asked for its first page forever.
|
|
84
|
+
*
|
|
85
|
+
* Any other error is thrown from the iteration. Rows added or removed during
|
|
86
|
+
* the walk can be skipped or seen twice, since each page is a separate query.
|
|
87
|
+
*
|
|
88
|
+
* `options` reaches every page's command.
|
|
89
|
+
*/
|
|
90
|
+
async function* pages(client, command, parse, advanced, options = {}) {
|
|
91
|
+
const { pageSize = DEFAULT_PAGE_SIZE, ...rest } = options;
|
|
92
|
+
if (!Number.isInteger(pageSize) || pageSize < 1) {
|
|
93
|
+
throw new RangeError(`a page size is a positive integer, not ${pageSize}`);
|
|
94
|
+
}
|
|
95
|
+
let start = 0;
|
|
96
|
+
let fullPage = 0;
|
|
97
|
+
let last;
|
|
98
|
+
for (;;) {
|
|
99
|
+
let rows;
|
|
100
|
+
try {
|
|
101
|
+
rows = await query(client, command, [
|
|
102
|
+
["start", start],
|
|
103
|
+
["duration", pageSize],
|
|
104
|
+
], rest);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
if (isEmptyResult(err))
|
|
108
|
+
return;
|
|
109
|
+
throw err;
|
|
110
|
+
}
|
|
111
|
+
if (rows.length === 0)
|
|
112
|
+
return;
|
|
113
|
+
const parsed = rows.map(parse);
|
|
114
|
+
if (last !== undefined && !advanced(last, parsed[0]))
|
|
115
|
+
return;
|
|
116
|
+
for (const item of parsed)
|
|
117
|
+
yield item;
|
|
118
|
+
last = parsed[parsed.length - 1];
|
|
119
|
+
if (rows.length < fullPage)
|
|
120
|
+
return;
|
|
121
|
+
fullPage = Math.max(fullPage, rows.length);
|
|
122
|
+
start += rows.length;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The row a command is defined to answer with, which must hold `key` when one
|
|
127
|
+
* is named. A server that acknowledged the command without it has not
|
|
128
|
+
* answered, which is a NoDataError rather than a row of empty fields.
|
|
129
|
+
*/
|
|
130
|
+
function firstRow(rows, command, key) {
|
|
131
|
+
const row = rows[0];
|
|
132
|
+
if (row === undefined || (key !== undefined && (row[key] ?? "") === "")) {
|
|
133
|
+
throw new NoDataError(command);
|
|
134
|
+
}
|
|
135
|
+
return row;
|
|
136
|
+
}
|
|
137
|
+
export { exec, query, list, pages, commandOptions, firstRow };
|
|
138
|
+
/**
|
|
139
|
+
* Encode an options object through its field table.
|
|
140
|
+
*
|
|
141
|
+
* The table, not the object, decides what is sent: a key missing from the
|
|
142
|
+
* table — a typo, or anything else a JavaScript caller put there — is ignored
|
|
143
|
+
* rather than forwarded onto the wire. An unset field (undefined, or null from
|
|
144
|
+
* JavaScript) is omitted; any other value is sent, so `""` is sent as an empty
|
|
145
|
+
* parameter, which is how a setting such as a channel password is cleared.
|
|
146
|
+
*/
|
|
147
|
+
export function encodeFields(fields, names) {
|
|
148
|
+
const out = [];
|
|
149
|
+
for (const key of Object.keys(names)) {
|
|
150
|
+
const value = fields[key];
|
|
151
|
+
if (value === undefined || value === null)
|
|
152
|
+
continue;
|
|
153
|
+
const field = names[key];
|
|
154
|
+
if (typeof field === "string")
|
|
155
|
+
out.push([field, value]);
|
|
156
|
+
else
|
|
157
|
+
out.push([field[0], field[1](value)]);
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
/** An encoder that omits an empty string instead of sending it. */
|
|
162
|
+
export const nonEmpty = (value) => (value === "" ? undefined : value);
|
|
163
|
+
/**
|
|
164
|
+
* An encoder that omits an id of 0 instead of sending it: where a command
|
|
165
|
+
* takes an id as a filter or a target, 0 names no channel, client or group,
|
|
166
|
+
* so it can only mean "any" or "none".
|
|
167
|
+
*/
|
|
168
|
+
export const nonZero = (value) => (value === 0n ? undefined : value);
|
|
169
|
+
// ---- Units ------------------------------------------------------------------
|
|
170
|
+
/** One second, in milliseconds: the unit most durations travel in. */
|
|
171
|
+
export const SECOND = 1000;
|
|
172
|
+
/** One millisecond: the unit `client_idle_time` and its like travel in. */
|
|
173
|
+
export const MILLISECOND = 1;
|
|
174
|
+
/**
|
|
175
|
+
* A duration in milliseconds, as the count of `unitMs` the wire carries.
|
|
176
|
+
*
|
|
177
|
+
* Rounds to the nearest unit, except that a positive duration never becomes 0:
|
|
178
|
+
* several fields read 0 as "forever" (a ban) or "never" (a temporary
|
|
179
|
+
* password), so half a second sent as 0 seconds would turn a short ban into a
|
|
180
|
+
* permanent one. A negative or non-finite duration is refused.
|
|
181
|
+
*/
|
|
182
|
+
export function toWireDuration(ms, unitMs) {
|
|
183
|
+
if (!Number.isFinite(ms) || ms < 0) {
|
|
184
|
+
throw new RangeError(`a duration is a non-negative number of milliseconds, not ${ms}`);
|
|
185
|
+
}
|
|
186
|
+
const units = Math.round(ms / unitMs);
|
|
187
|
+
return units === 0 && ms > 0 ? 1 : units;
|
|
188
|
+
}
|
|
189
|
+
/** An encoder for a millisecond field the wire carries in seconds. */
|
|
190
|
+
export const inSeconds = (ms) => toWireDuration(ms, SECOND);
|
|
191
|
+
// ---- Reading rows -----------------------------------------------------------
|
|
192
|
+
/**
|
|
193
|
+
* Read a string field, tolerating absence.
|
|
194
|
+
*
|
|
195
|
+
* The parser has already unescaped it; unescaping again would turn a nickname
|
|
196
|
+
* that really contains `\s` into one with a space.
|
|
197
|
+
*/
|
|
198
|
+
const str = (row, key) => row[key] ?? "";
|
|
199
|
+
/**
|
|
200
|
+
* Read an unsigned 64-bit field, tolerating absence. Garbage, and a value
|
|
201
|
+
* outside 0 to 2^64-1, read as 0: every field read this way is an id or a
|
|
202
|
+
* size, and reading one must not throw where the id constructors would.
|
|
203
|
+
*/
|
|
204
|
+
const big = (row, key) => {
|
|
205
|
+
const raw = row[key];
|
|
206
|
+
if (raw === undefined || !/^\d+$/.test(raw))
|
|
207
|
+
return 0n;
|
|
208
|
+
const value = BigInt(raw);
|
|
209
|
+
return value > MAX_UINT64 ? 0n : value;
|
|
210
|
+
};
|
|
211
|
+
const MAX_UINT64 = (1n << 64n) - 1n;
|
|
212
|
+
/**
|
|
213
|
+
* Read an id no wider than `max`: an integer from 0 to `max`, or 0 for
|
|
214
|
+
* anything else, so the id constructors never see a value they refuse.
|
|
215
|
+
*/
|
|
216
|
+
const uint = (row, key, max) => {
|
|
217
|
+
const value = num(row, key);
|
|
218
|
+
return Number.isInteger(value) && value >= 0 && value <= max ? value : 0;
|
|
219
|
+
};
|
|
220
|
+
/** The widths {@link uint} reads ids at. */
|
|
221
|
+
const U16 = 0xffff;
|
|
222
|
+
const U32 = 0xffff_ffff;
|
|
223
|
+
/** Read a number field, tolerating absence. Fractions are kept. */
|
|
224
|
+
const num = (row, key) => {
|
|
225
|
+
const raw = row[key];
|
|
226
|
+
if (raw === undefined || raw === "")
|
|
227
|
+
return 0;
|
|
228
|
+
const parsed = Number(raw);
|
|
229
|
+
return Number.isNaN(parsed) ? 0 : parsed;
|
|
230
|
+
};
|
|
231
|
+
/** Read a number field that may be absent: undefined when the key is missing, else as {@link num}. */
|
|
232
|
+
const optNum = (row, key) => row[key] === undefined ? undefined : num(row, key);
|
|
233
|
+
/** Read a boolean field: the protocol writes 0/1. */
|
|
234
|
+
const bool = (row, key) => num(row, key) !== 0;
|
|
235
|
+
/** Read an icon id, signed or unsigned, as its unsigned value; 0 is no icon. */
|
|
236
|
+
const icon = (row, key) => parseIconID(row[key]);
|
|
237
|
+
// Timestamps at or above these are not seconds. TS6 sends some in finer units —
|
|
238
|
+
// ftgetfilelist's datetime in milliseconds, ftgetfileinfo's in nanoseconds, for
|
|
239
|
+
// the same file — while TS3 sends seconds throughout. 1e11 seconds is the year
|
|
240
|
+
// 5138, and 1e11 milliseconds early 1973, so the magnitude settles the unit for
|
|
241
|
+
// any date this protocol will carry.
|
|
242
|
+
const MAX_UNIX_SECONDS = 10n ** 11n;
|
|
243
|
+
const MAX_UNIX_MILLIS = 10n ** 14n;
|
|
244
|
+
const MAX_UNIX_MICROS = 10n ** 17n;
|
|
245
|
+
/**
|
|
246
|
+
* Read a unix timestamp as a Date.
|
|
247
|
+
*
|
|
248
|
+
* 0, absence and garbage are `undefined`, not 1970: the server sends 0 for
|
|
249
|
+
* "never" (a client that never connected, a key never used).
|
|
250
|
+
*/
|
|
251
|
+
const date = (row, key) => {
|
|
252
|
+
const raw = row[key];
|
|
253
|
+
if (raw === undefined || !/^-?\d+$/.test(raw))
|
|
254
|
+
return undefined;
|
|
255
|
+
const value = BigInt(raw);
|
|
256
|
+
if (value <= 0n)
|
|
257
|
+
return undefined;
|
|
258
|
+
if (value < MAX_UNIX_SECONDS)
|
|
259
|
+
return new Date(Number(value) * 1000);
|
|
260
|
+
if (value < MAX_UNIX_MILLIS)
|
|
261
|
+
return new Date(Number(value));
|
|
262
|
+
if (value < MAX_UNIX_MICROS)
|
|
263
|
+
return new Date(Number(value / 1000n));
|
|
264
|
+
return new Date(Number(value / 1000000n));
|
|
265
|
+
};
|
|
266
|
+
/** Read a duration sent as a count of `unitMs`, in milliseconds. */
|
|
267
|
+
const durationMs = (row, key, unitMs) => num(row, key) * unitMs;
|
|
268
|
+
export { str, big, num, uint, U16, U32, bool, icon, date, durationMs };
|
|
269
|
+
// ---- Shared shapes ----------------------------------------------------------
|
|
270
|
+
/**
|
|
271
|
+
* The id of the group a create or copy just made.
|
|
272
|
+
*
|
|
273
|
+
* ServerQuery answers `servergroupadd` with the new id alone. The voice
|
|
274
|
+
* protocol answers with the whole group list instead (`notifyservergrouplist`),
|
|
275
|
+
* so taking the first row returned the first group on the server rather than
|
|
276
|
+
* the new one. The new group is the one with the requested name — the newest,
|
|
277
|
+
* should the name repeat across group types.
|
|
278
|
+
*
|
|
279
|
+
* The difference is a property of the answers, not a choice:
|
|
280
|
+
* `notifychannelcreated` names the client that invoked it, so `channelcreate`
|
|
281
|
+
* keeps only its own row, while the group commands answer with the whole list
|
|
282
|
+
* and name no invoker — `notifyservergrouplist` for `servergroupadd` and
|
|
283
|
+
* `servergroupcopy`, `notifychannelgrouplist` for `channelgroupadd` and
|
|
284
|
+
* `channelgroupcopy` — leaving nothing but the name to match on. A group of
|
|
285
|
+
* the same name created concurrently by another party is therefore
|
|
286
|
+
* indistinguishable from ours, channel groups as much as server groups, and
|
|
287
|
+
* the id returned may be theirs rather than the one we just made. That is a
|
|
288
|
+
* limit of what the notification reports, not of this function.
|
|
289
|
+
*/
|
|
290
|
+
export function createdGroupID(rows, idKey, name, command) {
|
|
291
|
+
const listed = rows.filter((row) => row["name"] !== undefined);
|
|
292
|
+
if (listed.length === 0)
|
|
293
|
+
return big(firstRow(rows, command, idKey), idKey);
|
|
294
|
+
let id = 0n;
|
|
295
|
+
for (const row of listed) {
|
|
296
|
+
if (row["name"] === name && big(row, idKey) > id)
|
|
297
|
+
id = big(row, idKey);
|
|
298
|
+
}
|
|
299
|
+
if (id === 0n) {
|
|
300
|
+
throw new NoDataError(command, `the server did not report the new group "${name}"`);
|
|
301
|
+
}
|
|
302
|
+
return id;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Encode a permission as `permid` or `permsid`, whichever names it.
|
|
306
|
+
*
|
|
307
|
+
* A JavaScript caller can pass an object naming neither, and a command sent
|
|
308
|
+
* with neither parameter fails on the server with a less helpful error, if it
|
|
309
|
+
* fails at all — so that is refused here.
|
|
310
|
+
*/
|
|
311
|
+
export function permissionParam(permission) {
|
|
312
|
+
const value = permission;
|
|
313
|
+
if (typeof value.name === "string" && value.name !== "")
|
|
314
|
+
return ["permsid", value.name];
|
|
315
|
+
// No permission has id 0: a Permission naming it names none.
|
|
316
|
+
if (typeof value.id === "number" && Number.isInteger(value.id) && value.id > 0) {
|
|
317
|
+
return ["permid", value.id];
|
|
318
|
+
}
|
|
319
|
+
throw new TypeError("a permission is permissionByID(id), id above 0, or permissionByName(name)");
|
|
320
|
+
}
|
|
321
|
+
function parseChannel(row) {
|
|
322
|
+
return {
|
|
323
|
+
id: asChannelID(big(row, "cid")),
|
|
324
|
+
parentID: asChannelID(big(row, "pid") || big(row, "cpid")),
|
|
325
|
+
name: str(row, "channel_name"),
|
|
326
|
+
topic: str(row, "channel_topic"),
|
|
327
|
+
description: str(row, "channel_description"),
|
|
328
|
+
order: asChannelID(big(row, "channel_order")),
|
|
329
|
+
hasPassword: bool(row, "channel_flag_password"),
|
|
330
|
+
isDefault: bool(row, "channel_flag_default"),
|
|
331
|
+
isPermanent: bool(row, "channel_flag_permanent"),
|
|
332
|
+
isSemiPermanent: bool(row, "channel_flag_semi_permanent"),
|
|
333
|
+
codec: num(row, "channel_codec"),
|
|
334
|
+
codecQuality: num(row, "channel_codec_quality"),
|
|
335
|
+
maxClients: num(row, "channel_maxclients"),
|
|
336
|
+
maxFamilyClients: num(row, "channel_maxfamilyclients"),
|
|
337
|
+
totalClients: optNum(row, "total_clients"),
|
|
338
|
+
totalFamilyClients: optNum(row, "total_clients_family"),
|
|
339
|
+
neededSubscribePower: optNum(row, "channel_needed_subscribe_power"),
|
|
340
|
+
neededTalkPower: num(row, "channel_needed_talk_power"),
|
|
341
|
+
iconID: icon(row, "channel_icon_id"),
|
|
342
|
+
uid: asChannelUID(str(row, "channel_unique_identifier")),
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
export { parseChannel };
|
|
346
|
+
/**
|
|
347
|
+
* Parse one permission row.
|
|
348
|
+
*
|
|
349
|
+
* A permission is addressable by id or by name, and the server answers in
|
|
350
|
+
* whichever form the request used, so a row carries one or the other.
|
|
351
|
+
*/
|
|
352
|
+
export function parsePermission(row) {
|
|
353
|
+
const name = str(row, "permsid");
|
|
354
|
+
return {
|
|
355
|
+
permission: name === ""
|
|
356
|
+
? permissionByID(asPermissionID(uint(row, "permid", U32)))
|
|
357
|
+
: permissionByName(name),
|
|
358
|
+
value: num(row, "permvalue"),
|
|
359
|
+
negated: bool(row, "permnegated"),
|
|
360
|
+
skip: bool(row, "permskip"),
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
//# sourceMappingURL=command.js.map
|