@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,247 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
* Complete API Coverage Test
|
|
5
|
+
*
|
|
6
|
+
* This script tests that ALL API endpoints are covered in both
|
|
7
|
+
* the public SDK and internal SDK extensions.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import SDK from './index.js';
|
|
11
|
+
import InternalSDK from '../sdk-internal/index.js';
|
|
12
|
+
|
|
13
|
+
async function testPublicSDKCompleteness() {
|
|
14
|
+
console.log('๐งช Testing complete public SDK coverage...');
|
|
15
|
+
|
|
16
|
+
const api = new SDK('test-namespace');
|
|
17
|
+
|
|
18
|
+
// Test all expected public services
|
|
19
|
+
const publicServices = [
|
|
20
|
+
// Core services
|
|
21
|
+
'login', 'objects', 'messaging', 'video', 'voice', 'ai',
|
|
22
|
+
'lookup', 'layouts', 'subscriptions', 'workflows', 'notes',
|
|
23
|
+
'storage', 'verification', 'portals', 'sipEndpoints',
|
|
24
|
+
|
|
25
|
+
// Additional services found in analysis
|
|
26
|
+
'externalOAuth', 'googleCalendar', 'enroll', 'phoneNumbers',
|
|
27
|
+
'recordTypes', 'generateId'
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
console.log(`๐ Checking ${publicServices.length} public services...`);
|
|
31
|
+
|
|
32
|
+
for (const service of publicServices) {
|
|
33
|
+
if (!api[service]) {
|
|
34
|
+
throw new Error(`โ Public service '${service}' missing from SDK`);
|
|
35
|
+
}
|
|
36
|
+
console.log(`โ
${service}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Test nested services
|
|
40
|
+
const nestedServices = [
|
|
41
|
+
{ path: 'messaging.sms', description: 'SMS messaging' },
|
|
42
|
+
{ path: 'messaging.email', description: 'Email messaging' },
|
|
43
|
+
{ path: 'messaging.campaigns', description: 'Messaging campaigns' },
|
|
44
|
+
{ path: 'ai.generative', description: 'Generative AI' },
|
|
45
|
+
{ path: 'ai.tts', description: 'Text-to-speech' },
|
|
46
|
+
{ path: 'workflows.items', description: 'Workflow items' },
|
|
47
|
+
{ path: 'workflows.connections', description: 'Workflow connections' },
|
|
48
|
+
{ path: 'subscriptions.socket', description: 'Socket subscriptions' },
|
|
49
|
+
{ path: 'phoneNumbers.carrier', description: 'Phone number carrier ops' },
|
|
50
|
+
{ path: 'recordTypes.user', description: 'User record type defaults' },
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
console.log(`๐ Checking ${nestedServices.length} nested services...`);
|
|
54
|
+
|
|
55
|
+
for (const { path, description } of nestedServices) {
|
|
56
|
+
const pathParts = path.split('.');
|
|
57
|
+
let obj = api;
|
|
58
|
+
|
|
59
|
+
for (const part of pathParts) {
|
|
60
|
+
if (!obj[part]) {
|
|
61
|
+
throw new Error(`โ Nested service '${path}' (${description}) missing`);
|
|
62
|
+
}
|
|
63
|
+
obj = obj[part];
|
|
64
|
+
}
|
|
65
|
+
console.log(`โ
${path} - ${description}`);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.log('โ
All public services verified!');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function testInternalSDKCompleteness() {
|
|
72
|
+
console.log('๐งช Testing complete internal SDK coverage...');
|
|
73
|
+
|
|
74
|
+
const api = new SDK('test-namespace');
|
|
75
|
+
api.use(InternalSDK);
|
|
76
|
+
|
|
77
|
+
// Verify buildMasterAuth is available
|
|
78
|
+
if (typeof api.buildMasterAuth !== 'function') {
|
|
79
|
+
throw new Error('โ buildMasterAuth method not available on SDK');
|
|
80
|
+
}
|
|
81
|
+
console.log('โ
buildMasterAuth method available');
|
|
82
|
+
|
|
83
|
+
// Test all internal services
|
|
84
|
+
const internalServices = [
|
|
85
|
+
'sip', 'email', 'programmableVoice', 'servers', 'socket'
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
console.log(`๐ Checking ${internalServices.length} internal services...`);
|
|
89
|
+
|
|
90
|
+
for (const service of internalServices) {
|
|
91
|
+
if (!api.internal[service]) {
|
|
92
|
+
throw new Error(`โ Internal service '${service}' missing from SDK`);
|
|
93
|
+
}
|
|
94
|
+
console.log(`โ
internal.${service}`);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Test nested internal services
|
|
98
|
+
const nestedInternalServices = [
|
|
99
|
+
{ path: 'internal.programmableVoice.voiceChannel', description: 'Voice channel management' },
|
|
100
|
+
{ path: 'internal.programmableVoice.transcription', description: 'Transcription services' },
|
|
101
|
+
{ path: 'internal.servers.aws', description: 'AWS server management' },
|
|
102
|
+
];
|
|
103
|
+
|
|
104
|
+
console.log(`๐ Checking ${nestedInternalServices.length} nested internal services...`);
|
|
105
|
+
|
|
106
|
+
for (const { path, description } of nestedInternalServices) {
|
|
107
|
+
const pathParts = path.split('.');
|
|
108
|
+
let obj = api;
|
|
109
|
+
|
|
110
|
+
for (const part of pathParts) {
|
|
111
|
+
if (!obj[part]) {
|
|
112
|
+
throw new Error(`โ Nested internal service '${path}' (${description}) missing`);
|
|
113
|
+
}
|
|
114
|
+
obj = obj[part];
|
|
115
|
+
}
|
|
116
|
+
console.log(`โ
${path} - ${description}`);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
console.log('โ
All internal services verified!');
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function testMethodAvailability() {
|
|
123
|
+
console.log('๐งช Testing method availability across services...');
|
|
124
|
+
|
|
125
|
+
const api = new SDK('test-namespace');
|
|
126
|
+
api.use(InternalSDK);
|
|
127
|
+
|
|
128
|
+
// Sample of critical methods that should be available
|
|
129
|
+
const criticalMethods = [
|
|
130
|
+
// Public API methods
|
|
131
|
+
{ path: 'login.login', desc: 'User login' },
|
|
132
|
+
{ path: 'objects.query', desc: 'Object querying' },
|
|
133
|
+
{ path: 'messaging.sms.send', desc: 'SMS sending' },
|
|
134
|
+
{ path: 'messaging.email.send', desc: 'Email sending' },
|
|
135
|
+
{ path: 'video.createRoom', desc: 'Video room creation' },
|
|
136
|
+
{ path: 'voice.createCall', desc: 'Voice call creation' },
|
|
137
|
+
{ path: 'ai.generative.chat', desc: 'AI chat' },
|
|
138
|
+
{ path: 'phoneNumbers.search', desc: 'Phone number search' },
|
|
139
|
+
{ path: 'phoneNumbers.order', desc: 'Phone number ordering' },
|
|
140
|
+
{ path: 'recordTypes.create', desc: 'Record type creation' },
|
|
141
|
+
{ path: 'generateId.createId', desc: 'ID generation' },
|
|
142
|
+
|
|
143
|
+
// Internal API methods
|
|
144
|
+
{ path: 'internal.sip.router', desc: 'SIP routing' },
|
|
145
|
+
{ path: 'internal.email.incrementOpen', desc: 'Email tracking' },
|
|
146
|
+
{ path: 'internal.programmableVoice.setVariable', desc: 'Voice variables' },
|
|
147
|
+
{ path: 'internal.servers.create', desc: 'Server creation' },
|
|
148
|
+
{ path: 'internal.socket.createConnection', desc: 'Socket connections' },
|
|
149
|
+
];
|
|
150
|
+
|
|
151
|
+
console.log(`๐ Checking ${criticalMethods.length} critical methods...`);
|
|
152
|
+
|
|
153
|
+
for (const { path, desc } of criticalMethods) {
|
|
154
|
+
const pathParts = path.split('.');
|
|
155
|
+
let obj = api;
|
|
156
|
+
|
|
157
|
+
for (const part of pathParts) {
|
|
158
|
+
if (!obj[part]) {
|
|
159
|
+
throw new Error(`โ Method '${path}' (${desc}) not found`);
|
|
160
|
+
}
|
|
161
|
+
obj = obj[part];
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (typeof obj !== 'function') {
|
|
165
|
+
throw new Error(`โ '${path}' (${desc}) is not a function`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.log(`โ
${path} - ${desc}`);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
console.log('โ
All critical methods verified!');
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
async function testServiceCounts() {
|
|
175
|
+
console.log('๐งช Testing service counts...');
|
|
176
|
+
|
|
177
|
+
const api = new SDK('test-namespace');
|
|
178
|
+
api.use(InternalSDK);
|
|
179
|
+
|
|
180
|
+
// Count public services
|
|
181
|
+
const publicServiceCount = Object.keys(api).filter(key =>
|
|
182
|
+
typeof api[key] === 'object' &&
|
|
183
|
+
api[key] !== null &&
|
|
184
|
+
key !== 'internal' &&
|
|
185
|
+
!key.startsWith('_') &&
|
|
186
|
+
key !== 'namespace' &&
|
|
187
|
+
key !== 'baseURL' &&
|
|
188
|
+
key !== 'callId' &&
|
|
189
|
+
key !== 'token' &&
|
|
190
|
+
key !== 'fwRequestId' &&
|
|
191
|
+
key !== 'environment' &&
|
|
192
|
+
key !== 'transports'
|
|
193
|
+
).length;
|
|
194
|
+
|
|
195
|
+
// Count internal services
|
|
196
|
+
const internalServiceCount = Object.keys(api.internal || {}).length;
|
|
197
|
+
|
|
198
|
+
console.log(`๐ Public services: ${publicServiceCount}`);
|
|
199
|
+
console.log(`๐ Internal services: ${internalServiceCount}`);
|
|
200
|
+
|
|
201
|
+
// Expected counts based on our implementation
|
|
202
|
+
const expectedPublicServices = 21; // Updated count
|
|
203
|
+
const expectedInternalServices = 5;
|
|
204
|
+
|
|
205
|
+
if (publicServiceCount < expectedPublicServices) {
|
|
206
|
+
console.warn(`โ ๏ธ Expected at least ${expectedPublicServices} public services, found ${publicServiceCount}`);
|
|
207
|
+
} else {
|
|
208
|
+
console.log(`โ
Public service count: ${publicServiceCount} (expected: ${expectedPublicServices}+)`);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (internalServiceCount < expectedInternalServices) {
|
|
212
|
+
throw new Error(`โ Expected at least ${expectedInternalServices} internal services, found ${internalServiceCount}`);
|
|
213
|
+
} else {
|
|
214
|
+
console.log(`โ
Internal service count: ${internalServiceCount} (expected: ${expectedInternalServices})`);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function runAllTests() {
|
|
219
|
+
console.log('๐ Starting complete API coverage tests...\n');
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
await testPublicSDKCompleteness();
|
|
223
|
+
console.log('');
|
|
224
|
+
|
|
225
|
+
await testInternalSDKCompleteness();
|
|
226
|
+
console.log('');
|
|
227
|
+
|
|
228
|
+
await testMethodAvailability();
|
|
229
|
+
console.log('');
|
|
230
|
+
|
|
231
|
+
await testServiceCounts();
|
|
232
|
+
console.log('');
|
|
233
|
+
|
|
234
|
+
console.log('๐ ALL API COVERAGE TESTS PASSED!');
|
|
235
|
+
console.log('โ
The new modular SDK covers all public and internal API endpoints');
|
|
236
|
+
console.log('โ
Ready for production deployment');
|
|
237
|
+
|
|
238
|
+
} catch (error) {
|
|
239
|
+
console.error('๐ฅ Test failed:', error.message);
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Run tests if this file is executed directly
|
|
245
|
+
if (import.meta.url === `file://${process.argv[1]}`) {
|
|
246
|
+
runAllTests();
|
|
247
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/* eslint-disable indent */
|
|
2
|
+
/* eslint-disable prettier/prettier */
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Test both legacy positional and new object-based constructor patterns
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import SDK from './index.js';
|
|
9
|
+
|
|
10
|
+
console.log('Testing SDK Constructor Patterns...\n');
|
|
11
|
+
|
|
12
|
+
// Test 1: Legacy positional parameters (backwards compatibility)
|
|
13
|
+
console.log('โ
Testing legacy positional parameters:');
|
|
14
|
+
try {
|
|
15
|
+
const legacySDK = new SDK('test-namespace', 'call-123', 'jwt-token', 'request-456');
|
|
16
|
+
console.log(` - namespace: ${legacySDK.namespace}`);
|
|
17
|
+
console.log(` - callId: ${legacySDK.callId}`);
|
|
18
|
+
console.log(` - token: ${legacySDK.token}`);
|
|
19
|
+
console.log(` - fwRequestId: ${legacySDK.fwRequestId}`);
|
|
20
|
+
console.log(' โ
Legacy positional constructor works!\n');
|
|
21
|
+
} catch (error) {
|
|
22
|
+
console.error(' โ Legacy constructor failed:', error.message);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Test 2: New object-based parameters
|
|
26
|
+
console.log('โ
Testing new object-based parameters:');
|
|
27
|
+
try {
|
|
28
|
+
const modernSDK = new SDK({
|
|
29
|
+
namespace: 'test-namespace',
|
|
30
|
+
callId: 'call-123',
|
|
31
|
+
token: 'jwt-token',
|
|
32
|
+
fwRequestId: 'request-456',
|
|
33
|
+
url: 'api.example.com',
|
|
34
|
+
socketStore: null
|
|
35
|
+
});
|
|
36
|
+
console.log(` - namespace: ${modernSDK.namespace}`);
|
|
37
|
+
console.log(` - callId: ${modernSDK.callId}`);
|
|
38
|
+
console.log(` - token: ${modernSDK.token}`);
|
|
39
|
+
console.log(` - fwRequestId: ${modernSDK.fwRequestId}`);
|
|
40
|
+
console.log(' โ
Object-based constructor works!\n');
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error(' โ Object constructor failed:', error.message);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Test 3: Partial object parameters
|
|
46
|
+
console.log('โ
Testing partial object parameters:');
|
|
47
|
+
try {
|
|
48
|
+
const partialSDK = new SDK({
|
|
49
|
+
namespace: 'test-namespace',
|
|
50
|
+
token: 'jwt-token'
|
|
51
|
+
// callId and fwRequestId are optional
|
|
52
|
+
});
|
|
53
|
+
console.log(` - namespace: ${partialSDK.namespace}`);
|
|
54
|
+
console.log(` - callId: ${partialSDK.callId || 'undefined'}`);
|
|
55
|
+
console.log(` - token: ${partialSDK.token}`);
|
|
56
|
+
console.log(` - fwRequestId: ${partialSDK.fwRequestId || 'undefined'}`);
|
|
57
|
+
console.log(' โ
Partial object constructor works!\n');
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error(' โ Partial object constructor failed:', error.message);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Test 4: Empty constructor
|
|
63
|
+
console.log('โ
Testing empty constructor:');
|
|
64
|
+
try {
|
|
65
|
+
const emptySDK = new SDK();
|
|
66
|
+
console.log(` - namespace: ${emptySDK.namespace || 'undefined'}`);
|
|
67
|
+
console.log(` - callId: ${emptySDK.callId || 'undefined'}`);
|
|
68
|
+
console.log(` - token: ${emptySDK.token || 'undefined'}`);
|
|
69
|
+
console.log(` - fwRequestId: ${emptySDK.fwRequestId || 'undefined'}`);
|
|
70
|
+
console.log(' โ
Empty constructor works!\n');
|
|
71
|
+
} catch (error) {
|
|
72
|
+
console.error(' โ Empty constructor failed:', error.message);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Test 5: Factory function
|
|
76
|
+
console.log('โ
Testing factory function:');
|
|
77
|
+
try {
|
|
78
|
+
const { createSDK } = await import('./index.js');
|
|
79
|
+
const factorySDK = createSDK({
|
|
80
|
+
namespace: 'factory-test',
|
|
81
|
+
token: 'factory-token'
|
|
82
|
+
});
|
|
83
|
+
console.log(` - namespace: ${factorySDK.namespace}`);
|
|
84
|
+
console.log(` - token: ${factorySDK.token}`);
|
|
85
|
+
console.log(' โ
Factory function works!\n');
|
|
86
|
+
} catch (error) {
|
|
87
|
+
console.error(' โ Factory function failed:', error.message);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
console.log('๐ All constructor pattern tests completed!');
|
|
91
|
+
|
|
92
|
+
// Test that services are still available
|
|
93
|
+
console.log('\nโ
Verifying services are available:');
|
|
94
|
+
const testSDK = new SDK({ namespace: 'test' });
|
|
95
|
+
const services = [
|
|
96
|
+
'login', 'objects', 'messaging', 'video', 'voice', 'ai',
|
|
97
|
+
'lookup', 'layouts', 'subscriptions', 'workflows', 'notes',
|
|
98
|
+
'storage', 'verification', 'portals', 'sipEndpoints',
|
|
99
|
+
'externalOAuth', 'googleCalendar', 'enroll', 'phoneNumbers',
|
|
100
|
+
'recordTypes', 'generateId'
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
services.forEach(service => {
|
|
104
|
+
if (testSDK[service]) {
|
|
105
|
+
console.log(` โ
${service}`);
|
|
106
|
+
} else {
|
|
107
|
+
console.log(` โ ${service} - MISSING!`);
|
|
108
|
+
}
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log('\n๐ Constructor pattern upgrade complete!');
|