@honeybbq/teamspeak 0.0.1 → 1.0.0-beta.7
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 +967 -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 +1132 -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,405 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File transfer commands.
|
|
3
|
+
*
|
|
4
|
+
* These are the control-plane half: they list, move and delete files, and they
|
|
5
|
+
* negotiate an upload or download. The actual bytes travel over a separate TCP
|
|
6
|
+
* connection to the file transfer port, which the voice client's
|
|
7
|
+
* `uploadFileData` and `downloadFileData` handle.
|
|
8
|
+
*
|
|
9
|
+
* Every command here takes a channel password as its `password` option, in
|
|
10
|
+
* cleartext: the voice client sends it as `base64(sha1(password))`, the same
|
|
11
|
+
* encoding `clientmove` uses, and ServerQuery as it is. Unset, it is sent
|
|
12
|
+
* empty, which is right for a channel with no password.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
uint,
|
|
17
|
+
U16,
|
|
18
|
+
firstRow,
|
|
19
|
+
commandOptions,
|
|
20
|
+
exec,
|
|
21
|
+
query,
|
|
22
|
+
list,
|
|
23
|
+
str,
|
|
24
|
+
big,
|
|
25
|
+
num,
|
|
26
|
+
date,
|
|
27
|
+
durationMs,
|
|
28
|
+
SECOND,
|
|
29
|
+
} from "./command.js";
|
|
30
|
+
import type { CommandExecutor, CommandOptions } from "../command/request.js";
|
|
31
|
+
import type {
|
|
32
|
+
ChannelID,
|
|
33
|
+
ClientFileTransferID,
|
|
34
|
+
ClientID,
|
|
35
|
+
ServerFileTransferID,
|
|
36
|
+
} from "../command/ids.js";
|
|
37
|
+
import { asClientFileTransferID, asClientID, asServerFileTransferID } from "../command/ids.js";
|
|
38
|
+
import type { FileDownloadInfo, FileUploadInfo } from "../types.js";
|
|
39
|
+
|
|
40
|
+
const asPath = (path: string): string => (path.startsWith("/") ? path : `/${path}`);
|
|
41
|
+
|
|
42
|
+
/** One entry of a directory listing, or one file's details. */
|
|
43
|
+
export interface FileEntry {
|
|
44
|
+
/** The file or directory name. */
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/** The size in bytes; 0 for a directory. */
|
|
47
|
+
readonly size: bigint;
|
|
48
|
+
/**
|
|
49
|
+
* When it was last modified. TS3 sends seconds, TS6 milliseconds in a
|
|
50
|
+
* listing and nanoseconds in `getFileInfo`; all are read as the same time.
|
|
51
|
+
*/
|
|
52
|
+
readonly modifiedAt: Date | undefined;
|
|
53
|
+
/**
|
|
54
|
+
* Whether this is a directory. The listing sends `type=0` for a directory
|
|
55
|
+
* and `type=1` for a file; `getFileInfo`'s answer carries no type, so there
|
|
56
|
+
* it is always false.
|
|
57
|
+
*/
|
|
58
|
+
readonly isDirectory: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** The channel password a file command needs. */
|
|
62
|
+
export interface FileOptions extends CommandOptions {
|
|
63
|
+
/** The channel's password, in cleartext; "" by default (`cpw`). */
|
|
64
|
+
readonly password?: string | undefined;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const parseFileEntry = (row: Record<string, string>): FileEntry => ({
|
|
68
|
+
name: str(row, "name"),
|
|
69
|
+
size: big(row, "size"),
|
|
70
|
+
modifiedAt: date(row, "datetime"),
|
|
71
|
+
isDirectory: row["type"] === "0",
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
/** Directory listing for one path in a channel's file area. */
|
|
75
|
+
export async function listFiles(
|
|
76
|
+
client: CommandExecutor,
|
|
77
|
+
cid: ChannelID,
|
|
78
|
+
path: string,
|
|
79
|
+
options: FileOptions = {},
|
|
80
|
+
): Promise<FileEntry[]> {
|
|
81
|
+
const rows = await list(
|
|
82
|
+
client,
|
|
83
|
+
"ftgetfilelist",
|
|
84
|
+
[
|
|
85
|
+
["cid", cid],
|
|
86
|
+
["path", asPath(path)],
|
|
87
|
+
["cpw", options.password ?? ""],
|
|
88
|
+
],
|
|
89
|
+
options,
|
|
90
|
+
{ passwords: ["cpw"] },
|
|
91
|
+
);
|
|
92
|
+
return rows.map(parseFileEntry);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Size and timestamp of one file. */
|
|
96
|
+
export async function getFileInfo(
|
|
97
|
+
client: CommandExecutor,
|
|
98
|
+
cid: ChannelID,
|
|
99
|
+
path: string,
|
|
100
|
+
options: FileOptions = {},
|
|
101
|
+
): Promise<FileEntry> {
|
|
102
|
+
const rows = await query(
|
|
103
|
+
client,
|
|
104
|
+
"ftgetfileinfo",
|
|
105
|
+
[
|
|
106
|
+
["cid", cid],
|
|
107
|
+
["name", asPath(path)],
|
|
108
|
+
["cpw", options.password ?? ""],
|
|
109
|
+
],
|
|
110
|
+
options,
|
|
111
|
+
["cpw"],
|
|
112
|
+
);
|
|
113
|
+
return parseFileEntry(firstRow(rows, "ftgetfileinfo"));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Delete one or more files, in one command: each name is a row of it
|
|
118
|
+
* (`name=/a|name=/b`).
|
|
119
|
+
*/
|
|
120
|
+
export async function deleteFile(
|
|
121
|
+
client: CommandExecutor,
|
|
122
|
+
cid: ChannelID,
|
|
123
|
+
paths: string | readonly string[],
|
|
124
|
+
options: FileOptions = {},
|
|
125
|
+
): Promise<void> {
|
|
126
|
+
const names = (typeof paths === "string" ? [paths] : paths).map(asPath);
|
|
127
|
+
if (names.length === 0) return;
|
|
128
|
+
|
|
129
|
+
await client.send(
|
|
130
|
+
{
|
|
131
|
+
command: "ftdeletefile",
|
|
132
|
+
params: [
|
|
133
|
+
["cid", cid],
|
|
134
|
+
["cpw", options.password ?? ""],
|
|
135
|
+
],
|
|
136
|
+
rows: names.map((name) => [["name", name]]),
|
|
137
|
+
passwords: ["cpw"],
|
|
138
|
+
},
|
|
139
|
+
commandOptions(options),
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/** Create a directory, including any missing parents. */
|
|
144
|
+
export async function createDirectory(
|
|
145
|
+
client: CommandExecutor,
|
|
146
|
+
cid: ChannelID,
|
|
147
|
+
dirname: string,
|
|
148
|
+
options: FileOptions = {},
|
|
149
|
+
): Promise<void> {
|
|
150
|
+
await exec(
|
|
151
|
+
client,
|
|
152
|
+
"ftcreatedir",
|
|
153
|
+
[
|
|
154
|
+
["cid", cid],
|
|
155
|
+
["dirname", asPath(dirname)],
|
|
156
|
+
["cpw", options.password ?? ""],
|
|
157
|
+
],
|
|
158
|
+
options,
|
|
159
|
+
["cpw"],
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Where {@link renameFile} moves a file, and the passwords it needs. */
|
|
164
|
+
export interface FileRenameOptions extends CommandOptions {
|
|
165
|
+
/** The source channel's password, in cleartext; "" by default (`cpw`, always sent). */
|
|
166
|
+
readonly password?: string | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* Move the file into this channel's file area; unset or 0 keeps it in the
|
|
169
|
+
* same channel, and omits `tcid` and `tcpw` both (`tcid`).
|
|
170
|
+
*/
|
|
171
|
+
readonly targetChannelID?: ChannelID | undefined;
|
|
172
|
+
/**
|
|
173
|
+
* The target channel's password, in cleartext; "" by default. Sent, as
|
|
174
|
+
* `tcpw`, only with a `targetChannelID`.
|
|
175
|
+
*/
|
|
176
|
+
readonly targetChannelPassword?: string | undefined;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Rename or move a file, optionally into another channel.
|
|
181
|
+
*
|
|
182
|
+
* `cpw` is always sent, as for every file command; `tcid` and `tcpw` go
|
|
183
|
+
* together, and only when the file moves to another channel.
|
|
184
|
+
*/
|
|
185
|
+
export async function renameFile(
|
|
186
|
+
client: CommandExecutor,
|
|
187
|
+
cid: ChannelID,
|
|
188
|
+
oldName: string,
|
|
189
|
+
newName: string,
|
|
190
|
+
options: FileRenameOptions = {},
|
|
191
|
+
): Promise<void> {
|
|
192
|
+
await exec(
|
|
193
|
+
client,
|
|
194
|
+
"ftrenamefile",
|
|
195
|
+
[
|
|
196
|
+
["cid", cid],
|
|
197
|
+
["oldname", asPath(oldName)],
|
|
198
|
+
["newname", asPath(newName)],
|
|
199
|
+
["cpw", options.password ?? ""],
|
|
200
|
+
...(options.targetChannelID === undefined || options.targetChannelID === 0n
|
|
201
|
+
? []
|
|
202
|
+
: ([
|
|
203
|
+
["tcid", options.targetChannelID],
|
|
204
|
+
["tcpw", options.targetChannelPassword ?? ""],
|
|
205
|
+
] as const)),
|
|
206
|
+
],
|
|
207
|
+
options,
|
|
208
|
+
["cpw", "tcpw"],
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** How {@link stopFileTransfer} cancels. */
|
|
213
|
+
export interface FileTransferStopOptions extends CommandOptions {
|
|
214
|
+
/**
|
|
215
|
+
* Remove the partial file as well, which is usually what you want after a
|
|
216
|
+
* failed upload; false by default (`delete`, always sent).
|
|
217
|
+
*/
|
|
218
|
+
readonly removePartialFile?: boolean | undefined;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** Cancel a running transfer. */
|
|
222
|
+
export async function stopFileTransfer(
|
|
223
|
+
client: CommandExecutor,
|
|
224
|
+
serverFileTransferID: ServerFileTransferID,
|
|
225
|
+
options: FileTransferStopOptions = {},
|
|
226
|
+
): Promise<void> {
|
|
227
|
+
await exec(
|
|
228
|
+
client,
|
|
229
|
+
"ftstop",
|
|
230
|
+
[
|
|
231
|
+
["serverftfid", serverFileTransferID],
|
|
232
|
+
["delete", options.removePartialFile ?? false],
|
|
233
|
+
],
|
|
234
|
+
options,
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/** A running transfer, as `ftlist` reports it. */
|
|
239
|
+
export interface ActiveTransfer {
|
|
240
|
+
/** The client transferring. */
|
|
241
|
+
readonly clientID: ClientID;
|
|
242
|
+
/** The directory in the channel's file area. */
|
|
243
|
+
readonly path: string;
|
|
244
|
+
/** The file name. */
|
|
245
|
+
readonly name: string;
|
|
246
|
+
/** The file's size in bytes. */
|
|
247
|
+
readonly size: bigint;
|
|
248
|
+
/** How many bytes have been transferred. */
|
|
249
|
+
readonly sizeDone: bigint;
|
|
250
|
+
/** The client's id for the transfer. */
|
|
251
|
+
readonly clientFileTransferID: ClientFileTransferID;
|
|
252
|
+
/** The server's id for the transfer, which {@link stopFileTransfer} takes. */
|
|
253
|
+
readonly serverFileTransferID: ServerFileTransferID;
|
|
254
|
+
/** Which side sends the data, as the server reports it (`sender`). */
|
|
255
|
+
readonly sender: string;
|
|
256
|
+
/**
|
|
257
|
+
* The transfer's state, as the server reports it. A plain number: no table
|
|
258
|
+
* of its values is known.
|
|
259
|
+
*/
|
|
260
|
+
readonly status: number;
|
|
261
|
+
/** The current speed, in bytes per second. */
|
|
262
|
+
readonly currentSpeed: number;
|
|
263
|
+
/** The average speed, in bytes per second. */
|
|
264
|
+
readonly averageSpeed: number;
|
|
265
|
+
/** How long the transfer has been running, in milliseconds. The server reports seconds. */
|
|
266
|
+
readonly runtimeMs: number;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* File transfers in progress. Requires the file-transfer-info permission. None
|
|
271
|
+
* is an empty list.
|
|
272
|
+
*/
|
|
273
|
+
export async function listActiveTransfers(
|
|
274
|
+
client: CommandExecutor,
|
|
275
|
+
options?: CommandOptions,
|
|
276
|
+
): Promise<ActiveTransfer[]> {
|
|
277
|
+
const rows = await list(client, "ftlist", [], options);
|
|
278
|
+
return rows.map((row) => ({
|
|
279
|
+
clientID: asClientID(uint(row, "clid", U16)),
|
|
280
|
+
path: str(row, "path"),
|
|
281
|
+
name: str(row, "name"),
|
|
282
|
+
size: big(row, "size"),
|
|
283
|
+
sizeDone: big(row, "sizedone"),
|
|
284
|
+
clientFileTransferID: asClientFileTransferID(uint(row, "clientftfid", U16)),
|
|
285
|
+
serverFileTransferID: asServerFileTransferID(uint(row, "serverftfid", U16)),
|
|
286
|
+
sender: str(row, "sender"),
|
|
287
|
+
status: num(row, "status"),
|
|
288
|
+
currentSpeed: num(row, "current_speed"),
|
|
289
|
+
averageSpeed: num(row, "average_speed"),
|
|
290
|
+
runtimeMs: durationMs(row, "runtime", SECOND),
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* The `clientftfid` for the next negotiation.
|
|
296
|
+
*
|
|
297
|
+
* The server echoes it in the answer, and the echo is the only thing tying the
|
|
298
|
+
* answer to the request — it arrives after the command has already returned —
|
|
299
|
+
* so two transfers negotiated at once must not share one.
|
|
300
|
+
*/
|
|
301
|
+
let lastClientFileTransferID = 0;
|
|
302
|
+
function nextClientFileTransferID(): ClientFileTransferID {
|
|
303
|
+
lastClientFileTransferID = (lastClientFileTransferID % 65535) + 1;
|
|
304
|
+
return asClientFileTransferID(lastClientFileTransferID);
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/** How {@link initFileUpload} negotiates an upload. */
|
|
308
|
+
export interface FileUploadOptions extends CommandOptions {
|
|
309
|
+
/** The channel's password, in cleartext; "" by default (`cpw`). */
|
|
310
|
+
readonly password?: string | undefined;
|
|
311
|
+
/**
|
|
312
|
+
* Replace a file already at the path; false by default, so an upload never
|
|
313
|
+
* destroys a file unless asked to (`overwrite`, always sent).
|
|
314
|
+
*/
|
|
315
|
+
readonly overwrite?: boolean | undefined;
|
|
316
|
+
/** Continue a partial upload; false by default (`resume`). */
|
|
317
|
+
readonly resume?: boolean | undefined;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Negotiate an upload, returning the key and port to dial over TCP.
|
|
322
|
+
*
|
|
323
|
+
* Pass the result to the client's `uploadFileData` to send the data; it does
|
|
324
|
+
* not go through this command. A refusal — no permission to upload, say — is
|
|
325
|
+
* thrown as a ServerError, even though the voice protocol reports it in a
|
|
326
|
+
* separate notification after the command itself has succeeded.
|
|
327
|
+
*/
|
|
328
|
+
export async function initFileUpload(
|
|
329
|
+
client: CommandExecutor,
|
|
330
|
+
cid: ChannelID,
|
|
331
|
+
path: string,
|
|
332
|
+
size: bigint,
|
|
333
|
+
options: FileUploadOptions = {},
|
|
334
|
+
): Promise<FileUploadInfo> {
|
|
335
|
+
const rows = await query(
|
|
336
|
+
client,
|
|
337
|
+
"ftinitupload",
|
|
338
|
+
[
|
|
339
|
+
["clientftfid", nextClientFileTransferID()],
|
|
340
|
+
["name", asPath(path)],
|
|
341
|
+
["cid", cid],
|
|
342
|
+
["cpw", options.password ?? ""],
|
|
343
|
+
["size", size],
|
|
344
|
+
["overwrite", options.overwrite ?? false],
|
|
345
|
+
["resume", options.resume ?? false],
|
|
346
|
+
// proto is required: omitting it fails the whole call with 1539
|
|
347
|
+
// (parameter not found) rather than defaulting.
|
|
348
|
+
["proto", 0],
|
|
349
|
+
],
|
|
350
|
+
options,
|
|
351
|
+
["cpw"],
|
|
352
|
+
);
|
|
353
|
+
const row = firstRow(rows, "ftinitupload", "ftkey");
|
|
354
|
+
return {
|
|
355
|
+
fileTransferKey: str(row, "ftkey"),
|
|
356
|
+
port: num(row, "port"),
|
|
357
|
+
seekPosition: big(row, "seekpos"),
|
|
358
|
+
clientFileTransferID: asClientFileTransferID(uint(row, "clientftfid", U16)),
|
|
359
|
+
serverFileTransferID: asServerFileTransferID(uint(row, "serverftfid", U16)),
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/** How {@link initFileDownload} negotiates a download. */
|
|
364
|
+
export interface FileDownloadOptions extends CommandOptions {
|
|
365
|
+
/** The channel's password, in cleartext; "" by default (`cpw`). */
|
|
366
|
+
readonly password?: string | undefined;
|
|
367
|
+
/** The byte offset to start from, to resume; 0 by default (`seekpos`). */
|
|
368
|
+
readonly seekPosition?: bigint | undefined;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/**
|
|
372
|
+
* Negotiate a download, returning the key, port and size to dial over TCP.
|
|
373
|
+
*
|
|
374
|
+
* Pass the result to the client's `downloadFileData`. Refusals are thrown as
|
|
375
|
+
* for {@link initFileUpload}.
|
|
376
|
+
*/
|
|
377
|
+
export async function initFileDownload(
|
|
378
|
+
client: CommandExecutor,
|
|
379
|
+
cid: ChannelID,
|
|
380
|
+
path: string,
|
|
381
|
+
options: FileDownloadOptions = {},
|
|
382
|
+
): Promise<FileDownloadInfo> {
|
|
383
|
+
const rows = await query(
|
|
384
|
+
client,
|
|
385
|
+
"ftinitdownload",
|
|
386
|
+
[
|
|
387
|
+
["clientftfid", nextClientFileTransferID()],
|
|
388
|
+
["name", asPath(path)],
|
|
389
|
+
["cid", cid],
|
|
390
|
+
["cpw", options.password ?? ""],
|
|
391
|
+
["seekpos", options.seekPosition ?? 0n],
|
|
392
|
+
["proto", 0],
|
|
393
|
+
],
|
|
394
|
+
options,
|
|
395
|
+
["cpw"],
|
|
396
|
+
);
|
|
397
|
+
const row = firstRow(rows, "ftinitdownload", "ftkey");
|
|
398
|
+
return {
|
|
399
|
+
fileTransferKey: str(row, "ftkey"),
|
|
400
|
+
port: num(row, "port"),
|
|
401
|
+
size: big(row, "size"),
|
|
402
|
+
clientFileTransferID: asClientFileTransferID(uint(row, "clientftfid", U16)),
|
|
403
|
+
serverFileTransferID: asServerFileTransferID(uint(row, "serverftfid", U16)),
|
|
404
|
+
};
|
|
405
|
+
}
|