quickbase-js 2.3.0 → 2.4.1
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 +145 -1107
- package/dist/auth/ticket.d.ts.map +1 -1
- package/dist/auth/ticket.js +4 -3
- package/dist/auth/ticket.js.map +1 -1
- package/dist/client/request.d.ts +4 -0
- package/dist/client/request.d.ts.map +1 -1
- package/dist/client/request.js +15 -3
- package/dist/client/request.js.map +1 -1
- package/dist/generated/client.d.ts +2 -0
- package/dist/generated/client.d.ts.map +1 -1
- package/dist/generated/client.js +134 -113
- package/dist/generated/client.js.map +1 -1
- package/dist/generated/types.d.ts +2700 -2256
- package/dist/generated/types.d.ts.map +1 -1
- package/dist/generated/types.js +0 -2
- package/dist/generated/types.js.map +1 -1
- package/dist/quickbase.esm.js +3 -3
- package/dist/quickbase.esm.js.map +3 -3
- package/dist/quickbase.min.js +3 -3
- package/dist/quickbase.min.js.map +3 -3
- package/package.json +16 -13
- package/src/auth/index.ts +55 -0
- package/src/auth/sso-token.ts +143 -0
- package/src/auth/temp-token.ts +160 -0
- package/src/auth/ticket.ts +329 -0
- package/src/auth/token-cache.ts +97 -0
- package/src/auth/types.ts +50 -0
- package/src/auth/user-token.ts +38 -0
- package/src/cli/schema.ts +512 -0
- package/src/client/index.ts +36 -0
- package/src/client/pagination.ts +337 -0
- package/src/client/request.ts +544 -0
- package/src/client/retry.ts +169 -0
- package/src/client/throttle.ts +105 -0
- package/src/core/config.ts +160 -0
- package/src/core/dates.ts +63 -0
- package/src/core/errors.ts +349 -0
- package/src/core/index.ts +50 -0
- package/src/core/logger.ts +113 -0
- package/src/core/schema.ts +213 -0
- package/src/core/transform.ts +295 -0
- package/src/core/types.ts +337 -0
- package/src/generated/client.ts +1785 -0
- package/src/generated/operations.json +672 -0
- package/src/generated/types.ts +4884 -0
- package/src/index.ts +259 -0
- package/src/xml/codepages.ts +119 -0
- package/src/xml/dbvars.ts +75 -0
- package/src/xml/errors.ts +133 -0
- package/src/xml/fields.ts +121 -0
- package/src/xml/groups.ts +560 -0
- package/src/xml/html.ts +152 -0
- package/src/xml/index.ts +1196 -0
- package/src/xml/metadata.ts +111 -0
- package/src/xml/records.ts +301 -0
- package/src/xml/request.ts +238 -0
- package/src/xml/roles.ts +321 -0
- package/src/xml/schema.ts +436 -0
- package/src/xml/transform.ts +381 -0
- package/src/xml/types.ts +602 -0
- package/src/xml/users.ts +221 -0
- package/src/xml/webhooks.ts +260 -0
package/src/xml/roles.ts
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* XML API Role Management
|
|
3
|
+
*
|
|
4
|
+
* Endpoints for managing roles and user role assignments.
|
|
5
|
+
*
|
|
6
|
+
* XML-API: Remove this file when QuickBase discontinues the XML API.
|
|
7
|
+
* To find all XML API code, search for: XML-API
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import type {
|
|
11
|
+
XmlCaller,
|
|
12
|
+
Role,
|
|
13
|
+
RoleAccess,
|
|
14
|
+
UserRole,
|
|
15
|
+
RoleMember,
|
|
16
|
+
UserWithRoles,
|
|
17
|
+
GetRoleInfoResult,
|
|
18
|
+
UserRolesResult,
|
|
19
|
+
GetUserRoleResult,
|
|
20
|
+
} from './types.js';
|
|
21
|
+
import { checkError } from './errors.js';
|
|
22
|
+
import {
|
|
23
|
+
buildRequest,
|
|
24
|
+
escapeXml,
|
|
25
|
+
parseBaseResponse,
|
|
26
|
+
getTagContent,
|
|
27
|
+
getAttribute,
|
|
28
|
+
getAllElements,
|
|
29
|
+
parseXmlNumber,
|
|
30
|
+
} from './request.js';
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Parse a single role element from XML
|
|
34
|
+
*/
|
|
35
|
+
function parseRole(roleXml: string): Role {
|
|
36
|
+
const id = parseXmlNumber(getAttribute(roleXml, 'id'));
|
|
37
|
+
const name = getTagContent(roleXml, 'name');
|
|
38
|
+
|
|
39
|
+
// Parse access element
|
|
40
|
+
const accessMatch = roleXml.match(/<access[^>]*id="(\d+)"[^>]*>([^<]*)<\/access>/);
|
|
41
|
+
const access: RoleAccess = {
|
|
42
|
+
id: accessMatch ? parseXmlNumber(accessMatch[1] ?? '0') : 0,
|
|
43
|
+
description: accessMatch?.[2] ?? '',
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
return { id, name, access };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Parse a role with member info (from GetUserRole with inclgrps)
|
|
51
|
+
*/
|
|
52
|
+
function parseUserRole(roleXml: string): UserRole {
|
|
53
|
+
const role = parseRole(roleXml);
|
|
54
|
+
|
|
55
|
+
// Parse member element if present
|
|
56
|
+
const memberMatch = roleXml.match(/<member[^>]*type="([^"]*)"[^>]*>([^<]*)<\/member>/);
|
|
57
|
+
const member: RoleMember | undefined = memberMatch && memberMatch[1] && memberMatch[2]
|
|
58
|
+
? { type: memberMatch[1], name: memberMatch[2] }
|
|
59
|
+
: undefined;
|
|
60
|
+
|
|
61
|
+
return { ...role, member };
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Parse a user with roles from UserRoles response
|
|
66
|
+
*/
|
|
67
|
+
function parseUserWithRoles(userXml: string): UserWithRoles {
|
|
68
|
+
const id = getAttribute(userXml, 'id');
|
|
69
|
+
const type = getAttribute(userXml, 'type') || 'user';
|
|
70
|
+
const name = getTagContent(userXml, 'name');
|
|
71
|
+
const firstName = getTagContent(userXml, 'firstName') || undefined;
|
|
72
|
+
const lastName = getTagContent(userXml, 'lastName') || undefined;
|
|
73
|
+
const lastAccess = getTagContent(userXml, 'lastAccess') || undefined;
|
|
74
|
+
const lastAccessAppLocal = getTagContent(userXml, 'lastAccessAppLocal') || undefined;
|
|
75
|
+
|
|
76
|
+
// Parse roles
|
|
77
|
+
const roleElements = getAllElements(userXml, 'role');
|
|
78
|
+
const roles = roleElements.map(parseRole);
|
|
79
|
+
|
|
80
|
+
return {
|
|
81
|
+
id,
|
|
82
|
+
type,
|
|
83
|
+
name,
|
|
84
|
+
firstName,
|
|
85
|
+
lastName,
|
|
86
|
+
lastAccess,
|
|
87
|
+
lastAccessAppLocal,
|
|
88
|
+
roles,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Get all roles defined in an application.
|
|
94
|
+
*
|
|
95
|
+
* @see https://help.quickbase.com/docs/api-getroleinfo
|
|
96
|
+
*
|
|
97
|
+
* @example
|
|
98
|
+
* ```typescript
|
|
99
|
+
* const result = await getRoleInfo(caller, 'bqxyz123');
|
|
100
|
+
* for (const role of result.roles) {
|
|
101
|
+
* console.log(`Role ${role.id}: ${role.name} (${role.access.description})`);
|
|
102
|
+
* }
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export async function getRoleInfo(
|
|
106
|
+
caller: XmlCaller,
|
|
107
|
+
appId: string
|
|
108
|
+
): Promise<GetRoleInfoResult> {
|
|
109
|
+
const body = buildRequest('');
|
|
110
|
+
const xml = await caller.doXml(appId, 'API_GetRoleInfo', body);
|
|
111
|
+
|
|
112
|
+
const base = parseBaseResponse(xml);
|
|
113
|
+
checkError(base);
|
|
114
|
+
|
|
115
|
+
// Parse roles
|
|
116
|
+
const roleElements = getAllElements(xml, 'role');
|
|
117
|
+
const roles = roleElements.map(parseRole);
|
|
118
|
+
|
|
119
|
+
return { roles };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Get all users in an application and their role assignments.
|
|
124
|
+
*
|
|
125
|
+
* Requires Basic Access with Sharing or Full Administration access.
|
|
126
|
+
*
|
|
127
|
+
* @see https://help.quickbase.com/docs/api-userroles
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* const result = await userRoles(caller, 'bqxyz123');
|
|
132
|
+
* for (const user of result.users) {
|
|
133
|
+
* console.log(`${user.name}: ${user.roles.map(r => r.name).join(', ')}`);
|
|
134
|
+
* }
|
|
135
|
+
* ```
|
|
136
|
+
*/
|
|
137
|
+
export async function userRoles(
|
|
138
|
+
caller: XmlCaller,
|
|
139
|
+
appId: string
|
|
140
|
+
): Promise<UserRolesResult> {
|
|
141
|
+
const body = buildRequest('');
|
|
142
|
+
const xml = await caller.doXml(appId, 'API_UserRoles', body);
|
|
143
|
+
|
|
144
|
+
const base = parseBaseResponse(xml);
|
|
145
|
+
checkError(base);
|
|
146
|
+
|
|
147
|
+
// Parse users
|
|
148
|
+
const userElements = getAllElements(xml, 'user');
|
|
149
|
+
const users = userElements.map(parseUserWithRoles);
|
|
150
|
+
|
|
151
|
+
return { users };
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get roles for a specific user.
|
|
156
|
+
*
|
|
157
|
+
* If userId is omitted, returns your own roles.
|
|
158
|
+
* Set includeGroups to true to include roles assigned via groups.
|
|
159
|
+
*
|
|
160
|
+
* @see https://help.quickbase.com/docs/api-getuserrole
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```typescript
|
|
164
|
+
* const result = await getUserRole(caller, 'bqxyz123', '112149.bhsv', true);
|
|
165
|
+
* console.log(`User: ${result.userName}`);
|
|
166
|
+
* for (const role of result.roles) {
|
|
167
|
+
* if (role.member) {
|
|
168
|
+
* console.log(` ${role.name} (via ${role.member.type}: ${role.member.name})`);
|
|
169
|
+
* } else {
|
|
170
|
+
* console.log(` ${role.name}`);
|
|
171
|
+
* }
|
|
172
|
+
* }
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export async function getUserRole(
|
|
176
|
+
caller: XmlCaller,
|
|
177
|
+
appId: string,
|
|
178
|
+
userId?: string,
|
|
179
|
+
includeGroups?: boolean
|
|
180
|
+
): Promise<GetUserRoleResult> {
|
|
181
|
+
let inner = '';
|
|
182
|
+
if (userId) {
|
|
183
|
+
inner += `<userid>${escapeXml(userId)}</userid>`;
|
|
184
|
+
}
|
|
185
|
+
if (includeGroups) {
|
|
186
|
+
inner += '<inclgrps>1</inclgrps>';
|
|
187
|
+
}
|
|
188
|
+
const body = buildRequest(inner);
|
|
189
|
+
const xml = await caller.doXml(appId, 'API_GetUserRole', body);
|
|
190
|
+
|
|
191
|
+
const base = parseBaseResponse(xml);
|
|
192
|
+
checkError(base);
|
|
193
|
+
|
|
194
|
+
// Parse user element
|
|
195
|
+
const userMatch = xml.match(/<user[^>]*id="([^"]*)"[^>]*>([\s\S]*?)<\/user>/);
|
|
196
|
+
if (!userMatch || !userMatch[1]) {
|
|
197
|
+
throw new Error('Invalid API_GetUserRole response: no user element');
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const userIdResult = userMatch[1];
|
|
201
|
+
const userXml = userMatch[0];
|
|
202
|
+
const userName = getTagContent(userXml, 'name');
|
|
203
|
+
|
|
204
|
+
// Parse roles (with member info if inclgrps was used)
|
|
205
|
+
const roleElements = getAllElements(userXml, 'role');
|
|
206
|
+
const roles = roleElements.map(parseUserRole);
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
userId: userIdResult,
|
|
210
|
+
userName,
|
|
211
|
+
roles,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Assign a user to a role.
|
|
217
|
+
*
|
|
218
|
+
* You can call this multiple times to give a user multiple roles.
|
|
219
|
+
* After assigning, use sendInvitation to invite the user.
|
|
220
|
+
*
|
|
221
|
+
* Requires Basic Access with Sharing or Full Administration access.
|
|
222
|
+
* Users with Basic Access cannot add users to admin roles.
|
|
223
|
+
*
|
|
224
|
+
* @see https://help.quickbase.com/docs/api-addusertorole
|
|
225
|
+
*
|
|
226
|
+
* @example
|
|
227
|
+
* ```typescript
|
|
228
|
+
* await addUserToRole(caller, 'bqxyz123', '112149.bhsv', 10);
|
|
229
|
+
* ```
|
|
230
|
+
*/
|
|
231
|
+
export async function addUserToRole(
|
|
232
|
+
caller: XmlCaller,
|
|
233
|
+
appId: string,
|
|
234
|
+
userId: string,
|
|
235
|
+
roleId: number
|
|
236
|
+
): Promise<void> {
|
|
237
|
+
const inner =
|
|
238
|
+
`<userid>${escapeXml(userId)}</userid>` +
|
|
239
|
+
`<roleid>${roleId}</roleid>`;
|
|
240
|
+
const body = buildRequest(inner);
|
|
241
|
+
const xml = await caller.doXml(appId, 'API_AddUserToRole', body);
|
|
242
|
+
|
|
243
|
+
const base = parseBaseResponse(xml);
|
|
244
|
+
checkError(base);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Remove a user from a specific role.
|
|
249
|
+
*
|
|
250
|
+
* If this is the user's only role, they lose all access to the app
|
|
251
|
+
* and are removed from the app's user list.
|
|
252
|
+
*
|
|
253
|
+
* To temporarily disable access while keeping the user in the app,
|
|
254
|
+
* use changeUserRole with newRoleId=0 instead.
|
|
255
|
+
*
|
|
256
|
+
* @see https://help.quickbase.com/docs/api-removeuserfromrole
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* await removeUserFromRole(caller, 'bqxyz123', '112149.bhsv', 10);
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
263
|
+
export async function removeUserFromRole(
|
|
264
|
+
caller: XmlCaller,
|
|
265
|
+
appId: string,
|
|
266
|
+
userId: string,
|
|
267
|
+
roleId: number
|
|
268
|
+
): Promise<void> {
|
|
269
|
+
const inner =
|
|
270
|
+
`<userid>${escapeXml(userId)}</userid>` +
|
|
271
|
+
`<roleid>${roleId}</roleid>`;
|
|
272
|
+
const body = buildRequest(inner);
|
|
273
|
+
const xml = await caller.doXml(appId, 'API_RemoveUserFromRole', body);
|
|
274
|
+
|
|
275
|
+
const base = parseBaseResponse(xml);
|
|
276
|
+
checkError(base);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Change a user's role or disable their access.
|
|
281
|
+
*
|
|
282
|
+
* This is preferred over removeUserFromRole when you want to keep the
|
|
283
|
+
* user in the app's user list but change/disable their access.
|
|
284
|
+
*
|
|
285
|
+
* Pass newRoleId=0 (or omit it) to set the role to "None" (role ID 9),
|
|
286
|
+
* which disables access while keeping the user on the app's user list.
|
|
287
|
+
*
|
|
288
|
+
* @see https://help.quickbase.com/docs/api-changeuserrole
|
|
289
|
+
*
|
|
290
|
+
* @example
|
|
291
|
+
* ```typescript
|
|
292
|
+
* // Change from role 10 to role 11
|
|
293
|
+
* await changeUserRole(caller, 'bqxyz123', '112149.bhsv', 10, 11);
|
|
294
|
+
*
|
|
295
|
+
* // Disable access (set to None role)
|
|
296
|
+
* await changeUserRole(caller, 'bqxyz123', '112149.bhsv', 10, 0);
|
|
297
|
+
* ```
|
|
298
|
+
*/
|
|
299
|
+
export async function changeUserRole(
|
|
300
|
+
caller: XmlCaller,
|
|
301
|
+
appId: string,
|
|
302
|
+
userId: string,
|
|
303
|
+
currentRoleId: number,
|
|
304
|
+
newRoleId?: number
|
|
305
|
+
): Promise<void> {
|
|
306
|
+
let inner =
|
|
307
|
+
`<userid>${escapeXml(userId)}</userid>` +
|
|
308
|
+
`<roleid>${currentRoleId}</roleid>`;
|
|
309
|
+
|
|
310
|
+
// If newRoleId is provided and > 0, include it
|
|
311
|
+
// If omitted or 0, QuickBase sets role to None (9)
|
|
312
|
+
if (newRoleId !== undefined && newRoleId > 0) {
|
|
313
|
+
inner += `<newRoleid>${newRoleId}</newRoleid>`;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const body = buildRequest(inner);
|
|
317
|
+
const xml = await caller.doXml(appId, 'API_ChangeUserRole', body);
|
|
318
|
+
|
|
319
|
+
const base = parseBaseResponse(xml);
|
|
320
|
+
checkError(base);
|
|
321
|
+
}
|