or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

batch-processing.mdconfiguration-utilities.mdcrm-actions-functions.mdcrud-operations.mdentity-associations.mdindex.md

configuration-utilities.mddocs/

0

# Configuration and Utilities

1

2

Client configuration, URL building, header management, and utility functions for customizing WebApiClient behavior and accessing low-level functionality.

3

4

## Capabilities

5

6

### Client Configuration

7

8

Global configuration properties for customizing WebApiClient behavior.

9

10

```typescript { .api }

11

import * as bluebird from "bluebird";

12

13

/** CRM Web API version to use (default: "8.0") */

14

let ApiVersion: string;

15

16

/** Automatically retrieve all pages for multi-page results (default: false) */

17

let ReturnAllPages: boolean;

18

19

/** Format errors in readable format vs raw JSON (default: true) */

20

let PrettifyErrors: boolean;

21

22

/** Send requests asynchronously vs synchronously (default: true) */

23

let Async: boolean;

24

25

/** Base URL for single page application scenarios */

26

let ClientUrl: string;

27

28

/** Authentication token for single page application scenarios */

29

let Token: string;

30

31

/** WebApiClient library version */

32

let Version: string;

33

34

/** Bluebird promise implementation used internally */

35

let Promise: typeof bluebird;

36

```

37

38

**Configuration Examples:**

39

40

```typescript

41

// Basic configuration

42

WebApiClient.ApiVersion = "9.0";

43

WebApiClient.ReturnAllPages = true;

44

WebApiClient.PrettifyErrors = false;

45

WebApiClient.Async = true;

46

47

// Single Page Application configuration

48

WebApiClient.ClientUrl = "https://orgname.crm.dynamics.com/api/data/v9.0/";

49

WebApiClient.Token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJS...";

50

WebApiClient.ApiVersion = "9.0";

51

52

// Power Pages configuration

53

WebApiClient.ClientUrl = "/_api/";

54

55

// Access Bluebird promise library

56

const customPromise = WebApiClient.Promise.resolve(data);

57

```

58

59

### URL and Entity Utilities

60

61

Functions for building URLs and working with entity names.

62

63

```typescript { .api }

64

/**

65

* Get the base Web API URL for the current CRM context

66

* @returns Base URL string for Web API endpoints

67

*/

68

function GetApiUrl(): string;

69

70

/**

71

* Get the entity set name for an entity logical name

72

* @param entity - Entity logical name (e.g., "account", "contact")

73

* @returns Entity set name for Web API URLs (e.g., "accounts", "contacts")

74

*/

75

function GetSetName(entity: string): string;

76

```

77

78

**Usage Examples:**

79

80

```typescript

81

// Get API base URL

82

const apiUrl = WebApiClient.GetApiUrl();

83

console.log(apiUrl); // https://orgname.crm.dynamics.com/api/data/v9.0/

84

85

// Get entity set names

86

const accountSetName = WebApiClient.GetSetName("account");

87

console.log(accountSetName); // "accounts"

88

89

const contactSetName = WebApiClient.GetSetName("contact");

90

console.log(contactSetName); // "contacts"

91

92

const userSetName = WebApiClient.GetSetName("systemuser");

93

console.log(userSetName); // "systemusers"

94

95

// Build custom URLs

96

const customUrl = WebApiClient.GetApiUrl() + WebApiClient.GetSetName("account") +

97

"?$select=name,revenue&$filter=statecode eq 0";

98

```

99

100

### Header Management

101

102

Headers are managed per-request using the headers parameter in request objects.

103

104

```typescript { .api }

105

interface Header {

106

/** Header name */

107

key: string;

108

/** Header value */

109

value: string;

110

}

111

```

112

113

**Usage Examples:**

114

115

```typescript

116

// Add custom headers to individual requests

117

await WebApiClient.Create({

118

entityName: "account",

119

entity: { name: "Test Account" },

120

headers: [

121

{ key: "Prefer", value: "return=representation" },

122

{ key: "CustomHeader", value: "CustomValue" }

123

]

124

});

125

126

// Authentication header for external access

127

await WebApiClient.Retrieve({

128

entityName: "account",

129

entityId: accountId,

130

headers: [

131

{ key: "Authorization", value: "Bearer " + accessToken }

132

]

133

});

134

135

// CSRF token for Power Pages

136

await WebApiClient.Update({

137

entityName: "account",

138

entityId: accountId,

139

entity: { name: "Updated Name" },

140

headers: [

141

{ key: "__RequestVerificationToken", value: csrfToken }

142

]

143

});

144

```

145

146

### Low-Level Request Function

147

148

Direct HTTP request function for custom operations not covered by other methods.

149

150

```typescript { .api }

151

/**

152

* Send a raw HTTP request to the Web API

153

* @param method - HTTP method (GET, POST, PATCH, DELETE, etc.)

154

* @param url - Full URL for the request

155

* @param payload - Request payload object

156

* @param parameters - Additional request parameters

157

* @returns Promise resolving to response data

158

*/

159

function SendRequest(

160

method: string,

161

url: string,

162

payload: object,

163

parameters?: BaseParameters

164

): Promise<any> | any | BatchRequest;

165

```

166

167

**Usage Examples:**

168

169

```typescript

170

// Custom action execution

171

const actionUrl = WebApiClient.GetApiUrl() + "WinOpportunity";

172

const result = await WebApiClient.SendRequest("POST", actionUrl, {

173

Status: 3,

174

OpportunityClose: {

175

subject: "Won the deal!",

176

actualrevenue: 100000,

177

"opportunityid@odata.bind": "/opportunities(" + opportunityId + ")"

178

}

179

});

180

181

// Custom query with complex URL

182

const complexUrl = WebApiClient.GetApiUrl() +

183

WebApiClient.GetSetName("account") +

184

"?$select=name,revenue&$expand=contact_customer_accounts($select=fullname,emailaddress1)";

185

186

const complexResults = await WebApiClient.SendRequest("GET", complexUrl, null);

187

188

// Custom entity operation

189

const customEntityUrl = WebApiClient.GetApiUrl() +

190

WebApiClient.GetSetName("new_customentity") +

191

"(" + entityId + ")/Microsoft.Dynamics.CRM.new_CustomAction";

192

193

const customResult = await WebApiClient.SendRequest("POST", customEntityUrl, {

194

InputParameter: "value"

195

}, {

196

headers: [{ key: "Prefer", value: "return=representation" }]

197

});

198

```

199

200

### Navigation Property Expansion

201

202

Collection-valued navigation properties can be expanded using the $expand query parameter in retrieve operations.

203

204

**Usage Example:**

205

206

```typescript

207

// Retrieve records with collection expansion

208

const accountsWithContacts = await WebApiClient.Retrieve({

209

entityName: "account",

210

queryParams: "?$select=name&$expand=contact_customer_accounts($select=fullname,emailaddress1)"

211

});

212

213

console.log("Accounts with expanded contacts:", accountsWithContacts.value);

214

215

// Handle paginated expanded results

216

for (const account of accountsWithContacts.value) {

217

if (account["contact_customer_accounts@odata.nextLink"]) {

218

// Additional requests needed for remaining pages

219

console.log("More contacts available at:", account["contact_customer_accounts@odata.nextLink"]);

220

}

221

}

222

```

223

224

### Promise Integration

225

226

Access to the Bluebird promise library used internally for advanced promise operations.

227

228

```typescript { .api }

229

/** Bluebird promise implementation with additional methods */

230

let Promise: typeof bluebird;

231

```

232

233

**Usage Examples:**

234

235

```typescript

236

// Use Promise.all for concurrent operations

237

const promises = [

238

WebApiClient.Retrieve({ entityName: "account", entityId: account1Id }),

239

WebApiClient.Retrieve({ entityName: "account", entityId: account2Id }),

240

WebApiClient.Retrieve({ entityName: "account", entityId: account3Id })

241

];

242

243

const allAccounts = await WebApiClient.Promise.all(promises);

244

245

// Use Promise.map for processing arrays

246

const accountIds = ["id1", "id2", "id3", "id4", "id5"];

247

248

const accountDetails = await WebApiClient.Promise.map(accountIds, async (id) => {

249

return WebApiClient.Retrieve({

250

entityName: "account",

251

entityId: id,

252

queryParams: "?$select=name,revenue"

253

});

254

}, { concurrency: 3 }); // Process 3 at a time

255

256

// Use additional Bluebird methods

257

const timeoutResult = await WebApiClient.Retrieve({

258

entityName: "account",

259

queryParams: "?$select=name"

260

})

261

.timeout(5000) // 5 second timeout

262

.catch(WebApiClient.Promise.TimeoutError, (error) => {

263

console.log("Request timed out");

264

return { value: [] }; // Return empty result

265

});

266

```

267

268

## Environment-Specific Configuration

269

270

### CRM Forms and Web Resources

271

272

When running within CRM forms or web resources, the client automatically detects the context:

273

274

```typescript

275

// No additional configuration needed - automatic context detection

276

const currentUser = await WebApiClient.Execute(WebApiClient.Requests.WhoAmIRequest);

277

```

278

279

### Power Pages (PowerApps Portals)

280

281

```typescript

282

// Configure for Power Pages

283

WebApiClient.ClientUrl = "/_api/";

284

285

// Add CSRF token for updates (get from shell.getTokenDeferred())

286

const csrfToken = await shell.getTokenDeferred();

287

WebApiClient.AppendToDefaultHeaders({

288

key: "__RequestVerificationToken",

289

value: csrfToken

290

});

291

```

292

293

### Single Page Applications

294

295

```typescript

296

// Configure for external SPA

297

WebApiClient.Configure({

298

ClientUrl: "https://orgname.crm.dynamics.com/api/data/v9.0/",

299

Token: "Bearer " + oauthToken,

300

ApiVersion: "9.0"

301

});

302

303

// Or using header

304

WebApiClient.ClientUrl = "https://orgname.crm.dynamics.com/api/data/v9.0/";

305

WebApiClient.AppendToDefaultHeaders({

306

key: "Authorization",

307

value: "Bearer " + oauthToken

308

});

309

```

310

311

## Advanced Configuration

312

313

### Custom Entity Set Names

314

315

For entities with non-standard naming:

316

317

```typescript

318

// Use overriddenSetName for unusual entity set names

319

await WebApiClient.Create({

320

overriddenSetName: "contactleadscollection", // Instead of auto-generated name

321

entity: { name: "Custom Entity" }

322

});

323

```

324

325

### Synchronous Operations

326

327

```typescript

328

// Global synchronous mode

329

WebApiClient.Async = false;

330

331

// Per-request synchronous mode

332

const syncResult = WebApiClient.Retrieve({

333

entityName: "account",

334

entityId: accountId,

335

async: false

336

});

337

```

338

339

### Error Handling Configuration

340

341

```typescript

342

// Raw JSON errors instead of formatted messages

343

WebApiClient.PrettifyErrors = false;

344

345

try {

346

await WebApiClient.Create({

347

entityName: "account",

348

entity: { invalid_field: "value" }

349

});

350

} catch (error) {

351

// With PrettifyErrors = false, error contains full JSON response

352

const errorJson = JSON.parse(error);

353

console.log("Error code:", errorJson.error.code);

354

console.log("Error message:", errorJson.error.message);

355

}

356

```

357

358

### API Version Management

359

360

```typescript

361

// Set specific API version

362

WebApiClient.ApiVersion = "9.2";

363

364

// Per-request API version override

365

await WebApiClient.Create({

366

entityName: "account",

367

entity: { name: "Test" },

368

apiVersion: "8.2"

369

});

370

```