/* eslint-disable @typescript-eslint/consistent-type-assertions */ /* eslint-disable @typescript-eslint/no-unnecessary-type-constraint */ /* eslint-disable @typescript-eslint/no-explicit-any */ /** * https://github.com/kiliman/remix-superjson/ */ import { useActionData, useLoaderData } from 'react-router'; import * as _superjson from 'superjson'; export type SuperJsonFunction = ( data: Data, init?: number | ResponseInit, ) => SuperTypedResponse; export declare type SuperTypedResponse = Response & { superjson(): Promise; }; type AppData = any; type DataFunction = (...args: any[]) => unknown; // matches any function type DataOrFunction = AppData | DataFunction; export type UseDataFunctionReturn = T extends ( ...args: any[] ) => infer Output ? Awaited extends SuperTypedResponse ? U : Awaited> : Awaited; export const superLoaderJson: SuperJsonFunction = (data, init = {}) => { const responseInit = typeof init === 'number' ? { status: init } : init; const headers = new Headers(responseInit.headers); if (!headers.has('Content-Type')) { headers.set('Content-Type', 'application/json; charset=utf-8'); } return new Response(_superjson.stringify(data), { ...responseInit, headers, }) as SuperTypedResponse; }; export function useSuperLoaderData(): UseDataFunctionReturn { const data = useLoaderData(); return _superjson.deserialize(data); } export function useSuperActionData(): UseDataFunctionReturn | null { const data = useActionData(); return data ? _superjson.deserialize(data) : null; }