UNPKG

@wristband/react-client-auth

Version:

A lightweight React SDK that pairs with your backend server auth to initialize and sync frontend sessions via secure session cookies.

83 lines (79 loc) 3.3 kB
'use strict'; var index = require('../error/index.js'); var apiClientUtils = require('../utils/api-client-utils.js'); /** * API client for authenticated REST API requests. * * Provides methods for making authenticated HTTP requests to your backend server with built-in CSRF protection and * standardized error handling. * * @namespace apiClient */ const apiClient = { /** * Makes an authenticated GET request to the specified endpoint. * * Automatically handles: * - CSRF token retrieval and inclusion in request headers * - Cookie-based authentication via credentials: 'include' * - JSON parsing of response body * - Error handling for non-2xx responses * * @template T - The expected type of data in the response * * @param {string} url - The endpoint URL to request * @required * @param {RequestOptions} options - Additional request options and configuration. Extends the standard fetch RequestInit options. * @param {string} [options.csrfCookieName='CSRF-TOKEN'] - Name of the cookie containing the CSRF token * @param {string} [options.csrfHeaderName='X-CSRF-TOKEN'] - Name of the header to send the CSRF token in * @returns {Promise<ApiResponse<T>>} A promise that resolves to a standardized API response containing the data, status code, and headers. * @throws {ApiError} When the server responds with a non-2xx status code. Includes status, statusText, and the original Response object. * * @example * // Basic usage * try { * const response = await apiClient.get('/api/users/me'); * console.log(response.data); * } catch (error) { * if (error instanceof ApiError && error.status === 401) { * // Handle unauthorized error * } * } * * @example * // With type safety and custom CSRF configuration * interface UserProfile { * id: string; * name: string; * email: string; * } * * const response = await apiClient.get<UserProfile>('/api/users/me', { * csrfCookieName: 'MY-CSRF-COOKIE', * csrfHeaderName: 'X-MY-CSRF-TOKEN' * }); * * // TypeScript knows response.data has id, name, and email properties * const { id, name, email } = response.data; */ async get(url, options = {}) { const { csrfCookieName = 'CSRF-TOKEN', csrfHeaderName = 'X-CSRF-TOKEN' } = options; const csrfToken = apiClientUtils.getCsrfToken(csrfCookieName); const headers = { 'Content-Type': 'application/json', Accept: 'application/json', ...(csrfToken ? { [csrfHeaderName]: csrfToken } : {}), }; const response = await fetch(url, { method: 'GET', credentials: 'include', headers }); if (response.status < 200 || response.status >= 300) { const error = new index.ApiError(`[HTTP Error] Status: ${response.status}`); error.status = response.status; error.statusText = response.statusText; error.response = response; throw error; } const data = (await response.json()); return { data, status: response.status, headers: response.headers }; }, }; module.exports = apiClient;