• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ringcentral / ringcentral-js-widgets / 5607299609

pending completion
5607299609

push

github

web-flow
sync features and bugfixs from dd3f20d7 (#1730)

8800 of 15728 branches covered (55.95%)

Branch coverage included in aggregate %.

881 of 1290 new or added lines in 248 files covered. (68.29%)

13 existing lines in 7 files now uncovered.

14708 of 22609 relevant lines covered (65.05%)

142084.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/packages/utils/src/utils/MultiPartUTF8FormData.ts
1
import { fileToBase64 } from './base64Handler';
2

3
type MultiPartDataType = {
4
  key: string;
5
  source: string;
6
  filename?: string;
7
  type?: string;
8
};
9

10
export type MultiPartUTF8FormDataOptions = {
11
  fields?: Record<string, any>;
12
  files?: Record<string, File | Blob | File[] | Blob[]>;
13
};
14

15
/**
16
 * make you can send custom form data with `filename*=`
17
 */
18
export class MultiPartUTF8FormData {
NEW
19
  private _boundary = `----Boundary${Math.random().toString(35).substring(2)}`;
×
20

21
  constructor(private dataList: MultiPartUTF8FormDataOptions) {}
22

23
  async getData(contentType = 'multipart/form-data') {
×
NEW
24
    const formDataStringList = await this.getFormStringList();
×
NEW
25
    const wrappedBoundary = `--${this._boundary}`;
×
NEW
26
    const outputRowData = `${formDataStringList
×
NEW
27
      .map((body) => `${wrappedBoundary}\r\n${body}`)
×
28
      .join('\r\n')}`;
29

NEW
30
    return {
×
31
      contentType: `${contentType}; boundary=${this._boundary}`,
32
      formData: `${outputRowData}\r\n${wrappedBoundary}--`,
33
    };
34
  }
35

36
  private async getFormStringList() {
NEW
37
    const result = await Promise.all([
×
38
      ...Object.entries(this.dataList.fields || {}).map(
×
39
        async ([key, value]) => {
NEW
40
          if (typeof value === 'object') {
×
NEW
41
            return this.getJsonFormString({
×
42
              key,
43
              source: JSON.stringify(value),
44
            });
45
          }
46

NEW
47
          return this.getJsonFormString({
×
48
            key,
49
            source: value,
50
          });
51
        },
52
      ),
53
      ...Object.entries(this.dataList.files || {}).map(async ([key, value]) => {
×
NEW
54
        if (Array.isArray(value)) {
×
NEW
55
          return Promise.all(value.map((file) => this.processFile(key, file)));
×
56
        }
57

NEW
58
        return this.processFile(key, value);
×
59
      }),
60
    ]);
61

NEW
62
    return result.flat();
×
63
  }
64

65
  private async processFile(key: string, file: File | Blob) {
NEW
66
    const base64 = await fileToBase64(file);
×
67

NEW
68
    return this.getBase64FormString({
×
69
      key,
70
      source: base64,
71
      filename: file instanceof File ? file.name : 'blob',
×
72
      type: file.type,
73
    });
74
  }
75

76
  private getJsonFormString({
77
    key,
78
    source,
79
    type = 'application/json',
×
80
  }: MultiPartDataType) {
NEW
81
    return [
×
82
      `Content-Disposition: form-data; name="${key}"`,
83
      `Content-type: ${type}`,
84
      '',
85
      `${source}`,
86
    ].join('\r\n');
87
  }
88

89
  private getBase64FormString({
90
    key,
91
    source,
92
    filename = 'blob',
×
93
    type = 'application/octet-stream',
×
94
  }: MultiPartDataType) {
NEW
95
    const encodedFileName = encodeURI(filename);
×
NEW
96
    const contentType = type;
×
NEW
97
    const dataUrl = source.split('base64,')[1];
×
98

NEW
99
    return [
×
100
      `Content-Disposition: form-data; name="${key}"; filename*="UTF-8''${encodedFileName}"; filename="${encodedFileName}"`,
101
      `Content-Type: ${contentType}`,
102
      'Content-Transfer-Encoding: base64',
103
      '',
104
      dataUrl,
105
    ].join('\r\n');
106
  }
107
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc