@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.
@@ -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
+ }