{"version":3,"file":"index.cjs","sources":["../../src/index.ts"],"sourcesContent":["import {\n  encode,\n  isNotFound,\n  isPlainObject,\n  isRedirect,\n  parseRedirect,\n} from '@tanstack/router-core'\nimport { startSerializer } from '@tanstack/start-client-core'\nimport type { FunctionMiddlewareClientFnOptions } from '@tanstack/start-client-core'\n\nexport async function serverFnFetcher(\n  url: string,\n  args: Array<any>,\n  handler: (url: string, requestInit: RequestInit) => Promise<Response>,\n) {\n  const _first = args[0]\n\n  // If createServerFn was used to wrap the fetcher,\n  // We need to handle the arguments differently\n  if (isPlainObject(_first) && _first.method) {\n    const first = _first as FunctionMiddlewareClientFnOptions<\n      any,\n      any,\n      any,\n      any\n    > & {\n      headers: HeadersInit\n    }\n    const type = first.data instanceof FormData ? 'formData' : 'payload'\n\n    // Arrange the headers\n    const headers = new Headers({\n      'x-tsr-redirect': 'manual',\n      ...(type === 'payload'\n        ? {\n            'content-type': 'application/json',\n            accept: 'application/json',\n          }\n        : {}),\n      ...(first.headers instanceof Headers\n        ? Object.fromEntries(first.headers.entries())\n        : first.headers),\n    })\n\n    // If the method is GET, we need to move the payload to the query string\n    if (first.method === 'GET') {\n      // If the method is GET, we need to move the payload to the query string\n      const encodedPayload = encode({\n        payload: startSerializer.stringify({\n          data: first.data,\n          context: first.context,\n        }),\n      })\n\n      if (encodedPayload) {\n        if (url.includes('?')) {\n          url += `&${encodedPayload}`\n        } else {\n          url += `?${encodedPayload}`\n        }\n      }\n    }\n\n    if (url.includes('?')) {\n      url += `&createServerFn`\n    } else {\n      url += `?createServerFn`\n    }\n    if (first.response === 'raw') {\n      url += `&raw`\n    }\n\n    return await getResponse(() =>\n      handler(url, {\n        method: first.method,\n        headers,\n        signal: first.signal,\n        ...getFetcherRequestOptions(first),\n      }),\n    )\n  }\n\n  // If not a custom fetcher, it was probably\n  // a `use server` function, so just proxy the arguments\n  // through as a POST request\n  return await getResponse(() =>\n    handler(url, {\n      method: 'POST',\n      headers: {\n        Accept: 'application/json',\n        'Content-Type': 'application/json',\n      },\n      body: JSON.stringify(args),\n      redirect: 'manual',\n    }),\n  )\n}\n\nfunction getFetcherRequestOptions(\n  opts: FunctionMiddlewareClientFnOptions<any, any, any, any>,\n) {\n  if (opts.method === 'POST') {\n    if (opts.data instanceof FormData) {\n      opts.data.set('__TSR_CONTEXT', startSerializer.stringify(opts.context))\n      return {\n        body: opts.data,\n      }\n    }\n\n    return {\n      body: startSerializer.stringify({\n        data: opts.data ?? null,\n        context: opts.context,\n      }),\n    }\n  }\n\n  return {}\n}\n\n/**\n * Retrieves a response from a given function and manages potential errors\n * and special response types including redirects and not found errors.\n *\n * @param fn - The function to execute for obtaining the response.\n * @returns The processed response from the function.\n * @throws If the response is invalid or an error occurs during processing.\n */\nasync function getResponse(fn: () => Promise<Response>) {\n  const response = await (async () => {\n    try {\n      return await fn()\n    } catch (error) {\n      if (error instanceof Response) {\n        return error\n      }\n\n      throw error\n    }\n  })()\n\n  // If the response is not ok, throw an error\n  if (!response.ok) {\n    const contentType = response.headers.get('content-type')\n    const isJson = contentType && contentType.includes('application/json')\n\n    if (isJson) {\n      // If it's JSON, decode it and throw it\n      throw startSerializer.decode(await response.json())\n    }\n\n    throw new Error(await response.text())\n  }\n\n  // Check if the response is JSON\n  if (response.headers.get('content-type')?.includes('application/json')) {\n    // Even though the response is JSON, we need to decode it\n    // because the server may have transformed it\n    let json = startSerializer.decode(await response.json())\n\n    const redirect = parseRedirect(json)\n\n    if (redirect) json = redirect\n\n    // If the response is a redirect or not found, throw it\n    // for the router to handle\n    if (isRedirect(json) || isNotFound(json) || json instanceof Error) {\n      throw json\n    }\n\n    return json\n  }\n\n  return response\n}\n"],"names":["isPlainObject","encode","startSerializer","parseRedirect","isRedirect","isNotFound"],"mappings":"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"}