@unboundcx/sdk 2.7.6 → 2.8.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.
@@ -26,55 +26,45 @@ export class ObjectsService {
26
26
  * Retrieve an object by ID
27
27
  *
28
28
  * Preferred usage (new signature):
29
- * sdk.objects.byId({ id: 'someId', expandDetails: true })
29
+ * sdk.objects.byId({ id: 'someId', expandDetails: true, isAiPrompt: true })
30
30
  *
31
31
  * Legacy usage (deprecated, but supported):
32
32
  * sdk.objects.byId('someId', { 'select[]': ['field1', 'field2'] })
33
33
  *
34
34
  * @param {string|object} args - Either ID string or options object
35
+ * @param {boolean} [args.isAiPrompt] - Clean data for AI prompt usage (removes system fields)
35
36
  * @returns {Promise} Object data
36
37
  */
37
- async byId(...args) {
38
- // New signature: byId({ id, expandDetails })
39
- if (
40
- args.length === 1 &&
41
- typeof args[0] === 'object' &&
42
- !Array.isArray(args[0])
43
- ) {
44
- const { id, expandDetails = false } = args[0];
45
-
46
- this.sdk.validateParams(
47
- { id, expandDetails },
48
- {
49
- id: { type: 'string', required: true },
50
- expandDetails: { type: 'boolean', required: false },
51
- },
52
- );
53
-
54
- const query = {};
55
- if (expandDetails) query.expandDetails = expandDetails;
56
-
57
- const params = { query };
58
- return await this.sdk._fetch(`/object/${id}`, 'GET', params);
38
+ async byId(arg1, arg2) {
39
+ let id;
40
+ let query = {};
41
+ if (typeof arg1 === 'string') {
42
+ id = arg1;
43
+ if (typeof arg2 === 'object') {
44
+ query = { ...arg2 };
45
+ }
46
+ } else if (typeof arg1 === 'object') {
47
+ id = arg1.id;
48
+ query = { ...arg1 };
49
+ if (query.id) {
50
+ delete query.id;
51
+ }
59
52
  }
60
53
 
61
- // Old signature: byId(id, queryParams)
62
- if (args.length >= 1 && typeof args[0] === 'string') {
63
- const [id, queryParams = {}] = args;
64
-
65
- this.sdk.validateParams(
66
- { id },
67
- {
68
- id: { type: 'string', required: true },
69
- },
70
- );
71
-
72
- const query = { ...queryParams };
73
- const params = { query };
74
- return await this.sdk._fetch(`/object/${id}`, 'GET', params);
54
+ if (Array.isArray(query.select)) {
55
+ query.select = query.select.join(',');
75
56
  }
76
57
 
77
- throw new Error('Invalid arguments for byId method');
58
+ this.sdk.validateParams(
59
+ { id },
60
+ {
61
+ id: { type: 'string', required: true },
62
+ },
63
+ );
64
+
65
+ const params = { query };
66
+ const result = await this.sdk._fetch(`/object/${id}`, 'GET', params);
67
+ return result;
78
68
  }
79
69
 
80
70
  /**
@@ -4,6 +4,27 @@ export class RecordTypesService {
4
4
  this.user = new UserRecordTypeDefaultsService(sdk);
5
5
  }
6
6
 
7
+ /**
8
+ * Create a new recordType with permission rules
9
+ * @param {Object} recordType - RecordType configuration
10
+ * @param {string} recordType.name - RecordType name (required)
11
+ * @param {string} recordType.description - RecordType description (required)
12
+ * @param {Array|null} recordType.create - User IDs who can create (null = universal access)
13
+ * @param {Array|null} recordType.read - User IDs who can read (null = universal access)
14
+ * @param {Array|null} recordType.update - User IDs who can update (null = universal access)
15
+ * @param {Array|null} recordType.delete - User IDs who can delete (null = universal access)
16
+ * @returns {Promise<Object>} Created recordType information
17
+ * @example
18
+ * // Create a recordType with mixed permissions
19
+ * await sdk.recordTypes.create({
20
+ * name: 'Sales - Private',
21
+ * description: 'Sensitive sales data',
22
+ * create: ['user1', 'user2'], // Only specific users can create
23
+ * read: null, // Everyone can read
24
+ * update: ['admin1'], // Only admin can update
25
+ * delete: ['admin1'] // Only admin can delete
26
+ * });
27
+ */
7
28
  async create({
8
29
  name,
9
30
  description,
@@ -38,6 +59,35 @@ export class RecordTypesService {
38
59
  return result;
39
60
  }
40
61
 
62
+ /**
63
+ * Update an existing recordType using add/remove pattern for permissions
64
+ * @param {string} id - RecordType ID to update
65
+ * @param {Object} updates - Update configuration
66
+ * @param {string} updates.name - New name (optional)
67
+ * @param {string} updates.description - New description (optional)
68
+ * @param {Object} updates.add - Users to ADD to permissions
69
+ * @param {Array} updates.add.create - Add these users to create permission
70
+ * @param {Array} updates.add.read - Add these users to read permission
71
+ * @param {Array} updates.add.update - Add these users to update permission
72
+ * @param {Array} updates.add.delete - Add these users to delete permission
73
+ * @param {Object} updates.remove - Users to REMOVE from permissions
74
+ * @param {Array} updates.remove.create - Remove these users from create permission
75
+ * @param {Array} updates.remove.read - Remove these users from read permission
76
+ * @param {Array} updates.remove.update - Remove these users from update permission
77
+ * @param {Array} updates.remove.delete - Remove these users from delete permission
78
+ * @returns {Promise<Object>} Updated recordType information
79
+ * @example
80
+ * // Add new users to create permission, remove a user from update
81
+ * await sdk.recordTypes.update('recordTypeId', {
82
+ * add: {
83
+ * create: ['newUser1', 'newUser2'],
84
+ * delete: ['manager1']
85
+ * },
86
+ * remove: {
87
+ * update: ['oldUser1']
88
+ * }
89
+ * });
90
+ */
41
91
  async update(id, { name, description, remove, add }) {
42
92
  this.sdk.validateParams(
43
93
  { id },
@@ -64,6 +114,13 @@ export class RecordTypesService {
64
114
  return result;
65
115
  }
66
116
 
117
+ /**
118
+ * Delete a recordType
119
+ * @param {string} id - RecordType ID to delete
120
+ * @returns {Promise<Object>} Deletion confirmation
121
+ * @example
122
+ * await sdk.recordTypes.delete('recordTypeId');
123
+ */
67
124
  async delete(id) {
68
125
  this.sdk.validateParams(
69
126
  { id },
@@ -76,7 +133,25 @@ export class RecordTypesService {
76
133
  return result;
77
134
  }
78
135
 
79
- async get(id) {
136
+ /**
137
+ * Get detailed information about a specific recordType
138
+ * @param {string} id - RecordType ID
139
+ * @param {Object} options - Additional options
140
+ * @param {boolean} options.includeUsers - Include user default assignments (default: false)
141
+ * @returns {Promise<Object>} Detailed recordType with permissions and current user access
142
+ * @example
143
+ * // Get recordType with user assignments
144
+ * const recordType = await sdk.recordTypes.get('recordTypeId', {
145
+ * includeUsers: true
146
+ * });
147
+ *
148
+ * // Check current user's permissions
149
+ * console.log(recordType.currentUserAccess.canCreate); // true/false
150
+ * console.log(recordType.permissions.read.type); // 'universal' or 'restricted'
151
+ */
152
+ async get(id, options = {}) {
153
+ const { includeUsers } = options;
154
+
80
155
  this.sdk.validateParams(
81
156
  { id },
82
157
  {
@@ -84,12 +159,73 @@ export class RecordTypesService {
84
159
  },
85
160
  );
86
161
 
87
- const result = await this.sdk._fetch(`/recordTypes/${id}`, 'GET');
162
+ // Validate optional parameters
163
+ if ('includeUsers' in options) {
164
+ this.sdk.validateParams(
165
+ { includeUsers },
166
+ {
167
+ includeUsers: { type: 'boolean' },
168
+ },
169
+ );
170
+ }
171
+
172
+ const params = {
173
+ query: options,
174
+ };
175
+
176
+ const result = await this.sdk._fetch(`/recordTypes/${id}`, 'GET', params);
88
177
  return result;
89
178
  }
90
179
 
91
- async list() {
92
- const result = await this.sdk._fetch('/recordTypes/', 'GET');
180
+ /**
181
+ * List recordTypes with optional filtering and pagination
182
+ * @param {Object} options - Filter and pagination options
183
+ * @param {string} options.search - Search in name or description
184
+ * @param {boolean} options.isAccountDefault - Filter by account default status
185
+ * @param {number} options.page - Page number (default: 1)
186
+ * @param {number} options.limit - Items per page (default: 50, max: 100)
187
+ * @param {string} options.sortBy - Sort field: 'name', 'createdAt', 'updatedAt' (default: 'name')
188
+ * @param {string} options.sortOrder - Sort order: 'asc', 'desc' (default: 'asc')
189
+ * @returns {Promise<Object>} Object containing recordTypes, pagination, and summary
190
+ * @example
191
+ * // List with search and pagination
192
+ * const result = await sdk.recordTypes.list({
193
+ * search: 'sales',
194
+ * isAccountDefault: false,
195
+ * page: 1,
196
+ * limit: 25,
197
+ * sortBy: 'name',
198
+ * sortOrder: 'asc'
199
+ * });
200
+ *
201
+ * // Access results
202
+ * console.log(result.recordTypes); // Array of recordTypes
203
+ * console.log(result.pagination); // Pagination info
204
+ * console.log(result.summary); // Statistics
205
+ */
206
+ async list(options = {}) {
207
+ const { search, isAccountDefault, page, limit, sortBy, sortOrder } =
208
+ options;
209
+
210
+ // Validate optional parameters
211
+ const validationSchema = {};
212
+ if ('search' in options) validationSchema.search = { type: 'string' };
213
+ if ('isAccountDefault' in options)
214
+ validationSchema.isAccountDefault = { type: 'boolean' };
215
+ if ('page' in options) validationSchema.page = { type: 'number' };
216
+ if ('limit' in options) validationSchema.limit = { type: 'number' };
217
+ if ('sortBy' in options) validationSchema.sortBy = { type: 'string' };
218
+ if ('sortOrder' in options) validationSchema.sortOrder = { type: 'string' };
219
+
220
+ if (Object.keys(validationSchema).length > 0) {
221
+ this.sdk.validateParams(options, validationSchema);
222
+ }
223
+
224
+ const params = {
225
+ query: options,
226
+ };
227
+
228
+ const result = await this.sdk._fetch('/recordTypes/', 'GET', params);
93
229
  return result;
94
230
  }
95
231
  }
@@ -181,4 +317,91 @@ export class UserRecordTypeDefaultsService {
181
317
  const result = await this.sdk._fetch('/recordTypes/user/', 'GET', params);
182
318
  return result;
183
319
  }
320
+
321
+ /**
322
+ * Get all recordType defaults for a specific user
323
+ * Perfect for User Detail Page to show all user's recordType preferences
324
+ * @param {string} userId - User ID (optional - defaults to current user)
325
+ * @param {Object} options - Additional options
326
+ * @param {boolean} options.includeRecordTypeDetails - Include recordType name/description
327
+ * @returns {Promise<Object>} User's recordType defaults organized by object type
328
+ */
329
+ async getDefaults(userId, options = {}) {
330
+ const { includeRecordTypeDetails } = options;
331
+
332
+ // Validate optional parameters
333
+ if (userId) {
334
+ this.sdk.validateParams(
335
+ { userId },
336
+ {
337
+ userId: { type: 'string' },
338
+ },
339
+ );
340
+ }
341
+
342
+ if ('includeRecordTypeDetails' in options) {
343
+ this.sdk.validateParams(
344
+ { includeRecordTypeDetails },
345
+ {
346
+ includeRecordTypeDetails: { type: 'boolean' },
347
+ },
348
+ );
349
+ }
350
+
351
+ const params = {
352
+ query: options,
353
+ };
354
+
355
+ const url = userId
356
+ ? `/recordTypes/user/defaults/${userId}`
357
+ : '/recordTypes/user/defaults';
358
+
359
+ const result = await this.sdk._fetch(url, 'GET', params);
360
+ return result;
361
+ }
362
+
363
+ /**
364
+ * List users who have a specific recordType as their default
365
+ * Perfect for RecordType Detail Page to show who uses this recordType
366
+ * @param {string} recordTypeId - RecordType ID
367
+ * @param {Object} options - Filter and pagination options
368
+ * @param {string} options.object - Filter by specific object type
369
+ * @param {boolean} options.includeUserDetails - Include user name/email
370
+ * @param {number} options.page - Page number (default: 1)
371
+ * @param {number} options.limit - Items per page (default: 50, max: 100)
372
+ * @returns {Promise<Object>} Users organized by object type with statistics
373
+ */
374
+ async listUsersWithDefault(recordTypeId, options = {}) {
375
+ const { object, includeUserDetails, page, limit } = options;
376
+
377
+ this.sdk.validateParams(
378
+ { recordTypeId },
379
+ {
380
+ recordTypeId: { type: 'string', required: true },
381
+ },
382
+ );
383
+
384
+ // Validate optional parameters
385
+ const validationSchema = {};
386
+ if ('object' in options) validationSchema.object = { type: 'string' };
387
+ if ('includeUserDetails' in options)
388
+ validationSchema.includeUserDetails = { type: 'boolean' };
389
+ if ('page' in options) validationSchema.page = { type: 'number' };
390
+ if ('limit' in options) validationSchema.limit = { type: 'number' };
391
+
392
+ if (Object.keys(validationSchema).length > 0) {
393
+ this.sdk.validateParams(options, validationSchema);
394
+ }
395
+
396
+ const params = {
397
+ query: options,
398
+ };
399
+
400
+ const result = await this.sdk._fetch(
401
+ `/recordTypes/${recordTypeId}/users`,
402
+ 'GET',
403
+ params,
404
+ );
405
+ return result;
406
+ }
184
407
  }
@@ -3,24 +3,24 @@ export class SipEndpointsService {
3
3
  this.sdk = sdk;
4
4
  }
5
5
 
6
- async create({ username, password, domain, displayName, description }) {
6
+ async create({ recordTypeId, type, userId, name }) {
7
7
  this.sdk.validateParams(
8
- { username, password, domain },
8
+ { recordTypeId, type, userId, name },
9
9
  {
10
- username: { type: 'string', required: true },
11
- password: { type: 'string', required: true },
12
- domain: { type: 'string', required: true },
13
- displayName: { type: 'string', required: false },
14
- description: { type: 'string', required: false },
10
+ recordTypeId: { type: 'string', required: false },
11
+ type: { type: 'string', required: true },
12
+ userId: { type: 'string', required: false },
13
+ name: { type: 'string', required: false },
15
14
  },
16
15
  );
17
16
 
18
- const endpointData = { username, password, domain };
19
- if (displayName) endpointData.displayName = displayName;
20
- if (description) endpointData.description = description;
21
-
22
17
  const params = {
23
- body: endpointData,
18
+ body: {
19
+ recordTypeId,
20
+ type,
21
+ userId,
22
+ name,
23
+ },
24
24
  };
25
25
 
26
26
  const result = await this.sdk._fetch('/sipEndpoints', 'POST', params);
@@ -212,6 +212,7 @@ export class StorageService {
212
212
  fileName,
213
213
  formFields,
214
214
  endpoint = '/storage/upload',
215
+ method = 'POST',
215
216
  ) {
216
217
  const isNode = typeof window === 'undefined';
217
218
  let formData, headers;
@@ -231,7 +232,7 @@ export class StorageService {
231
232
  headers,
232
233
  };
233
234
 
234
- return await this.sdk._fetch(endpoint, 'POST', params, true);
235
+ return await this.sdk._fetch(endpoint, method, params, true);
235
236
  }
236
237
 
237
238
  async upload({
@@ -584,4 +585,228 @@ export class StorageService {
584
585
  );
585
586
  return result;
586
587
  }
588
+
589
+ /**
590
+ * List storage configurations with optional filtering
591
+ * @param {Object} options - Filter options
592
+ * @param {string} options.classification - Filter by classification
593
+ * @param {string} options.country - Filter by country
594
+ * @param {boolean} options.isSystem - Filter by system/custom configs
595
+ * @param {boolean} options.includeGlobal - Include global configurations (default: true)
596
+ * @returns {Promise<Object>} Object containing configurations and summary
597
+ */
598
+ async listStorageConfigurations(options = {}) {
599
+ const { classification, country, isSystem, includeGlobal } = options;
600
+
601
+ // Validate optional parameters
602
+ const validationSchema = {};
603
+ if ('classification' in options)
604
+ validationSchema.classification = { type: 'string' };
605
+ if ('country' in options) validationSchema.country = { type: 'string' };
606
+ if ('isSystem' in options) validationSchema.isSystem = { type: 'boolean' };
607
+ if ('includeGlobal' in options)
608
+ validationSchema.includeGlobal = { type: 'boolean' };
609
+
610
+ if (Object.keys(validationSchema).length > 0) {
611
+ this.sdk.validateParams(options, validationSchema);
612
+ }
613
+
614
+ const params = {
615
+ query: options,
616
+ };
617
+
618
+ const result = await this.sdk._fetch(
619
+ '/storage/configurations',
620
+ 'GET',
621
+ params,
622
+ );
623
+ return result;
624
+ }
625
+
626
+ /**
627
+ * Create a new custom storage configuration
628
+ * @param {Object} config - Configuration data
629
+ * @param {string} config.classification - Configuration classification
630
+ * @param {string} config.country - Country code
631
+ * @param {Array} config.s3Regions - S3 regions array
632
+ * @param {Array} config.gccRegions - Google Cloud regions array
633
+ * @param {Array} config.azureRegions - Azure regions array
634
+ * @param {number} config.minimumProviders - Minimum number of providers (default: 1)
635
+ * @param {number} config.minimumRegionsS3 - Minimum S3 regions (default: 1)
636
+ * @param {number} config.minimumRegionsGCC - Minimum GCC regions (default: 1)
637
+ * @param {number} config.minimumRegionsAzure - Minimum Azure regions (default: 1)
638
+ * @returns {Promise<Object>} Created configuration object
639
+ */
640
+ async createStorageConfiguration(config) {
641
+ const {
642
+ classification,
643
+ country,
644
+ s3Regions,
645
+ gccRegions,
646
+ azureRegions,
647
+ minimumProviders,
648
+ minimumRegionsS3,
649
+ minimumRegionsGCC,
650
+ minimumRegionsAzure,
651
+ } = config;
652
+
653
+ this.sdk.validateParams(config, {
654
+ classification: { type: 'string', required: true },
655
+ country: { type: 'string', required: true },
656
+ s3Regions: { type: 'object', required: false },
657
+ gccRegions: { type: 'object', required: false },
658
+ azureRegions: { type: 'object', required: false },
659
+ minimumProviders: { type: 'number', required: false },
660
+ minimumRegionsS3: { type: 'number', required: false },
661
+ minimumRegionsGCC: { type: 'number', required: false },
662
+ minimumRegionsAzure: { type: 'number', required: false },
663
+ });
664
+
665
+ const params = {
666
+ body: config,
667
+ };
668
+
669
+ const result = await this.sdk._fetch(
670
+ '/storage/configurations',
671
+ 'POST',
672
+ params,
673
+ );
674
+ return result;
675
+ }
676
+
677
+ /**
678
+ * Update an existing storage configuration
679
+ * System configurations have limited update capabilities (only regions and minimum levels)
680
+ * Custom configurations can update all fields
681
+ * @param {string} id - Configuration ID
682
+ * @param {Object} updates - Update data
683
+ * @returns {Promise<Object>} Updated configuration object
684
+ */
685
+ async updateStorageConfiguration(id, updates) {
686
+ this.sdk.validateParams(
687
+ { id, updates },
688
+ {
689
+ id: { type: 'string', required: true },
690
+ updates: { type: 'object', required: true },
691
+ },
692
+ );
693
+
694
+ const params = {
695
+ body: updates,
696
+ };
697
+
698
+ const result = await this.sdk._fetch(
699
+ `/storage/configurations/${id}`,
700
+ 'PUT',
701
+ params,
702
+ );
703
+ return result;
704
+ }
705
+
706
+ /**
707
+ * Delete a custom storage configuration
708
+ * System configurations cannot be deleted
709
+ * @param {string} id - Configuration ID
710
+ * @returns {Promise<Object>} Deletion confirmation
711
+ */
712
+ async deleteStorageConfiguration(id) {
713
+ this.sdk.validateParams(
714
+ { id },
715
+ {
716
+ id: { type: 'string', required: true },
717
+ },
718
+ );
719
+
720
+ const result = await this.sdk._fetch(
721
+ `/storage/configurations/${id}`,
722
+ 'DELETE',
723
+ );
724
+ return result;
725
+ }
726
+
727
+ /**
728
+ * Update file contents and metadata
729
+ * @param {string} storageId - Storage file ID (required)
730
+ * @param {Object} params - Update parameters
731
+ * @param {Object} [params.file] - New file content (Buffer, File, or binary data)
732
+ * @param {string} [params.fileName] - New file name
733
+ * @param {string} [params.classification] - New classification
734
+ * @param {string} [params.folder] - New folder path
735
+ * @param {boolean} [params.isPublic] - Public access setting
736
+ * @param {string} [params.country] - Country setting
737
+ * @param {string} [params.expireAfter] - Expiration setting
738
+ * @param {string} [params.relatedId] - Related record ID
739
+ * @returns {Promise<Object>} Updated file details
740
+ */
741
+ async updateFile(
742
+ storageId,
743
+ {
744
+ file,
745
+ fileName,
746
+ classification,
747
+ folder,
748
+ isPublic,
749
+ country,
750
+ expireAfter,
751
+ relatedId,
752
+ },
753
+ ) {
754
+ this.sdk.validateParams(
755
+ { storageId },
756
+ {
757
+ storageId: { type: 'string', required: true },
758
+ file: { type: 'object', required: false },
759
+ fileName: { type: 'string', required: false },
760
+ classification: { type: 'string', required: false },
761
+ folder: { type: 'string', required: false },
762
+ isPublic: { type: 'boolean', required: false },
763
+ country: { type: 'string', required: false },
764
+ expireAfter: { type: 'string', required: false },
765
+ relatedId: { type: 'string', required: false },
766
+ },
767
+ );
768
+
769
+ if (file) {
770
+ // If updating file content, use multipart form data
771
+ const formFields = [];
772
+ if (classification) formFields.push(['classification', classification]);
773
+ if (folder) formFields.push(['folder', folder]);
774
+ if (fileName) formFields.push(['fileName', fileName]);
775
+ if (isPublic !== undefined)
776
+ formFields.push(['isPublic', isPublic.toString()]);
777
+ if (country) formFields.push(['country', country]);
778
+ if (expireAfter) formFields.push(['expireAfter', expireAfter]);
779
+ if (relatedId) formFields.push(['relatedId', relatedId]);
780
+
781
+ return this._performUpload(
782
+ file,
783
+ fileName,
784
+ formFields,
785
+ `/storage/${storageId}`,
786
+ 'PUT',
787
+ );
788
+ } else {
789
+ // If only updating metadata, use JSON request
790
+ const updateData = {};
791
+ if (fileName !== undefined) updateData.fileName = fileName;
792
+ if (classification !== undefined)
793
+ updateData.classification = classification;
794
+ if (folder !== undefined) updateData.folder = folder;
795
+ if (isPublic !== undefined) updateData.isPublic = isPublic;
796
+ if (country !== undefined) updateData.country = country;
797
+ if (expireAfter !== undefined) updateData.expireAfter = expireAfter;
798
+ if (relatedId !== undefined) updateData.relatedId = relatedId;
799
+
800
+ const options = {
801
+ body: updateData,
802
+ };
803
+
804
+ const result = await this.sdk._fetch(
805
+ `/storage/${storageId}`,
806
+ 'PUT',
807
+ options,
808
+ );
809
+ return result;
810
+ }
811
+ }
587
812
  }