@unboundcx/sdk 1.0.2 → 1.0.4
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/README.md +73 -54
- package/base.js +24 -16
- package/index.js +27 -15
- package/package.json +2 -2
- package/services/ai.js +62 -16
- package/services/enroll.js +48 -11
- package/services/externalOAuth.js +11 -3
- package/services/generateId.js +1 -1
- package/services/googleCalendar.js +22 -6
- package/services/layouts.js +12 -8
- package/services/login.js +12 -3
- package/services/lookup.js +1 -1
- package/services/messaging.js +140 -52
- package/services/notes.js +2 -8
- package/services/objects.js +34 -28
- package/services/phoneNumbers.js +85 -53
- package/services/portals.js +19 -4
- package/services/recordTypes.js +14 -3
- package/services/sipEndpoints.js +10 -3
- package/services/storage.js +227 -11
- package/services/subscriptions.js +19 -11
- package/services/verification.js +11 -3
- package/services/video.js +55 -22
- package/services/voice.js +169 -32
- package/services/workflows.js +122 -54
- package/test-backwards-compatibility.js +82 -51
- package/test-complete-coverage.js +113 -73
- package/test-constructor-patterns.js +32 -11
package/services/phoneNumbers.js
CHANGED
|
@@ -4,31 +4,36 @@ export class PhoneNumbersService {
|
|
|
4
4
|
this.carrier = new PhoneNumberCarrierService(sdk);
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
async search({
|
|
8
|
-
type,
|
|
9
|
-
country,
|
|
10
|
-
state,
|
|
11
|
-
city,
|
|
12
|
-
startsWith,
|
|
13
|
-
endsWith,
|
|
14
|
-
contains,
|
|
15
|
-
limit,
|
|
16
|
-
minimumBlockSize,
|
|
17
|
-
sms,
|
|
18
|
-
mms,
|
|
19
|
-
voice
|
|
7
|
+
async search({
|
|
8
|
+
type,
|
|
9
|
+
country,
|
|
10
|
+
state,
|
|
11
|
+
city,
|
|
12
|
+
startsWith,
|
|
13
|
+
endsWith,
|
|
14
|
+
contains,
|
|
15
|
+
limit,
|
|
16
|
+
minimumBlockSize,
|
|
17
|
+
sms,
|
|
18
|
+
mms,
|
|
19
|
+
voice,
|
|
20
20
|
}) {
|
|
21
21
|
// Validate optional parameters
|
|
22
22
|
const validationSchema = {};
|
|
23
23
|
if ('type' in arguments[0]) validationSchema.type = { type: 'string' };
|
|
24
|
-
if ('country' in arguments[0])
|
|
24
|
+
if ('country' in arguments[0])
|
|
25
|
+
validationSchema.country = { type: 'string' };
|
|
25
26
|
if ('state' in arguments[0]) validationSchema.state = { type: 'string' };
|
|
26
27
|
if ('city' in arguments[0]) validationSchema.city = { type: 'string' };
|
|
27
|
-
if ('startsWith' in arguments[0])
|
|
28
|
-
|
|
29
|
-
if ('
|
|
28
|
+
if ('startsWith' in arguments[0])
|
|
29
|
+
validationSchema.startsWith = { type: 'string' };
|
|
30
|
+
if ('endsWith' in arguments[0])
|
|
31
|
+
validationSchema.endsWith = { type: 'string' };
|
|
32
|
+
if ('contains' in arguments[0])
|
|
33
|
+
validationSchema.contains = { type: 'string' };
|
|
30
34
|
if ('limit' in arguments[0]) validationSchema.limit = { type: 'number' };
|
|
31
|
-
if ('minimumBlockSize' in arguments[0])
|
|
35
|
+
if ('minimumBlockSize' in arguments[0])
|
|
36
|
+
validationSchema.minimumBlockSize = { type: 'number' };
|
|
32
37
|
if ('sms' in arguments[0]) validationSchema.sms = { type: 'boolean' };
|
|
33
38
|
if ('mms' in arguments[0]) validationSchema.mms = { type: 'boolean' };
|
|
34
39
|
if ('voice' in arguments[0]) validationSchema.voice = { type: 'boolean' };
|
|
@@ -38,19 +43,19 @@ export class PhoneNumbersService {
|
|
|
38
43
|
}
|
|
39
44
|
|
|
40
45
|
const params = {
|
|
41
|
-
query: {
|
|
42
|
-
type,
|
|
43
|
-
country,
|
|
44
|
-
state,
|
|
45
|
-
city,
|
|
46
|
-
startsWith,
|
|
47
|
-
endsWith,
|
|
48
|
-
contains,
|
|
49
|
-
limit,
|
|
50
|
-
minimumBlockSize,
|
|
51
|
-
sms,
|
|
52
|
-
mms,
|
|
53
|
-
voice
|
|
46
|
+
query: {
|
|
47
|
+
type,
|
|
48
|
+
country,
|
|
49
|
+
state,
|
|
50
|
+
city,
|
|
51
|
+
startsWith,
|
|
52
|
+
endsWith,
|
|
53
|
+
contains,
|
|
54
|
+
limit,
|
|
55
|
+
minimumBlockSize,
|
|
56
|
+
sms,
|
|
57
|
+
mms,
|
|
58
|
+
voice,
|
|
54
59
|
},
|
|
55
60
|
};
|
|
56
61
|
|
|
@@ -86,21 +91,27 @@ export class PhoneNumbersService {
|
|
|
86
91
|
},
|
|
87
92
|
);
|
|
88
93
|
|
|
89
|
-
const result = await this.sdk._fetch(
|
|
94
|
+
const result = await this.sdk._fetch(
|
|
95
|
+
`/phoneNumbers/${phoneNumber}`,
|
|
96
|
+
'DELETE',
|
|
97
|
+
);
|
|
90
98
|
return result;
|
|
91
99
|
}
|
|
92
100
|
|
|
93
|
-
async update(
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
101
|
+
async update(
|
|
102
|
+
id,
|
|
103
|
+
{
|
|
104
|
+
name,
|
|
105
|
+
messagingWebHookUrl,
|
|
106
|
+
voiceWebHookUrl,
|
|
107
|
+
voiceAppExternalUrl,
|
|
108
|
+
voiceAppExternalMethod,
|
|
109
|
+
voiceApp,
|
|
110
|
+
voiceAppMetaData,
|
|
111
|
+
voiceRecordTypeId,
|
|
112
|
+
messagingRecordTypeId,
|
|
113
|
+
},
|
|
114
|
+
) {
|
|
104
115
|
this.sdk.validateParams(
|
|
105
116
|
{ id },
|
|
106
117
|
{
|
|
@@ -119,14 +130,18 @@ export class PhoneNumbersService {
|
|
|
119
130
|
|
|
120
131
|
const updateData = {};
|
|
121
132
|
if (name) updateData.name = name;
|
|
122
|
-
if (messagingWebHookUrl)
|
|
133
|
+
if (messagingWebHookUrl)
|
|
134
|
+
updateData.messagingWebHookUrl = messagingWebHookUrl;
|
|
123
135
|
if (voiceWebHookUrl) updateData.voiceWebHookUrl = voiceWebHookUrl;
|
|
124
|
-
if (voiceAppExternalUrl)
|
|
125
|
-
|
|
136
|
+
if (voiceAppExternalUrl)
|
|
137
|
+
updateData.voiceAppExternalUrl = voiceAppExternalUrl;
|
|
138
|
+
if (voiceAppExternalMethod)
|
|
139
|
+
updateData.voiceAppExternalMethod = voiceAppExternalMethod;
|
|
126
140
|
if (voiceApp) updateData.voiceApp = voiceApp;
|
|
127
141
|
if (voiceAppMetaData) updateData.voiceAppMetaData = voiceAppMetaData;
|
|
128
142
|
if (voiceRecordTypeId) updateData.voiceRecordTypeId = voiceRecordTypeId;
|
|
129
|
-
if (messagingRecordTypeId)
|
|
143
|
+
if (messagingRecordTypeId)
|
|
144
|
+
updateData.messagingRecordTypeId = messagingRecordTypeId;
|
|
130
145
|
|
|
131
146
|
const params = {
|
|
132
147
|
body: updateData,
|
|
@@ -149,7 +164,11 @@ export class PhoneNumbersService {
|
|
|
149
164
|
body: { cnam },
|
|
150
165
|
};
|
|
151
166
|
|
|
152
|
-
const result = await this.sdk._fetch(
|
|
167
|
+
const result = await this.sdk._fetch(
|
|
168
|
+
`/phoneNumbers/cnam/${phoneNumber}`,
|
|
169
|
+
'PUT',
|
|
170
|
+
params,
|
|
171
|
+
);
|
|
153
172
|
return result;
|
|
154
173
|
}
|
|
155
174
|
|
|
@@ -161,7 +180,10 @@ export class PhoneNumbersService {
|
|
|
161
180
|
},
|
|
162
181
|
);
|
|
163
182
|
|
|
164
|
-
const result = await this.sdk._fetch(
|
|
183
|
+
const result = await this.sdk._fetch(
|
|
184
|
+
`/phoneNumbers/format/${number}`,
|
|
185
|
+
'GET',
|
|
186
|
+
);
|
|
165
187
|
return result;
|
|
166
188
|
}
|
|
167
189
|
}
|
|
@@ -185,7 +207,11 @@ export class PhoneNumberCarrierService {
|
|
|
185
207
|
query: { updateVoiceConnection, updateMessagingConnection },
|
|
186
208
|
};
|
|
187
209
|
|
|
188
|
-
const result = await this.sdk._fetch(
|
|
210
|
+
const result = await this.sdk._fetch(
|
|
211
|
+
`/phoneNumbers/carrier/syncPhoneNumbers/${carrier}`,
|
|
212
|
+
'POST',
|
|
213
|
+
params,
|
|
214
|
+
);
|
|
189
215
|
return result;
|
|
190
216
|
}
|
|
191
217
|
|
|
@@ -197,7 +223,10 @@ export class PhoneNumberCarrierService {
|
|
|
197
223
|
},
|
|
198
224
|
);
|
|
199
225
|
|
|
200
|
-
const result = await this.sdk._fetch(
|
|
226
|
+
const result = await this.sdk._fetch(
|
|
227
|
+
`/phoneNumbers/carrier/${phoneNumber}`,
|
|
228
|
+
'GET',
|
|
229
|
+
);
|
|
201
230
|
return result;
|
|
202
231
|
}
|
|
203
232
|
|
|
@@ -209,7 +238,10 @@ export class PhoneNumberCarrierService {
|
|
|
209
238
|
},
|
|
210
239
|
);
|
|
211
240
|
|
|
212
|
-
const result = await this.sdk._fetch(
|
|
241
|
+
const result = await this.sdk._fetch(
|
|
242
|
+
`/phoneNumbers/carrier/${phoneNumber}`,
|
|
243
|
+
'DELETE',
|
|
244
|
+
);
|
|
213
245
|
return result;
|
|
214
246
|
}
|
|
215
|
-
}
|
|
247
|
+
}
|
package/services/portals.js
CHANGED
|
@@ -3,7 +3,16 @@ export class PortalsService {
|
|
|
3
3
|
this.sdk = sdk;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
async create({
|
|
6
|
+
async create({
|
|
7
|
+
name,
|
|
8
|
+
domain,
|
|
9
|
+
settings,
|
|
10
|
+
isPublic,
|
|
11
|
+
customCss,
|
|
12
|
+
customJs,
|
|
13
|
+
favicon,
|
|
14
|
+
logo,
|
|
15
|
+
}) {
|
|
7
16
|
this.sdk.validateParams(
|
|
8
17
|
{ name, domain },
|
|
9
18
|
{
|
|
@@ -34,7 +43,10 @@ export class PortalsService {
|
|
|
34
43
|
return result;
|
|
35
44
|
}
|
|
36
45
|
|
|
37
|
-
async update(
|
|
46
|
+
async update(
|
|
47
|
+
portalId,
|
|
48
|
+
{ name, domain, settings, isPublic, customCss, customJs, favicon, logo },
|
|
49
|
+
) {
|
|
38
50
|
this.sdk.validateParams(
|
|
39
51
|
{ portalId },
|
|
40
52
|
{
|
|
@@ -121,7 +133,10 @@ export class PortalsService {
|
|
|
121
133
|
},
|
|
122
134
|
);
|
|
123
135
|
|
|
124
|
-
const result = await this.sdk._fetch(
|
|
136
|
+
const result = await this.sdk._fetch(
|
|
137
|
+
`/portals/${portalId}/verify-dns`,
|
|
138
|
+
'POST',
|
|
139
|
+
);
|
|
125
140
|
return result;
|
|
126
141
|
}
|
|
127
|
-
}
|
|
142
|
+
}
|
package/services/recordTypes.js
CHANGED
|
@@ -4,7 +4,14 @@ export class RecordTypesService {
|
|
|
4
4
|
this.user = new UserRecordTypeDefaultsService(sdk);
|
|
5
5
|
}
|
|
6
6
|
|
|
7
|
-
async create({
|
|
7
|
+
async create({
|
|
8
|
+
name,
|
|
9
|
+
description,
|
|
10
|
+
create,
|
|
11
|
+
update,
|
|
12
|
+
read,
|
|
13
|
+
delete: deleteUsers,
|
|
14
|
+
}) {
|
|
8
15
|
this.sdk.validateParams(
|
|
9
16
|
{ name, description },
|
|
10
17
|
{
|
|
@@ -150,7 +157,11 @@ export class UserRecordTypeDefaultsService {
|
|
|
150
157
|
body: deleteData,
|
|
151
158
|
};
|
|
152
159
|
|
|
153
|
-
const result = await this.sdk._fetch(
|
|
160
|
+
const result = await this.sdk._fetch(
|
|
161
|
+
'/recordTypes/user/',
|
|
162
|
+
'DELETE',
|
|
163
|
+
params,
|
|
164
|
+
);
|
|
154
165
|
return result;
|
|
155
166
|
}
|
|
156
167
|
|
|
@@ -170,4 +181,4 @@ export class UserRecordTypeDefaultsService {
|
|
|
170
181
|
const result = await this.sdk._fetch('/recordTypes/user/', 'GET', params);
|
|
171
182
|
return result;
|
|
172
183
|
}
|
|
173
|
-
}
|
|
184
|
+
}
|
package/services/sipEndpoints.js
CHANGED
|
@@ -75,7 +75,11 @@ export class SipEndpointsService {
|
|
|
75
75
|
body: updateData,
|
|
76
76
|
};
|
|
77
77
|
|
|
78
|
-
const result = await this.sdk._fetch(
|
|
78
|
+
const result = await this.sdk._fetch(
|
|
79
|
+
`/sipEndpoints/${endpointId}`,
|
|
80
|
+
'PUT',
|
|
81
|
+
params,
|
|
82
|
+
);
|
|
79
83
|
return result;
|
|
80
84
|
}
|
|
81
85
|
|
|
@@ -87,7 +91,10 @@ export class SipEndpointsService {
|
|
|
87
91
|
},
|
|
88
92
|
);
|
|
89
93
|
|
|
90
|
-
const result = await this.sdk._fetch(
|
|
94
|
+
const result = await this.sdk._fetch(
|
|
95
|
+
`/sipEndpoints/${endpointId}`,
|
|
96
|
+
'DELETE',
|
|
97
|
+
);
|
|
91
98
|
return result;
|
|
92
99
|
}
|
|
93
|
-
}
|
|
100
|
+
}
|
package/services/storage.js
CHANGED
|
@@ -3,6 +3,203 @@ export class StorageService {
|
|
|
3
3
|
this.sdk = sdk;
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
+
async upload({
|
|
7
|
+
classification = 'generic',
|
|
8
|
+
folder,
|
|
9
|
+
fileName,
|
|
10
|
+
file,
|
|
11
|
+
isPublic = false,
|
|
12
|
+
country = 'US',
|
|
13
|
+
expireAfter,
|
|
14
|
+
relatedId,
|
|
15
|
+
createAccessKey = false,
|
|
16
|
+
accessKeyExpiresIn,
|
|
17
|
+
}) {
|
|
18
|
+
this.sdk.validateParams(
|
|
19
|
+
{
|
|
20
|
+
classification,
|
|
21
|
+
folder,
|
|
22
|
+
fileName,
|
|
23
|
+
file,
|
|
24
|
+
isPublic,
|
|
25
|
+
country,
|
|
26
|
+
expireAfter,
|
|
27
|
+
relatedId,
|
|
28
|
+
createAccessKey,
|
|
29
|
+
accessKeyExpiresIn,
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
classification: { type: 'string', required: false },
|
|
33
|
+
folder: { type: 'string', required: false },
|
|
34
|
+
fileName: { type: 'string', required: false },
|
|
35
|
+
file: { type: 'object', required: true },
|
|
36
|
+
isPublic: { type: 'boolean', required: false },
|
|
37
|
+
country: { type: 'string', required: false },
|
|
38
|
+
expireAfter: { type: 'string', required: false },
|
|
39
|
+
relatedId: { type: 'string', required: false },
|
|
40
|
+
createAccessKey: { type: 'boolean', required: false },
|
|
41
|
+
accessKeyExpiresIn: { type: 'string', required: false },
|
|
42
|
+
},
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const isNode = typeof window === 'undefined';
|
|
46
|
+
let formData;
|
|
47
|
+
const headers = {};
|
|
48
|
+
|
|
49
|
+
if (isNode) {
|
|
50
|
+
// Node.js environment - use direct buffer approach
|
|
51
|
+
// Create a simple body with the file buffer and metadata
|
|
52
|
+
const boundary = `----formdata-${Date.now()}-${Math.random().toString(36)}`;
|
|
53
|
+
const CRLF = '\r\n';
|
|
54
|
+
let body = '';
|
|
55
|
+
|
|
56
|
+
// Add file field with proper MIME type detection
|
|
57
|
+
let contentType = 'application/octet-stream';
|
|
58
|
+
if (fileName) {
|
|
59
|
+
try {
|
|
60
|
+
// Try to use mime-types package if available
|
|
61
|
+
const mime = await import('mime-types');
|
|
62
|
+
contentType = mime.lookup(fileName) || 'application/octet-stream';
|
|
63
|
+
} catch (error) {
|
|
64
|
+
// Fallback to basic extension mapping
|
|
65
|
+
const ext = fileName.split('.').pop().toLowerCase();
|
|
66
|
+
const commonTypes = {
|
|
67
|
+
// Documents
|
|
68
|
+
pdf: 'application/pdf',
|
|
69
|
+
doc: 'application/msword',
|
|
70
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
71
|
+
xls: 'application/vnd.ms-excel',
|
|
72
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
73
|
+
ppt: 'application/vnd.ms-powerpoint',
|
|
74
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
75
|
+
odt: 'application/vnd.oasis.opendocument.text',
|
|
76
|
+
ods: 'application/vnd.oasis.opendocument.spreadsheet',
|
|
77
|
+
odp: 'application/vnd.oasis.opendocument.presentation',
|
|
78
|
+
rtf: 'application/rtf',
|
|
79
|
+
// Images
|
|
80
|
+
jpg: 'image/jpeg',
|
|
81
|
+
jpeg: 'image/jpeg',
|
|
82
|
+
png: 'image/png',
|
|
83
|
+
gif: 'image/gif',
|
|
84
|
+
bmp: 'image/bmp',
|
|
85
|
+
webp: 'image/webp',
|
|
86
|
+
svg: 'image/svg+xml',
|
|
87
|
+
ico: 'image/x-icon',
|
|
88
|
+
tiff: 'image/tiff',
|
|
89
|
+
tif: 'image/tiff',
|
|
90
|
+
psd: 'image/vnd.adobe.photoshop',
|
|
91
|
+
raw: 'image/x-canon-cr2',
|
|
92
|
+
heic: 'image/heic',
|
|
93
|
+
heif: 'image/heif',
|
|
94
|
+
// Audio
|
|
95
|
+
mp3: 'audio/mpeg',
|
|
96
|
+
wav: 'audio/wav',
|
|
97
|
+
flac: 'audio/flac',
|
|
98
|
+
aac: 'audio/aac',
|
|
99
|
+
ogg: 'audio/ogg',
|
|
100
|
+
wma: 'audio/x-ms-wma',
|
|
101
|
+
m4a: 'audio/mp4',
|
|
102
|
+
opus: 'audio/opus',
|
|
103
|
+
// Video
|
|
104
|
+
mp4: 'video/mp4',
|
|
105
|
+
avi: 'video/avi',
|
|
106
|
+
mkv: 'video/mkv',
|
|
107
|
+
mov: 'video/quicktime',
|
|
108
|
+
wmv: 'video/x-ms-wmv',
|
|
109
|
+
flv: 'video/x-flv',
|
|
110
|
+
webm: 'video/webm',
|
|
111
|
+
// Archives
|
|
112
|
+
zip: 'application/zip',
|
|
113
|
+
rar: 'application/x-rar-compressed',
|
|
114
|
+
'7z': 'application/x-7z-compressed',
|
|
115
|
+
tar: 'application/x-tar',
|
|
116
|
+
gz: 'application/gzip',
|
|
117
|
+
// Text
|
|
118
|
+
txt: 'text/plain',
|
|
119
|
+
csv: 'text/csv',
|
|
120
|
+
json: 'application/json',
|
|
121
|
+
xml: 'application/xml',
|
|
122
|
+
html: 'text/html',
|
|
123
|
+
css: 'text/css',
|
|
124
|
+
js: 'application/javascript',
|
|
125
|
+
// Other
|
|
126
|
+
sql: 'application/sql',
|
|
127
|
+
log: 'text/plain',
|
|
128
|
+
};
|
|
129
|
+
contentType = commonTypes[ext] || 'application/octet-stream';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
body += `--${boundary}${CRLF}`;
|
|
134
|
+
body += `Content-Disposition: form-data; name="files"; filename="${fileName || 'file'}"${CRLF}`;
|
|
135
|
+
body += `Content-Type: ${contentType}${CRLF}${CRLF}`;
|
|
136
|
+
|
|
137
|
+
// Add other form fields
|
|
138
|
+
const formFields = [];
|
|
139
|
+
if (classification) formFields.push(['classification', classification]);
|
|
140
|
+
if (folder) formFields.push(['folder', folder]);
|
|
141
|
+
if (isPublic !== undefined) formFields.push(['isPublic', isPublic.toString()]);
|
|
142
|
+
if (country) formFields.push(['country', country]);
|
|
143
|
+
if (expireAfter) formFields.push(['expireAfter', expireAfter]);
|
|
144
|
+
if (relatedId) formFields.push(['relatedId', relatedId]);
|
|
145
|
+
if (createAccessKey !== undefined) formFields.push(['createAccessKey', createAccessKey.toString()]);
|
|
146
|
+
if (accessKeyExpiresIn) formFields.push(['accessKeyExpiresIn', accessKeyExpiresIn]);
|
|
147
|
+
|
|
148
|
+
// Convert to buffers and combine
|
|
149
|
+
const headerBuffer = Buffer.from(body, 'utf8');
|
|
150
|
+
const fileBuffer = Buffer.isBuffer(file) ? file : Buffer.from(file);
|
|
151
|
+
|
|
152
|
+
// Add form fields
|
|
153
|
+
let fieldsBuffer = Buffer.alloc(0);
|
|
154
|
+
for (const [name, value] of formFields) {
|
|
155
|
+
const fieldData = `${CRLF}--${boundary}${CRLF}Content-Disposition: form-data; name="${name}"${CRLF}${CRLF}${value}`;
|
|
156
|
+
fieldsBuffer = Buffer.concat([fieldsBuffer, Buffer.from(fieldData, 'utf8')]);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Final boundary
|
|
160
|
+
const endBoundary = Buffer.from(`${CRLF}--${boundary}--${CRLF}`, 'utf8');
|
|
161
|
+
|
|
162
|
+
// Combine all parts
|
|
163
|
+
formData = Buffer.concat([headerBuffer, fileBuffer, fieldsBuffer, endBoundary]);
|
|
164
|
+
|
|
165
|
+
// Set proper Content-Type header
|
|
166
|
+
headers['content-type'] = `multipart/form-data; boundary=${boundary}`;
|
|
167
|
+
} else {
|
|
168
|
+
// Browser environment - use native FormData
|
|
169
|
+
formData = new FormData();
|
|
170
|
+
|
|
171
|
+
// Add the file - handle both Buffer and File objects
|
|
172
|
+
if (Buffer.isBuffer(file)) {
|
|
173
|
+
const blob = new Blob([file]);
|
|
174
|
+
formData.append('files', blob, fileName || 'file');
|
|
175
|
+
} else if (file instanceof File) {
|
|
176
|
+
formData.append('files', file);
|
|
177
|
+
} else {
|
|
178
|
+
throw new Error('In browser environment, file must be a Buffer or File object');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Add other parameters
|
|
182
|
+
if (classification) formData.append('classification', classification);
|
|
183
|
+
if (folder) formData.append('folder', folder);
|
|
184
|
+
if (isPublic !== undefined) formData.append('isPublic', isPublic.toString());
|
|
185
|
+
if (country) formData.append('country', country);
|
|
186
|
+
if (expireAfter) formData.append('expireAfter', expireAfter);
|
|
187
|
+
if (relatedId) formData.append('relatedId', relatedId);
|
|
188
|
+
if (createAccessKey !== undefined) formData.append('createAccessKey', createAccessKey.toString());
|
|
189
|
+
if (accessKeyExpiresIn) formData.append('accessKeyExpiresIn', accessKeyExpiresIn);
|
|
190
|
+
|
|
191
|
+
// Don't set Content-Type - let browser handle it automatically
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const params = {
|
|
195
|
+
body: formData,
|
|
196
|
+
headers,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
const result = await this.sdk._fetch('/storage/upload', 'POST', params, true);
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
|
|
6
203
|
async uploadFiles(files, options = {}) {
|
|
7
204
|
const { classification, expireAfter, isPublic, metadata } = options;
|
|
8
205
|
|
|
@@ -33,26 +230,29 @@ export class StorageService {
|
|
|
33
230
|
formData = new FormData();
|
|
34
231
|
formData.append('files', files);
|
|
35
232
|
} else {
|
|
36
|
-
throw new Error(
|
|
233
|
+
throw new Error(
|
|
234
|
+
'Invalid files format. Expected FormData, FileList, File array, or File object',
|
|
235
|
+
);
|
|
37
236
|
}
|
|
38
237
|
|
|
39
238
|
// Add optional parameters to FormData
|
|
40
239
|
if (classification) formData.append('classification', classification);
|
|
41
240
|
if (expireAfter) formData.append('expireAfter', expireAfter);
|
|
42
|
-
if (isPublic !== undefined)
|
|
241
|
+
if (isPublic !== undefined)
|
|
242
|
+
formData.append('isPublic', isPublic.toString());
|
|
43
243
|
if (metadata) formData.append('metadata', JSON.stringify(metadata));
|
|
44
244
|
|
|
45
245
|
const params = {
|
|
46
246
|
body: formData,
|
|
47
247
|
headers: {
|
|
48
248
|
// Let browser/Node.js set Content-Type with boundary for multipart/form-data
|
|
49
|
-
}
|
|
249
|
+
},
|
|
50
250
|
};
|
|
51
251
|
|
|
52
252
|
// Remove Content-Type to let FormData set it properly
|
|
53
253
|
delete params.headers['Content-Type'];
|
|
54
254
|
|
|
55
|
-
const result = await this.sdk._fetch('/storage/upload', 'POST', params);
|
|
255
|
+
const result = await this.sdk._fetch('/storage/upload', 'POST', params, true);
|
|
56
256
|
return result;
|
|
57
257
|
}
|
|
58
258
|
|
|
@@ -70,7 +270,11 @@ export class StorageService {
|
|
|
70
270
|
params.query = { download: 'true' };
|
|
71
271
|
}
|
|
72
272
|
|
|
73
|
-
const result = await this.sdk._fetch(
|
|
273
|
+
const result = await this.sdk._fetch(
|
|
274
|
+
`/storage/file/${storageId}`,
|
|
275
|
+
'GET',
|
|
276
|
+
params,
|
|
277
|
+
);
|
|
74
278
|
return result;
|
|
75
279
|
}
|
|
76
280
|
|
|
@@ -105,7 +309,10 @@ export class StorageService {
|
|
|
105
309
|
},
|
|
106
310
|
);
|
|
107
311
|
|
|
108
|
-
const result = await this.sdk._fetch(
|
|
312
|
+
const result = await this.sdk._fetch(
|
|
313
|
+
`/storage/file/${storageId}`,
|
|
314
|
+
'DELETE',
|
|
315
|
+
);
|
|
109
316
|
return result;
|
|
110
317
|
}
|
|
111
318
|
|
|
@@ -122,7 +329,10 @@ export class StorageService {
|
|
|
122
329
|
},
|
|
123
330
|
);
|
|
124
331
|
|
|
125
|
-
const result = await this.sdk._fetch(
|
|
332
|
+
const result = await this.sdk._fetch(
|
|
333
|
+
`/storage/file/${storageId}/info`,
|
|
334
|
+
'GET',
|
|
335
|
+
);
|
|
126
336
|
return result;
|
|
127
337
|
}
|
|
128
338
|
|
|
@@ -139,7 +349,11 @@ export class StorageService {
|
|
|
139
349
|
body: { metadata },
|
|
140
350
|
};
|
|
141
351
|
|
|
142
|
-
const result = await this.sdk._fetch(
|
|
352
|
+
const result = await this.sdk._fetch(
|
|
353
|
+
`/storage/file/${storageId}/metadata`,
|
|
354
|
+
'PUT',
|
|
355
|
+
params,
|
|
356
|
+
);
|
|
143
357
|
return result;
|
|
144
358
|
}
|
|
145
359
|
|
|
@@ -148,11 +362,13 @@ export class StorageService {
|
|
|
148
362
|
|
|
149
363
|
// Validate optional parameters
|
|
150
364
|
const validationSchema = {};
|
|
151
|
-
if ('classification' in options)
|
|
365
|
+
if ('classification' in options)
|
|
366
|
+
validationSchema.classification = { type: 'string' };
|
|
152
367
|
if ('limit' in options) validationSchema.limit = { type: 'number' };
|
|
153
368
|
if ('offset' in options) validationSchema.offset = { type: 'number' };
|
|
154
369
|
if ('orderBy' in options) validationSchema.orderBy = { type: 'string' };
|
|
155
|
-
if ('orderDirection' in options)
|
|
370
|
+
if ('orderDirection' in options)
|
|
371
|
+
validationSchema.orderDirection = { type: 'string' };
|
|
156
372
|
|
|
157
373
|
if (Object.keys(validationSchema).length > 0) {
|
|
158
374
|
this.sdk.validateParams(options, validationSchema);
|
|
@@ -165,4 +381,4 @@ export class StorageService {
|
|
|
165
381
|
const result = await this.sdk._fetch('/storage/files', 'GET', params);
|
|
166
382
|
return result;
|
|
167
383
|
}
|
|
168
|
-
}
|
|
384
|
+
}
|
|
@@ -20,11 +20,15 @@ export class SocketSubscriptionsService {
|
|
|
20
20
|
|
|
21
21
|
const params = {
|
|
22
22
|
query: {
|
|
23
|
-
sessionId
|
|
24
|
-
}
|
|
25
|
-
}
|
|
23
|
+
sessionId,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
26
|
|
|
27
|
-
const result = await this.sdk._fetch(
|
|
27
|
+
const result = await this.sdk._fetch(
|
|
28
|
+
'/subscriptions/socket/connection',
|
|
29
|
+
'GET',
|
|
30
|
+
params,
|
|
31
|
+
);
|
|
28
32
|
return result;
|
|
29
33
|
}
|
|
30
34
|
|
|
@@ -41,8 +45,8 @@ export class SocketSubscriptionsService {
|
|
|
41
45
|
body: {
|
|
42
46
|
sessionId,
|
|
43
47
|
...subscriptionParams,
|
|
44
|
-
}
|
|
45
|
-
}
|
|
48
|
+
},
|
|
49
|
+
};
|
|
46
50
|
|
|
47
51
|
let uri = `/subscriptions/socket/`;
|
|
48
52
|
if (subscriptionParams?.id) {
|
|
@@ -63,11 +67,15 @@ export class SocketSubscriptionsService {
|
|
|
63
67
|
|
|
64
68
|
const params = {
|
|
65
69
|
body: {
|
|
66
|
-
sessionId
|
|
67
|
-
}
|
|
68
|
-
}
|
|
70
|
+
sessionId,
|
|
71
|
+
},
|
|
72
|
+
};
|
|
69
73
|
|
|
70
|
-
const result = await this.sdk._fetch(
|
|
74
|
+
const result = await this.sdk._fetch(
|
|
75
|
+
`/subscriptions/socket/${id}`,
|
|
76
|
+
'DELETE',
|
|
77
|
+
params,
|
|
78
|
+
);
|
|
71
79
|
return result;
|
|
72
80
|
}
|
|
73
|
-
}
|
|
81
|
+
}
|