@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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Unbound (Cameron J. Weeks)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,456 @@
1
+ # Unbound JavaScript SDK
2
+
3
+ [![npm version](https://badge.fury.io/js/%40unbound%2Fsdk.svg)](https://badge.fury.io/js/%40unbound%2Fsdk)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ The official JavaScript SDK for Unbound's comprehensive communication and AI platform. This SDK provides easy access to messaging (SMS/Email), voice calling, video conferencing, AI services, workflows, and data management capabilities.
7
+
8
+ ## Features
9
+
10
+ - 🚀 **Universal**: Works in Node.js and browsers
11
+ - 📱 **Messaging**: SMS/MMS and Email with templates and campaigns
12
+ - 📞 **Voice**: Call management, conferencing, recording, transcription
13
+ - 📹 **Video**: Video conferencing with advanced controls
14
+ - 🤖 **AI**: Generative AI chat and text-to-speech
15
+ - 💾 **Data**: Object management with queries and relationships
16
+ - 🔄 **Workflows**: Programmable workflow execution
17
+ - 🔌 **Extensible**: Plugin system for transports and extensions
18
+ - ⚡ **Performance**: Automatic transport optimization (NATS/Socket/HTTP)
19
+
20
+ ## Installation
21
+
22
+ ```bash
23
+ npm install @unbound/sdk
24
+ ```
25
+
26
+ ### Optional Dependencies
27
+
28
+ For enhanced functionality, you may also install:
29
+
30
+ ```bash
31
+ # For Socket.io transport (browser environments)
32
+ npm install socket.io-client
33
+
34
+ # For improved MIME type detection
35
+ npm install mime-types
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ### Basic Usage
41
+
42
+ ```javascript
43
+ import SDK from '@unbound/sdk';
44
+
45
+ // Initialize the SDK
46
+ const api = new SDK({
47
+ namespace: 'your-namespace',
48
+ token: 'your-jwt-token'
49
+ });
50
+
51
+ // Or using legacy positional parameters (backwards compatible)
52
+ const api = new SDK('your-namespace', null, 'your-jwt-token');
53
+
54
+ // Login (gets JWT token)
55
+ const login = await api.login.login('username', 'password');
56
+
57
+ // Send SMS
58
+ const sms = await api.messaging.sms.send({
59
+ from: '+1234567890',
60
+ to: '+0987654321',
61
+ message: 'Hello from Unbound!'
62
+ });
63
+
64
+ // Create video meeting
65
+ const meeting = await api.video.createRoom({
66
+ name: 'Team Meeting',
67
+ startTime: '2024-01-15T10:00:00Z',
68
+ duration: 60
69
+ });
70
+ ```
71
+
72
+ ### Client-Side Usage (Browser/Svelte)
73
+
74
+ ```javascript
75
+ import SDK from '@unbound/sdk';
76
+ import { socketAppStore } from './stores/socket.js';
77
+
78
+ // Initialize with socket transport for optimal performance
79
+ const api = new SDK('your-namespace', null, null, null, 'api.yourdomain.com', socketAppStore);
80
+
81
+ // The SDK will automatically use WebSocket when available, HTTP as fallback
82
+ const objects = await api.objects.query('contacts', {
83
+ limit: 10,
84
+ orderBy: 'createdAt'
85
+ });
86
+ ```
87
+
88
+ ### Server-Side Usage (Node.js)
89
+
90
+ ```javascript
91
+ import SDK from '@unbound/sdk';
92
+
93
+ // Initialize for server-side usage
94
+ const api = new SDK('your-namespace', 'call-id', 'jwt-token', 'request-id');
95
+
96
+ // Server-side exclusive: Master authentication
97
+ await api.buildMasterAuth({
98
+ namespace: 'target-namespace',
99
+ accountId: 'account-123',
100
+ userId: 'user-456'
101
+ });
102
+
103
+ // Use NATS transport automatically when available
104
+ const result = await api.objects.create('leads', {
105
+ name: 'John Doe',
106
+ email: 'john@example.com',
107
+ phone: '+1234567890'
108
+ });
109
+ ```
110
+
111
+ ## Constructor Options
112
+
113
+ The SDK constructor supports both object-based and legacy positional parameters:
114
+
115
+ ### Object-Based Constructor (Recommended)
116
+
117
+ ```javascript
118
+ const api = new SDK({
119
+ namespace: 'your-namespace', // Required: API namespace
120
+ token: 'jwt-token', // Optional: JWT authentication token
121
+ callId: 'call-123', // Optional: Call tracking ID
122
+ fwRequestId: 'request-456', // Optional: Request forwarding ID
123
+ url: 'api.example.com', // Optional: Custom API URL (browser only)
124
+ socketStore: socketAppStore // Optional: Socket.io store (Svelte/browser)
125
+ });
126
+ ```
127
+
128
+ ### Legacy Positional Constructor (Backwards Compatible)
129
+
130
+ ```javascript
131
+ const api = new SDK(
132
+ 'your-namespace', // namespace
133
+ 'call-123', // callId
134
+ 'jwt-token', // token
135
+ 'request-456', // fwRequestId
136
+ 'api.example.com', // url (browser only)
137
+ socketAppStore // socketStore (browser only)
138
+ );
139
+ ```
140
+
141
+ ### Factory Function
142
+
143
+ ```javascript
144
+ import { createSDK } from '@unbound/sdk';
145
+
146
+ const api = createSDK({
147
+ namespace: 'your-namespace',
148
+ token: 'jwt-token'
149
+ });
150
+ ```
151
+
152
+ ## API Reference
153
+
154
+ ### Core Services
155
+
156
+ #### Authentication (`api.login`)
157
+ ```javascript
158
+ // Login and get session
159
+ await api.login.login('username', 'password');
160
+ await api.login.logout();
161
+ await api.login.validate();
162
+ await api.login.changePassword('current', 'new');
163
+ ```
164
+
165
+ #### Objects (`api.objects`)
166
+ ```javascript
167
+ // CRUD operations on data objects
168
+ await api.objects.create('contacts', { name: 'John', email: 'john@example.com' });
169
+ await api.objects.query('contacts', { limit: 10 });
170
+ await api.objects.byId('contact-123');
171
+ await api.objects.updateById('contacts', 'contact-123', { name: 'Jane' });
172
+ await api.objects.deleteById('contacts', 'contact-123');
173
+ await api.objects.describe('contacts'); // Get schema
174
+ await api.objects.list(); // List all object types
175
+ ```
176
+
177
+ #### Messaging (`api.messaging`)
178
+ ```javascript
179
+ // SMS/MMS
180
+ await api.messaging.sms.send({
181
+ from: '+1234567890',
182
+ to: '+0987654321',
183
+ message: 'Hello!',
184
+ mediaUrls: ['https://example.com/image.jpg']
185
+ });
186
+
187
+ // Email
188
+ await api.messaging.email.send({
189
+ from: 'sender@example.com',
190
+ to: 'recipient@example.com',
191
+ subject: 'Hello',
192
+ htmlBody: '<h1>Hello World!</h1>'
193
+ });
194
+
195
+ // Templates
196
+ await api.messaging.sms.templates.create({
197
+ name: 'welcome',
198
+ message: 'Welcome {{name}}!',
199
+ variables: { name: 'string' }
200
+ });
201
+
202
+ // Campaign Management
203
+ await api.messaging.campaigns.tollFree.create({
204
+ companyName: 'Acme Corp',
205
+ phoneNumber: '+1234567890',
206
+ description: 'Marketing campaign'
207
+ });
208
+ ```
209
+
210
+ #### Video Conferencing (`api.video`)
211
+ ```javascript
212
+ // Room Management
213
+ const room = await api.video.createRoom({
214
+ name: 'Team Meeting',
215
+ password: 'secret123',
216
+ startTime: '2024-01-15T10:00:00Z',
217
+ waitingRoom: true,
218
+ hosts: ['user@example.com']
219
+ });
220
+
221
+ // Join meeting
222
+ await api.video.joinRoom(room.id, 'password', 'user@example.com');
223
+
224
+ // Participant controls
225
+ await api.video.mute(room.id, 'participant-id', 'microphone', true);
226
+ await api.video.removeParticipant(room.id, 'participant-id');
227
+
228
+ // Analytics
229
+ const analytics = await api.video.getMeetingAnalytics(room.id, {
230
+ startTime: '2024-01-15T10:00:00Z',
231
+ endTime: '2024-01-15T11:00:00Z'
232
+ });
233
+ ```
234
+
235
+ #### Voice Calling (`api.voice`)
236
+ ```javascript
237
+ // Make calls
238
+ const call = await api.voice.createCall({
239
+ to: '+1234567890',
240
+ from: '+0987654321',
241
+ record: true,
242
+ transcribe: true
243
+ });
244
+
245
+ // Call controls
246
+ await api.voice.mute(call.callControlId);
247
+ await api.voice.hold(call.callControlId);
248
+ await api.voice.sendDtmf(call.callControlId, '1234');
249
+ await api.voice.transfer(call.callControlId, '+1555555555');
250
+ await api.voice.hangup(call.callControlId);
251
+
252
+ // Conference calls
253
+ const conference = await api.voice.createConference({ name: 'Team Call' });
254
+ await api.voice.joinConference(call.callControlId, conference.id);
255
+ ```
256
+
257
+ #### AI Services (`api.ai`)
258
+ ```javascript
259
+ // Generative AI
260
+ const response = await api.ai.generative.chat({
261
+ messages: [{ role: 'user', content: 'Hello AI!' }],
262
+ model: 'gpt-4',
263
+ temperature: 0.7,
264
+ method: 'openai'
265
+ });
266
+
267
+ // Text-to-Speech
268
+ const audio = await api.ai.tts.create({
269
+ text: 'Hello, this is a test message',
270
+ voice: 'en-US-Standard-A',
271
+ audioEncoding: 'MP3'
272
+ });
273
+ ```
274
+
275
+ ### Utility Services
276
+
277
+ #### File Storage (`api.storage`)
278
+ ```javascript
279
+ // Upload files
280
+ const files = await api.storage.uploadFiles(fileData, {
281
+ classification: 'documents',
282
+ isPublic: false,
283
+ expireAfter: '30d'
284
+ });
285
+
286
+ // Get files
287
+ const fileUrl = api.storage.getFileUrl(files[0].storageId);
288
+ await api.storage.deleteFile(files[0].storageId);
289
+ ```
290
+
291
+ #### Workflows (`api.workflows`)
292
+ ```javascript
293
+ // Workflow items
294
+ await api.workflows.items.create({
295
+ workflowVersionId: 'wf-123',
296
+ category: 'communication',
297
+ type: 'sendEmail',
298
+ settings: { template: 'welcome' }
299
+ });
300
+
301
+ // Connections
302
+ await api.workflows.connections.create({
303
+ workflowItemId: 'item-1',
304
+ workflowItemPortId: 'output',
305
+ inWorkflowItemId: 'item-2',
306
+ inWorkflowItemPortId: 'input'
307
+ });
308
+ ```
309
+
310
+ ## Transport Plugins
311
+
312
+ The SDK automatically optimizes transport based on environment:
313
+
314
+ - **Node.js**: NATS → HTTP fallback
315
+ - **Browser**: WebSocket → HTTP fallback
316
+ - **Always available**: HTTP fetch
317
+
318
+ ### Custom Transports
319
+
320
+ ```javascript
321
+ import SDK from '@unbound/sdk';
322
+
323
+ class CustomTransport {
324
+ constructor(config) {
325
+ this.config = config;
326
+ this.name = 'custom';
327
+ }
328
+
329
+ getPriority() { return 10; } // Lower = higher priority
330
+
331
+ async isAvailable() {
332
+ return true; // Check if transport is ready
333
+ }
334
+
335
+ async request(endpoint, method, params, options) {
336
+ // Custom transport logic
337
+ return response;
338
+ }
339
+ }
340
+
341
+ const api = new SDK('namespace', null, 'token');
342
+ api.addTransport(new CustomTransport({}));
343
+ ```
344
+
345
+ ## Extensions
346
+
347
+ ### Internal SDK (Server-side only)
348
+
349
+ ```javascript
350
+ import SDK from '@unbound/sdk';
351
+
352
+ const api = new SDK('namespace');
353
+
354
+ // Now has access to internal APIs
355
+ await api.buildMasterAuth({ accountId: '123', userId: '456' });
356
+ await api.internal.sip.router('+1234567890', '+0987654321');
357
+ ```
358
+
359
+ ## Environment Support
360
+
361
+ ### Node.js
362
+ ```javascript
363
+ import SDK from '@unbound/sdk';
364
+
365
+ // Automatic environment detection
366
+ const api = new SDK(process.env.UNBOUND_NAMESPACE);
367
+ ```
368
+
369
+ ### Browser/Webpack
370
+ ```javascript
371
+ import SDK from '@unbound/sdk';
372
+
373
+ const api = new SDK('namespace', null, null, null, 'api.yourdomain.com');
374
+ ```
375
+
376
+ ### Svelte
377
+ ```javascript
378
+ import SDK from '@unbound/sdk';
379
+ import { socketAppStore } from '$lib/stores/socket.js';
380
+
381
+ const api = new SDK('namespace', null, null, null, 'api.yourdomain.com', socketAppStore);
382
+ ```
383
+
384
+ ## Error Handling
385
+
386
+ ```javascript
387
+ try {
388
+ await api.messaging.sms.send({ to: 'invalid' });
389
+ } catch (error) {
390
+ console.log(error.name); // 'API :: Error :: https :: POST :: /messaging/sms :: ...'
391
+ console.log(error.message); // 'Invalid phone number format'
392
+ console.log(error.status); // 400
393
+ console.log(error.method); // 'POST'
394
+ console.log(error.endpoint); // '/messaging/sms'
395
+ }
396
+ ```
397
+
398
+ ## TypeScript Support
399
+
400
+ The SDK includes TypeScript definitions:
401
+
402
+ ```typescript
403
+ import SDK, { MessagingService, VideoService } from '@unbound/sdk';
404
+
405
+ const api: SDK = new SDK('namespace', null, 'token');
406
+
407
+ // Full type safety
408
+ const sms: any = await api.messaging.sms.send({
409
+ from: '+1234567890',
410
+ to: '+0987654321',
411
+ message: 'Hello TypeScript!'
412
+ });
413
+ ```
414
+
415
+ ## Development
416
+
417
+ ### Setup
418
+ ```bash
419
+ git clone https://github.com/unbound/sdk-js.git
420
+ cd sdk-js
421
+ npm install
422
+ ```
423
+
424
+ ### Testing
425
+ ```bash
426
+ npm test # Run all tests
427
+ npm run test:unit # Unit tests only
428
+ npm run test:integration # Integration tests
429
+ npm run test:watch # Watch mode
430
+ ```
431
+
432
+ ### Building
433
+ ```bash
434
+ npm run build # Build for production
435
+ npm run lint # Check code style
436
+ npm run docs # Generate documentation
437
+ ```
438
+
439
+ ## Contributing
440
+
441
+ 1. Fork the repository
442
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
443
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
444
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
445
+ 5. Open a Pull Request
446
+
447
+ ## License
448
+
449
+ This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
450
+
451
+ ## Support
452
+
453
+ - 📚 [Documentation](https://docs.unbound.cx/sdk)
454
+ - 🐛 [Issue Tracker](https://github.com/unbound/sdk-js/issues)
455
+ - 💬 [Community Forum](https://community.unbound.cx)
456
+ - 📧 [Email Support](mailto:support@unbound.cx)