@unboundcx/sdk 4.1.2 → 4.2.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/README.md +66 -0
- package/index.js +3 -0
- package/package.json +18 -5
- package/schemas/layouts/SCHEMA.md +5100 -0
- package/schemas/layouts/action.js +17 -0
- package/schemas/layouts/compact.js +11 -0
- package/schemas/layouts/field.js +103 -0
- package/schemas/layouts/format.js +23 -0
- package/schemas/layouts/index.js +16 -0
- package/schemas/layouts/join.js +33 -0
- package/schemas/layouts/kanban.js +94 -0
- package/schemas/layouts/layoutDoc.js +35 -0
- package/schemas/layouts/migrations/deriveActions.js +70 -0
- package/schemas/layouts/migrations/deriveCompactFields.js +19 -0
- package/schemas/layouts/migrations/index.js +43 -0
- package/schemas/layouts/migrations/migrateV1toV2.js +162 -0
- package/schemas/layouts/migrations/normalizeJoin.js +44 -0
- package/schemas/layouts/migrations/normalizeKanban.js +54 -0
- package/schemas/layouts/migrations/promoteRelatedLists.js +67 -0
- package/schemas/layouts/primitives.js +44 -0
- package/schemas/layouts/relatedList.js +48 -0
- package/schemas/layouts/section.js +104 -0
- package/schemas/layouts/selectDynamic.js +40 -0
- package/schemas/layouts/validate.js +18 -0
- package/services/layouts.js +142 -1
- package/services/liveQuery.js +26 -5
- package/services/objects.js +2 -0
- package/services/permissions.js +377 -0
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
export class PermissionsService {
|
|
2
|
+
constructor(sdk) {
|
|
3
|
+
this.sdk = sdk;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* List permission groups
|
|
8
|
+
* @returns {Promise<Object>} Object with results: Array of permission groups
|
|
9
|
+
* @example
|
|
10
|
+
* const { results } = await sdk.permissions.listGroups();
|
|
11
|
+
*/
|
|
12
|
+
async listGroups() {
|
|
13
|
+
const result = await this.sdk._fetch('/permissions/groups', 'GET');
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Create a new permission group
|
|
19
|
+
* @param {Object} group - Group configuration
|
|
20
|
+
* @param {string} group.name - Group name (required)
|
|
21
|
+
* @param {string} group.description - Group description
|
|
22
|
+
* @returns {Promise<Object>} Created group
|
|
23
|
+
* @example
|
|
24
|
+
* await sdk.permissions.createGroup({
|
|
25
|
+
* name: 'Support Leads',
|
|
26
|
+
* description: 'Escalation-tier support agents',
|
|
27
|
+
* });
|
|
28
|
+
*/
|
|
29
|
+
async createGroup({ name, description }) {
|
|
30
|
+
this.sdk.validateParams(
|
|
31
|
+
{ name, description },
|
|
32
|
+
{
|
|
33
|
+
name: { type: 'string', required: true },
|
|
34
|
+
description: { type: 'string', required: false },
|
|
35
|
+
},
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
const groupData = { name };
|
|
39
|
+
if (description !== undefined) groupData.description = description;
|
|
40
|
+
|
|
41
|
+
const params = {
|
|
42
|
+
body: groupData,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const result = await this.sdk._fetch('/permissions/groups', 'POST', params);
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Update an existing permission group
|
|
51
|
+
* @param {string} groupId - Group ID to update
|
|
52
|
+
* @param {Object} data - Fields to update (e.g. name, description)
|
|
53
|
+
* @returns {Promise<Object>} Updated group
|
|
54
|
+
* @example
|
|
55
|
+
* await sdk.permissions.updateGroup('group-123', { description: 'Updated' });
|
|
56
|
+
*/
|
|
57
|
+
async updateGroup(groupId, data) {
|
|
58
|
+
groupId = String(groupId);
|
|
59
|
+
this.sdk.validateParams(
|
|
60
|
+
{ groupId },
|
|
61
|
+
{
|
|
62
|
+
groupId: { type: 'string', required: true },
|
|
63
|
+
},
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const params = {
|
|
67
|
+
body: data,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
const result = await this.sdk._fetch(
|
|
71
|
+
`/permissions/groups/${groupId}`,
|
|
72
|
+
'PUT',
|
|
73
|
+
params,
|
|
74
|
+
);
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Delete a permission group
|
|
80
|
+
* @param {string} groupId - Group ID to delete
|
|
81
|
+
* @returns {Promise<Object>} Deletion confirmation
|
|
82
|
+
* @example
|
|
83
|
+
* await sdk.permissions.deleteGroup('group-123');
|
|
84
|
+
*/
|
|
85
|
+
async deleteGroup(groupId) {
|
|
86
|
+
groupId = String(groupId);
|
|
87
|
+
this.sdk.validateParams(
|
|
88
|
+
{ groupId },
|
|
89
|
+
{
|
|
90
|
+
groupId: { type: 'string', required: true },
|
|
91
|
+
},
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const result = await this.sdk._fetch(
|
|
95
|
+
`/permissions/groups/${groupId}`,
|
|
96
|
+
'DELETE',
|
|
97
|
+
);
|
|
98
|
+
return result;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Add a user to a permission group
|
|
103
|
+
* @param {string} groupId - Group ID
|
|
104
|
+
* @param {string} userId - User ID to add
|
|
105
|
+
* @returns {Promise<Object>} Membership confirmation
|
|
106
|
+
* @example
|
|
107
|
+
* await sdk.permissions.addGroupMember('group-123', 'user-456');
|
|
108
|
+
*/
|
|
109
|
+
async addGroupMember(groupId, userId) {
|
|
110
|
+
groupId = String(groupId);
|
|
111
|
+
userId = String(userId);
|
|
112
|
+
this.sdk.validateParams(
|
|
113
|
+
{ groupId, userId },
|
|
114
|
+
{
|
|
115
|
+
groupId: { type: 'string', required: true },
|
|
116
|
+
userId: { type: 'string', required: true },
|
|
117
|
+
},
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
const params = {
|
|
121
|
+
body: { userId },
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
const result = await this.sdk._fetch(
|
|
125
|
+
`/permissions/groups/${groupId}/members`,
|
|
126
|
+
'POST',
|
|
127
|
+
params,
|
|
128
|
+
);
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Remove a user from a permission group
|
|
134
|
+
* @param {string} groupId - Group ID
|
|
135
|
+
* @param {string} userId - User ID to remove
|
|
136
|
+
* @returns {Promise<Object>} Removal confirmation
|
|
137
|
+
* @example
|
|
138
|
+
* await sdk.permissions.removeGroupMember('group-123', 'user-456');
|
|
139
|
+
*/
|
|
140
|
+
async removeGroupMember(groupId, userId) {
|
|
141
|
+
groupId = String(groupId);
|
|
142
|
+
userId = String(userId);
|
|
143
|
+
this.sdk.validateParams(
|
|
144
|
+
{ groupId, userId },
|
|
145
|
+
{
|
|
146
|
+
groupId: { type: 'string', required: true },
|
|
147
|
+
userId: { type: 'string', required: true },
|
|
148
|
+
},
|
|
149
|
+
);
|
|
150
|
+
|
|
151
|
+
const result = await this.sdk._fetch(
|
|
152
|
+
`/permissions/groups/${groupId}/members/${userId}`,
|
|
153
|
+
'DELETE',
|
|
154
|
+
);
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* List permission sets (system defaults are returned first)
|
|
160
|
+
* @returns {Promise<Object>} Object with results: Array of permission sets
|
|
161
|
+
* @example
|
|
162
|
+
* const { results } = await sdk.permissions.listPermissionSets();
|
|
163
|
+
*/
|
|
164
|
+
async listPermissionSets() {
|
|
165
|
+
const result = await this.sdk._fetch('/permissions/sets', 'GET');
|
|
166
|
+
return result;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Create a new permission set
|
|
171
|
+
* @param {Object} set - Permission set configuration
|
|
172
|
+
* @param {string} set.name - Permission set name (required)
|
|
173
|
+
* @param {Array<string>} set.scopes - Scopes granted by this set (required)
|
|
174
|
+
* @returns {Promise<Object>} Created permission set
|
|
175
|
+
* @example
|
|
176
|
+
* await sdk.permissions.createPermissionSet({
|
|
177
|
+
* name: 'Voice Admin',
|
|
178
|
+
* scopes: ['voice:calls:read', 'voice:calls:write'],
|
|
179
|
+
* });
|
|
180
|
+
*/
|
|
181
|
+
async createPermissionSet({ name, scopes }) {
|
|
182
|
+
this.sdk.validateParams(
|
|
183
|
+
{ name, scopes },
|
|
184
|
+
{
|
|
185
|
+
name: { type: 'string', required: true },
|
|
186
|
+
scopes: { type: 'array', required: true },
|
|
187
|
+
},
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
const params = {
|
|
191
|
+
body: { name, scopes },
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const result = await this.sdk._fetch('/permissions/sets', 'POST', params);
|
|
195
|
+
return result;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Update an existing permission set
|
|
200
|
+
* @param {string} setId - Permission set ID to update
|
|
201
|
+
* @param {Object} data - Fields to update (e.g. name, scopes)
|
|
202
|
+
* @returns {Promise<Object>} Updated permission set
|
|
203
|
+
* @example
|
|
204
|
+
* await sdk.permissions.updatePermissionSet('set-123', { scopes: ['voice:calls:read'] });
|
|
205
|
+
*/
|
|
206
|
+
async updatePermissionSet(setId, data) {
|
|
207
|
+
setId = String(setId);
|
|
208
|
+
this.sdk.validateParams(
|
|
209
|
+
{ setId },
|
|
210
|
+
{
|
|
211
|
+
setId: { type: 'string', required: true },
|
|
212
|
+
},
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
const params = {
|
|
216
|
+
body: data,
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
const result = await this.sdk._fetch(
|
|
220
|
+
`/permissions/sets/${setId}`,
|
|
221
|
+
'PUT',
|
|
222
|
+
params,
|
|
223
|
+
);
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* Delete a permission set
|
|
229
|
+
* @param {string} setId - Permission set ID to delete
|
|
230
|
+
* @returns {Promise<Object>} Deletion confirmation
|
|
231
|
+
* @example
|
|
232
|
+
* await sdk.permissions.deletePermissionSet('set-123');
|
|
233
|
+
*/
|
|
234
|
+
async deletePermissionSet(setId) {
|
|
235
|
+
setId = String(setId);
|
|
236
|
+
this.sdk.validateParams(
|
|
237
|
+
{ setId },
|
|
238
|
+
{
|
|
239
|
+
setId: { type: 'string', required: true },
|
|
240
|
+
},
|
|
241
|
+
);
|
|
242
|
+
|
|
243
|
+
const result = await this.sdk._fetch(
|
|
244
|
+
`/permissions/sets/${setId}`,
|
|
245
|
+
'DELETE',
|
|
246
|
+
);
|
|
247
|
+
return result;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Assign a permission set to a principal (user or group)
|
|
252
|
+
* @param {Object} assignment - Assignment configuration
|
|
253
|
+
* @param {string} assignment.permissionSetId - Permission set ID (required)
|
|
254
|
+
* @param {string} assignment.principalType - Principal type, e.g. 'user' or 'group' (required)
|
|
255
|
+
* @param {string} assignment.principalId - Principal ID (required)
|
|
256
|
+
* @param {string} assignment.grantType - Grant type, e.g. 'allow' or 'deny' (required)
|
|
257
|
+
* @returns {Promise<Object>} Created assignment
|
|
258
|
+
* @example
|
|
259
|
+
* await sdk.permissions.assignPermissionSet({
|
|
260
|
+
* permissionSetId: 'set-123',
|
|
261
|
+
* principalType: 'user',
|
|
262
|
+
* principalId: 'user-456',
|
|
263
|
+
* grantType: 'allow',
|
|
264
|
+
* });
|
|
265
|
+
*/
|
|
266
|
+
async assignPermissionSet({
|
|
267
|
+
permissionSetId,
|
|
268
|
+
principalType,
|
|
269
|
+
principalId,
|
|
270
|
+
grantType,
|
|
271
|
+
}) {
|
|
272
|
+
permissionSetId = String(permissionSetId);
|
|
273
|
+
principalId = String(principalId);
|
|
274
|
+
this.sdk.validateParams(
|
|
275
|
+
{ permissionSetId, principalType, principalId, grantType },
|
|
276
|
+
{
|
|
277
|
+
permissionSetId: { type: 'string', required: true },
|
|
278
|
+
principalType: { type: 'string', required: true },
|
|
279
|
+
principalId: { type: 'string', required: true },
|
|
280
|
+
grantType: { type: 'string', required: true },
|
|
281
|
+
},
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const params = {
|
|
285
|
+
body: { permissionSetId, principalType, principalId, grantType },
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
const result = await this.sdk._fetch(
|
|
289
|
+
'/permissions/assignments',
|
|
290
|
+
'POST',
|
|
291
|
+
params,
|
|
292
|
+
);
|
|
293
|
+
return result;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Remove a permission set assignment from a principal
|
|
298
|
+
* @param {string} permissionSetId - Permission set ID
|
|
299
|
+
* @param {string} principalType - Principal type, e.g. 'user' or 'group'
|
|
300
|
+
* @param {string} principalId - Principal ID
|
|
301
|
+
* @returns {Promise<Object>} Removal confirmation
|
|
302
|
+
* @example
|
|
303
|
+
* await sdk.permissions.unassignPermissionSet('set-123', 'user', 'user-456');
|
|
304
|
+
*/
|
|
305
|
+
async unassignPermissionSet(permissionSetId, principalType, principalId) {
|
|
306
|
+
permissionSetId = String(permissionSetId);
|
|
307
|
+
principalId = String(principalId);
|
|
308
|
+
this.sdk.validateParams(
|
|
309
|
+
{ permissionSetId, principalType, principalId },
|
|
310
|
+
{
|
|
311
|
+
permissionSetId: { type: 'string', required: true },
|
|
312
|
+
principalType: { type: 'string', required: true },
|
|
313
|
+
principalId: { type: 'string', required: true },
|
|
314
|
+
},
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
const result = await this.sdk._fetch(
|
|
318
|
+
`/permissions/assignments/${permissionSetId}/${principalType}/${principalId}`,
|
|
319
|
+
'DELETE',
|
|
320
|
+
);
|
|
321
|
+
return result;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Get a user's effective scopes, resolved from all assigned permission sets
|
|
326
|
+
* @param {string} userId - User ID
|
|
327
|
+
* @returns {Promise<Object>} Object with userId, scopes, breakdown ({scope, sources}[]), deniedScopes
|
|
328
|
+
* @example
|
|
329
|
+
* const { scopes, breakdown, deniedScopes } = await sdk.permissions.getEffectiveScopes('user-456');
|
|
330
|
+
*/
|
|
331
|
+
/**
|
|
332
|
+
* Effective scopes contributed by membership in a group.
|
|
333
|
+
* @param {string|number} groupId - Group ID (required)
|
|
334
|
+
* @returns {Promise<Object>} { groupId, scopes, breakdown, deniedScopes }
|
|
335
|
+
*/
|
|
336
|
+
async getGroupEffectiveScopes(groupId) {
|
|
337
|
+
groupId = String(groupId);
|
|
338
|
+
this.sdk.validateParams(
|
|
339
|
+
{ groupId },
|
|
340
|
+
{
|
|
341
|
+
groupId: { type: 'string', required: true },
|
|
342
|
+
},
|
|
343
|
+
);
|
|
344
|
+
const result = await this.sdk._fetch(
|
|
345
|
+
`/permissions/groups/${groupId}/effective-scopes`,
|
|
346
|
+
'GET',
|
|
347
|
+
);
|
|
348
|
+
return result;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
async getEffectiveScopes(userId) {
|
|
352
|
+
userId = String(userId);
|
|
353
|
+
this.sdk.validateParams(
|
|
354
|
+
{ userId },
|
|
355
|
+
{
|
|
356
|
+
userId: { type: 'string', required: true },
|
|
357
|
+
},
|
|
358
|
+
);
|
|
359
|
+
|
|
360
|
+
const result = await this.sdk._fetch(
|
|
361
|
+
`/permissions/users/${userId}/effective-scopes`,
|
|
362
|
+
'GET',
|
|
363
|
+
);
|
|
364
|
+
return result;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/**
|
|
368
|
+
* Get the full catalog of available scopes, grouped by pillar
|
|
369
|
+
* @returns {Promise<Object>} Object with pillars: Array of {pillar, scopes: [{scope, label}]}
|
|
370
|
+
* @example
|
|
371
|
+
* const { pillars } = await sdk.permissions.getScopeCatalog();
|
|
372
|
+
*/
|
|
373
|
+
async getScopeCatalog() {
|
|
374
|
+
const result = await this.sdk._fetch('/permissions/scope-catalog', 'GET');
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
}
|