or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

content-manager.mdfeatures.mdhooks.mdindex.mdtypes.mdui-components.mdutilities.md

utilities.mddocs/

0

# Utilities

1

2

The @strapi/helper-plugin package provides 18+ utility functions for common operations including HTTP client creation, error handling, data transformation, authentication, file operations, and internationalization. These utilities ensure consistent functionality across Strapi plugins.

3

4

## HTTP & Network Utilities

5

6

Functions for creating HTTP clients, making requests, and handling network operations.

7

8

```typescript { .api }

9

// Create configured HTTP client

10

interface FetchClient {

11

get: <TData = any, R = AxiosResponse<TData>, TSend = any>(

12

url: string,

13

config?: AxiosRequestConfig<TSend>

14

) => Promise<R>;

15

put: <TData = any, R = AxiosResponse<TData>, TSend = any>(

16

url: string,

17

data?: TSend,

18

config?: AxiosRequestConfig<TSend>

19

) => Promise<R>;

20

post: <TData = any, R = AxiosResponse<TData>, TSend = any>(

21

url: string,

22

data?: TSend,

23

config?: AxiosRequestConfig<TSend>

24

) => Promise<R>;

25

del: <TData = any, R = AxiosResponse<TData>, TSend = any>(

26

url: string,

27

config?: AxiosRequestConfig<TSend>

28

) => Promise<R>;

29

}

30

31

function getFetchClient(defaultOptions?: AxiosRequestConfig): FetchClient;

32

33

// Legacy request function (deprecated)

34

interface RequestOptions extends RequestInit {

35

params?: Record<string, string>;

36

}

37

38

function request<ResponseType = unknown>(

39

url: string,

40

options?: RequestOptions,

41

shouldWatchServerRestart?: boolean,

42

stringify?: boolean,

43

config?: { noAuth?: boolean }

44

): Promise<ResponseType>;

45

46

// Wrap axios instance with custom functionality

47

function wrapAxiosInstance(

48

instance: AxiosInstance,

49

options?: AxiosRequestConfig

50

): AxiosInstance;

51

52

// Promise error handling utility

53

function awaitToJs<T, U = Error>(

54

promise: Promise<T>,

55

errorExt?: object

56

): Promise<[U, undefined] | [null, T]>;

57

```

58

59

**Usage Examples:**

60

61

```typescript

62

// Create HTTP client

63

const client = getFetchClient({

64

timeout: 5000,

65

headers: { 'X-Custom': 'value' }

66

});

67

68

// Make requests

69

const articles = await client.get<Article[]>('/api/articles');

70

const created = await client.post<Article>('/api/articles', articleData);

71

72

// Error handling with awaitToJs

73

const [error, result] = await awaitToJs(

74

client.get('/api/articles')

75

);

76

77

if (error) {

78

console.error('Request failed:', error);

79

} else {

80

console.log('Articles:', result);

81

}

82

```

83

84

## Error Handling Utilities

85

86

Functions for processing, normalizing, and extracting error information from API responses.

87

88

```typescript { .api }

89

// Extract inner errors from API responses

90

interface GetAPIInnerErrorsOptions {

91

getTrad: (id: string) => string;

92

}

93

94

function getAPIInnerErrors(

95

error: AxiosError<{ error: ApiError }>,

96

options: GetAPIInnerErrorsOptions

97

): Record<string, MessageDescriptor> | string | undefined;

98

99

// Normalize API error responses

100

interface NormalizeErrorOptions {

101

name?: string;

102

intlMessagePrefixCallback?: (id: string) => string;

103

}

104

105

interface NormalizeErrorReturn {

106

id: string;

107

defaultMessage: string;

108

name?: string;

109

values: Record<'path', string> | Record<string, never>;

110

}

111

112

function normalizeAPIError(

113

apiError: AxiosError<{ error: ApiError }>,

114

intlMessagePrefixCallback?: (id: string) => string

115

): NormalizeErrorReturn | {

116

name: string;

117

message: string | null;

118

errors: NormalizeErrorReturn[]

119

} | null;

120

121

// Extract Yup validation errors

122

function getYupInnerErrors(yupError: any): Record<string, any>;

123

124

// Translated error constants

125

const translatedErrors: {

126

readonly email: 'components.Input.error.validation.email';

127

readonly json: 'components.Input.error.validation.json';

128

readonly lowercase: 'components.Input.error.validation.lowercase';

129

readonly max: 'components.Input.error.validation.max';

130

readonly maxLength: 'components.Input.error.validation.maxLength';

131

readonly min: 'components.Input.error.validation.min';

132

readonly minLength: 'components.Input.error.validation.minLength';

133

readonly regex: 'components.Input.error.validation.regex';

134

readonly required: 'components.Input.error.validation.required';

135

readonly unique: 'components.Input.error.validation.unique';

136

readonly integer: 'component.Input.error.validation.integer';

137

};

138

```

139

140

**Usage Examples:**

141

142

```typescript

143

// Handle API errors

144

const handleError = (error: AxiosError) => {

145

const normalized = normalizeAPIError(error, (id) => `errors.${id}`);

146

147

if (normalized && 'errors' in normalized) {

148

// Handle validation errors

149

normalized.errors.forEach(err => {

150

console.error(`Field ${err.values.path}: ${err.defaultMessage}`);

151

});

152

} else if (normalized) {

153

// Handle single error

154

console.error(normalized.defaultMessage);

155

}

156

};

157

158

// Use translated errors

159

const errorMessage = translatedErrors.required; // 'components.Input.error.validation.required'

160

```

161

162

## Authentication & Storage Utilities

163

164

Functions for managing authentication tokens and browser storage.

165

166

```typescript { .api }

167

// User information interface

168

interface UserInfo {

169

email: string;

170

firstname?: string;

171

lastname?: string;

172

username?: string;

173

preferedLanguage?: string;

174

id: number;

175

isActive?: boolean;

176

blocked: boolean;

177

createdAt: string;

178

updatedAt: string;

179

}

180

181

// Storage items interface

182

interface StorageItems {

183

userInfo: UserInfo;

184

jwtToken: string;

185

STRAPI_THEME: 'light' | 'dark';

186

GUIDED_TOUR_CURRENT_STEP: string | null;

187

GUIDED_TOUR_COMPLETED_STEPS: string[] | null;

188

GUIDED_TOUR_SKIPPED: boolean | null;

189

STRAPI_UPDATE_NOTIF: boolean | null;

190

STRAPI_UPLOAD_MODAL_VIEW: 0 | 1 | null;

191

STRAPI_UPLOAD_LIBRARY_VIEW: 0 | 1 | null;

192

videos: unknown;

193

onboarding: unknown;

194

}

195

196

// Auth utility object (deprecated)

197

const auth: {

198

clear: <T extends keyof StorageItems>(key: T) => void;

199

clearAppStorage: () => void;

200

get: <T extends keyof StorageItems>(key: T) => StorageItems[T] | null;

201

set: (value: any, key: keyof StorageItems, isLocalStorage: boolean) => void;

202

203

// Deprecated methods

204

getToken: (tokenKey?: 'jwtToken') => string | null;

205

setToken: (value?: any, isLocalStorage?: boolean, tokenKey?: 'jwtToken') => void;

206

clearToken: (tokenKey?: 'jwtToken') => void;

207

getUserInfo: (userInfoKey?: 'userInfo') => UserInfo | null;

208

setUserInfo: (value: any, isLocalStorage?: boolean, userInfo?: 'userInfo') => void;

209

clearUserInfo: (userInfoKey?: 'userInfo') => void;

210

updateToken: (value?: any) => void;

211

};

212

```

213

214

**Usage Examples:**

215

216

```typescript

217

// Manage authentication tokens

218

const token = auth.get('jwtToken');

219

if (token) {

220

// User is authenticated

221

}

222

223

// Store user preferences

224

auth.set('light', 'STRAPI_THEME', true);

225

226

// Clear authentication data

227

auth.clearAppStorage(); // Clears all auth-related storage while preserving preferences

228

```

229

230

## Permission Utilities

231

232

Functions for checking and validating user permissions.

233

234

```typescript { .api }

235

// Permission type definitions

236

interface Permission {

237

id?: Entity.ID;

238

action: string;

239

actionParameters?: object;

240

subject?: string | null;

241

properties?: {

242

fields?: string[];

243

locales?: string[];

244

[key: string]: any;

245

};

246

conditions?: string[];

247

}

248

249

type PermissionToCheckAgainst = Pick<Permission, 'action' | 'subject'> &

250

Partial<Pick<Permission, 'actionParameters' | 'conditions' | 'properties'>>;

251

252

// Permission checking functions

253

function hasPermissions(

254

userPermissions: Permission[],

255

permissions: PermissionToCheckAgainst[],

256

signal?: GenericAbortSignal

257

): Promise<boolean>;

258

259

function findMatchingPermissions(

260

userPermissions: Permission[],

261

permissions: PermissionToCheckAgainst[]

262

): Permission[];

263

264

function formatPermissionsForRequest(permissions: Permission[]): Partial<Permission>[];

265

266

function shouldCheckPermissions(permissions: Permission[]): boolean;

267

```

268

269

**Usage Examples:**

270

271

```typescript

272

// Check if user has permissions

273

const canCreateArticles = await hasPermissions(

274

userPermissions,

275

[{ action: 'create', subject: 'api::article.article' }]

276

);

277

278

if (canCreateArticles) {

279

// Show create button

280

}

281

282

// Find matching permissions for multiple actions

283

const matchingPermissions = findMatchingPermissions(

284

userPermissions,

285

[

286

{ action: 'read', subject: 'api::article.article' },

287

{ action: 'update', subject: 'api::article.article' }

288

]

289

);

290

```

291

292

## Data Transformation Utilities

293

294

Functions for data processing, formatting, and manipulation.

295

296

```typescript { .api }

297

// Calculate difference between objects/arrays

298

function difference<T>(original: T, comparison: T): Partial<T>;

299

300

// Content type data formatting

301

function formatContentTypeData<

302

TSchema extends Schema.ContentType,

303

TData extends { [K in keyof TSchema['attributes']]: Attribute.GetValue<TSchema['attributes'][K]> }

304

>(

305

data: TData,

306

contentTypeSchema: TSchema,

307

componentSchema: Record<string, Schema.Component>

308

): TData;

309

310

// Remove fields from content data

311

function contentManagementUtilRemoveFieldsFromData<

312

TSchema extends Schema.ContentType,

313

TData extends { [K in keyof TSchema['attributes']]: Attribute.GetValue<TSchema['attributes'][K]> }

314

>(

315

data: TData,

316

contentTypeSchema: TSchema,

317

componentSchema: Record<string, Schema.Component>,

318

fields?: string[]

319

): TData;

320

```

321

322

**Usage Examples:**

323

324

```typescript

325

// Calculate object differences

326

const changes = difference(originalData, modifiedData);

327

console.log('Changed fields:', changes);

328

329

// Format data for editing

330

const editableData = formatContentTypeData(

331

rawData,

332

contentTypeSchema,

333

componentSchemas

334

);

335

336

// Clean data before submission

337

const cleanData = contentManagementUtilRemoveFieldsFromData(

338

formData,

339

contentTypeSchema,

340

componentSchemas,

341

['createdAt', 'updatedAt'] // Additional fields to remove

342

);

343

```

344

345

## File & URL Utilities

346

347

Functions for handling file operations and URL manipulation.

348

349

```typescript { .api }

350

// Extract file extension from filename

351

function getFileExtension(filename: string): string;

352

353

// Prefix file URLs with backend URL

354

function prefixFileUrlWithBackendUrl(fileURL: string): string;

355

356

// Prefix plugin translation keys

357

function prefixPluginTranslations(

358

translations: Record<string, string>,

359

pluginId: string

360

): Record<string, string>;

361

```

362

363

**Usage Examples:**

364

365

```typescript

366

// Get file extension

367

const extension = getFileExtension('document.pdf'); // Returns: 'pdf'

368

369

// Build complete file URL

370

const fullUrl = prefixFileUrlWithBackendUrl('/uploads/image.jpg');

371

// Returns: 'http://localhost:1337/uploads/image.jpg'

372

373

// Prefix translation keys

374

const prefixedTranslations = prefixPluginTranslations(

375

{

376

'button.save': 'Save',

377

'button.cancel': 'Cancel'

378

},

379

'my-plugin'

380

);

381

// Returns: { 'my-plugin.button.save': 'Save', 'my-plugin.button.cancel': 'Cancel' }

382

```

383

384

## UI Utilities

385

386

Functions for styling, layout, and user interface operations.

387

388

```typescript { .api }

389

// Convert pixels to rem units

390

function pxToRem(px: number): string;

391

392

// Set opacity on hex color values

393

function setHexOpacity(hex: string, opacity: number): string;

394

395

// Stop event propagation

396

function stopPropagation(event: Event): void;

397

```

398

399

**Usage Examples:**

400

401

```typescript

402

// Convert pixels to rem

403

const remValue = pxToRem(16); // Returns: '1rem'

404

const spacing = pxToRem(24); // Returns: '1.5rem'

405

406

// Adjust color opacity

407

const semiTransparentBlue = setHexOpacity('#0066cc', 0.5); // Returns: '#0066cc80'

408

409

// Stop event propagation

410

const handleClick = (event: React.MouseEvent) => {

411

stopPropagation(event);

412

// Handle click without bubbling

413

};

414

```

415

416

## Content Manager Utilities

417

418

Specialized utilities for content management operations (also documented in Content Manager section).

419

420

```typescript { .api }

421

// Get schema attribute type information

422

function getType(schema: Schema.Schema, attrName: string): string;

423

424

// Get nested attribute information

425

function getOtherInfos(schema: Schema.Schema, path: string[]): any;

426

```

427

428

**Usage Examples:**

429

430

```typescript

431

// Get field type from schema

432

const fieldType = getType(contentTypeSchema, 'title'); // Returns: 'string'

433

434

// Get component information

435

const componentUid = getOtherInfos(schema, ['myComponent', 'component']);

436

const isRepeatable = getOtherInfos(schema, ['myComponent', 'repeatable']);

437

```

438

439

## Utility Integration Patterns

440

441

### Error Handling Pipeline

442

443

```typescript

444

// Create comprehensive error handler

445

const createErrorHandler = () => {

446

return async (operation: () => Promise<any>) => {

447

const [error, result] = await awaitToJs(operation());

448

449

if (error) {

450

const normalized = normalizeAPIError(error);

451

452

if (normalized) {

453

// Handle normalized error

454

console.error(normalized.defaultMessage);

455

}

456

457

throw error;

458

}

459

460

return result;

461

};

462

};

463

464

// Usage

465

const safeApiCall = createErrorHandler();

466

const articles = await safeApiCall(() => client.get('/api/articles'));

467

```

468

469

### Content Processing Pipeline

470

471

```typescript

472

// Create content processing utility

473

const processContentData = (

474

data: any,

475

schema: Schema.ContentType,

476

components: Record<string, Schema.Component>

477

) => {

478

// Format for editing

479

const formatted = formatContentTypeData(data, schema, components);

480

481

// Calculate differences

482

const changes = difference(data, formatted);

483

484

// Clean for submission

485

const cleaned = contentManagementUtilRemoveFieldsFromData(

486

formatted,

487

schema,

488

components

489

);

490

491

return { formatted, changes, cleaned };

492

};

493

```

494

495

### Plugin Utilities Bundle

496

497

```typescript

498

// Create plugin utility bundle

499

const createPluginUtils = (pluginId: string) => {

500

const client = getFetchClient();

501

502

const prefixTranslations = (translations: Record<string, string>) =>

503

prefixPluginTranslations(translations, pluginId);

504

505

const handleError = (error: AxiosError) => {

506

const normalized = normalizeAPIError(error);

507

// Handle error appropriately

508

};

509

510

return {

511

client,

512

prefixTranslations,

513

handleError,

514

pxToRem,

515

setHexOpacity,

516

getFileExtension

517

};

518

};

519

```

520

521

## Performance Considerations

522

523

- **HTTP Client Caching**: `getFetchClient` should be called once per component/module

524

- **Error Processing**: Normalize errors early to avoid repeated processing

525

- **Data Transformation**: Cache processed data when possible

526

- **Permission Checks**: Use `hasPermissions` with abort signals for cancellable requests

527

- **Storage Operations**: Batch storage operations when updating multiple items

528

529

## Migration Notes

530

531

- `request` function is deprecated; use `useFetchClient` hook instead

532

- `auth` utility methods are deprecated; use direct storage access

533

- Many utilities include deprecation warnings for smooth migration to newer APIs