docs
0
# Utility Functions
1
2
Error handling, network utilities, authentication helpers, and common constants for robust client operations.
3
4
## Capabilities
5
6
### Network Error Handling
7
8
Custom error class providing detailed information about HTTP failures and response data.
9
10
```typescript { .api }
11
/**
12
* Enhanced error class for network-related failures
13
* Provides access to HTTP response and parsed response data
14
*/
15
class NetworkError extends Error {
16
/** The HTTP Response object that caused the error */
17
response: Response;
18
/** Parsed response data (JSON, text, etc.) */
19
responseData: unknown;
20
21
/**
22
* Create a new NetworkError instance
23
* @param message - Error message describing the failure
24
* @param options - Error options with response details
25
*/
26
constructor(message: string, options: NetworkErrorOptions);
27
}
28
29
/**
30
* Options for NetworkError construction
31
*/
32
interface NetworkErrorOptions {
33
/** HTTP Response object */
34
response: Response;
35
/** Parsed response data */
36
responseData: unknown;
37
}
38
```
39
40
**Usage Examples:**
41
42
```typescript
43
import { NetworkError } from "@keycloak/keycloak-admin-client";
44
45
try {
46
await kcAdminClient.users.findOne({ id: "non-existent-user-id" });
47
} catch (error) {
48
if (error instanceof NetworkError) {
49
console.log("HTTP Status:", error.response.status); // 404
50
console.log("Status Text:", error.response.statusText); // "Not Found"
51
console.log("Response Data:", error.responseData); // Error details from server
52
console.log("Error Message:", error.message); // "Request failed with status 404"
53
54
// Handle specific error cases
55
switch (error.response.status) {
56
case 401:
57
console.log("Authentication required");
58
break;
59
case 403:
60
console.log("Insufficient permissions");
61
break;
62
case 404:
63
console.log("Resource not found");
64
break;
65
case 409:
66
console.log("Resource conflict (duplicate)");
67
break;
68
}
69
}
70
}
71
```
72
73
### Enhanced Fetch Function
74
75
HTTP utility function with automatic error handling and response parsing.
76
77
```typescript { .api }
78
/**
79
* Enhanced fetch function with automatic error handling
80
* Throws NetworkError for non-2xx responses
81
* @param input - Request URL, Request object, or URL object
82
* @param init - Optional RequestInit configuration
83
* @returns Promise resolving to Response object
84
* @throws NetworkError for HTTP errors
85
*/
86
function fetchWithError(
87
input: Request | string | URL,
88
init?: RequestInit,
89
): Promise<Response>;
90
91
/**
92
* Parse response body automatically based on Content-Type
93
* @param response - HTTP Response object
94
* @returns Parsed response data (JSON object, text, etc.)
95
*/
96
function parseResponse(response: Response): Promise<any>;
97
```
98
99
**Usage Examples:**
100
101
```typescript
102
import { fetchWithError, parseResponse } from "@keycloak/keycloak-admin-client";
103
104
// Basic usage with automatic error handling
105
try {
106
const response = await fetchWithError("https://api.example.com/data", {
107
method: "POST",
108
headers: {
109
"Content-Type": "application/json",
110
"Authorization": `Bearer ${token}`,
111
},
112
body: JSON.stringify({ data: "example" }),
113
});
114
115
const data = await parseResponse(response);
116
console.log("Success:", data);
117
} catch (error) {
118
if (error instanceof NetworkError) {
119
console.log("Request failed:", error.message);
120
}
121
}
122
```
123
124
### Query Parameter Utilities
125
126
Utility functions for converting objects to URL query parameters.
127
128
```typescript { .api }
129
/**
130
* Convert object to URL search parameters string
131
* Handles nested objects, arrays, and undefined values
132
* @param params - Object with query parameters
133
* @returns URL-encoded query string (without leading '?')
134
*/
135
function stringifyQueryParams(params: Record<string, unknown>): string;
136
```
137
138
**Usage Examples:**
139
140
```typescript
141
import { stringifyQueryParams } from "@keycloak/keycloak-admin-client";
142
143
// Simple parameters
144
const queryString = stringifyQueryParams({
145
max: 10,
146
first: 0,
147
search: "john",
148
enabled: true,
149
});
150
// Result: "max=10&first=0&search=john&enabled=true"
151
152
// Complex parameters with arrays and nested objects
153
const complexQuery = stringifyQueryParams({
154
max: 50,
155
attributes: ["email", "firstName", "lastName"],
156
filter: {
157
enabled: true,
158
emailVerified: false,
159
},
160
sort: "username:asc",
161
});
162
// Properly encoded query string for complex data structures
163
```
164
165
### Required Action Constants
166
167
Predefined constants for Keycloak required actions.
168
169
```typescript { .api }
170
/**
171
* Standard Keycloak required action aliases
172
* Used for user required actions and email actions
173
*/
174
enum RequiredActionAlias {
175
/** Email verification required action */
176
VERIFY_EMAIL = "VERIFY_EMAIL",
177
/** Profile update required action */
178
UPDATE_PROFILE = "UPDATE_PROFILE",
179
/** TOTP configuration required action */
180
CONFIGURE_TOTP = "CONFIGURE_TOTP",
181
/** Password update required action */
182
UPDATE_PASSWORD = "UPDATE_PASSWORD",
183
/** Terms and conditions acceptance required action */
184
TERMS_AND_CONDITIONS = "TERMS_AND_CONDITIONS",
185
}
186
187
/**
188
* Exported required action constant for convenience
189
* Alias for RequiredActionAlias enum
190
*/
191
const requiredAction: typeof RequiredActionAlias;
192
```
193
194
**Usage Examples:**
195
196
```typescript
197
import { requiredAction } from "@keycloak/keycloak-admin-client";
198
199
// Send email with required actions
200
await kcAdminClient.users.executeActionsEmail({
201
id: userId,
202
actions: [
203
requiredAction.VERIFY_EMAIL,
204
requiredAction.UPDATE_PROFILE,
205
requiredAction.CONFIGURE_TOTP,
206
],
207
clientId: "my-client",
208
redirectUri: "https://myapp.com/welcome",
209
lifespan: 3600, // 1 hour
210
});
211
212
// Check all available required actions
213
const allActions = Object.values(requiredAction);
214
console.log("Available required actions:", allActions);
215
// ["VERIFY_EMAIL", "UPDATE_PROFILE", "CONFIGURE_TOTP", "UPDATE_PASSWORD", "TERMS_AND_CONDITIONS"]
216
```
217
218
### Configuration Constants
219
220
Default configuration values used throughout the client.
221
222
```typescript { .api }
223
/**
224
* Default Keycloak server base URL
225
* Used when no baseUrl is provided in ConnectionConfig
226
*/
227
const defaultBaseUrl = "http://127.0.0.1:8180";
228
229
/**
230
* Default realm name for authentication and operations
231
* Used when no realmName is provided in ConnectionConfig
232
*/
233
const defaultRealm = "master";
234
```
235
236
**Usage Examples:**
237
238
```typescript
239
import { defaultBaseUrl, defaultRealm } from "@keycloak/keycloak-admin-client";
240
241
// Use defaults explicitly
242
const kcAdminClient = new KeycloakAdminClient({
243
baseUrl: defaultBaseUrl, // "http://127.0.0.1:8180"
244
realmName: defaultRealm, // "master"
245
});
246
247
// Check if using defaults
248
console.log("Using default URL:", kcAdminClient.baseUrl === defaultBaseUrl);
249
console.log("Using default realm:", kcAdminClient.realmName === defaultRealm);
250
```
251
252
### Authentication Utilities
253
254
Low-level authentication functions for custom token management.
255
256
```typescript { .api }
257
/**
258
* Settings for token acquisition
259
*/
260
interface Settings {
261
/** Realm name for authentication */
262
realmName?: string;
263
/** Keycloak base URL */
264
baseUrl?: string;
265
/** OAuth2 scope parameter */
266
scope?: string;
267
/** Authentication credentials */
268
credentials: Credentials;
269
/** Additional request options */
270
requestOptions?: RequestInit;
271
}
272
273
/**
274
* Acquire access and refresh tokens using specified settings
275
* Low-level function used internally by auth() method
276
* @param settings - Authentication settings and credentials
277
* @returns Promise resolving to token response
278
* @throws NetworkError for authentication failures
279
*/
280
function getToken(settings: Settings): Promise<TokenResponse>;
281
```
282
283
**Usage Examples:**
284
285
```typescript
286
import { getToken } from "@keycloak/keycloak-admin-client";
287
288
// Direct token acquisition (advanced usage)
289
try {
290
const tokenResponse = await getToken({
291
baseUrl: "https://keycloak.example.com",
292
realmName: "my-realm",
293
credentials: {
294
grantType: "client_credentials",
295
clientId: "service-account",
296
clientSecret: "secret-key",
297
},
298
requestOptions: {
299
timeout: 10000,
300
},
301
});
302
303
console.log("Access Token:", tokenResponse.accessToken);
304
console.log("Expires In:", tokenResponse.expiresIn);
305
console.log("Token Type:", tokenResponse.tokenType);
306
} catch (error) {
307
if (error instanceof NetworkError) {
308
console.log("Token acquisition failed:", error.responseData);
309
}
310
}
311
```
312
313
## Error Handling Patterns
314
315
Common patterns for handling different types of errors in Keycloak operations.
316
317
```typescript
318
// Pattern 1: Resource not found handling
319
try {
320
const user = await kcAdminClient.users.findOne({ id: userId });
321
console.log("User found:", user);
322
} catch (error) {
323
if (error instanceof NetworkError && error.response.status === 404) {
324
console.log("User does not exist");
325
return null;
326
}
327
throw error; // Re-throw other errors
328
}
329
330
// Pattern 2: Using catchNotFound option
331
const user = await kcAdminClient.users.findOne(
332
{ id: userId },
333
{ catchNotFound: true }
334
);
335
if (!user) {
336
console.log("User does not exist");
337
}
338
339
// Pattern 3: Batch operations error handling
340
const results = [];
341
const errors = [];
342
343
for (const userData of usersToCreate) {
344
try {
345
const result = await kcAdminClient.users.create(userData);
346
results.push(result);
347
} catch (error) {
348
if (error instanceof NetworkError) {
349
errors.push({
350
userData,
351
status: error.response.status,
352
error: error.responseData,
353
});
354
} else {
355
errors.push({ userData, error: error.message });
356
}
357
}
358
}
359
360
console.log(`Created ${results.length} users, ${errors.length} errors`);
361
```