### Local Development Setup for My Module Source: https://github.com/posva/mande/blob/main/nuxt-module/README.md Commands for setting up and developing My Module locally. Includes dependency installation, type stub generation, and running the development server. ```bash # Install dependencies npm install # Generate type stubs npm run dev:prepare # Develop with the playground npm run dev # Build the playground npm run dev:build # Run ESLint npm run lint # Run Vitest npm run test npm run test:watch # Release new version npm run release ``` -------------------------------- ### Install Mande Source: https://github.com/posva/mande/blob/main/README.md Install mande using npm or yarn. ```sh npm install mande yarn add mande ``` -------------------------------- ### Add My Module to Nuxt App Source: https://github.com/posva/mande/blob/main/nuxt-module/README.md Install the module to your Nuxt application using this command. No further setup is required. ```bash npx nuxi module add my-module ``` -------------------------------- ### Perform GET Requests with Mande Source: https://context7.com/posva/mande/llms.txt Send HTTP GET requests using the `get()` method. Supports requests to the base URL, specific paths, or with query parameters. Use TypeScript generics for typed responses. ```typescript import { mande } from 'mande' const users = mande('/api/users') // GET /api/users const allUsers = await users.get() // GET /api/users/123 const user = await users.get(123) // GET /api/users/profile (string path) const profile = await users.get('profile') // GET /api/users?page=2&limit=10 (with query params) const paginatedUsers = await users.get({ query: { page: 2, limit: 10 } }) // GET /api/users/active?status=online const activeUsers = await users.get('active', { query: { status: 'online' } }) // With TypeScript generics for typed responses interface User { id: number name: string email: string } const typedUser = await users.get(123) // typedUser is typed as User ``` -------------------------------- ### Nuxt 2 SSR Integration with nuxtWrap Source: https://context7.com/posva/mande/llms.txt The nuxtWrap function enables SSR-compatible API functions in Nuxt 2, automatically proxying cookies and headers from the server request. Usage examples include fetching user data and creating/updating user profiles. ```typescript // api/users.js import { mande, nuxtWrap } from 'mande' const BASE_URL = process.server ? process.env.NODE_ENV !== 'production' ? 'http://localhost:3000' : 'https://api.example.com' : '' const fetchPolyfill = process.server ? require('node-fetch') : fetch const users = mande(BASE_URL + '/api/users', {}, fetchPolyfill) // Wrap functions to proxy cookies/headers during SSR export const getUserById = nuxtWrap(users, (api, id: string) => { return api.get(id) }) export const createUser = nuxtWrap(users, (api, userData: CreateUserData) => { return api.post(userData) }) export const updateUser = nuxtWrap(users, (api, id: string, data: UpdateUserData) => { return api.put(id, data) }) // Usage in Nuxt pages/components export default { async asyncData() { const user = await getUserById('123') return { user } } } ``` -------------------------------- ### Managing Instance Headers Source: https://context7.com/posva/mande/llms.txt Explains how to dynamically manage headers for a specific Mande instance using `options.headers`. Headers set on the instance apply to all subsequent requests and can be removed by setting them to `null`. ```APIDOC ## Managing Instance Headers The `options.headers` property on a mande instance allows dynamic header management. Headers set on the instance apply to all subsequent requests. Set a header to `null` to remove it. ```typescript import { mande } from 'mande' const api = mande('/api') // Add Authorization header for all requests api.options.headers.Authorization = 'Bearer eyJhbGciOiJIUzI1NiIs...' // Add custom headers api.options.headers['X-Client-Version'] = '1.0.0' api.options.headers['X-Request-Source'] = 'web-app' // All subsequent requests include these headers const data = await api.get('/protected-resource') // Clear a specific header delete api.options.headers.Authorization // Example: Auth token management function setAuthToken(token: string) { api.options.headers.Authorization = `Bearer ${token}` } function clearAuthToken() { delete api.options.headers.Authorization } // React to auth state changes onAuthStateChange((user) => { if (user) { setAuthToken(user.accessToken) } else { clearAuthToken() } }) ``` ``` -------------------------------- ### Create API Layer Source: https://github.com/posva/mande/blob/main/README.md Set up a basic API layer using mande for specific endpoints like users. ```js // api/users import { mande } from 'mande' const users = mande('/api/users', usersApiOptions) export function getUserById(id) { return users.get(id) } export function createUser(userData) { return users.post(userData) } ``` -------------------------------- ### Basic Fetch Request Source: https://github.com/posva/mande/blob/main/README.md Compares a standard fetch request with a more concise mande equivalent for creating a new user. ```js fetch('/api/users', { method: 'POST', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'Dio', password: 'irejectmyhumanityjojo', }), }) .then((response) => { if (response.status >= 200 && response.status < 300) { return response.json() } // reject if the response is not 2xx throw new Error(response.statusText) }) .then((user) => { // ... }) ``` ```js const users = mande('/api/users') users .post({ name: 'Dio', password: 'irejectmyhumanityjojo', }) .then((user) => { // ... }) ``` -------------------------------- ### Set Global Default Options Source: https://github.com/posva/mande/blob/main/README.md Configure default headers for all mande instances globally. ```js import { defaults } from 'mande' defaults.headers.Authorization = 'Bearer token' ``` -------------------------------- ### Global Defaults Source: https://context7.com/posva/mande/llms.txt Details how to configure global defaults for all Mande instances using the `defaults` object. This includes setting default headers, `responseAs` options, and custom `stringify` functions. ```APIDOC ## Global Defaults The `defaults` object sets options applied to ALL mande instances. It includes default headers (`Accept: application/json`), the `responseAs` setting, and the `stringify` function. ```typescript import { mande, defaults } from 'mande' // View current defaults console.log(defaults) // { // responseAs: 'json', // headers: { Accept: 'application/json' }, // stringify: JSON.stringify // } // Add global Authorization to all instances defaults.headers.Authorization = 'Bearer global-token' // Add global query params defaults.query = { apiVersion: '2.0' } // Custom stringify function for all instances defaults.stringify = (data) => { return JSON.stringify(data, null, 0) } // All new mande instances inherit these defaults const api1 = mande('/api/users') const api2 = mande('/api/posts') // Both api1 and api2 will use the global Authorization header // Clean up global defaults delete defaults.query delete defaults.headers.Authorization ``` ``` -------------------------------- ### Create Mande API Client Instance Source: https://context7.com/posva/mande/llms.txt Instantiate a Mande API client bound to a base URL. Configure default headers and query parameters for all requests. Supports fetch polyfills for SSR. ```typescript import { mande } from 'mande' // Create a basic API client const users = mande('/api/users') // Create with custom options const api = mande('https://api.example.com/v1', { headers: { 'X-Custom-Header': 'value' }, query: { apiKey: 'your-api-key' } }) // Create with a fetch polyfill (for Node.js/SSR) const fetchPolyfill = require('node-fetch') const serverApi = mande('https://api.example.com', {}, fetchPolyfill) ``` -------------------------------- ### Manage Instance Headers in Mande Source: https://context7.com/posva/mande/llms.txt Set dynamic headers on a Mande instance using `options.headers`. These headers apply to all subsequent requests. Set a header to `null` or use `delete` to remove it. ```typescript import { mande } from 'mande' const api = mande('/api') // Add Authorization header for all requests api.options.headers.Authorization = 'Bearer eyJhbGciOiJIUzI1NiIs...' // Add custom headers api.options.headers['X-Client-Version'] = '1.0.0' api.options.headers['X-Request-Source'] = 'web-app' // All subsequent requests include these headers const data = await api.get('/protected-resource') // Clear a specific header delete api.options.headers.Authorization // Example: Auth token management function setAuthToken(token: string) { api.options.headers.Authorization = `Bearer ${token}` } function clearAuthToken() { delete api.options.headers.Authorization } // React to auth state changes onAuthStateChange((user) => { if (user) { setAuthToken(user.accessToken) } else { clearAuthToken() } }) ``` -------------------------------- ### Configure Global Defaults for Mande Instances Source: https://context7.com/posva/mande/llms.txt Use the `defaults` object to set options applied to all Mande instances. This includes default headers, `responseAs` settings, and custom `stringify` functions. Changes to `defaults` affect all new instances created after the change. ```typescript import { mande, defaults } from 'mande' // View current defaults console.log(defaults) // { // responseAs: 'json', // headers: { Accept: 'application/json' }, // stringify: JSON.stringify // } // Add global Authorization to all instances defaults.headers.Authorization = 'Bearer global-token' // Add global query params defaults.query = { apiVersion: '2.0' } // Custom stringify function for all instances defaults.stringify = (data) => { return JSON.stringify(data, null, 0) } // All new mande instances inherit these defaults const api1 = mande('/api/users') const api2 = mande('/api/posts') // Both api1 and api2 will use the global Authorization header // Clean up global defaults delete defaults.query delete defaults.headers.Authorization ``` -------------------------------- ### SSR Fetch Polyfill Source: https://github.com/posva/mande/blob/main/README.md Configure Mande for Server-Side Rendering (SSR) by providing a fetch polyfill and using full URLs. ```js export const BASE_URL = process.server ? process.env.NODE_ENV !== 'production' ? 'http://localhost:3000' : 'https://example.com' : // on client, do not add the domain, so urls end up like `/api/something` '' const fetchPolyfill = process.server ? require('node-fetch') : fetch const contents = mande(BASE_URL + '/api', {}, fetchPolyfill) ``` -------------------------------- ### Override and Delete Headers Source: https://github.com/posva/mande/blob/main/README.md Demonstrates how to override default headers for specific requests or delete them by passing null. ```ts const legacy = mande('/api/v1/data', { headers: { // override all requests 'Content-Type': 'application/xml', }, }) // override only this request legacy.post(new FormData(), { headers: { // overrides Accept: 'application/json' only for this request Accept: null, 'Content-Type': null, }, }) ``` -------------------------------- ### Configure Mande Nuxt Module Source: https://context7.com/posva/mande/llms.txt Add the Mande Nuxt module to nuxt.config.js to enable SSR cookie/header proxying. Configure options like callError and proxyHeadersIgnore. ```javascript // nuxt.config.js module.exports = { buildModules: ['mande/nuxt'], // Optional module configuration mande: { // Call ctx.error() on API errors (default: true) callError: true, // Headers to ignore when proxying (default list shown) proxyHeadersIgnore: [ 'accept', 'host', 'cf-ray', 'cf-connecting-ip', 'content-length', 'content-md5', 'content-type', ] } } ``` ```json // tsconfig.json - Add types for TypeScript { "compilerOptions": { "types": ["@types/node", "@nuxt/types", "mande/nuxt"] } } ``` ```javascript // Usage in components with $mande export default { async asyncData({ $mande }) { // $mande automatically handles SSR cookie proxying const user = await $mande(getUserById, '123') return { user } } } ``` -------------------------------- ### Nuxt Configuration for Mande Source: https://github.com/posva/mande/blob/main/README.md Add Mande as a build module in your Nuxt configuration file. ```js // nuxt.config.js module.exports = { buildModules: ['mande/nuxt'], } ``` -------------------------------- ### Add Authorization Tokens Source: https://github.com/posva/mande/blob/main/README.md Dynamically set and clear Authorization headers for API requests. ```js // api/users import { mande } from 'mande' const todos = mande('/api/todos', todosApiOptions) export function setToken(token) { // todos.options will be used for all requests todos.options.headers.Authorization = 'Bearer ' + token } export function clearToken() { delete todos.options.headers.Authorization } export function createTodo(todoData) { return todo.post(todoData) } ``` ```js // In a different file, setting the token whenever the login status changes. This depends on your frontend code, for instance, some libraries like Firebase provide this kind of callback but you could use a watcher on Vue. onAuthChange((user) => { if (user) setToken(user.token) else clearToken() }) ``` -------------------------------- ### TypeScript Configuration for Nuxt Source: https://github.com/posva/mande/blob/main/README.md Include 'mande/nuxt' in your tsconfig.json for proper TypeScript support in Nuxt. ```json { "types": ["@types/node", "@nuxt/types", "mande/nuxt"] } ``` -------------------------------- ### Create Typed API Layer with Mande Source: https://context7.com/posva/mande/llms.txt Organize Mande instances into modules for a clean API abstraction layer. Define interfaces for request/response types and export typed functions for each endpoint. ```typescript // api/users.ts import { mande } from 'mande' interface User { id: number name: string email: string role: 'admin' | 'user' } interface CreateUserDTO { name: string email: string password: string } const users = mande('/api/users') export function setAuthToken(token: string) { users.options.headers.Authorization = `Bearer ${token}` } export function clearAuthToken() { delete users.options.headers.Authorization } export const getUsers = (page = 1, limit = 20) => users.get({ query: { page, limit } }) export const getUserById = (id: number) => users.get(id) export const createUser = (data: CreateUserDTO) => users.post(data) export const updateUser = (id: number, data: Partial) => users.patch(id, data) export const deleteUser = (id: number) => users.delete(id) ``` ```typescript // api/posts.ts import { mande } from 'mande' interface Post { id: number title: string content: string authorId: number } const posts = mande('/api/posts') export const getPosts = () => posts.get() export const getPostById = (id: number) => posts.get(id) export const createPost = (data: Omit) => posts.post(data) ``` ```typescript // Usage import { getUsers, getUserById, setAuthToken } from './api/users' import { getPosts } from './api/posts' setAuthToken(localStorage.getItem('token')) const users = await getUsers(1, 50) const user = await getUserById(123) const posts = await getPosts() ``` -------------------------------- ### Perform POST Requests with Mande Source: https://context7.com/posva/mande/llms.txt Send HTTP POST requests with a JSON body using the `post()` method. Data is automatically serialized. Supports POSTing to specific endpoints and includes options for headers and query parameters. Use TypeScript generics for typed responses. ```typescript import { mande } from 'mande' const users = mande('/api/users') // POST /api/users with JSON body const newUser = await users.post({ name: 'John Doe', email: 'john@example.com', password: 'securepassword123' }) // POST to a specific endpoint: /api/users/register const registeredUser = await users.post('register', { name: 'Jane Doe', email: 'jane@example.com' }) // POST with additional options const userWithOptions = await users.post({ name: 'Bob' }, { headers: { 'X-Request-ID': 'abc123' }, query: { notify: 'true' } }) // With TypeScript generics interface CreateUserResponse { id: number name: string createdAt: string } const created = await users.post({ name: 'Alice' }) ``` -------------------------------- ### DELETE Requests Source: https://context7.com/posva/mande/llms.txt Demonstrates how to perform DELETE requests using the `delete()` method. It can be used to delete the base URL resource, a specific resource by ID, or with custom query parameters. ```APIDOC ## DELETE Requests The `delete()` method sends HTTP DELETE requests. It doesn't typically include a body, but can accept options like query parameters. ```typescript import { mande } from 'mande' const users = mande('/api/users') // DELETE /api/users (delete at base URL) await users.delete() // DELETE /api/users/123 await users.delete(123) // DELETE with options only await users.delete({ query: { permanent: 'true' } }) // DELETE specific path with options await users.delete('inactive', { query: { olderThan: '30days' } }) ``` ``` -------------------------------- ### Perform PUT Requests with Mande Source: https://context7.com/posva/mande/llms.txt Send HTTP PUT requests for full resource updates using the `put()` method. Data is automatically JSON-serialized. Supports updating at the base URL, specific resources by ID, or string paths. ```typescript import { mande } from 'mande' const users = mande('/api/users') // PUT /api/users (update at base URL) const updated = await users.put({ id: 1, name: 'Updated Name', email: 'updated@example.com' }) // PUT /api/users/123 (update specific resource) const updatedUser = await users.put(123, { name: 'John Updated', email: 'john.updated@example.com', role: 'admin' }) // PUT with string path const settings = await users.put('settings', { theme: 'dark', notifications: true }) ``` -------------------------------- ### Request Timeout with AbortSignal Source: https://context7.com/posva/mande/llms.txt Use AbortSignal for request timeouts and cancellation. AbortSignal.timeout() is for simple timeouts, while AbortController provides manual control. Ensure to handle 'TimeoutError' or 'AbortError' in catch blocks. ```typescript import { mande } from 'mande' const api = mande('/api') // Timeout after 5 seconds try { const data = await api.get('/slow-endpoint', { signal: AbortSignal.timeout(5000) }) } catch (error) { if (error.name === 'TimeoutError') { console.log('Request timed out') } } ``` ```typescript // Manual abort control const controller = new AbortController() // Start the request const requestPromise = api.get('/large-download', { signal: controller.signal }) // Cancel after 2 seconds setTimeout(() => controller.abort(), 2000) try { const data = await requestPromise } catch (error) { if (error.name === 'AbortError') { console.log('Request was cancelled') } } ``` ```typescript // Cancel on component unmount (React example) useEffect(() => { const controller = new AbortController() api.get('/data', { signal: controller.signal }) .then(setData) .catch(err => { if (err.name !== 'AbortError') console.error(err) }) return () => controller.abort() }, []) ``` -------------------------------- ### Perform PATCH Requests with Mande Source: https://context7.com/posva/mande/llms.txt Send HTTP PATCH requests for partial resource updates using the `patch()` method. Only fields to be updated need to be included. Supports partial updates at the base URL, specific resources, or with additional options. ```typescript import { mande } from 'mande' const users = mande('/api/users') // PATCH /api/users (partial update at base) const patched = await users.patch({ status: 'active' }) // PATCH /api/users/123 (partial update specific resource) const patchedUser = await users.patch(123, { name: 'New Name Only' }) // PATCH with additional options const result = await users.patch('profile', { bio: 'Updated bio' }, { headers: { 'If-Match': 'etag-value' } } ) ``` -------------------------------- ### Error Handling with MandeError Source: https://context7.com/posva/mande/llms.txt Details how Mande handles errors for non-2xx status codes by throwing a `MandeError`. It includes information on accessing the `response` object and `body`, and using `isMandeError()` for type checking. ```APIDOC ## Error Handling with MandeError Failed requests (non-2xx status codes) throw a `MandeError` with the `response` object and parsed `body`. Use `isMandeError()` to type-check errors. ```typescript import { mande, isMandeError, MandeError } from 'mande' const api = mande('/api') try { const user = await api.get('/users/999') } catch (error) { if (isMandeError(error)) { // error is typed as MandeError console.log('Status:', error.response.status) // e.g., 404 console.log('Status Text:', error.response.statusText) // e.g., "Not Found" console.log('Error Body:', error.body) // e.g., { message: "User not found" } console.log('Error Message:', error.message) // Same as statusText // Handle specific status codes if (error.response.status === 401) { redirectToLogin() } else if (error.response.status === 404) { showNotFoundPage() } else if (error.response.status >= 500) { showServerErrorMessage() } } else { // Network error or other non-HTTP error console.error('Network error:', error) } } // Async/await with typed error handling async function fetchUser(id: number) { try { return await api.get(`/users/${id}`) } catch (error) { if (isMandeError<{ message: string }>(error)) { // error.body is typed as { message: string } throw new Error(error.body.message) } throw error } } ``` ``` -------------------------------- ### Nuxt SSR Wrapper Source: https://github.com/posva/mande/blob/main/README.md Use `nuxtWrap` to ensure proper cookie and header proxying in Nuxt SSR applications. ```js import { mande, nuxtWrap } from 'mande' const fetchPolyfill = process.server ? require('node-fetch') : fetch const users = mande(BASE_URL + '/api/users', {}, fetchPolyfill) export const getUserById = nuxtWrap(users, (api, id: string) => api.get(id)) ``` -------------------------------- ### Response Types Source: https://context7.com/posva/mande/llms.txt Explains the `responseAs` option, which controls how responses are parsed. Available options are `'json'` (default), `'text'`, or `'response'` for the raw Response object. ```APIDOC ## Response Types The `responseAs` option controls how responses are parsed. Options are `'json'` (default), `'text'`, or `'response'` (raw Response object). ```typescript import { mande } from 'mande' const api = mande('/api') // Default: JSON response (automatically parsed) const jsonData = await api.get('/data') // jsonData is the parsed JSON object // Text response const textContent = await api.get('/readme', { responseAs: 'text' }) // textContent is a string // Raw Response object (for fine-grained control) const rawResponse = await api.get('/download', { responseAs: 'response' }) // rawResponse is a native Response object console.log(rawResponse.status) console.log(rawResponse.headers.get('Content-Type')) const blob = await rawResponse.blob() // Check for 204 No Content const deleteResponse = await api.delete('/resource/123', { responseAs: 'response' }) if (deleteResponse.status === 204) { console.log('Resource deleted successfully') } ``` ``` -------------------------------- ### Send HTTP DELETE Requests with Mande Source: https://context7.com/posva/mande/llms.txt Use the `delete()` method to send HTTP DELETE requests. It can accept an ID or options for query parameters. No body is typically sent with DELETE requests. ```typescript import { mande } from 'mande' const users = mande('/api/users') // DELETE /api/users (delete at base URL) await users.delete() // DELETE /api/users/123 await users.delete(123) // DELETE with options only await users.delete({ query: { permanent: 'true' } }) // DELETE specific path with options await users.delete('inactive', { query: { olderThan: '30days' } }) ``` -------------------------------- ### Typed API Responses Source: https://github.com/posva/mande/blob/main/README.md Use TypeScript generics with mande to strongly type API responses. ```ts const todos = mande('/api/todos', globalOptions) todos.get<{ text: string; id: number; isFinished: boolean }[]>().then((todos) => { // todos is correctly typed }) ``` -------------------------------- ### FormData Uploads with Mande Source: https://context7.com/posva/mande/llms.txt Mande automatically handles FormData uploads by omitting the Content-Type header, allowing the browser to set the correct multipart boundary. Supports single files, multiple files, and mixed form data. ```typescript import { mande } from 'mande' const api = mande('/api') // File upload with FormData const formData = new FormData() formData.append('file', fileInput.files[0]) formData.append('name', 'document.pdf') formData.append('description', 'Important document') const uploadResult = await api.post('/upload', formData) // Content-Type is automatically set to multipart/form-data with boundary ``` ```typescript // Multiple files const multiFormData = new FormData() for (const file of fileInput.files) { multiFormData.append('files[]', file) } await api.post('/upload/batch', multiFormData) ``` ```typescript // Mixed form data const profileForm = new FormData() profileForm.append('avatar', avatarFile) profileForm.append('username', 'johndoe') profileForm.append('bio', 'Hello world!') await api.put('/profile', profileForm) ``` -------------------------------- ### Timeout Request with AbortSignal Source: https://github.com/posva/mande/blob/main/README.md Set a timeout for a request using the native AbortSignal.timeout() method. This is supported in modern browsers. ```typescript mande('/api').get('/users', { signal: AbortSignal.timeout(2000) }) ``` -------------------------------- ### Control Response Parsing with `responseAs` Source: https://context7.com/posva/mande/llms.txt The `responseAs` option in Mande controls how responses are parsed. Options include `'json'` (default), `'text'`, or `'response'` for the raw `Response` object. ```typescript import { mande } from 'mande' const api = mande('/api') // Default: JSON response (automatically parsed) const jsonData = await api.get('/data') // jsonData is the parsed JSON object // Text response const textContent = await api.get('/readme', { responseAs: 'text' }) // textContent is a string // Raw Response object (for fine-grained control) const rawResponse = await api.get('/download', { responseAs: 'response' }) // rawResponse is a native Response object console.log(rawResponse.status) console.log(rawResponse.headers.get('Content-Type')) const blob = await rawResponse.blob() // Check for 204 No Content const deleteResponse = await api.delete('/resource/123', { responseAs: 'response' }) if (deleteResponse.status === 204) { console.log('Resource deleted successfully') } ``` -------------------------------- ### Handle Errors with MandeError Source: https://context7.com/posva/mande/llms.txt Failed requests throw a `MandeError` containing the `response` object and parsed `body`. Use `isMandeError()` for type checking. Handle specific status codes or network errors within the catch block. ```typescript import { mande, isMandeError, MandeError } from 'mande' const api = mande('/api') try { const user = await api.get('/users/999') } catch (error) { if (isMandeError(error)) { // error is typed as MandeError console.log('Status:', error.response.status) // e.g., 404 console.log('Status Text:', error.response.statusText) // e.g., "Not Found" console.log('Error Body:', error.body) // e.g., { message: "User not found" } console.log('Error Message:', error.message) // Same as statusText // Handle specific status codes if (error.response.status === 401) { redirectToLogin() } else if (error.response.status === 404) { showNotFoundPage() } else if (error.response.status >= 500) { showServerErrorMessage() } } else { // Network error or other non-HTTP error console.error('Network error:', error) } } // Async/await with typed error handling async function fetchUser(id: number) { try { return await api.get(`/users/${id}`) } catch (error) { if (isMandeError<{ message: string }>(error)) { // error.body is typed as { message: string } throw new Error(error.body.message) } throw error } } ``` -------------------------------- ### Custom Stringify Function for Serialization Source: https://context7.com/posva/mande/llms.txt Override Mande's default JSON.stringify with a custom function for special serialization needs, such as handling Date objects or circular references. This can be set at the instance level. ```typescript import { mande } from 'mande' // Instance-level custom stringify const api = mande('/api', { stringify: (data) => { // Custom date serialization return JSON.stringify(data, (key, value) => { if (value instanceof Date) { return value.toISOString() } return value }) } }) // Post with Date objects - automatically serialized await api.post('/events', { name: 'Meeting', startDate: new Date('2024-03-15T10:00:00'), endDate: new Date('2024-03-15T11:00:00') }) ``` ```typescript // Using a library like superjson for complex types import superjson from 'superjson' const advancedApi = mande('/api', { stringify: superjson.stringify }) await advancedApi.post('/data', { map: new Map([['key', 'value']]), set: new Set([1, 2, 3]), date: new Date() }) ``` -------------------------------- ### Handling FormData in Mande Source: https://github.com/posva/mande/blob/main/README.md When sending FormData, Mande automatically omits the Content-Type header. You can manually set it if necessary, either on the instance or per request. ```typescript const api = mande('/api/', { headers: { 'Content-Type': null } }) api.post(formData, { headers: { 'Content-Type': 'multipart/form-data' }, }) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.