@perk-net/perk-pushplus-sdk 1.2.0 → 1.2.2

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.
@@ -0,0 +1,62 @@
1
+ import { PushPlusError } from './exception';
2
+
3
+ /** 二进制文件输入。 */
4
+ export type FileInput = Uint8Array | ArrayBuffer | Blob;
5
+
6
+ export interface FileMultipart {
7
+ contentType: string;
8
+ body: Uint8Array;
9
+ }
10
+
11
+ /** 构造仅含一个 file 字段的 multipart/form-data 请求体。 */
12
+ export function buildFileMultipart(
13
+ fileName: string,
14
+ contentType: string | undefined,
15
+ fileBytes: Uint8Array,
16
+ ): FileMultipart {
17
+ if (fileBytes == null || fileBytes.byteLength === 0) {
18
+ throw new PushPlusError('上传文件内容不能为空');
19
+ }
20
+ const safeName = fileName && fileName.trim() ? fileName : 'file';
21
+ const mime = contentType && contentType.trim() ? contentType : 'application/octet-stream';
22
+ const boundary = '----PushPlusBoundary' + randomBoundarySuffix();
23
+ const crlf = '\r\n';
24
+ const enc = new TextEncoder();
25
+ const head = enc.encode(
26
+ `--${boundary}${crlf}` +
27
+ `Content-Disposition: form-data; name="file"; filename="${escapeFileName(safeName)}"${crlf}` +
28
+ `Content-Type: ${mime}${crlf}${crlf}`,
29
+ );
30
+ const tail = enc.encode(`${crlf}--${boundary}--${crlf}`);
31
+ const body = new Uint8Array(head.byteLength + fileBytes.byteLength + tail.byteLength);
32
+ body.set(head, 0);
33
+ body.set(fileBytes, head.byteLength);
34
+ body.set(tail, head.byteLength + fileBytes.byteLength);
35
+ return { contentType: `multipart/form-data; boundary=${boundary}`, body };
36
+ }
37
+
38
+ export async function toFileBytes(file: FileInput): Promise<Uint8Array> {
39
+ if (file instanceof Uint8Array) {
40
+ return file;
41
+ }
42
+ if (file instanceof ArrayBuffer) {
43
+ return new Uint8Array(file);
44
+ }
45
+ if (typeof Blob !== 'undefined' && file instanceof Blob) {
46
+ const ab = await file.arrayBuffer();
47
+ return new Uint8Array(ab);
48
+ }
49
+ throw new PushPlusError(`不支持的上传文件类型: ${Object.prototype.toString.call(file)}`);
50
+ }
51
+
52
+ function escapeFileName(name: string): string {
53
+ return name.replace(/"/g, '_').replace(/\r/g, ' ').replace(/\n/g, ' ');
54
+ }
55
+
56
+ function randomBoundarySuffix(): string {
57
+ let s = '';
58
+ for (let i = 0; i < 32; i++) {
59
+ s += Math.floor(Math.random() * 16).toString(16);
60
+ }
61
+ return s;
62
+ }