@honeybbq/teamspeak 1.0.0-beta.19 → 1.0.0-beta.21
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/dist/client/api/avatars.d.ts.map +1 -1
- package/dist/client/api/avatars.js +11 -2
- package/dist/client/api/avatars.js.map +1 -1
- package/dist/client/api/files.d.ts +36 -14
- package/dist/client/api/files.d.ts.map +1 -1
- package/dist/client/api/files.js +58 -9
- package/dist/client/api/files.js.map +1 -1
- package/dist/client/api/upload-checks.d.ts +36 -0
- package/dist/client/api/upload-checks.d.ts.map +1 -0
- package/dist/client/api/upload-checks.js +77 -0
- package/dist/client/api/upload-checks.js.map +1 -0
- package/dist/client/api/voice.d.ts +2 -1
- package/dist/client/api/voice.d.ts.map +1 -1
- package/dist/client/api/voice.js +6 -2
- package/dist/client/api/voice.js.map +1 -1
- package/dist/client/client.d.ts +13 -3
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +151 -49
- package/dist/client/client.js.map +1 -1
- package/dist/client/crypto/crypt.d.ts +6 -0
- package/dist/client/crypto/crypt.d.ts.map +1 -1
- package/dist/client/crypto/crypt.js +13 -7
- package/dist/client/crypto/crypt.js.map +1 -1
- package/dist/client/crypto/eax.d.ts +4 -0
- package/dist/client/crypto/eax.d.ts.map +1 -1
- package/dist/client/crypto/eax.js +27 -21
- package/dist/client/crypto/eax.js.map +1 -1
- package/dist/client/errors.d.ts +13 -0
- package/dist/client/errors.d.ts.map +1 -1
- package/dist/client/errors.js +23 -0
- package/dist/client/errors.js.map +1 -1
- package/dist/client/handshake/crypt-handshake.d.ts +2 -1
- package/dist/client/handshake/crypt-handshake.d.ts.map +1 -1
- package/dist/client/handshake/crypt-handshake.js +4 -2
- package/dist/client/handshake/crypt-handshake.js.map +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/index.js +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/throttle.d.ts +11 -0
- package/dist/client/throttle.d.ts.map +1 -1
- package/dist/client/throttle.js +38 -3
- package/dist/client/throttle.js.map +1 -1
- package/dist/client/transfer.d.ts +37 -4
- package/dist/client/transfer.d.ts.map +1 -1
- package/dist/client/transfer.js +155 -15
- package/dist/client/transfer.js.map +1 -1
- package/dist/client/transport/handler.d.ts.map +1 -1
- package/dist/client/transport/handler.js +47 -43
- package/dist/client/transport/handler.js.map +1 -1
- package/dist/core/api/clients.d.ts +15 -15
- package/dist/core/api/clients.d.ts.map +1 -1
- package/dist/core/api/clients.js.map +1 -1
- package/dist/core/api/command.d.ts +8 -6
- package/dist/core/api/command.d.ts.map +1 -1
- package/dist/core/api/command.js +1 -1
- package/dist/core/api/command.js.map +1 -1
- package/dist/core/api/files.d.ts +23 -6
- package/dist/core/api/files.d.ts.map +1 -1
- package/dist/core/api/files.js +12 -9
- package/dist/core/api/files.js.map +1 -1
- package/dist/core/api/groups.d.ts +17 -2
- package/dist/core/api/groups.d.ts.map +1 -1
- package/dist/core/api/groups.js +13 -11
- package/dist/core/api/groups.js.map +1 -1
- package/dist/core/api/parse.d.ts +5 -5
- package/dist/core/api/parse.d.ts.map +1 -1
- package/dist/core/api/parse.js +16 -15
- package/dist/core/api/parse.js.map +1 -1
- package/dist/core/command/request.d.ts +6 -0
- package/dist/core/command/request.d.ts.map +1 -1
- package/dist/core/command/request.js +12 -0
- package/dist/core/command/request.js.map +1 -1
- package/dist/core/errors.d.ts +46 -3
- package/dist/core/errors.d.ts.map +1 -1
- package/dist/core/errors.js +73 -20
- package/dist/core/errors.js.map +1 -1
- package/dist/core/events.d.ts +24 -8
- package/dist/core/events.d.ts.map +1 -1
- package/dist/core/internal.d.ts +1 -1
- package/dist/core/internal.d.ts.map +1 -1
- package/dist/core/internal.js +1 -1
- package/dist/core/internal.js.map +1 -1
- package/dist/core/notifications.d.ts +1 -1
- package/dist/core/notifications.js +9 -8
- package/dist/core/notifications.js.map +1 -1
- package/dist/core/reconnect.d.ts +16 -5
- package/dist/core/reconnect.d.ts.map +1 -1
- package/dist/core/reconnect.js +32 -4
- package/dist/core/reconnect.js.map +1 -1
- package/dist/core/types.d.ts +15 -16
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/query/client.d.ts +4 -0
- package/dist/query/client.d.ts.map +1 -1
- package/dist/query/client.js +145 -23
- package/dist/query/client.js.map +1 -1
- package/dist/query/errors.d.ts +20 -0
- package/dist/query/errors.d.ts.map +1 -1
- package/dist/query/errors.js +31 -0
- package/dist/query/errors.js.map +1 -1
- package/dist/query/index.d.ts +1 -1
- package/dist/query/index.d.ts.map +1 -1
- package/dist/query/index.js +1 -1
- package/dist/query/index.js.map +1 -1
- package/dist/query/lines.d.ts +11 -0
- package/dist/query/lines.d.ts.map +1 -1
- package/dist/query/lines.js +36 -6
- package/dist/query/lines.js.map +1 -1
- package/dist/query/options.d.ts +30 -0
- package/dist/query/options.d.ts.map +1 -1
- package/dist/query/options.js +7 -0
- package/dist/query/options.js.map +1 -1
- package/dist/query/reconnect.d.ts +5 -0
- package/dist/query/reconnect.d.ts.map +1 -1
- package/dist/query/reconnect.js +26 -7
- package/dist/query/reconnect.js.map +1 -1
- package/dist/query/ssh.js +9 -4
- package/dist/query/ssh.js.map +1 -1
- package/dist/query/stream.d.ts +2 -0
- package/dist/query/stream.d.ts.map +1 -1
- package/dist/query/stream.js +19 -1
- package/dist/query/stream.js.map +1 -1
- package/dist/query/transport.d.ts +12 -2
- package/dist/query/transport.d.ts.map +1 -1
- package/dist/query/web.d.ts +3 -1
- package/dist/query/web.d.ts.map +1 -1
- package/dist/query/web.js +82 -18
- package/dist/query/web.js.map +1 -1
- package/dist/stream/published.d.ts.map +1 -1
- package/dist/stream/published.js +61 -25
- package/dist/stream/published.js.map +1 -1
- package/dist/stream/streams.d.ts.map +1 -1
- package/dist/stream/streams.js +51 -10
- package/dist/stream/streams.js.map +1 -1
- package/dist/stream/wire.d.ts +2 -2
- package/dist/stream/wire.d.ts.map +1 -1
- package/dist/stream/wire.js +27 -7
- package/dist/stream/wire.js.map +1 -1
- package/package.json +1 -1
- package/src/client/api/avatars.ts +15 -2
- package/src/client/api/files.ts +83 -23
- package/src/client/api/upload-checks.ts +96 -0
- package/src/client/api/voice.ts +5 -2
- package/src/client/client.ts +154 -42
- package/src/client/crypto/crypt.ts +15 -7
- package/src/client/crypto/eax.ts +27 -22
- package/src/client/errors.ts +25 -0
- package/src/client/handshake/crypt-handshake.ts +6 -3
- package/src/client/index.ts +1 -0
- package/src/client/throttle.ts +41 -3
- package/src/client/transfer.ts +172 -28
- package/src/client/transport/handler.ts +54 -46
- package/src/core/api/clients.ts +24 -21
- package/src/core/api/command.ts +9 -7
- package/src/core/api/files.ts +30 -16
- package/src/core/api/groups.ts +32 -13
- package/src/core/api/parse.ts +16 -15
- package/src/core/command/request.ts +18 -0
- package/src/core/errors.ts +74 -20
- package/src/core/events.ts +24 -8
- package/src/core/internal.ts +7 -1
- package/src/core/notifications.ts +9 -8
- package/src/core/reconnect.ts +60 -8
- package/src/core/types.ts +15 -16
- package/src/query/client.ts +144 -20
- package/src/query/errors.ts +34 -0
- package/src/query/index.ts +1 -0
- package/src/query/lines.ts +38 -6
- package/src/query/options.ts +36 -0
- package/src/query/reconnect.ts +27 -7
- package/src/query/ssh.ts +11 -4
- package/src/query/stream.ts +17 -1
- package/src/query/testing/live.ts +4 -4
- package/src/query/transport.ts +10 -2
- package/src/query/web.ts +76 -21
- package/src/stream/published.ts +70 -23
- package/src/stream/streams.ts +47 -13
- package/src/stream/wire.ts +30 -11
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatars.d.ts","sourceRoot":"","sources":["../../../src/client/api/avatars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"avatars.d.ts","sourceRoot":"","sources":["../../../src/client/api/avatars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,OAAO,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1D,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,mBAAmB,EAAE,QAAQ,GAAG,OAAO,CAAC,CAAC;AAiClF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAgBjB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,GAAG,GAAG,MAAM,EACjB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEjC;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,UAAU,EAChB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAEjC"}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
import { createHash } from "node:crypto";
|
|
9
9
|
import { Readable, Writable } from "node:stream";
|
|
10
10
|
import { ErrorCode, ServerError, asChannelID, avatarFileName, deleteFile, iconFileName, iconIDOf, initFileDownload, initFileUpload, updateClient, } from "@honeybbq/teamspeak";
|
|
11
|
+
import { verifyStored, withDialCleanup } from "./upload-checks.js";
|
|
11
12
|
const CHANNEL_ZERO = asChannelID(0n);
|
|
12
13
|
async function download(client, name, options) {
|
|
13
14
|
let info;
|
|
@@ -54,7 +55,12 @@ export async function uploadAvatar(client, data, options = {}) {
|
|
|
54
55
|
overwrite: true,
|
|
55
56
|
...(options.signal ? { signal: options.signal } : {}),
|
|
56
57
|
});
|
|
57
|
-
await client.uploadFileData(client.host, info, Readable.from([data]), options);
|
|
58
|
+
await withDialCleanup(client, info.serverFileTransferID, () => client.uploadFileData(client.host, info, Readable.from([data]), options));
|
|
59
|
+
// Stored under a name the server derives from the uploader's uid, not the
|
|
60
|
+
// one asked for (measured on TeamSpeak 3 3.13.8 and TeamSpeak 6 6.0.0).
|
|
61
|
+
await verifyStored(client, CHANNEL_ZERO, `/${avatarFileName(client.uid)}`, BigInt(data.length), {
|
|
62
|
+
signal: options.signal,
|
|
63
|
+
});
|
|
58
64
|
await updateClient(client, { avatar: md5 });
|
|
59
65
|
return md5;
|
|
60
66
|
}
|
|
@@ -108,7 +114,10 @@ export async function uploadIcon(client, data, options = {}) {
|
|
|
108
114
|
overwrite: true,
|
|
109
115
|
...(options.signal ? { signal: options.signal } : {}),
|
|
110
116
|
});
|
|
111
|
-
await client.uploadFileData(client.host, info, Readable.from([data]), options);
|
|
117
|
+
await withDialCleanup(client, info.serverFileTransferID, () => client.uploadFileData(client.host, info, Readable.from([data]), options));
|
|
118
|
+
await verifyStored(client, CHANNEL_ZERO, iconFileName(id), BigInt(data.length), {
|
|
119
|
+
signal: options.signal,
|
|
120
|
+
});
|
|
112
121
|
return id;
|
|
113
122
|
}
|
|
114
123
|
/** The bytes of an icon, or undefined when the server has no file for the id. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatars.js","sourceRoot":"","sources":["../../../src/client/api/avatars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,YAAY,GACb,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"avatars.js","sourceRoot":"","sources":["../../../src/client/api/avatars.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,EACL,SAAS,EACT,WAAW,EACX,WAAW,EACX,cAAc,EACd,UAAU,EACV,YAAY,EACZ,QAAQ,EACR,gBAAgB,EAChB,cAAc,EACd,YAAY,GACb,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKnE,MAAM,YAAY,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC;AAErC,KAAK,UAAU,QAAQ,CACrB,MAAc,EACd,IAAY,EACZ,OAA8B;IAE9B,IAAI,IAAI,CAAC;IACT,IAAI,CAAC;QACH,IAAI,GAAG,MAAM,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACrE,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,2EAA2E;QAC3E,IACE,KAAK,YAAY,WAAW;YAC5B,CAAC,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,eAAe,CAAC,EACnF,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC;QACxB,KAAK,CAAC,KAAa,EAAE,SAAS,EAAE,IAAI;YAClC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACnB,IAAI,EAAE,CAAC;QACT,CAAC;KACF,CAAC,CAAC;IACH,MAAM,MAAM,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IAChE,OAAO,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,IAAgB,EAChB,OAAO,GAA0B,EAAE;IAEnC,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACzD,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,WAAW,GAAG,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC7F,SAAS,EAAE,IAAI;QACf,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC,CAAC;IACH,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAC5D,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CACzE,CAAC;IACF,0EAA0E;IAC1E,wEAAwE;IACxE,MAAM,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC9F,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,MAAM,YAAY,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC5C,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAC5B,MAAc,EACd,GAAiB,EACjB,OAAO,GAA0B,EAAE;IAEnC,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;AAC9D,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAc,EACd,OAAO,GAA0B,EAAE;IAEnC,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,eAAe;YAAE,OAAO,KAAK,CAAC;QAC3F,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAc,EACd,IAAgB,EAChB,OAAO,GAA0B,EAAE;IAEnC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC7F,SAAS,EAAE,IAAI;QACf,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACtD,CAAC,CAAC;IACH,MAAM,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAC5D,MAAM,CAAC,cAAc,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,CACzE,CAAC;IACF,MAAM,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE;QAC9E,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,YAAY,CAC1B,MAAc,EACd,EAAU,EACV,OAAO,GAA0B,EAAE;IAEnC,OAAO,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC;AACrD,CAAC"}
|
|
@@ -14,11 +14,10 @@ import type { ChannelID, CommandExecutor, FileDownloadOptions, FileUploadOptions
|
|
|
14
14
|
import type { FileTransferOptions } from "../transfer.js";
|
|
15
15
|
/**
|
|
16
16
|
* How {@link uploadFile} negotiates and moves the file: the options of
|
|
17
|
-
* `initFileUpload
|
|
18
|
-
*
|
|
19
|
-
* signal to the transfer too.
|
|
17
|
+
* `initFileUpload` and those of `uploadFileData`. `signal` and `timeoutMs`
|
|
18
|
+
* apply to the negotiation, and the signal to the transfer too.
|
|
20
19
|
*/
|
|
21
|
-
export interface UploadFileOptions extends
|
|
20
|
+
export interface UploadFileOptions extends FileUploadOptions, FileTransferOptions {
|
|
22
21
|
/**
|
|
23
22
|
* The host of the file transfer port. A voice client sends to the host it
|
|
24
23
|
* connected to, so it needs none; any other connection must name it. A host
|
|
@@ -28,24 +27,29 @@ export interface UploadFileOptions extends Omit<FileUploadOptions, "resume">, Fi
|
|
|
28
27
|
/**
|
|
29
28
|
* The size in bytes of a stream passed as the data, which the server needs
|
|
30
29
|
* before it takes the file. Required for a `Readable`; for bytes it is their
|
|
31
|
-
* length, and a different value here is refused.
|
|
30
|
+
* length, and a different value here is refused. A stream that gives fewer
|
|
31
|
+
* or more bytes fails the upload.
|
|
32
32
|
*/
|
|
33
33
|
readonly size?: bigint | number | undefined;
|
|
34
34
|
}
|
|
35
|
-
/**
|
|
36
|
-
|
|
35
|
+
/**
|
|
36
|
+
* How {@link downloadFile} negotiates and moves the file. With a
|
|
37
|
+
* `seekPosition` the bytes are the file's from there to its end.
|
|
38
|
+
*/
|
|
39
|
+
export interface DownloadFileOptions extends FileDownloadOptions, FileTransferOptions {
|
|
37
40
|
/** The host of the file transfer port, as for {@link UploadFileOptions}. */
|
|
38
41
|
readonly host?: string | undefined;
|
|
39
42
|
/**
|
|
40
43
|
* Write the file into this stream instead of returning its bytes. The stream
|
|
41
|
-
* is
|
|
44
|
+
* is neither ended nor destroyed, as for `downloadFileData`, so it may take
|
|
45
|
+
* several downloads; a failed transfer still rejects the call.
|
|
42
46
|
*/
|
|
43
47
|
readonly dest?: Writable | undefined;
|
|
44
48
|
/**
|
|
45
|
-
* The
|
|
46
|
-
*
|
|
47
|
-
* {@link FileTransferError} before any byte is read
|
|
48
|
-
* negotiated is
|
|
49
|
+
* The most bytes to hold in memory when no `dest` is given; 268435456
|
|
50
|
+
* (256 MiB) by default. A larger download is refused with a
|
|
51
|
+
* {@link FileTransferError} before any byte is read, and the transfer the
|
|
52
|
+
* server negotiated is stopped.
|
|
49
53
|
*/
|
|
50
54
|
readonly maxSize?: number | undefined;
|
|
51
55
|
}
|
|
@@ -54,7 +58,21 @@ export interface DownloadFileOptions extends Omit<FileDownloadOptions, "seekPosi
|
|
|
54
58
|
* (`initFileUpload`) and send the bytes (`uploadFileData`), in one call.
|
|
55
59
|
*
|
|
56
60
|
* `data` is the bytes, or a `Readable` with `options.size` the number of bytes
|
|
57
|
-
* it will give.
|
|
61
|
+
* it will give. It resolves once the server has closed the transfer
|
|
62
|
+
* connection and, by `ftgetfileinfo` (one more command), holds a file of
|
|
63
|
+
* exactly that size: the server does not say whether it stored a file, so a
|
|
64
|
+
* close alone could be a transfer someone stopped. A size that differs, or a
|
|
65
|
+
* file that is not there, fails the call with a {@link FileTransferError}; a
|
|
66
|
+
* client with no browse power cannot ask (2568) and resolves on the close. A
|
|
67
|
+
* stream that gives fewer or more bytes than `size` fails the call, and the
|
|
68
|
+
* connection is closed. When the connection to the file transfer port is
|
|
69
|
+
* refused or times out, the negotiated transfer is stopped on the server (else
|
|
70
|
+
* it lingers in `ftlist` for about 10 seconds), as it is for `downloadFile`.
|
|
71
|
+
*
|
|
72
|
+
* With `resume`, `data` is still the whole file: the server says how much it
|
|
73
|
+
* already holds from an interrupted upload (a file that is not there is
|
|
74
|
+
* refused with 2054), and only the rest is sent; `overwrite` cannot go with it
|
|
75
|
+
* (2056). An existing file is not replaced unless `overwrite` is set, and
|
|
58
76
|
* the directory the file goes in must exist (a missing one is refused with
|
|
59
77
|
* 2054, invalid file path): make it with `createDirectory` first. A refusal of
|
|
60
78
|
* the negotiation is thrown as the ServerError it is, before anything is sent;
|
|
@@ -72,7 +90,11 @@ export declare function uploadFile(client: CommandExecutor, channelID: ChannelID
|
|
|
72
90
|
* call. With `options.dest` the bytes go into that stream instead and nothing
|
|
73
91
|
* is held, which is the way to fetch a large file.
|
|
74
92
|
*
|
|
75
|
-
*
|
|
93
|
+
* With `seekPosition` the bytes are the file's from there to its end, which is
|
|
94
|
+
* how to resume a partial download: append them to what was already fetched.
|
|
95
|
+
*
|
|
96
|
+
* More than `maxSize` bytes (256 MiB unless set) is refused when no `dest` is
|
|
97
|
+
* given, and the transfer the server negotiated is stopped.
|
|
76
98
|
* A file that is not there is the ServerError of the negotiation: 2051 on TS3
|
|
77
99
|
* 3.13.8 and TS6 beta13.1. A path that names a directory is not refused by the
|
|
78
100
|
* server: it announces a size and sends nothing, so the call rejects with a
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/client/api/files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,
|
|
1
|
+
{"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/client/api/files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAa,QAAQ,EAAY,MAAM,aAAa,CAAC;AAEtE,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EAEf,mBAAmB,EAEnB,iBAAiB,EAClB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D;;;;GAIG;AACH,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB,EAAE,mBAAmB;IAC/E;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;;;OAKG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC7C;AAED;;;GAGG;AACH,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB,EAAE,mBAAmB;IACnF,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC;;;;OAIG;IACH,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IACrC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACvC;AAsGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,GAAG,QAAQ,EAC3B,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,IAAI,CAAC,CAqBf;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,mBAAmB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAA;CAAE,GACzD,OAAO,CAAC,IAAI,CAAC,CAAC;AACjB,wBAAgB,YAAY,CAC1B,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,UAAU,CAAC,CAAC"}
|
package/dist/client/api/files.js
CHANGED
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
* file transfer port a voice client's does. WebQuery refuses every file command
|
|
10
10
|
* (error 5120), on both servers.
|
|
11
11
|
*/
|
|
12
|
-
import { Readable, Writable } from "node:stream";
|
|
13
|
-
import { initFileDownload, initFileUpload } from "@honeybbq/teamspeak";
|
|
12
|
+
import { Readable, Transform, Writable, pipeline } from "node:stream";
|
|
13
|
+
import { initFileDownload, initFileUpload, stopFileTransfer } from "@honeybbq/teamspeak";
|
|
14
14
|
import { FileTransferError } from "../errors.js";
|
|
15
15
|
import { downloadFileData, uploadFileData } from "../transfer.js";
|
|
16
|
+
import { verifyStored, withDialCleanup } from "./upload-checks.js";
|
|
16
17
|
function isTransferCapable(client) {
|
|
17
18
|
const candidate = client;
|
|
18
19
|
return (typeof candidate.host === "string" &&
|
|
@@ -65,12 +66,42 @@ function sizeOf(data, declared) {
|
|
|
65
66
|
}
|
|
66
67
|
return size;
|
|
67
68
|
}
|
|
69
|
+
/** Drops the first `count` bytes of a stream. */
|
|
70
|
+
function skipBytes(count) {
|
|
71
|
+
let left = count;
|
|
72
|
+
return new Transform({
|
|
73
|
+
transform(chunk, _encoding, callback) {
|
|
74
|
+
if (left >= chunk.length) {
|
|
75
|
+
left -= chunk.length;
|
|
76
|
+
callback();
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
const rest = chunk.subarray(left);
|
|
80
|
+
left = 0;
|
|
81
|
+
callback(null, rest);
|
|
82
|
+
},
|
|
83
|
+
});
|
|
84
|
+
}
|
|
68
85
|
/**
|
|
69
86
|
* Upload a file into a channel's file area: negotiate the transfer
|
|
70
87
|
* (`initFileUpload`) and send the bytes (`uploadFileData`), in one call.
|
|
71
88
|
*
|
|
72
89
|
* `data` is the bytes, or a `Readable` with `options.size` the number of bytes
|
|
73
|
-
* it will give.
|
|
90
|
+
* it will give. It resolves once the server has closed the transfer
|
|
91
|
+
* connection and, by `ftgetfileinfo` (one more command), holds a file of
|
|
92
|
+
* exactly that size: the server does not say whether it stored a file, so a
|
|
93
|
+
* close alone could be a transfer someone stopped. A size that differs, or a
|
|
94
|
+
* file that is not there, fails the call with a {@link FileTransferError}; a
|
|
95
|
+
* client with no browse power cannot ask (2568) and resolves on the close. A
|
|
96
|
+
* stream that gives fewer or more bytes than `size` fails the call, and the
|
|
97
|
+
* connection is closed. When the connection to the file transfer port is
|
|
98
|
+
* refused or times out, the negotiated transfer is stopped on the server (else
|
|
99
|
+
* it lingers in `ftlist` for about 10 seconds), as it is for `downloadFile`.
|
|
100
|
+
*
|
|
101
|
+
* With `resume`, `data` is still the whole file: the server says how much it
|
|
102
|
+
* already holds from an interrupted upload (a file that is not there is
|
|
103
|
+
* refused with 2054), and only the rest is sent; `overwrite` cannot go with it
|
|
104
|
+
* (2056). An existing file is not replaced unless `overwrite` is set, and
|
|
74
105
|
* the directory the file goes in must exist (a missing one is refused with
|
|
75
106
|
* 2054, invalid file path): make it with `createDirectory` first. A refusal of
|
|
76
107
|
* the negotiation is thrown as the ServerError it is, before anything is sent;
|
|
@@ -87,11 +118,22 @@ export async function uploadFile(client, channelID, path, data, options = {}) {
|
|
|
87
118
|
const info = await initFileUpload(client, channelID, path, size, {
|
|
88
119
|
password: options.password,
|
|
89
120
|
overwrite: options.overwrite,
|
|
121
|
+
resume: options.resume,
|
|
90
122
|
signal: options.signal,
|
|
91
123
|
timeoutMs: options.timeoutMs,
|
|
92
124
|
});
|
|
93
|
-
|
|
94
|
-
|
|
125
|
+
// What the server holds is not sent again; a position past the end is for
|
|
126
|
+
// the transfer to refuse.
|
|
127
|
+
const skip = Number(info.seekPosition);
|
|
128
|
+
let source;
|
|
129
|
+
if (data instanceof Uint8Array)
|
|
130
|
+
source = Readable.from([data.subarray(skip)]);
|
|
131
|
+
else if (skip === 0)
|
|
132
|
+
source = data;
|
|
133
|
+
else
|
|
134
|
+
source = pipeline(data, skipBytes(skip), () => { });
|
|
135
|
+
await withDialCleanup(client, info.serverFileTransferID, () => route.upload(info, source, transferOptions(options)));
|
|
136
|
+
await verifyStored(client, channelID, path, size, options);
|
|
95
137
|
}
|
|
96
138
|
export async function downloadFile(client, channelID, path, options = {}) {
|
|
97
139
|
const maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
|
|
@@ -101,15 +143,22 @@ export async function downloadFile(client, channelID, path, options = {}) {
|
|
|
101
143
|
const route = routeFor(client, options);
|
|
102
144
|
const info = await initFileDownload(client, channelID, path, {
|
|
103
145
|
password: options.password,
|
|
146
|
+
seekPosition: options.seekPosition,
|
|
104
147
|
signal: options.signal,
|
|
105
148
|
timeoutMs: options.timeoutMs,
|
|
106
149
|
});
|
|
107
150
|
if (options.dest !== undefined) {
|
|
108
|
-
|
|
151
|
+
const dest = options.dest;
|
|
152
|
+
await withDialCleanup(client, info.serverFileTransferID, () => route.download(info, dest, transferOptions(options)));
|
|
109
153
|
return;
|
|
110
154
|
}
|
|
111
|
-
|
|
112
|
-
|
|
155
|
+
const wanted = info.size - info.seekPosition;
|
|
156
|
+
if (wanted > BigInt(maxSize)) {
|
|
157
|
+
// The server holds the negotiated transfer, and lists it among the active
|
|
158
|
+
// ones, until it is used or stopped. It is this connection's own, which is
|
|
159
|
+
// the only kind `ftstop` is safe to send.
|
|
160
|
+
await stopFileTransfer(client, info.serverFileTransferID).catch(() => { });
|
|
161
|
+
throw new FileTransferError(`the download is ${wanted} bytes, over the ${maxSize} bytes maxSize allows in memory`);
|
|
113
162
|
}
|
|
114
163
|
const chunks = [];
|
|
115
164
|
const sink = new Writable({
|
|
@@ -118,7 +167,7 @@ export async function downloadFile(client, channelID, path, options = {}) {
|
|
|
118
167
|
done();
|
|
119
168
|
},
|
|
120
169
|
});
|
|
121
|
-
await route.download(info, sink, transferOptions(options));
|
|
170
|
+
await withDialCleanup(client, info.serverFileTransferID, () => route.download(info, sink, transferOptions(options)));
|
|
122
171
|
return Buffer.concat(chunks);
|
|
123
172
|
}
|
|
124
173
|
const DEFAULT_MAX_SIZE = 256 * 1024 * 1024;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/client/api/files.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/client/api/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an upload does around its data phase: stop a transfer whose connection
|
|
3
|
+
* was never made, and check what the server stored once it closed the
|
|
4
|
+
* connection. Shared by the file and avatar helpers; not exported from the
|
|
5
|
+
* package.
|
|
6
|
+
*/
|
|
7
|
+
import type { ChannelID, CommandExecutor, FileUploadInfo } from "@honeybbq/teamspeak";
|
|
8
|
+
/**
|
|
9
|
+
* Runs the data phase of a transfer the server has negotiated. When it fails
|
|
10
|
+
* because the connection to the file transfer port was refused or timed out,
|
|
11
|
+
* nothing has reached the server, and the transfer would sit in its list until
|
|
12
|
+
* it expires: stop it, as a refused `maxSize` download does. The stop is best
|
|
13
|
+
* effort and never replaces the dial's error. Not sent once the connection
|
|
14
|
+
* opened (the key may be written and the server may have dropped the transfer),
|
|
15
|
+
* nor after `STOP_WITHIN_MS`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function withDialCleanup(client: CommandExecutor, serverFileTransferID: FileUploadInfo["serverFileTransferID"], move: () => Promise<void>): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Checks that the server holds the whole file after an upload's connection
|
|
20
|
+
* closed. Measured on TeamSpeak 3 3.13.8 and TeamSpeak 6 6.0.0: a completed
|
|
21
|
+
* upload gets no status from the server, so a close after the last byte looks
|
|
22
|
+
* the same whether the file was stored or the transfer was stopped (the voice
|
|
23
|
+
* protocol reports that, 2066, only after the close), and `ftgetfileinfo`
|
|
24
|
+
* already answers the final size 6 to 45 ms after the close, in every case.
|
|
25
|
+
* Permissions are checked at the negotiation only, so no refusal comes later.
|
|
26
|
+
*
|
|
27
|
+
* A client without browse power gets 2568 for `ftgetfileinfo`: the file cannot
|
|
28
|
+
* be checked, and the upload resolves on the close. Any other failure of the
|
|
29
|
+
* command is thrown as it is.
|
|
30
|
+
*/
|
|
31
|
+
export declare function verifyStored(client: CommandExecutor, channelID: ChannelID, path: string, size: bigint, options: {
|
|
32
|
+
readonly password?: string | undefined;
|
|
33
|
+
readonly signal?: AbortSignal | undefined;
|
|
34
|
+
readonly timeoutMs?: number | undefined;
|
|
35
|
+
}): Promise<void>;
|
|
36
|
+
//# sourceMappingURL=upload-checks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-checks.d.ts","sourceRoot":"","sources":["../../../src/client/api/upload-checks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAYtF;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,eAAe,EACvB,oBAAoB,EAAE,cAAc,CAAC,sBAAsB,CAAC,EAC5D,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GACxB,OAAO,CAAC,IAAI,CAAC,CAUf;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,eAAe,EACvB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE;IACP,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC,GACA,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an upload does around its data phase: stop a transfer whose connection
|
|
3
|
+
* was never made, and check what the server stored once it closed the
|
|
4
|
+
* connection. Shared by the file and avatar helpers; not exported from the
|
|
5
|
+
* package.
|
|
6
|
+
*/
|
|
7
|
+
import { ErrorCode, ServerError, getFileInfo, stopFileTransfer } from "@honeybbq/teamspeak";
|
|
8
|
+
import { FileTransferError } from "../errors.js";
|
|
9
|
+
import { failedToConnect } from "../transfer.js";
|
|
10
|
+
/**
|
|
11
|
+
* The server drops a transfer nobody dialled after about 10 seconds (measured
|
|
12
|
+
* on TeamSpeak 3 3.13.8 and TeamSpeak 6 6.0.0: it is gone from `ftlist` at
|
|
13
|
+
* 10.05 s, and the voice client hears 2059). `ftstop` of a transfer the server
|
|
14
|
+
* no longer has crashes TeamSpeak 6, so a stop is only sent well inside that.
|
|
15
|
+
*/
|
|
16
|
+
const STOP_WITHIN_MS = 5_000;
|
|
17
|
+
/**
|
|
18
|
+
* Runs the data phase of a transfer the server has negotiated. When it fails
|
|
19
|
+
* because the connection to the file transfer port was refused or timed out,
|
|
20
|
+
* nothing has reached the server, and the transfer would sit in its list until
|
|
21
|
+
* it expires: stop it, as a refused `maxSize` download does. The stop is best
|
|
22
|
+
* effort and never replaces the dial's error. Not sent once the connection
|
|
23
|
+
* opened (the key may be written and the server may have dropped the transfer),
|
|
24
|
+
* nor after `STOP_WITHIN_MS`.
|
|
25
|
+
*/
|
|
26
|
+
export async function withDialCleanup(client, serverFileTransferID, move) {
|
|
27
|
+
const negotiatedAt = performance.now();
|
|
28
|
+
try {
|
|
29
|
+
await move();
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (failedToConnect(error) && performance.now() - negotiatedAt < STOP_WITHIN_MS) {
|
|
33
|
+
await stopFileTransfer(client, serverFileTransferID).catch(() => { });
|
|
34
|
+
}
|
|
35
|
+
throw error;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Checks that the server holds the whole file after an upload's connection
|
|
40
|
+
* closed. Measured on TeamSpeak 3 3.13.8 and TeamSpeak 6 6.0.0: a completed
|
|
41
|
+
* upload gets no status from the server, so a close after the last byte looks
|
|
42
|
+
* the same whether the file was stored or the transfer was stopped (the voice
|
|
43
|
+
* protocol reports that, 2066, only after the close), and `ftgetfileinfo`
|
|
44
|
+
* already answers the final size 6 to 45 ms after the close, in every case.
|
|
45
|
+
* Permissions are checked at the negotiation only, so no refusal comes later.
|
|
46
|
+
*
|
|
47
|
+
* A client without browse power gets 2568 for `ftgetfileinfo`: the file cannot
|
|
48
|
+
* be checked, and the upload resolves on the close. Any other failure of the
|
|
49
|
+
* command is thrown as it is.
|
|
50
|
+
*/
|
|
51
|
+
export async function verifyStored(client, channelID, path, size, options) {
|
|
52
|
+
let stored;
|
|
53
|
+
try {
|
|
54
|
+
stored = (await getFileInfo(client, channelID, path, {
|
|
55
|
+
password: options.password,
|
|
56
|
+
signal: options.signal,
|
|
57
|
+
timeoutMs: options.timeoutMs,
|
|
58
|
+
})).size;
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
if (error instanceof ServerError) {
|
|
62
|
+
if (error.code === ErrorCode.PermissionsClientInsufficient)
|
|
63
|
+
return;
|
|
64
|
+
// 2051 on TeamSpeak 6, 2052 on TeamSpeak 3 for a file that is not there.
|
|
65
|
+
if (error.code === ErrorCode.FileNotFound || error.code === ErrorCode.FileIOError) {
|
|
66
|
+
throw new FileTransferError(`the server closed the upload but has no file ${path}`, {
|
|
67
|
+
cause: error,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
if (stored !== size) {
|
|
74
|
+
throw new FileTransferError(`the server closed the upload but holds ${stored} of the ${size} bytes of ${path}`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=upload-checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-checks.js","sourceRoot":"","sources":["../../../src/client/api/upload-checks.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5F,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD;;;;;GAKG;AACH,MAAM,cAAc,GAAG,KAAK,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAAuB,EACvB,oBAA4D,EAC5D,IAAyB;IAEzB,MAAM,YAAY,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,IAAI,EAAE,CAAC;IACf,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,eAAe,CAAC,KAAK,CAAC,IAAI,WAAW,CAAC,GAAG,EAAE,GAAG,YAAY,GAAG,cAAc,EAAE,CAAC;YAChF,MAAM,gBAAgB,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,MAAuB,EACvB,SAAoB,EACpB,IAAY,EACZ,IAAY,EACZ,OAIC;IAED,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,CACP,MAAM,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE;YACzC,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,SAAS,EAAE,OAAO,CAAC,SAAS;SAC7B,CAAC,CACH,CAAC,IAAI,CAAC;IACT,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC;YACjC,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,6BAA6B;gBAAE,OAAO;YACnE,yEAAyE;YACzE,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,YAAY,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,WAAW,EAAE,CAAC;gBAClF,MAAM,IAAI,iBAAiB,CAAC,gDAAgD,IAAI,EAAE,EAAE;oBAClF,KAAK,EAAE,KAAK;iBACb,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,iBAAiB,CACzB,0CAA0C,MAAM,WAAW,IAAI,aAAa,IAAI,EAAE,CACnF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -11,7 +11,8 @@ import type { ChannelID, ClientID, CommandOptions } from "@honeybbq/teamspeak";
|
|
|
11
11
|
/**
|
|
12
12
|
* The channel's description, which `listChannels` omits for bandwidth. The
|
|
13
13
|
* server answers with a `notifychanneledited` that the client does not report as
|
|
14
|
-
* a `channelEdited` event, since it is no edit.
|
|
14
|
+
* a `channelEdited` event, since it is no edit. Rejects with a NoDataError if
|
|
15
|
+
* the server sends no such answer.
|
|
15
16
|
*/
|
|
16
17
|
export declare function getChannelDescription(client: Client, cid: ChannelID, options?: CommandOptions): Promise<string>;
|
|
17
18
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE/E
|
|
1
|
+
{"version":3,"file":"voice.d.ts","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAE3C,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE/E;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAYjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAO3C;AAED;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,8DAA8D;AAC9D,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,gDAAgD;AAChD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,oDAAoD;AACpD,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAalB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,SAAS,EACd,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,OAAO,CAAC,CAgBlB;AAaD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,IAAI,CAAC,CAEf"}
|
package/dist/client/api/voice.js
CHANGED
|
@@ -10,7 +10,8 @@ import { ErrorCode, NoDataError, ServerError } from "@honeybbq/teamspeak";
|
|
|
10
10
|
/**
|
|
11
11
|
* The channel's description, which `listChannels` omits for bandwidth. The
|
|
12
12
|
* server answers with a `notifychanneledited` that the client does not report as
|
|
13
|
-
* a `channelEdited` event, since it is no edit.
|
|
13
|
+
* a `channelEdited` event, since it is no edit. Rejects with a NoDataError if
|
|
14
|
+
* the server sends no such answer.
|
|
14
15
|
*/
|
|
15
16
|
export async function getChannelDescription(client, cid, options) {
|
|
16
17
|
const rows = await client.send({ command: "channelgetdescription", params: [["cid", cid]] }, options);
|
|
@@ -18,7 +19,10 @@ export async function getChannelDescription(client, cid, options) {
|
|
|
18
19
|
// can arrive while the command waits, a real edit with other properties,
|
|
19
20
|
// and the first row is then not the answer.
|
|
20
21
|
const answer = rows.find((row) => row["cid"] === String(cid) && "channel_description" in row);
|
|
21
|
-
|
|
22
|
+
// A missing answer is not an empty description.
|
|
23
|
+
if (answer === undefined)
|
|
24
|
+
throw new NoDataError("channelgetdescription");
|
|
25
|
+
return answer["channel_description"] ?? "";
|
|
22
26
|
}
|
|
23
27
|
/**
|
|
24
28
|
* The virtual server's properties as the server sends them on request, which
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG1E
|
|
1
|
+
{"version":3,"file":"voice.js","sourceRoot":"","sources":["../../../src/client/api/voice.ts"],"names":[],"mappings":"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"}
|
package/dist/client/client.d.ts
CHANGED
|
@@ -75,7 +75,10 @@ export declare class Client implements CommandExecutor, AsyncDisposable {
|
|
|
75
75
|
* Leave the server and close the connection.
|
|
76
76
|
*
|
|
77
77
|
* Says goodbye first, waiting for the server's acknowledgement for a second
|
|
78
|
-
* at most, or less if `signal` aborts sooner. The
|
|
78
|
+
* at most, or less if `signal` aborts sooner. The goodbye is sent at once,
|
|
79
|
+
* past the flood throttle, and also by a client still connecting whose
|
|
80
|
+
* clientinit is out; commands still waiting for their turn reject with a
|
|
81
|
+
* NotConnectedError and are never sent. The connection is closed
|
|
79
82
|
* either way. A `connect()` still waiting for its handshake rejects with a
|
|
80
83
|
* NotConnectedError, and so do the commands still waiting for an answer.
|
|
81
84
|
* Resolves once `disconnected` has been delivered to the listeners, so one
|
|
@@ -104,6 +107,11 @@ export declare class Client implements CommandExecutor, AsyncDisposable {
|
|
|
104
107
|
*
|
|
105
108
|
* Rejects with a NotConnectedError unless the client is connected: while it
|
|
106
109
|
* is still connecting, the session's keys may not exist yet.
|
|
110
|
+
*
|
|
111
|
+
* A command the server refuses as flooding (`ErrorCode.ClientIsFlooding`)
|
|
112
|
+
* with a time to wait is sent again after it, and every other command waits
|
|
113
|
+
* too, up to three times and while its timeout allows; the refusal that
|
|
114
|
+
* remains rejects as it is.
|
|
107
115
|
*/
|
|
108
116
|
exec(command: string, options?: CommandOptions): Promise<Record<string, string>[]>;
|
|
109
117
|
/**
|
|
@@ -217,8 +225,10 @@ export declare class Client implements CommandExecutor, AsyncDisposable {
|
|
|
217
225
|
*/
|
|
218
226
|
sendGroupWhisper(data: Uint8Array, target: GroupWhisperTarget, codec: Codec): void;
|
|
219
227
|
/**
|
|
220
|
-
* Send one encoded audio frame to the channel this client is in.
|
|
221
|
-
*
|
|
228
|
+
* Send one encoded audio frame to the channel this client is in. An empty
|
|
229
|
+
* frame marks the end of speech: the server relays it, and listeners get a
|
|
230
|
+
* `voiceData` event with empty `data`. Throws a NotConnectedError unless the
|
|
231
|
+
* client is connected.
|
|
222
232
|
*/
|
|
223
233
|
sendVoice(data: Uint8Array, codec: Codec, options?: VoiceOptions): void;
|
|
224
234
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAOnB,MAAM,YAAY,CAAC;AAIpB,OAAO,EACL,KAAK,SAAS,EAEd,KAAK,QAAQ,EACb,KAAK,KAAK,EAGV,KAAK,cAAc,EACnB,KAAK,GAAG,EAGR,KAAK,QAAQ,EAGb,KAAK,WAAW,EAGhB,YAAY,EAKb,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client/client.ts"],"names":[],"mappings":"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"}
|