@unboundcx/sdk 1.0.0
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 +456 -0
- package/base.js +263 -0
- package/index.js +181 -0
- package/package.json +88 -0
- package/services/ai.js +151 -0
- package/services/enroll.js +238 -0
- package/services/externalOAuth.js +117 -0
- package/services/generateId.js +39 -0
- package/services/googleCalendar.js +92 -0
- package/services/layouts.js +91 -0
- package/services/login.js +76 -0
- package/services/lookup.js +53 -0
- package/services/messaging.js +687 -0
- package/services/notes.js +137 -0
- package/services/objects.js +163 -0
- package/services/phoneNumbers.js +215 -0
- package/services/portals.js +127 -0
- package/services/recordTypes.js +173 -0
- package/services/sipEndpoints.js +93 -0
- package/services/storage.js +168 -0
- package/services/subscriptions.js +73 -0
- package/services/verification.js +87 -0
- package/services/video.js +380 -0
- package/services/voice.js +434 -0
- package/services/workflows.js +291 -0
- package/test-backwards-compatibility.js +195 -0
- package/test-complete-coverage.js +247 -0
- package/test-constructor-patterns.js +111 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
export class WorkflowsService {
|
|
2
|
+
constructor(sdk) {
|
|
3
|
+
this.sdk = sdk;
|
|
4
|
+
this.items = new WorkflowItemsService(sdk);
|
|
5
|
+
this.connections = new WorkflowConnectionsService(sdk);
|
|
6
|
+
this.sessions = new WorkflowSessionsService(sdk);
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
async getSettings(type) {
|
|
10
|
+
this.sdk.validateParams(
|
|
11
|
+
{ type },
|
|
12
|
+
{
|
|
13
|
+
type: { type: 'string', required: true },
|
|
14
|
+
},
|
|
15
|
+
);
|
|
16
|
+
|
|
17
|
+
const params = {
|
|
18
|
+
query: { type },
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const result = await this.sdk._fetch('/workflows/settings', 'GET', params);
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class WorkflowItemsService {
|
|
27
|
+
constructor(sdk) {
|
|
28
|
+
this.sdk = sdk;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async delete(id) {
|
|
32
|
+
this.sdk.validateParams(
|
|
33
|
+
{ id },
|
|
34
|
+
{
|
|
35
|
+
id: { type: 'string', required: true },
|
|
36
|
+
},
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const params = {
|
|
40
|
+
body: {
|
|
41
|
+
where: {
|
|
42
|
+
id
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result = await this.sdk._fetch('/object/workflowItems', 'DELETE', params);
|
|
48
|
+
return result;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async list(workflowVersionId) {
|
|
52
|
+
this.sdk.validateParams(
|
|
53
|
+
{ workflowVersionId },
|
|
54
|
+
{
|
|
55
|
+
workflowVersionId: { type: 'string', required: true },
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const params = {
|
|
60
|
+
query: {
|
|
61
|
+
expandDetails: true,
|
|
62
|
+
workflowVersionId
|
|
63
|
+
},
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const result = await this.sdk._fetch('/object/workflowItems', 'GET', params);
|
|
67
|
+
return result;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async get(id) {
|
|
71
|
+
this.sdk.validateParams(
|
|
72
|
+
{ id },
|
|
73
|
+
{
|
|
74
|
+
id: { type: 'string', required: true },
|
|
75
|
+
},
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return this.sdk.objects.byId(id);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
async create({ workflowVersionId, category, type, description, position, settings }) {
|
|
82
|
+
this.sdk.validateParams(
|
|
83
|
+
{ workflowVersionId, category, type },
|
|
84
|
+
{
|
|
85
|
+
workflowVersionId: { type: 'string', required: true },
|
|
86
|
+
category: { type: 'string', required: true },
|
|
87
|
+
type: { type: 'string', required: true },
|
|
88
|
+
description: { type: 'string', required: false },
|
|
89
|
+
position: { type: 'object', required: false },
|
|
90
|
+
settings: { type: 'object', required: false },
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const params = {
|
|
95
|
+
body: {
|
|
96
|
+
workflowVersionId,
|
|
97
|
+
category,
|
|
98
|
+
type,
|
|
99
|
+
description,
|
|
100
|
+
position,
|
|
101
|
+
settings,
|
|
102
|
+
},
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const result = await this.sdk._fetch('/object/workflowItems', 'POST', params);
|
|
106
|
+
return result;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
async update({
|
|
110
|
+
id,
|
|
111
|
+
description,
|
|
112
|
+
label,
|
|
113
|
+
labelBgColor,
|
|
114
|
+
labelTextColor,
|
|
115
|
+
descriptionBgColor,
|
|
116
|
+
descriptionTextColor,
|
|
117
|
+
icon,
|
|
118
|
+
iconBgColor,
|
|
119
|
+
iconTextColor,
|
|
120
|
+
ports,
|
|
121
|
+
connections,
|
|
122
|
+
position,
|
|
123
|
+
settings
|
|
124
|
+
}) {
|
|
125
|
+
this.sdk.validateParams(
|
|
126
|
+
{ id },
|
|
127
|
+
{
|
|
128
|
+
id: { type: 'string', required: true },
|
|
129
|
+
description: { type: 'string', required: false },
|
|
130
|
+
label: { type: 'string', required: false },
|
|
131
|
+
labelBgColor: { type: 'string', required: false },
|
|
132
|
+
labelTextColor: { type: 'string', required: false },
|
|
133
|
+
descriptionBgColor: { type: 'string', required: false },
|
|
134
|
+
descriptionTextColor: { type: 'string', required: false },
|
|
135
|
+
icon: { type: 'string', required: false },
|
|
136
|
+
iconBgColor: { type: 'string', required: false },
|
|
137
|
+
iconTextColor: { type: 'string', required: false },
|
|
138
|
+
ports: { type: 'array', required: false },
|
|
139
|
+
connections: { type: 'object', required: false },
|
|
140
|
+
position: { type: 'object', required: false },
|
|
141
|
+
settings: { type: 'object', required: false }
|
|
142
|
+
},
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
const updateData = {};
|
|
146
|
+
if (description !== undefined) updateData.description = description;
|
|
147
|
+
if (label !== undefined) updateData.label = label;
|
|
148
|
+
if (labelBgColor !== undefined) updateData.labelBgColor = labelBgColor;
|
|
149
|
+
if (labelTextColor !== undefined) updateData.labelTextColor = labelTextColor;
|
|
150
|
+
if (descriptionBgColor !== undefined) updateData.descriptionBgColor = descriptionBgColor;
|
|
151
|
+
if (descriptionTextColor !== undefined) updateData.descriptionTextColor = descriptionTextColor;
|
|
152
|
+
if (icon !== undefined) updateData.icon = icon;
|
|
153
|
+
if (iconBgColor !== undefined) updateData.iconBgColor = iconBgColor;
|
|
154
|
+
if (iconTextColor !== undefined) updateData.iconTextColor = iconTextColor;
|
|
155
|
+
if (ports !== undefined) updateData.ports = ports;
|
|
156
|
+
if (position !== undefined) updateData.position = position;
|
|
157
|
+
if (settings !== undefined) updateData.settings = settings;
|
|
158
|
+
|
|
159
|
+
const params = {
|
|
160
|
+
body: {
|
|
161
|
+
where: {
|
|
162
|
+
id
|
|
163
|
+
},
|
|
164
|
+
update: updateData
|
|
165
|
+
},
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const result = await this.sdk._fetch('/object/workflowItems', 'PUT', params);
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export class WorkflowConnectionsService {
|
|
174
|
+
constructor(sdk) {
|
|
175
|
+
this.sdk = sdk;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async delete(workflowItemId, workflowItemPortId, inWorkflowItemId, inWorkflowItemPortId) {
|
|
179
|
+
this.sdk.validateParams(
|
|
180
|
+
{ workflowItemId, workflowItemPortId, inWorkflowItemId, inWorkflowItemPortId },
|
|
181
|
+
{
|
|
182
|
+
workflowItemId: { type: 'string', required: true },
|
|
183
|
+
workflowItemPortId: { type: 'string', required: true },
|
|
184
|
+
inWorkflowItemId: { type: 'string', required: true },
|
|
185
|
+
inWorkflowItemPortId: { type: 'string', required: true },
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const params = {
|
|
190
|
+
body: {
|
|
191
|
+
where: {
|
|
192
|
+
workflowItemId,
|
|
193
|
+
workflowItemPortId,
|
|
194
|
+
inWorkflowItemId,
|
|
195
|
+
inWorkflowItemPortId
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const result = await this.sdk._fetch('/object/workflowItemConnections', 'DELETE', params);
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
async create({ workflowItemPortId, workflowItemId, inWorkflowItemId, inWorkflowItemPortId }) {
|
|
205
|
+
this.sdk.validateParams(
|
|
206
|
+
{ workflowItemPortId, workflowItemId, inWorkflowItemId, inWorkflowItemPortId },
|
|
207
|
+
{
|
|
208
|
+
workflowItemPortId: { type: 'string', required: true },
|
|
209
|
+
workflowItemId: { type: 'string', required: true },
|
|
210
|
+
inWorkflowItemId: { type: 'string', required: true },
|
|
211
|
+
inWorkflowItemPortId: { type: 'string', required: true },
|
|
212
|
+
},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const params = {
|
|
216
|
+
body: {
|
|
217
|
+
workflowItemPortId,
|
|
218
|
+
workflowItemId,
|
|
219
|
+
inWorkflowItemId,
|
|
220
|
+
inWorkflowItemPortId
|
|
221
|
+
},
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const result = await this.sdk._fetch('/object/workflowItemConnections', 'POST', params);
|
|
225
|
+
return result;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export class WorkflowSessionsService {
|
|
230
|
+
constructor(sdk) {
|
|
231
|
+
this.sdk = sdk;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async create(workflowId, sessionData) {
|
|
235
|
+
this.sdk.validateParams(
|
|
236
|
+
{ workflowId, sessionData },
|
|
237
|
+
{
|
|
238
|
+
workflowId: { type: 'string', required: true },
|
|
239
|
+
sessionData: { type: 'object', required: true },
|
|
240
|
+
},
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const params = {
|
|
244
|
+
body: sessionData,
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const result = await this.sdk._fetch(`/workflows/${workflowId}/sessions`, 'POST', params);
|
|
248
|
+
return result;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
async get(sessionId) {
|
|
252
|
+
this.sdk.validateParams(
|
|
253
|
+
{ sessionId },
|
|
254
|
+
{
|
|
255
|
+
sessionId: { type: 'string', required: true },
|
|
256
|
+
},
|
|
257
|
+
);
|
|
258
|
+
|
|
259
|
+
const result = await this.sdk._fetch(`/workflows/sessions/${sessionId}`, 'GET');
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async update(sessionId, updateData) {
|
|
264
|
+
this.sdk.validateParams(
|
|
265
|
+
{ sessionId, updateData },
|
|
266
|
+
{
|
|
267
|
+
sessionId: { type: 'string', required: true },
|
|
268
|
+
updateData: { type: 'object', required: true },
|
|
269
|
+
},
|
|
270
|
+
);
|
|
271
|
+
|
|
272
|
+
const params = {
|
|
273
|
+
body: updateData,
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
const result = await this.sdk._fetch(`/workflows/sessions/${sessionId}`, 'PUT', params);
|
|
277
|
+
return result;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
async delete(sessionId) {
|
|
281
|
+
this.sdk.validateParams(
|
|
282
|
+
{ sessionId },
|
|
283
|
+
{
|
|
284
|
+
sessionId: { type: 'string', required: true },
|
|
285
|
+
},
|
|
286
|
+
);
|
|
287
|
+
|
|
288
|
+
const result = await this.sdk._fetch(`/workflows/sessions/${sessionId}`, 'DELETE');
|
|
289
|
+
return result;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Backwards Compatibility Test
|
|
5
|
+
*
|
|
6
|
+
* This script tests that the new modular SDK is backwards compatible
|
|
7
|
+
* with the existing monolithic SDK usage patterns.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import SDK from './index.js';
|
|
11
|
+
|
|
12
|
+
async function testBasicSDKFunctionality() {
|
|
13
|
+
console.log('🧪 Testing basic SDK functionality...');
|
|
14
|
+
|
|
15
|
+
// Test SDK initialization (same as original)
|
|
16
|
+
const api = new SDK('test-namespace', 'call-123', 'fake-jwt-token', 'request-456');
|
|
17
|
+
|
|
18
|
+
// Verify all main services are available
|
|
19
|
+
const expectedServices = [
|
|
20
|
+
'login', 'objects', 'messaging', 'video', 'voice', 'ai', 'lookup',
|
|
21
|
+
'layouts', 'subscriptions', 'workflows', 'notes', 'storage',
|
|
22
|
+
'verification', 'portals', 'sipEndpoints', 'externalOAuth',
|
|
23
|
+
'googleCalendar', 'enroll'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
for (const service of expectedServices) {
|
|
27
|
+
if (!api[service]) {
|
|
28
|
+
throw new Error(`❌ Service '${service}' not found on SDK instance`);
|
|
29
|
+
}
|
|
30
|
+
console.log(`✅ Service '${service}' is available`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Test nested services
|
|
34
|
+
if (!api.messaging.sms) {
|
|
35
|
+
throw new Error('❌ messaging.sms not found');
|
|
36
|
+
}
|
|
37
|
+
console.log('✅ messaging.sms is available');
|
|
38
|
+
|
|
39
|
+
if (!api.messaging.email) {
|
|
40
|
+
throw new Error('❌ messaging.email not found');
|
|
41
|
+
}
|
|
42
|
+
console.log('✅ messaging.email is available');
|
|
43
|
+
|
|
44
|
+
if (!api.ai.generative) {
|
|
45
|
+
throw new Error('❌ ai.generative not found');
|
|
46
|
+
}
|
|
47
|
+
console.log('✅ ai.generative is available');
|
|
48
|
+
|
|
49
|
+
if (!api.workflows.items) {
|
|
50
|
+
throw new Error('❌ workflows.items not found');
|
|
51
|
+
}
|
|
52
|
+
console.log('✅ workflows.items is available');
|
|
53
|
+
|
|
54
|
+
console.log('✅ All services are properly available');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function testSDKMethods() {
|
|
58
|
+
console.log('🧪 Testing SDK method signatures...');
|
|
59
|
+
|
|
60
|
+
const api = new SDK('test-namespace');
|
|
61
|
+
|
|
62
|
+
// Test that all expected methods exist with correct signatures
|
|
63
|
+
const methodTests = [
|
|
64
|
+
// Login service
|
|
65
|
+
{ path: 'login.login', params: ['username', 'password'] },
|
|
66
|
+
{ path: 'login.logout', params: [] },
|
|
67
|
+
{ path: 'login.validate', params: [] },
|
|
68
|
+
|
|
69
|
+
// Objects service
|
|
70
|
+
{ path: 'objects.byId', params: ['id', 'query'] },
|
|
71
|
+
{ path: 'objects.query', params: ['object', 'query'] },
|
|
72
|
+
{ path: 'objects.create', params: ['object', 'body'] },
|
|
73
|
+
{ path: 'objects.updateById', params: ['object', 'id', 'update'] },
|
|
74
|
+
|
|
75
|
+
// Messaging service
|
|
76
|
+
{ path: 'messaging.sms.send', params: [{}] },
|
|
77
|
+
{ path: 'messaging.email.send', params: [{}] },
|
|
78
|
+
|
|
79
|
+
// Video service
|
|
80
|
+
{ path: 'video.createRoom', params: [{}] },
|
|
81
|
+
{ path: 'video.joinRoom', params: ['room', 'password', 'email'] },
|
|
82
|
+
|
|
83
|
+
// AI service
|
|
84
|
+
{ path: 'ai.generative.chat', params: [{}] },
|
|
85
|
+
{ path: 'ai.tts.create', params: [{}] },
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
for (const test of methodTests) {
|
|
89
|
+
const pathParts = test.path.split('.');
|
|
90
|
+
let obj = api;
|
|
91
|
+
|
|
92
|
+
for (const part of pathParts) {
|
|
93
|
+
if (!obj[part]) {
|
|
94
|
+
throw new Error(`❌ Method '${test.path}' not found`);
|
|
95
|
+
}
|
|
96
|
+
obj = obj[part];
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (typeof obj !== 'function') {
|
|
100
|
+
throw new Error(`❌ '${test.path}' is not a function`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
console.log(`✅ Method '${test.path}' exists and is a function`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function testSDKExtensibility() {
|
|
108
|
+
console.log('🧪 Testing SDK extensibility...');
|
|
109
|
+
|
|
110
|
+
const api = new SDK('test-namespace');
|
|
111
|
+
|
|
112
|
+
// Test plugin system
|
|
113
|
+
const testPlugin = {
|
|
114
|
+
install: (sdk) => {
|
|
115
|
+
sdk.testPluginFeature = () => 'plugin-working';
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
api.use(testPlugin);
|
|
120
|
+
|
|
121
|
+
if (!api.testPluginFeature) {
|
|
122
|
+
throw new Error('❌ Plugin system not working');
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (api.testPluginFeature() !== 'plugin-working') {
|
|
126
|
+
throw new Error('❌ Plugin not properly installed');
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
console.log('✅ Plugin system working correctly');
|
|
130
|
+
|
|
131
|
+
// Test extension system
|
|
132
|
+
class TestExtension {
|
|
133
|
+
constructor(sdk) {
|
|
134
|
+
this.testExtensionMethod = () => 'extension-working';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
api.extend(TestExtension);
|
|
139
|
+
|
|
140
|
+
if (!api.testExtensionMethod) {
|
|
141
|
+
throw new Error('❌ Extension system not working');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
if (api.testExtensionMethod() !== 'extension-working') {
|
|
145
|
+
throw new Error('❌ Extension not properly installed');
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
console.log('✅ Extension system working correctly');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function testClientServerCompatibility() {
|
|
152
|
+
console.log('🧪 Testing client/server environment compatibility...');
|
|
153
|
+
|
|
154
|
+
// Test server-side initialization
|
|
155
|
+
const serverApi = new SDK('test-namespace', 'call-123', 'jwt-token', 'request-456');
|
|
156
|
+
|
|
157
|
+
if (serverApi.environment !== 'node') {
|
|
158
|
+
console.log('⚠️ Expected Node.js environment, this might be running in browser');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Test client-side style initialization
|
|
162
|
+
const clientApi = new SDK('test-namespace', null, null, null, 'api.example.com');
|
|
163
|
+
|
|
164
|
+
console.log('✅ Both server and client initialization patterns work');
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
async function runAllTests() {
|
|
168
|
+
console.log('🚀 Starting backwards compatibility tests...\n');
|
|
169
|
+
|
|
170
|
+
try {
|
|
171
|
+
await testBasicSDKFunctionality();
|
|
172
|
+
console.log('');
|
|
173
|
+
|
|
174
|
+
testSDKMethods();
|
|
175
|
+
console.log('');
|
|
176
|
+
|
|
177
|
+
testSDKExtensibility();
|
|
178
|
+
console.log('');
|
|
179
|
+
|
|
180
|
+
testClientServerCompatibility();
|
|
181
|
+
console.log('');
|
|
182
|
+
|
|
183
|
+
console.log('🎉 All backwards compatibility tests passed!');
|
|
184
|
+
console.log('✅ The new modular SDK is fully backwards compatible');
|
|
185
|
+
|
|
186
|
+
} catch (error) {
|
|
187
|
+
console.error('💥 Test failed:', error.message);
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// Run tests if this file is executed directly
|
|
193
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
194
|
+
runAllTests();
|
|
195
|
+
}
|