@zayne-labs/callapi 1.11.43 → 1.11.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { G as FallBackRouteSchemaKey, K as fallBackRouteSchemaKey, et as RequestContext, lt as fetchSpecificKeys } from "../index-UfuQFNcf.js";
1
+ import { G as FallBackRouteSchemaKey, K as fallBackRouteSchemaKey, et as RequestContext, lt as fetchSpecificKeys } from "../index-DCyPkUNR.js";
2
2
 
3
3
  //#region src/constants/defaults.d.ts
4
4
  declare const extraOptionDefaults: Readonly<Readonly<{
@@ -1 +1 @@
1
- {"version":3,"file":"defaults-D5uiLm4M.js","names":[],"sources":["../src/types/type-helpers.ts","../src/utils/guards.ts","../src/auth.ts","../src/constants/common.ts","../src/constants/validation.ts","../src/utils/external/error.ts","../src/validation.ts","../src/url.ts","../src/utils/common.ts","../src/constants/defaults.ts"],"sourcesContent":["// == These two types allows for adding arbitrary literal types, while still provided autocomplete for defaults.\n\n// == Usually intersection with \"{}\" or \"NonNullable<unknown>\" would make it work fine, but the placeholder with never type is added to make the AnyWhatever type appear last in a given union.\nexport type AnyString = string & NonNullable<unknown>;\nexport type AnyNumber = number & NonNullable<unknown>;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is fine here\nexport type AnyObject = Record<keyof any, any>;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport type AnyFunction<TResult = unknown> = (...args: any[]) => TResult;\n\nexport type Prettify<TObject> = NonNullable<unknown> & { [Key in keyof TObject]: TObject[Key] };\n\ntype WriteableLevel = \"deep\" | \"shallow\";\n\n/**\n * Makes all properties in an object type writeable (removes readonly modifiers).\n * Supports both shallow and deep modes, and handles special cases like arrays, tuples, and unions.\n * @template TObject - The object type to make writeable\n * @template TVariant - The level of writeable transformation (\"shallow\" | \"deep\")\n */\n\ntype ArrayOrObject = Record<number | string | symbol, unknown> | unknown[] | readonly unknown[];\n\nexport type Writeable<TObject, TLevel extends WriteableLevel = \"shallow\"> =\n\tTObject extends ArrayOrObject ?\n\t\t{\n\t\t\t-readonly [Key in keyof TObject]: TLevel extends \"deep\" ?\n\t\t\t\tNonNullable<TObject[Key]> extends ArrayOrObject ?\n\t\t\t\t\tWriteable<TObject[Key], \"deep\">\n\t\t\t\t:\tTObject[Key]\n\t\t\t:\tTObject[Key];\n\t\t}\n\t:\tTObject;\n\nexport const defineEnum = <const TValue extends object>(value: TValue) =>\n\tObject.freeze(value) as Readonly<Writeable<TValue>>;\n\nexport type UnionToIntersection<TUnion> =\n\t(TUnion extends unknown ? (param: TUnion) => void : never) extends (param: infer TParam) => void ?\n\t\tTParam\n\t:\tnever;\n\n// == Using this Immediately Indexed Mapped type helper to help show computed type of anything passed to it instead of just the type name\nexport type UnmaskType<TValue> = { value: TValue }[\"value\"];\n\n/**\n * @description Userland implementation of NoInfer intrinsic type, but this one doesn't show up on hover like the intrinsic one\n *\n * Prevents TypeScript from inferring `TGeneric` at this position by creating a circular dependency.\n * The tuple index `[TGeneric extends unknown ? 0 : never]` depends on `TGeneric`, forcing TS to\n * skip this site for inference and use other arguments or defaults instead.\n */\nexport type NoInferUnMasked<TGeneric> = [TGeneric][TGeneric extends unknown ? 0 : never];\n\ntype RemoveSlashImpl<TUrl extends string, TDirection extends \"leading\" | \"trailing\"> =\n\tTDirection extends \"leading\" ?\n\t\tTUrl extends `/${infer TWithoutLeadingSlash}` ?\n\t\t\tTWithoutLeadingSlash\n\t\t:\tTUrl\n\t: TDirection extends \"trailing\" ?\n\t\tTUrl extends `${infer TWithoutTailingSlash}/` ?\n\t\t\tTWithoutTailingSlash\n\t\t:\tTUrl\n\t:\tnever;\n\nexport type RemoveTrailingSlash<TUrl extends string> = RemoveSlashImpl<TUrl, \"trailing\">;\nexport type RemoveLeadingSlash<TUrl extends string> = RemoveSlashImpl<TUrl, \"leading\">;\n\nexport type Awaitable<TValue> = Promise<TValue> | TValue;\n\n// export type MatchExactObjectType<TActualObject extends TExpectedObject, TExpectedObject> = {\n// \t[Key in keyof TActualObject]: Key extends keyof TExpectedObject ? TActualObject[Key] : never;\n// };\n\nexport type Satisfies<TActualObject extends TExpectedObject, TExpectedObject> = {\n\t[Key in keyof TActualObject]: Key extends keyof TExpectedObject ? TActualObject[Key] : never;\n};\n// export type Satisfies<TActualObject extends TExpectedObject, TExpectedObject> = {\n// \t[Key in keyof TActualObject & keyof TExpectedObject]: TActualObject[Key];\n// };\n\nexport type DistributiveOmit<TObject, TKeysToOmit extends keyof TObject> =\n\tTObject extends unknown ? Omit<TObject, TKeysToOmit> : never;\n\ntype ErrorMessages<TType extends number | string | symbol = never> = Partial<\n\tRecord<\"$all\" | number | symbol | (AnyString | TType), unknown>\n> | null;\n\n/**\n * Type utility that takes two types and allows only the properties of the first type. The properties of the second will be disallowed (typed as `never` by default or a custom message).\n *\n * @template TFirstType The first type. Properties of this type will be required.\n * @template TSecondType The second type. Properties of this type will be disallowed.\n * @template TErrorMessages An object of custom messages to display on the properties of the second type that are disallowed.\n */\ntype AllowOnlyFirst<TFirstType, TSecondType, TErrorMessages extends ErrorMessages = never> = Prettify<\n\tTFirstType & {\n\t\t[Key in keyof Omit<TSecondType, keyof TFirstType>]?: Key extends keyof TErrorMessages ?\n\t\t\tTErrorMessages[Key]\n\t\t: \"$all\" extends keyof TErrorMessages ? TErrorMessages[\"$all\"]\n\t\t: TErrorMessages extends null ? TErrorMessages\n\t\t: never;\n\t}\n>;\n\n/**\n * Merges all types in an array of types into one type.\n *\n * @template TArrayOfTypes Array of types to merge\n * @template TAccumulator Accumulator for the resulting merged type\n */\ntype MergeTypes<TArrayOfTypes extends unknown[], TAccumulator = NonNullable<unknown>> =\n\tTArrayOfTypes extends [infer TFirstType, ...infer TRestOfTypes] ?\n\t\tMergeTypes<\n\t\t\tTRestOfTypes,\n\t\t\t{ [Key in keyof TAccumulator | keyof TFirstType]: (TAccumulator & TFirstType)[Key] }\n\t\t>\n\t:\tTAccumulator;\n\n/**\n * Type utility that extracts discriminated properties from a union of types.\n * Takes an array of types and returns a union of types where each type has unique properties.\n *\n * @template TArrayOfTypes Array of types to process\n * @template TErrorMessages An object of custom messages to display on the properties that are disallowed.\n * @template TAccumulator Accumulator for the resulting union\n * @template TMergedProperties Merged properties from all types\n */\n\nexport type UnionDiscriminator<\n\tTArrayOfTypes extends unknown[],\n\tTErrorMessages extends ErrorMessages<keyof MergeTypes<TArrayOfTypes>> = never,\n\tTAccumulator = never,\n\tTMergedProperties = MergeTypes<TArrayOfTypes>,\n> =\n\tTArrayOfTypes extends [infer TFirstType, ...infer TRestOfTypes] ?\n\t\tUnionDiscriminator<\n\t\t\tTRestOfTypes,\n\t\t\tTErrorMessages,\n\t\t\t// eslint-disable-next-line perfectionist/sort-union-types -- Let TAccumulator be first\n\t\t\tTAccumulator | AllowOnlyFirst<TFirstType, TMergedProperties, TErrorMessages>,\n\t\t\tTMergedProperties\n\t\t>\n\t:\tTAccumulator;\n\nexport type CommonRequestHeaders =\n\t| \"Access-Control-Allow-Credentials\"\n\t| \"Access-Control-Allow-Headers\"\n\t| \"Access-Control-Allow-Methods\"\n\t| \"Access-Control-Allow-Origin\"\n\t| \"Access-Control-Expose-Headers\"\n\t| \"Access-Control-Max-Age\"\n\t| \"Age\"\n\t| \"Allow\"\n\t| \"Cache-Control\"\n\t| \"Clear-Site-Data\"\n\t| \"Content-Disposition\"\n\t| \"Content-Encoding\"\n\t| \"Content-Language\"\n\t| \"Content-Length\"\n\t| \"Content-Location\"\n\t| \"Content-Range\"\n\t| \"Content-Security-Policy-Report-Only\"\n\t| \"Content-Security-Policy\"\n\t| \"Cookie\"\n\t| \"Cross-Origin-Embedder-Policy\"\n\t| \"Cross-Origin-Opener-Policy\"\n\t| \"Cross-Origin-Resource-Policy\"\n\t| \"Date\"\n\t| \"ETag\"\n\t| \"Expires\"\n\t| \"Last-Modified\"\n\t| \"Location\"\n\t| \"Permissions-Policy\"\n\t| \"Pragma\"\n\t| \"Retry-After\"\n\t| \"Save-Data\"\n\t| \"Sec-CH-Prefers-Color-Scheme\"\n\t| \"Sec-CH-Prefers-Reduced-Motion\"\n\t| \"Sec-CH-UA-Arch\"\n\t| \"Sec-CH-UA-Bitness\"\n\t| \"Sec-CH-UA-Form-Factor\"\n\t| \"Sec-CH-UA-Full-Version-List\"\n\t| \"Sec-CH-UA-Full-Version\"\n\t| \"Sec-CH-UA-Mobile\"\n\t| \"Sec-CH-UA-Model\"\n\t| \"Sec-CH-UA-Platform-Version\"\n\t| \"Sec-CH-UA-Platform\"\n\t| \"Sec-CH-UA-WoW64\"\n\t| \"Sec-CH-UA\"\n\t| \"Sec-Fetch-Dest\"\n\t| \"Sec-Fetch-Mode\"\n\t| \"Sec-Fetch-Site\"\n\t| \"Sec-Fetch-User\"\n\t| \"Sec-GPC\"\n\t| \"Server-Timing\"\n\t| \"Server\"\n\t| \"Service-Worker-Navigation-Preload\"\n\t| \"Set-Cookie\"\n\t| \"Strict-Transport-Security\"\n\t| \"Timing-Allow-Origin\"\n\t| \"Trailer\"\n\t| \"Transfer-Encoding\"\n\t| \"Upgrade\"\n\t| \"Vary\"\n\t| \"Warning\"\n\t| \"WWW-Authenticate\"\n\t| \"X-Content-Type-Options\"\n\t| \"X-DNS-Prefetch-Control\"\n\t| \"X-Frame-Options\"\n\t| \"X-Permitted-Cross-Domain-Policies\"\n\t| \"X-Powered-By\"\n\t| \"X-Robots-Tag\"\n\t| \"X-XSS-Protection\"\n\t| AnyString;\n\nexport type CommonAuthorizationHeaders = `${\"Basic\" | \"Bearer\" | \"Token\"} ${string}`;\n\nexport type CommonContentTypes =\n\t| \"application/epub+zip\"\n\t| \"application/gzip\"\n\t| \"application/json\"\n\t| \"application/ld+json\"\n\t| \"application/octet-stream\"\n\t| \"application/ogg\"\n\t| \"application/pdf\"\n\t| \"application/rtf\"\n\t| \"application/vnd.ms-fontobject\"\n\t| \"application/wasm\"\n\t| \"application/xhtml+xml\"\n\t| \"application/xml\"\n\t| \"application/zip\"\n\t| \"audio/aac\"\n\t| \"audio/mpeg\"\n\t| \"audio/ogg\"\n\t| \"audio/opus\"\n\t| \"audio/webm\"\n\t| \"audio/x-midi\"\n\t| \"font/otf\"\n\t| \"font/ttf\"\n\t| \"font/woff\"\n\t| \"font/woff2\"\n\t| \"image/avif\"\n\t| \"image/bmp\"\n\t| \"image/gif\"\n\t| \"image/jpeg\"\n\t| \"image/png\"\n\t| \"image/svg+xml\"\n\t| \"image/tiff\"\n\t| \"image/webp\"\n\t| \"image/x-icon\"\n\t| \"model/gltf-binary\"\n\t| \"model/gltf+json\"\n\t| \"text/calendar\"\n\t| \"text/css\"\n\t| \"text/csv\"\n\t| \"text/html\"\n\t| \"text/javascript\"\n\t| \"text/plain\"\n\t| \"video/3gpp\"\n\t| \"video/3gpp2\"\n\t| \"video/av1\"\n\t| \"video/mp2t\"\n\t| \"video/mp4\"\n\t| \"video/mpeg\"\n\t| \"video/ogg\"\n\t| \"video/webm\"\n\t| \"video/x-msvideo\"\n\t| AnyString;\n","import type { AnyFunction } from \"../types/type-helpers\";\n\nexport const isArray = <TArrayItem>(value: unknown): value is TArrayItem[] => Array.isArray(value);\n\nexport const isBoolean = (value: unknown): value is boolean => typeof value === \"boolean\";\n\nexport const isBlob = (value: unknown): value is Blob => value instanceof Blob;\n\nexport const isObject = <TObject extends object>(value: unknown): value is TObject => {\n\treturn typeof value === \"object\" && value !== null;\n};\n\nconst hasObjectPrototype = (value: unknown) => {\n\treturn Object.prototype.toString.call(value) === \"[object Object]\";\n};\n\n/**\n * @description Copied from TanStack Query's isPlainObject\n * @see https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L321\n */\nexport const isPlainObject = <TPlainObject extends Record<string, unknown>>(\n\tvalue: unknown\n): value is TPlainObject => {\n\tif (!hasObjectPrototype(value)) {\n\t\treturn false;\n\t}\n\n\t// If has no constructor\n\tconst constructor = (value as object | undefined)?.constructor;\n\tif (constructor === undefined) {\n\t\treturn true;\n\t}\n\n\t// If has modified prototype\n\tconst prototype = constructor.prototype as object;\n\tif (!hasObjectPrototype(prototype)) {\n\t\treturn false;\n\t}\n\n\t// If constructor does not have an Object-specific method\n\tif (!Object.hasOwn(prototype, \"isPrototypeOf\")) {\n\t\treturn false;\n\t}\n\n\t// Handles Objects created by Object.create(<arbitrary prototype>)\n\tif (Object.getPrototypeOf(value) !== Object.prototype) {\n\t\treturn false;\n\t}\n\n\t// It's probably a plain object at this point\n\treturn true;\n};\n\nexport const isValidJsonString = (value: unknown): value is string => {\n\tif (!isString(value)) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tJSON.parse(value);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport const isSerializableObject = (value: unknown) => {\n\treturn (\n\t\tisPlainObject(value)\n\t\t|| isArray(value)\n\t\t|| typeof (value as { toJSON: unknown } | undefined)?.toJSON === \"function\"\n\t);\n};\n\nexport const isFunction = <TFunction extends AnyFunction>(value: unknown): value is TFunction =>\n\ttypeof value === \"function\";\n\nexport const isQueryString = (value: unknown): value is string => isString(value) && value.includes(\"=\");\n\nexport const isString = (value: unknown) => typeof value === \"string\";\n\nexport const isPromise = (value: unknown) => value instanceof Promise;\n\nexport const isReadableStream = (value: unknown): value is ReadableStream<unknown> => {\n\treturn value instanceof ReadableStream;\n};\n\n// https://github.com/unjs/ofetch/blob/main/src/utils.ts\nexport const isJSONSerializable = (value: unknown) => {\n\tif (value === undefined) {\n\t\treturn false;\n\t}\n\tconst t = typeof value;\n\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- No time to make this more type-safe\n\tif (t === \"string\" || t === \"number\" || t === \"boolean\" || t === null) {\n\t\treturn true;\n\t}\n\tif (t !== \"object\") {\n\t\treturn false;\n\t}\n\tif (isArray(value)) {\n\t\treturn true;\n\t}\n\tif ((value as Buffer | null)?.buffer) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\tvalue?.constructor.name === \"Object\"\n\t\t|| typeof (value as { toJSON: () => unknown } | null)?.toJSON === \"function\"\n\t);\n};\n","/* eslint-disable perfectionist/sort-object-types -- Avoid Sorting for now */\n\nimport type { CallApiExtraOptions } from \"./types/common\";\nimport type { Awaitable } from \"./types/type-helpers\";\nimport { isFunction, isObject, isPromise } from \"./utils/guards\";\n\ntype PossibleAuthValue = Awaitable<string | null | undefined>;\n\ntype PossibleAuthValueOrGetter = PossibleAuthValue | (() => PossibleAuthValue);\n\n// export type BearerOrTokenAuth =\n// \t| {\n// \t\t\ttype?: \"Bearer\" | undefined;\n// \t\t\tbearer?: PossibleAuthValueOrGetter;\n// \t\t\ttoken?: never;\n// \t }\n// \t| {\n// \t\t\ttype?: \"Token\";\n// \t\t\tbearer?: never;\n// \t\t\ttoken?: PossibleAuthValueOrGetter;\n// \t };\n\nexport type BearerAuth = {\n\ttype: \"Bearer\";\n\tvalue: PossibleAuthValueOrGetter;\n};\n\nexport type TokenAuth = {\n\ttype: \"Token\";\n\tvalue: PossibleAuthValueOrGetter;\n};\n\nexport type BasicAuth = {\n\ttype: \"Basic\";\n\tusername: PossibleAuthValueOrGetter;\n\tpassword: PossibleAuthValueOrGetter;\n};\n\n/**\n * Custom auth\n *\n * @param prefix - prefix of the header\n * @param authValue - value of the header\n *\n * @example\n * ```ts\n * {\n * type: \"Custom\",\n * prefix: \"Token\",\n * authValue: \"token\"\n * }\n * ```\n */\nexport type CustomAuth = {\n\ttype: \"Custom\";\n\tprefix: PossibleAuthValueOrGetter;\n\tvalue: PossibleAuthValueOrGetter;\n};\n\n// eslint-disable-next-line perfectionist/sort-union-types -- Let the first one be first\nexport type AuthOption = PossibleAuthValueOrGetter | BearerAuth | TokenAuth | BasicAuth | CustomAuth;\n\nconst resolveAuthValue = (value: PossibleAuthValueOrGetter) => (isFunction(value) ? value() : value);\n\ntype AuthHeaderObject = { Authorization: string };\n\nexport const getAuthHeader = async (\n\tauth: CallApiExtraOptions[\"auth\"]\n): Promise<AuthHeaderObject | undefined> => {\n\tif (auth === undefined) return;\n\n\tif (isPromise(auth) || isFunction(auth) || !isObject(auth)) {\n\t\tconst authValue = await resolveAuthValue(auth);\n\n\t\tif (authValue === undefined) return;\n\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${authValue}`,\n\t\t};\n\t}\n\n\tswitch (auth.type) {\n\t\tcase \"Basic\": {\n\t\t\tconst [username, password] = await Promise.all([\n\t\t\t\tresolveAuthValue(auth.username),\n\t\t\t\tresolveAuthValue(auth.password),\n\t\t\t]);\n\n\t\t\tif (username === undefined || password === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `Basic ${globalThis.btoa(`${username}:${password}`)}`,\n\t\t\t};\n\t\t}\n\t\tcase \"Bearer\": {\n\t\t\tconst value = await resolveAuthValue(auth.value);\n\n\t\t\tif (value === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `Bearer ${value}`,\n\t\t\t};\n\t\t}\n\t\tcase \"Custom\": {\n\t\t\tconst [prefix, value] = await Promise.all([\n\t\t\t\tresolveAuthValue(auth.prefix),\n\t\t\t\tresolveAuthValue(auth.value),\n\t\t\t]);\n\n\t\t\tif (value === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `${prefix} ${value}`,\n\t\t\t};\n\t\t}\n\n\t\tcase \"Token\": {\n\t\t\tconst value = await resolveAuthValue(auth.value);\n\n\t\t\tif (value === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `Token ${value}`,\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\tauth satisfies never;\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// default: {\n\t\t// \tconst [bearer, token] = await Promise.all([\n\t\t// \t\tresolveAuthValue(auth.bearer),\n\t\t// \t\tresolveAuthValue(auth.token),\n\t\t// \t]);\n\n\t\t// \tif (bearer !== undefined) {\n\t\t// \t\treturn { Authorization: `Bearer ${bearer}` };\n\t\t// \t}\n\n\t\t// \tif (token === undefined) return;\n\n\t\t// \treturn { Authorization: `Token ${token}` };\n\t\t// }\n\t}\n};\n","import type { ModifiedRequestInit } from \"../types/common\";\nimport { defineEnum } from \"../types/type-helpers\";\n\nexport const fetchSpecificKeys = defineEnum([\n\t\"body\",\n\t\"integrity\",\n\t\"duplex\",\n\t\"method\",\n\t\"headers\",\n\t\"signal\",\n\t\"cache\",\n\t\"redirect\",\n\t\"window\",\n\t\"credentials\",\n\t\"keepalive\",\n\t\"referrer\",\n\t\"priority\",\n\t\"mode\",\n\t\"referrerPolicy\",\n] satisfies Array<keyof ModifiedRequestInit> as Array<keyof ModifiedRequestInit>);\n","export const fallBackRouteSchemaKey = \"@default\";\n\nexport type FallBackRouteSchemaKey = typeof fallBackRouteSchemaKey;\n","import { extraOptionDefaults } from \"../../constants/defaults\";\nimport type { CallApiExtraOptions } from \"../../types/common\";\nimport type { StandardSchemaV1 } from \"../../types/standard-schema\";\nimport type { CallApiSchema, CallApiSchemaConfig } from \"../../validation\";\nimport { isObject, isString } from \"../guards\";\n\ntype HTTPErrorDetails<TErrorData> = Pick<CallApiExtraOptions, \"defaultHTTPErrorMessage\"> & {\n\terrorData: TErrorData;\n\tresponse: Response;\n};\n\nconst httpErrorSymbol = Symbol(\"HTTPError\");\n\nexport class HTTPError<TErrorData = Record<string, unknown>> extends Error {\n\terrorData: HTTPErrorDetails<TErrorData>[\"errorData\"];\n\n\treadonly httpErrorSymbol = httpErrorSymbol;\n\n\toverride name = \"HTTPError\" as const;\n\n\tresponse: HTTPErrorDetails<TErrorData>[\"response\"];\n\n\tconstructor(errorDetails: HTTPErrorDetails<TErrorData>, errorOptions?: ErrorOptions) {\n\t\tconst { defaultHTTPErrorMessage, errorData, response } = errorDetails;\n\n\t\tconst resolvedDefaultHTTPErrorMessage =\n\t\t\tisString(defaultHTTPErrorMessage) ? defaultHTTPErrorMessage : (\n\t\t\t\tdefaultHTTPErrorMessage?.({ errorData, response })\n\t\t\t);\n\n\t\tconst selectedDefaultErrorMessage =\n\t\t\tresolvedDefaultHTTPErrorMessage\n\t\t\t?? (response.statusText || extraOptionDefaults.defaultHTTPErrorMessage);\n\n\t\tconst message =\n\t\t\t(errorData as { message?: string } | undefined)?.message ?? selectedDefaultErrorMessage;\n\n\t\tsuper(message, errorOptions);\n\n\t\tthis.errorData = errorData;\n\t\tthis.response = response;\n\t}\n\n\t/**\n\t * @description Checks if the given error is an instance of HTTPError\n\t * @param error - The error to check\n\t * @returns true if the error is an instance of HTTPError, false otherwise\n\t */\n\tstatic override isError<TErrorData>(error: unknown): error is HTTPError<TErrorData> {\n\t\tif (!isObject<HTTPError>(error)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (error instanceof HTTPError) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst actualError = error as HTTPError;\n\n\t\treturn (\n\t\t\tactualError.httpErrorSymbol === httpErrorSymbol\n\t\t\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- Allow\n\t\t\t&& actualError.name === \"HTTPError\"\n\t\t);\n\t}\n}\n\nconst prettifyPath = (path: ValidationError[\"errorData\"][number][\"path\"]) => {\n\tif (!path || path.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst pathString = path.map((segment) => (isObject(segment) ? segment.key : segment)).join(\".\");\n\n\treturn ` → at ${pathString}`;\n};\n\nconst prettifyValidationIssues = (issues: ValidationError[\"errorData\"]) => {\n\tconst issuesString = issues.map((issue) => `✖ ${issue.message}${prettifyPath(issue.path)}`).join(\" | \");\n\n\treturn issuesString;\n};\n\ntype SafeExtract<TUnion, TKey extends TUnion> = Extract<TUnion, TKey>;\n\ntype ValidationErrorDetails = {\n\t/**\n\t * The cause of the validation error.\n\t *\n\t * It's either the name the schema for which validation failed, or the name of the schema config option that led to the validation error.\n\t */\n\tissueCause:\n\t\t| \"toFormData\"\n\t\t| \"toQueryString\"\n\t\t| \"unknown\"\n\t\t| `schemaConfig-(${SafeExtract<keyof CallApiSchemaConfig, \"strict\">})`\n\t\t| keyof CallApiSchema;\n\n\t/**\n\t * The issues that caused the validation error.\n\t */\n\tissues: readonly StandardSchemaV1.Issue[];\n\n\t/**\n\t * The response from server, if any.\n\t */\n\tresponse: Response | null;\n};\n\nconst validationErrorSymbol = Symbol(\"ValidationErrorSymbol\");\n\nexport class ValidationError extends Error {\n\terrorData: ValidationErrorDetails[\"issues\"];\n\n\tissueCause: ValidationErrorDetails[\"issueCause\"];\n\n\toverride name = \"ValidationError\" as const;\n\n\tresponse: ValidationErrorDetails[\"response\"];\n\n\treadonly validationErrorSymbol = validationErrorSymbol;\n\n\tconstructor(details: ValidationErrorDetails, errorOptions?: ErrorOptions) {\n\t\tconst { issueCause, issues, response } = details;\n\n\t\tconst prettyMessage = prettifyValidationIssues(issues);\n\n\t\tconst message = `(${issueCause.toUpperCase()}) - ${prettyMessage}`;\n\n\t\tsuper(message, errorOptions);\n\n\t\tthis.errorData = issues;\n\t\tthis.response = response;\n\t\tthis.issueCause = issueCause;\n\t}\n\n\t/**\n\t * @description Checks if the given error is an instance of ValidationError\n\t * @param error - The error to check\n\t * @returns true if the error is an instance of ValidationError, false otherwise\n\t */\n\tstatic override isError(error: unknown): error is ValidationError {\n\t\tif (!isObject<ValidationError>(error)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (error instanceof ValidationError) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst actualError = error as ValidationError;\n\n\t\treturn (\n\t\t\tactualError.validationErrorSymbol === validationErrorSymbol\n\t\t\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- Allow\n\t\t\t&& actualError.name === \"ValidationError\"\n\t\t);\n\t}\n}\n","import type { AuthOption } from \"./auth\";\nimport { fallBackRouteSchemaKey, type FallBackRouteSchemaKey } from \"./constants/validation\";\nimport type {\n\tBaseCallApiExtraOptions,\n\tCallApiExtraOptions,\n\tCallApiRequestOptions,\n\tGlobalMeta,\n} from \"./types/common\";\nimport type { Body, HeadersOption, MethodUnion } from \"./types/conditional-types\";\nimport type { StandardSchemaV1 } from \"./types/standard-schema\";\nimport {\n\tdefineEnum,\n\ttype AnyFunction,\n\ttype AnyString,\n\ttype Awaitable,\n\ttype UnionDiscriminator,\n\ttype UnionToIntersection,\n} from \"./types/type-helpers\";\nimport {\n\tatSymbol,\n\textractMethodFromURL,\n\tnormalizeURL,\n\ttype AtSymbol,\n\ttype Params,\n\ttype Query,\n} from \"./url\";\nimport { toArray } from \"./utils/common\";\nimport { ValidationError } from \"./utils/external/error\";\nimport { isFunction, isObject } from \"./utils/guards\";\n\ntype ResultVariant = \"infer-input\" | \"infer-output\";\n\nexport type InferSchemaResult<TSchema, TFallbackResult, TResultVariant extends ResultVariant> =\n\t// == Checking for undefined first and returning fallback to avoid type errors when passing the config around (weird tbh)\n\tundefined extends TSchema ? TFallbackResult\n\t: TSchema extends StandardSchemaV1 ?\n\t\tTResultVariant extends \"infer-input\" ?\n\t\t\tStandardSchemaV1.InferInput<TSchema>\n\t\t:\tStandardSchemaV1.InferOutput<TSchema>\n\t: TSchema extends AnyFunction<infer TResult> ? Awaited<TResult>\n\t: TFallbackResult;\n\nexport type InferSchemaOutput<TSchema, TFallbackResult = unknown> = InferSchemaResult<\n\tTSchema,\n\tTFallbackResult,\n\t\"infer-output\"\n>;\n\nexport type InferSchemaInput<TSchema, TFallbackResult = unknown> = InferSchemaResult<\n\tTSchema,\n\tTFallbackResult,\n\t\"infer-input\"\n>;\n\nconst handleValidatorFunction = <TInput>(\n\tvalidator: AnyFunction,\n\tinputData: TInput\n): Promise<StandardSchemaV1.Result<TInput>> => {\n\tconst result = new Promise((resolve) => resolve(validator(inputData as never)))\n\t\t.then((value) => ({ issues: undefined, value: value as never }))\n\t\t.catch((error) => ({ issues: toArray(error) as never, value: undefined }));\n\n\treturn result;\n};\n\nexport const getValidatedValue = <\n\tTSchema extends AnyFunction | StandardSchemaV1,\n\tTVariant extends \"async\" | \"sync\",\n>(\n\tinputValue: InferSchemaOutput<TSchema>,\n\tschema?: TSchema,\n\t_ignoredOptions?: { variant: TVariant }\n): TVariant extends \"async\" ? Promise<StandardSchemaV1.Result<typeof inputValue>>\n:\tStandardSchemaV1.Result<typeof inputValue> => {\n\tif (!schema) {\n\t\treturn { issues: undefined, value: inputValue } as never;\n\t}\n\n\tconst result =\n\t\tisFunction(schema) ?\n\t\t\thandleValidatorFunction(schema, inputValue)\n\t\t:\tschema[\"~standard\"].validate(inputValue);\n\n\treturn result as never;\n};\n\nconst callApiSchemaParser = async <\n\tTFullSchema extends CallApiSchema,\n\tTSchemaName extends keyof CallApiSchema,\n\tTSchema extends NonNullable<TFullSchema[TSchemaName]>,\n>(\n\tfullSchema: TFullSchema | undefined,\n\tschemaName: TSchemaName,\n\toptions: { inputValue: InferSchemaInput<TSchema>; response?: Response | null }\n): Promise<InferSchemaOutput<TSchema>> => {\n\tconst { inputValue, response } = options;\n\n\tconst schema = fullSchema?.[schemaName];\n\n\tconst result = await getValidatedValue(inputValue, schema);\n\n\tif (result.issues) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: schemaName,\n\t\t\tissues: result.issues,\n\t\t\tresponse: response ?? null,\n\t\t});\n\t}\n\n\treturn result.value as never;\n};\n\ntype BooleanObject = {\n\t[Key in keyof CallApiSchema]: boolean;\n};\n\nexport interface CallApiSchemaConfig {\n\t/**\n\t * The base url of the schema. By default it's the baseURL of the callApi instance.\n\t */\n\tbaseURL?: \"\" | AnyString;\n\n\t/**\n\t * Disables runtime validation for the schema.\n\t */\n\tdisableRuntimeValidation?: boolean | BooleanObject;\n\n\t/**\n\t * If `true`, the original input value will be used instead of the transformed/validated output.\n\t *\n\t * When true, the original input is returned unchanged after validation, ignoring any schema-level\n\t * transformations such as type coercion, default values, or field mapping. Only the validation\n\t * step is executed; the resulting value is discarded in favor of the raw input.\n\t */\n\tdisableRuntimeValidationTransform?: boolean | BooleanObject;\n\n\t/**\n\t * Optional url prefix that will be substituted for the `baseURL` of the schemaConfig at runtime.\n\t *\n\t * Enables a short, stable prefix for routes while keeping the full `baseURL` centralized in config.\n\t * Keeps route definitions concise and shields them from changes to the underlying base URL.\n\t */\n\tprefix?: \"\" | AnyString;\n\n\t/**\n\t * Controls the strictness of API route validation.\n\t *\n\t * When true:\n\t * - Only routes explicitly defined in the schema will be considered valid to typescript and the runtime.\n\t * - Attempting to call routes not defined in the schema will result in both type errors and runtime validation errors.\n\t * - Useful for ensuring API calls conform exactly to your schema definition\n\t *\n\t * When false or undefined (default):\n\t * - All routes will be allowed, whether they are defined in the schema or not\n\t */\n\tstrict?: boolean;\n}\n\nexport type CallApiSchemaType<TInput> =\n\t| StandardSchemaV1<TInput | undefined>\n\t| ((value: TInput) => Awaitable<TInput | undefined>);\n\nexport interface CallApiSchema {\n\tauth?: CallApiSchemaType<AuthOption>;\n\n\t/**\n\t * The schema to use for validating the request body.\n\t */\n\tbody?: CallApiSchemaType<Body>;\n\n\t/**\n\t * The schema to use for validating the response data.\n\t */\n\tdata?: CallApiSchemaType<unknown>;\n\n\t/**\n\t * The schema to use for validating the response error data.\n\t */\n\terrorData?: CallApiSchemaType<unknown>;\n\n\t/**\n\t * The schema to use for validating the request headers.\n\t */\n\theaders?: CallApiSchemaType<HeadersOption>;\n\n\t/**\n\t * The schema to use for validating the meta option.\n\t */\n\tmeta?: CallApiSchemaType<GlobalMeta>;\n\n\t/**\n\t * The schema to use for validating the request method.\n\t */\n\tmethod?: CallApiSchemaType<MethodUnion>;\n\n\t/**\n\t * The schema to use for validating the request url parameters.\n\t */\n\tparams?: CallApiSchemaType<Params>;\n\n\t/**\n\t * The schema to use for validating the request url queries.\n\t */\n\tquery?: CallApiSchemaType<Query>;\n}\n\nexport const routeKeyMethods = defineEnum([\"delete\", \"get\", \"patch\", \"post\", \"put\"]);\n\nexport type RouteKeyMethods = (typeof routeKeyMethods)[number];\n\nexport type RouteKeyMethodsURLUnion = `${AtSymbol}${RouteKeyMethods}/`;\n\nexport type BaseSchemaRouteKeyPrefixes = FallBackRouteSchemaKey | RouteKeyMethodsURLUnion;\n\nexport type BaseCallApiSchemaRoutes = Partial<\n\tRecord<AnyString | BaseSchemaRouteKeyPrefixes, CallApiSchema>\n>;\n\nexport type BaseCallApiSchemaAndConfig = {\n\tconfig?: CallApiSchemaConfig;\n\troutes: BaseCallApiSchemaRoutes;\n};\n\ntype ValidationOptions<\n\tTSchema extends CallApiSchema[keyof CallApiSchema] = CallApiSchema[keyof CallApiSchema],\n> = {\n\tinputValue: InferSchemaInput<TSchema>;\n\tresponse?: Response | null;\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n\tschemaConfig: CallApiSchemaConfig | undefined;\n};\n\nexport const handleSchemaValidation = async <\n\tTFullSchema extends CallApiSchema,\n\tTSchemaName extends keyof CallApiSchema,\n\tTSchema extends NonNullable<TFullSchema[TSchemaName]>,\n>(\n\tfullSchema: TFullSchema | undefined,\n\tschemaName: TSchemaName,\n\tvalidationOptions: ValidationOptions<TSchema>\n): Promise<InferSchemaOutput<TSchema>> => {\n\tconst { inputValue, response, resultMode, schemaConfig } = validationOptions;\n\n\t// == If resultMode is set to `fetchApi`, return the input value as is (which is going to be `null` in this)\n\tif (resultMode === \"fetchApi\" && (schemaName === \"data\" || schemaName === \"errorData\")) {\n\t\treturn inputValue as never;\n\t}\n\n\tconst disableRuntimeValidationBooleanObject =\n\t\tisObject(schemaConfig?.disableRuntimeValidation) ? schemaConfig.disableRuntimeValidation : {};\n\n\tconst shouldDisableRuntimeValidation =\n\t\tschemaConfig?.disableRuntimeValidation === true\n\t\t|| disableRuntimeValidationBooleanObject[schemaName] === true;\n\n\tif (shouldDisableRuntimeValidation) {\n\t\treturn inputValue as never;\n\t}\n\n\tconst validResult = await callApiSchemaParser(fullSchema, schemaName, { inputValue, response });\n\n\tconst disableResultApplicationBooleanObject =\n\t\tisObject(schemaConfig?.disableRuntimeValidationTransform) ?\n\t\t\tschemaConfig.disableRuntimeValidationTransform\n\t\t:\t{};\n\n\tconst shouldDisableResultApplication =\n\t\tschemaConfig?.disableRuntimeValidationTransform === true\n\t\t|| disableResultApplicationBooleanObject[schemaName] === true;\n\n\tif (shouldDisableResultApplication) {\n\t\treturn inputValue as never;\n\t}\n\n\treturn validResult as never;\n};\n\ntype LastOf<TValue> =\n\tUnionToIntersection<TValue extends unknown ? () => TValue : never> extends () => infer R ? R : never;\n\ntype Push<TArray extends unknown[], TArrayItem> = [...TArray, TArrayItem];\n\ntype UnionToTuple<\n\tTUnion,\n\tTComputedLastUnion = LastOf<TUnion>,\n\tTComputedIsUnionEqualToNever = [TUnion] extends [never] ? true : false,\n> =\n\ttrue extends TComputedIsUnionEqualToNever ? []\n\t:\tPush<UnionToTuple<Exclude<TUnion, TComputedLastUnion>>, TComputedLastUnion>;\n\nexport type Tuple<TTuple, TArray extends TTuple[] = []> =\n\tUnionToTuple<TTuple>[\"length\"] extends TArray[\"length\"] ? [...TArray]\n\t:\tTuple<TTuple, [TTuple, ...TArray]>;\n\ntype ExtraOptionsValidationOptions = {\n\toptions: CallApiExtraOptions;\n};\n\nconst extraOptionsToBeValidated = [\"meta\", \"params\", \"query\", \"auth\"] satisfies Tuple<\n\tExtract<keyof CallApiSchema, keyof CallApiExtraOptions>\n>;\n\ntype RequestOptionsValidationOptions = {\n\trequest: CallApiRequestOptions;\n};\n\nconst requestOptionsToBeValidated = [\"body\", \"headers\", \"method\"] satisfies Tuple<\n\tExtract<keyof CallApiSchema, keyof CallApiRequestOptions>\n>;\n\ntype OptionValidationOptions = UnionDiscriminator<\n\t[ExtraOptionsValidationOptions, RequestOptionsValidationOptions]\n> & {\n\tschema: CallApiSchema | undefined;\n\tschemaConfig: CallApiSchemaConfig | undefined;\n};\n\nconst handleOptionsValidation = async <TValidationOptions extends OptionValidationOptions>(\n\tvalidationOptions: TValidationOptions\n): Promise<\n\tundefined extends TValidationOptions[\"options\"] ?\n\t\tPick<CallApiRequestOptions, (typeof requestOptionsToBeValidated)[number]>\n\t:\tPick<CallApiExtraOptions, (typeof extraOptionsToBeValidated)[number]>\n> => {\n\tconst { options, request, schema, schemaConfig } = validationOptions;\n\n\tconst resolvedOptionsToBeValidated = options ? extraOptionsToBeValidated : requestOptionsToBeValidated;\n\n\tconst resolvedOptions = options ?? request;\n\n\tconst validationResultArray = await Promise.all(\n\t\tresolvedOptionsToBeValidated.map((schemaName) =>\n\t\t\thandleSchemaValidation(schema, schemaName, {\n\t\t\t\tinputValue: resolvedOptions[schemaName as keyof typeof resolvedOptions],\n\t\t\t\tresultMode: options?.resultMode,\n\t\t\t\tschemaConfig,\n\t\t\t})\n\t\t)\n\t);\n\n\tconst validatedResultObject: Record<string, unknown> = {};\n\n\tfor (const [index, schemaName] of resolvedOptionsToBeValidated.entries()) {\n\t\tconst validationResult = validationResultArray[index];\n\n\t\tif (validationResult === undefined) continue;\n\n\t\tvalidatedResultObject[schemaName] = validationResult;\n\t}\n\n\treturn validatedResultObject;\n};\n\nexport const handleConfigValidation = async (\n\tvalidationOptions: ExtraOptionsValidationOptions\n\t\t& GetResolvedSchemaContext\n\t\t& RequestOptionsValidationOptions\n) => {\n\tconst { baseExtraOptions, currentRouteSchemaKey, extraOptions, options, request } = validationOptions;\n\n\tconst { currentRouteSchema, resolvedSchema } = getResolvedSchema({\n\t\tbaseExtraOptions,\n\t\tcurrentRouteSchemaKey,\n\t\textraOptions,\n\t});\n\n\tconst resolvedSchemaConfig = getResolvedSchemaConfig({ baseExtraOptions, extraOptions });\n\n\tif (resolvedSchemaConfig?.strict === true && !currentRouteSchema) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: \"schemaConfig-(strict)\",\n\t\t\tissues: [{ message: `Strict Mode - No schema found for route '${currentRouteSchemaKey}' ` }],\n\t\t\tresponse: null,\n\t\t});\n\t}\n\n\tconst [extraOptionsValidationResult, requestOptionsValidationResult] = await Promise.all([\n\t\thandleOptionsValidation({\n\t\t\toptions,\n\t\t\tschema: resolvedSchema,\n\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t}),\n\t\thandleOptionsValidation({\n\t\t\trequest,\n\t\t\tschema: resolvedSchema,\n\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t}),\n\t]);\n\n\treturn {\n\t\textraOptionsValidationResult,\n\t\trequestOptionsValidationResult,\n\t\tresolvedSchema,\n\t\tresolvedSchemaConfig,\n\t};\n};\n\ntype GetResolvedSchemaContext = {\n\tbaseExtraOptions: BaseCallApiExtraOptions;\n\tcurrentRouteSchemaKey: string;\n\textraOptions: CallApiExtraOptions;\n};\n\nexport const getResolvedSchema = (context: GetResolvedSchemaContext) => {\n\tconst { baseExtraOptions, currentRouteSchemaKey, extraOptions } = context;\n\n\tconst fallbackRouteSchema = baseExtraOptions.schema?.routes[fallBackRouteSchemaKey];\n\tconst currentRouteSchema = baseExtraOptions.schema?.routes[currentRouteSchemaKey];\n\n\tconst resolvedRouteSchema = {\n\t\t...fallbackRouteSchema,\n\t\t// == Current route schema takes precedence over fallback route schema\n\t\t...currentRouteSchema,\n\t} satisfies CallApiSchema as CallApiSchema | undefined;\n\n\tconst resolvedSchema =\n\t\tisFunction(extraOptions.schema) ?\n\t\t\textraOptions.schema({\n\t\t\t\tbaseSchemaRoutes: baseExtraOptions.schema?.routes ?? {},\n\t\t\t\tcurrentRouteSchema: resolvedRouteSchema ?? {},\n\t\t\t\tcurrentRouteSchemaKey,\n\t\t\t})\n\t\t:\t(extraOptions.schema ?? resolvedRouteSchema);\n\n\treturn { currentRouteSchema, resolvedSchema };\n};\n\nexport const getResolvedSchemaConfig = (\n\tcontext: Omit<GetResolvedSchemaContext, \"currentRouteSchemaKey\">\n) => {\n\tconst { baseExtraOptions, extraOptions } = context;\n\n\tconst resolvedSchemaConfig =\n\t\tisFunction(extraOptions.schemaConfig) ?\n\t\t\textraOptions.schemaConfig({ baseSchemaConfig: baseExtraOptions.schema?.config ?? {} })\n\t\t:\t(extraOptions.schemaConfig ?? baseExtraOptions.schema?.config);\n\n\treturn resolvedSchemaConfig;\n};\n\nconst removeLeadingSlash = (value: string) => (value.startsWith(\"/\") ? value.slice(1) : value);\n\nconst extractURLParts = (initURL: string) => {\n\treturn {\n\t\tmethodFromURL: extractMethodFromURL(initURL),\n\t\tpathWithoutMethod: normalizeURL(initURL, { retainLeadingSlashForRelativeURLs: false }),\n\t};\n};\n\nconst mergeURLParts = (options: { method: string | undefined; path: string }): string => {\n\tconst { method, path } = options;\n\n\treturn method ? `${atSymbol}${method}/${removeLeadingSlash(path)}` : path;\n};\n\nexport const getCurrentRouteSchemaKeyAndMainInitURL = (\n\tcontext: Pick<GetResolvedSchemaContext, \"baseExtraOptions\" | \"extraOptions\"> & { initURL: string }\n) => {\n\tconst { baseExtraOptions, extraOptions, initURL } = context;\n\n\tconst schemaConfig = getResolvedSchemaConfig({ baseExtraOptions, extraOptions });\n\n\tlet currentRouteSchemaKey = initURL;\n\tlet mainInitURL = initURL;\n\n\tconst { methodFromURL, pathWithoutMethod } = extractURLParts(initURL);\n\n\tconst prefixWithoutLeadingSlash = schemaConfig?.prefix && removeLeadingSlash(schemaConfig.prefix);\n\n\tif (prefixWithoutLeadingSlash && pathWithoutMethod.startsWith(prefixWithoutLeadingSlash)) {\n\t\tconst restOfPathWithoutPrefix = pathWithoutMethod.slice(prefixWithoutLeadingSlash.length);\n\n\t\tcurrentRouteSchemaKey = mergeURLParts({ method: methodFromURL, path: restOfPathWithoutPrefix });\n\n\t\tconst pathWithReplacedPrefix = pathWithoutMethod.replace(\n\t\t\tprefixWithoutLeadingSlash,\n\t\t\tschemaConfig.baseURL ?? \"\"\n\t\t);\n\n\t\tmainInitURL = mergeURLParts({ method: methodFromURL, path: pathWithReplacedPrefix });\n\t}\n\n\tif (schemaConfig?.baseURL && pathWithoutMethod.startsWith(schemaConfig.baseURL)) {\n\t\tconst restOfPathWithoutBaseURL = pathWithoutMethod.slice(schemaConfig.baseURL.length);\n\n\t\tcurrentRouteSchemaKey = mergeURLParts({ method: methodFromURL, path: restOfPathWithoutBaseURL });\n\t}\n\n\treturn { currentRouteSchemaKey, mainInitURL };\n};\n","import type { CallApiExtraOptions } from \"./types/common\";\nimport type { AnyString, UnmaskType } from \"./types/type-helpers\";\nimport { isArray } from \"./utils/guards\";\nimport { routeKeyMethods, type RouteKeyMethodsURLUnion } from \"./validation\";\n\nexport const slash = \"/\";\nconst colon = \":\";\nconst openBrace = \"{\";\nconst closeBrace = \"}\";\n\nconst handleArrayParams = (url: string, params: Extract<CallApiExtraOptions[\"params\"], unknown[]>) => {\n\tlet newUrl = url;\n\n\tconst urlParts = newUrl.split(slash);\n\n\t// == Find all parameters in order (both :param and {param} patterns)\n\tconst matchedParamsArray: string[] = [];\n\n\tfor (const part of urlParts) {\n\t\tconst isMatch = part.startsWith(colon) || (part.startsWith(openBrace) && part.endsWith(closeBrace));\n\n\t\tif (!isMatch) continue;\n\n\t\tmatchedParamsArray.push(part);\n\t}\n\n\tfor (const [paramIndex, matchedParam] of matchedParamsArray.entries()) {\n\t\tconst stringParamValue = String(params[paramIndex]);\n\t\tnewUrl = newUrl.replace(matchedParam, stringParamValue);\n\t}\n\n\treturn newUrl;\n};\n\nconst handleObjectParams = (\n\turl: string,\n\tparams: Extract<CallApiExtraOptions[\"params\"], Record<string, unknown>>\n) => {\n\tlet newUrl = url;\n\n\tfor (const [paramKey, paramValue] of Object.entries(params)) {\n\t\t// == Replace both :param and {param} patterns\n\t\tconst colonPattern = `${colon}${paramKey}` as const;\n\t\tconst bracePattern = `${openBrace}${paramKey}${closeBrace}` as const;\n\n\t\tconst stringValue = String(paramValue);\n\n\t\tnewUrl = newUrl.replace(colonPattern, stringValue);\n\t\tnewUrl = newUrl.replace(bracePattern, stringValue);\n\t}\n\n\treturn newUrl;\n};\n\nconst mergeUrlWithParams = (url: string, params: CallApiExtraOptions[\"params\"]) => {\n\tif (!params) {\n\t\treturn url;\n\t}\n\n\tconst newUrl = isArray(params) ? handleArrayParams(url, params) : handleObjectParams(url, params);\n\n\treturn newUrl;\n};\n\nconst questionMark = \"?\";\nconst ampersand = \"&\";\nconst mergeUrlWithQuery = (url: string, query: CallApiExtraOptions[\"query\"]): string => {\n\tif (!query) {\n\t\treturn url;\n\t}\n\n\tconst queryString = new URLSearchParams(query as Record<string, string> | URLSearchParams).toString();\n\n\tif (queryString.length === 0) {\n\t\treturn url;\n\t}\n\n\tif (url.endsWith(questionMark)) {\n\t\treturn `${url}${queryString}`;\n\t}\n\n\tif (url.includes(questionMark)) {\n\t\treturn `${url}${ampersand}${queryString}`;\n\t}\n\n\treturn `${url}${questionMark}${queryString}`;\n};\n\n/**\n * @description Extracts the HTTP method from method-prefixed route patterns.\n *\n * Analyzes URLs that start with method modifiers (e.g., \"@get/\", \"@post/\") and extracts\n * the HTTP method for use in API requests. This enables method specification directly\n * in route definitions.\n *\n * @param initURL - The URL string to analyze for method modifiers\n * @returns The extracted HTTP method (lowercase) if found, otherwise undefined\n *\n * @example\n * ```typescript\n * extractMethodFromURL(\"@get/users\"); // Returns: \"get\"\n * extractMethodFromURL(\"@post/users\"); // Returns: \"post\"\n * ```\n */\nexport const extractMethodFromURL = (initURL: string | undefined) => {\n\tif (!initURL?.startsWith(\"@\")) return;\n\n\tconst methodFromURL = routeKeyMethods.find((method) =>\n\t\tinitURL.startsWith(`${atSymbol}${method}${slash}`)\n\t);\n\n\tif (!methodFromURL) return;\n\n\treturn methodFromURL;\n};\n\ntype NormalizeURLOptions = {\n\tretainLeadingSlashForRelativeURLs?: boolean;\n};\n\nexport const atSymbol = \"@\";\nexport type AtSymbol = typeof atSymbol;\n\nexport const normalizeURL = (initURL: string, options: NormalizeURLOptions = {}) => {\n\tconst { retainLeadingSlashForRelativeURLs = true } = options;\n\n\tconst methodFromURL = extractMethodFromURL(initURL);\n\n\tif (!methodFromURL) {\n\t\treturn initURL;\n\t}\n\n\tconst normalizedURL =\n\t\tretainLeadingSlashForRelativeURLs && !initURL.includes(\"http\") ?\n\t\t\tinitURL.replace(`${atSymbol}${methodFromURL}`, \"\")\n\t\t:\tinitURL.replace(`${atSymbol}${methodFromURL}${slash}`, \"\");\n\n\treturn normalizedURL;\n};\n\ntype GetFullURLOptions = {\n\t/** Base URL to prepend to relative URLs */\n\tbaseURL: string | undefined;\n\t/** Initial URL pattern that may contain parameters and method modifiers */\n\tinitURL: string;\n\t/** Parameters to substitute into the URL path */\n\tparams: CallApiExtraOptions[\"params\"];\n\t/** Query parameters to append to the URL */\n\tquery: CallApiExtraOptions[\"query\"];\n};\n\nconst getFullURL = (initURL: string, baseURL: string | undefined) => {\n\tif (!baseURL || initURL.startsWith(\"http\")) {\n\t\treturn initURL;\n\t}\n\n\tconst shouldAddSlash = initURL.length > 0 && !initURL.startsWith(slash) && !baseURL.endsWith(slash);\n\n\treturn shouldAddSlash ? `${baseURL}${slash}${initURL}` : `${baseURL}${initURL}`;\n};\n\nexport const getFullAndNormalizedURL = (options: GetFullURLOptions) => {\n\tconst { baseURL, initURL, params, query } = options;\n\n\tconst normalizedInitURL = normalizeURL(initURL);\n\n\tconst initURLWithParams = mergeUrlWithParams(normalizedInitURL, params);\n\n\tconst initURLWithParamsAndQuery = mergeUrlWithQuery(initURLWithParams, query);\n\n\tconst fullURL = getFullURL(initURLWithParamsAndQuery, baseURL);\n\n\tif (!URL.canParse(fullURL)) {\n\t\tconst errorMessage =\n\t\t\t!baseURL ?\n\t\t\t\t`Invalid URL '${initURL}'. Are you passing a relative url to CallApi without setting the 'baseURL' option?`\n\t\t\t:\t`Invalid URL '${fullURL}'. Please validate that you are passing the correct url.`;\n\n\t\tconsole.error(errorMessage);\n\t}\n\n\treturn {\n\t\tfullURL,\n\t\tnormalizedInitURL,\n\t};\n};\n\nexport type AllowedQueryParamValues = UnmaskType<boolean | number | string>;\n\nexport type RecordStyleParams = UnmaskType<Record<string, AllowedQueryParamValues>>;\n\nexport type TupleStyleParams = UnmaskType<AllowedQueryParamValues[]>;\n\nexport type Params = UnmaskType<RecordStyleParams | TupleStyleParams>;\n\nexport type Query = UnmaskType<Record<string, AllowedQueryParamValues> | URLSearchParams>;\n\nexport type InitURLOrURLObject = AnyString | RouteKeyMethodsURLUnion | URL;\n\nexport interface URLOptions {\n\t/**\n\t * Base URL for all API requests. Will only be prepended to relative URLs.\n\t *\n\t * Absolute URLs (starting with http/https) will not be prepended by the baseURL.\n\t *\n\t * @example\n\t * ```ts\n\t * // Set base URL for all requests\n\t * baseURL: \"https://api.example.com/v1\"\n\t *\n\t * // Then use relative URLs in requests\n\t * callApi(\"/users\") // → https://api.example.com/v1/users\n\t * callApi(\"/posts/123\") // → https://api.example.com/v1/posts/123\n\t *\n\t * // Environment-specific base URLs\n\t * baseURL: process.env.NODE_ENV === \"production\"\n\t * ? \"https://api.example.com\"\n\t * : \"http://localhost:3000/api\"\n\t * ```\n\t */\n\tbaseURL?: string;\n\n\t/**\n\t * Resolved request URL after processing baseURL, parameters, and query strings (readonly)\n\t *\n\t * This is the final URL that will be used for the HTTP request, computed from\n\t * baseURL, initURL, params, and query parameters.\n\t *\n\t */\n\treadonly fullURL?: string;\n\n\t/**\n\t * The original URL string passed to the callApi instance (readonly)\n\t *\n\t * This preserves the original URL as provided, including any method modifiers like \"@get/\" or \"@post/\".\n\t *\n\t */\n\treadonly initURL?: string;\n\n\t/**\n\t * The URL string after normalization, with method modifiers removed(readonly)\n\t *\n\t * Method modifiers like \"@get/\", \"@post/\" are stripped to create a clean URL\n\t * for parameter substitution and final URL construction.\n\t *\n\t */\n\treadonly initURLNormalized?: string;\n\n\t/**\n\t * Parameters to be substituted into URL path segments.\n\t *\n\t * Supports both object-style (named parameters) and array-style (positional parameters)\n\t * for flexible URL parameter substitution.\n\t *\n\t * @example\n\t * ```typescript\n\t * // Object-style parameters (recommended)\n\t * const namedParams: URLOptions = {\n\t * initURL: \"/users/:userId/posts/:postId\",\n\t * params: { userId: \"123\", postId: \"456\" }\n\t * };\n\t * // Results in: /users/123/posts/456\n\t *\n\t * // Array-style parameters (positional)\n\t * const positionalParams: URLOptions = {\n\t * initURL: \"/users/:userId/posts/:postId\",\n\t * params: [\"123\", \"456\"] // Maps in order: userId=123, postId=456\n\t * };\n\t * // Results in: /users/123/posts/456\n\t *\n\t * // Single parameter\n\t * const singleParam: URLOptions = {\n\t * initURL: \"/users/:id\",\n\t * params: { id: \"user-123\" }\n\t * };\n\t * // Results in: /users/user-123\n\t * ```\n\t */\n\tparams?: Params;\n\n\t/**\n\t * Query parameters to append to the URL as search parameters.\n\t *\n\t * These will be serialized into the URL query string using standard\n\t * URL encoding practices.\n\t *\n\t * @example\n\t * ```typescript\n\t * // Basic query parameters\n\t * const queryOptions: URLOptions = {\n\t * initURL: \"/users\",\n\t * query: {\n\t * page: 1,\n\t * limit: 10,\n\t * search: \"john doe\",\n\t * active: true\n\t * }\n\t * };\n\t * // Results in: /users?page=1&limit=10&search=john%20doe&active=true\n\t *\n\t * // Filtering and sorting\n\t * const filterOptions: URLOptions = {\n\t * initURL: \"/products\",\n\t * query: {\n\t * category: \"electronics\",\n\t * minPrice: 100,\n\t * maxPrice: 500,\n\t * sortBy: \"price\",\n\t * order: \"asc\"\n\t * }\n\t * };\n\t * // Results in: /products?category=electronics&minPrice=100&maxPrice=500&sortBy=price&order=asc\n\t * ```\n\t */\n\tquery?: Query;\n}\n","import { getAuthHeader } from \"../auth\";\nimport { fetchSpecificKeys } from \"../constants/common\";\nimport { extraOptionDefaults, requestOptionDefaults } from \"../constants/defaults\";\nimport type { RequestContext } from \"../hooks\";\nimport type { Middlewares } from \"../middlewares\";\nimport type { BaseCallApiExtraOptions, CallApiExtraOptions, CallApiRequestOptions } from \"../types/common\";\nimport type { InferHeadersOption } from \"../types/conditional-types\";\nimport type { DistributiveOmit } from \"../types/type-helpers\";\nimport { extractMethodFromURL } from \"../url\";\nimport type { CallApiSchema } from \"../validation\";\nimport {\n\tisArray,\n\tisFunction,\n\tisPlainObject,\n\tisQueryString,\n\tisSerializableObject,\n\tisValidJsonString,\n} from \"./guards\";\n\nexport const omitKeys = <\n\tTObject extends Record<string, unknown>,\n\tconst TOmitArray extends Array<keyof TObject> | ReadonlyArray<keyof TObject>,\n>(\n\tinitialObject: TObject,\n\tkeysToOmit: TOmitArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToOmitSet = new Set(keysToOmit);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (!keysToOmitSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as DistributiveOmit<TObject, TOmitArray[number]>;\n};\n\nexport const pickKeys = <\n\tTObject extends Record<string, unknown>,\n\tconst TPickArray extends Array<keyof TObject> | ReadonlyArray<keyof TObject>,\n>(\n\tinitialObject: TObject,\n\tkeysToPick: TPickArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToPickSet = new Set(keysToPick);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (keysToPickSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as Pick<TObject, TPickArray[number]>;\n};\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitBaseConfig = (baseConfig: Record<string, any>) =>\n\t[\n\t\tpickKeys(baseConfig, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(baseConfig, fetchSpecificKeys) as BaseCallApiExtraOptions,\n\t] as const;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitConfig = (config: Record<string, any>) =>\n\t[\n\t\tpickKeys(config, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(config, fetchSpecificKeys) as CallApiExtraOptions,\n\t] as const;\n\nexport const objectifyHeaders = (headers: CallApiRequestOptions[\"headers\"]) => {\n\tif (!headers) {\n\t\treturn {};\n\t}\n\n\tif (isPlainObject(headers)) {\n\t\treturn headers as Record<string, string>;\n\t}\n\n\treturn Object.fromEntries(headers);\n};\n\nexport type GetResolvedHeadersOptions = {\n\tbaseHeaders: CallApiRequestOptions[\"headers\"];\n\theaders: InferHeadersOption<CallApiSchema>[\"headers\"];\n};\n\nexport const getResolvedHeaders = (options: GetResolvedHeadersOptions) => {\n\tconst { baseHeaders, headers } = options;\n\n\tconst resolvedHeaders =\n\t\tisFunction(headers) ?\n\t\t\theaders({ baseHeaders: objectifyHeaders(baseHeaders) })\n\t\t:\t(headers ?? baseHeaders);\n\n\treturn objectifyHeaders(resolvedHeaders);\n};\n\nconst detectContentTypeHeader = (body: CallApiRequestOptions[\"body\"]) => {\n\tif (isQueryString(body)) {\n\t\treturn { \"Content-Type\": \"application/x-www-form-urlencoded\" };\n\t}\n\n\tif (isSerializableObject(body) || isValidJsonString(body)) {\n\t\treturn { Accept: \"application/json\", \"Content-Type\": \"application/json\" };\n\t}\n\n\treturn null;\n};\n\nexport type GetHeadersOptions = {\n\tauth: CallApiExtraOptions[\"auth\"];\n\tbody: CallApiRequestOptions[\"body\"];\n\tresolvedHeaders: CallApiRequestOptions[\"headers\"];\n};\n\nexport const getHeaders = async (options: GetHeadersOptions) => {\n\tconst { auth, body, resolvedHeaders } = options;\n\n\tconst authHeaderObject = await getAuthHeader(auth);\n\n\tconst resolvedHeadersObject = objectifyHeaders(resolvedHeaders);\n\n\tconst hasExistingContentType =\n\t\tObject.hasOwn(resolvedHeadersObject, \"Content-Type\")\n\t\t|| Object.hasOwn(resolvedHeadersObject, \"content-type\");\n\n\tif (!hasExistingContentType) {\n\t\tconst contentTypeHeader = detectContentTypeHeader(body);\n\t\tcontentTypeHeader && Object.assign(resolvedHeadersObject, contentTypeHeader);\n\t}\n\n\tconst headersObject: Record<string, string> = {\n\t\t...authHeaderObject,\n\t\t...resolvedHeadersObject,\n\t};\n\n\treturn headersObject;\n};\n\nexport type GetMethodContext = {\n\t/** The URL string that may contain method modifiers like \"@get/\" or \"@post/\" */\n\tinitURL: string | undefined;\n\t/** Explicitly specified HTTP method */\n\tmethod: CallApiRequestOptions[\"method\"];\n};\n\nexport const getMethod = (ctx: GetMethodContext) => {\n\tconst { initURL, method } = ctx;\n\n\treturn (\n\t\tmethod?.toUpperCase() ?? extractMethodFromURL(initURL)?.toUpperCase() ?? requestOptionDefaults.method\n\t);\n};\n\nexport type GetBodyOptions = Pick<GetHeadersOptions, \"body\" | \"resolvedHeaders\"> & {\n\tbodySerializer: CallApiExtraOptions[\"bodySerializer\"];\n};\n\nexport const getBody = (options: GetBodyOptions) => {\n\tconst { body, bodySerializer, resolvedHeaders } = options;\n\n\tconst headers = new Headers(resolvedHeaders as Record<string, string>);\n\n\tconst existingContentType = headers.get(\"content-type\");\n\n\tif (!existingContentType && isSerializableObject(body)) {\n\t\tconst selectedBodySerializer = bodySerializer ?? extraOptionDefaults.bodySerializer;\n\n\t\treturn selectedBodySerializer(body);\n\t}\n\n\tif (existingContentType === \"application/x-www-form-urlencoded\" && isSerializableObject(body)) {\n\t\treturn new URLSearchParams(body as Record<string, string>).toString();\n\t}\n\n\treturn body;\n};\n\nexport const getInitFetchImpl = (customFetchImpl: CallApiExtraOptions[\"customFetchImpl\"]) => {\n\tif (customFetchImpl) {\n\t\treturn customFetchImpl;\n\t}\n\n\tif (typeof globalThis !== \"undefined\" && isFunction(globalThis.fetch)) {\n\t\treturn globalThis.fetch;\n\t}\n\n\tthrow new Error(\"No fetch implementation found\");\n};\n\nexport const getFetchImpl = (context: {\n\tcustomFetchImpl: CallApiExtraOptions[\"customFetchImpl\"];\n\tfetchMiddleware: Middlewares[\"fetchMiddleware\"];\n\trequestContext: RequestContext;\n}) => {\n\tconst { customFetchImpl, fetchMiddleware, requestContext } = context;\n\n\tconst initFetchImpl = getInitFetchImpl(customFetchImpl);\n\n\tconst resolvedFetchImpl =\n\t\tfetchMiddleware ? fetchMiddleware({ ...requestContext, fetchImpl: initFetchImpl }) : initFetchImpl;\n\n\treturn resolvedFetchImpl;\n};\n\nexport const waitFor = (delay: number) => {\n\tif (delay === 0) return;\n\n\tconst promise = new Promise((resolve) => setTimeout(resolve, delay));\n\n\treturn promise;\n};\n\nexport const createCombinedSignal = (...signals: Array<AbortSignal | null | undefined>) => {\n\tconst combinedSignal = AbortSignal.any(signals.filter((signal) => signal != null));\n\n\treturn combinedSignal;\n};\n\nexport const createTimeoutSignal = (milliseconds: number | null | undefined) => {\n\tif (milliseconds == null) {\n\t\treturn null;\n\t}\n\n\treturn AbortSignal.timeout(milliseconds);\n};\n\nexport const deterministicHashFn = (value: unknown): string => {\n\treturn JSON.stringify(value, (_, val: unknown) => {\n\t\tif (!isPlainObject(val)) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// eslint-disable-next-line unicorn/no-array-sort -- Not necessary here\n\t\tconst sortedKeys = Object.keys(val).sort();\n\n\t\tconst result: Record<string, unknown> = {};\n\n\t\tfor (const key of sortedKeys) {\n\t\t\tresult[key] = val[key];\n\t\t}\n\n\t\treturn result;\n\t});\n};\n\nexport const toArray = (value: unknown) => (isArray(value) ? value : [value]);\n","import type { CallApiConfig, CallApiExtraOptions } from \"../types/common\";\nimport { defineEnum } from \"../types/type-helpers\";\nimport { deterministicHashFn } from \"../utils/common\";\n\nexport const extraOptionDefaults = Object.freeze(\n\tdefineEnum({\n\t\t// Common defaults\n\t\tbodySerializer: JSON.stringify,\n\t\tdefaultHTTPErrorMessage: \"Request failed unexpectedly\",\n\n\t\t// Dedupe defaults\n\t\t/* eslint-disable perfectionist/sort-objects -- Allow */\n\t\tdedupeCacheScope: \"local\",\n\t\tdedupeKey: (ctx) =>\n\t\t\t`${ctx.options.fullURL}-${deterministicHashFn({ options: ctx.options, request: ctx.request })}`,\n\t\tdedupeCacheScopeKey: \"default\",\n\t\tdedupeStrategy: \"cancel\",\n\t\t/* eslint-enable perfectionist/sort-objects -- Allow */\n\n\t\t// Hook defaults\n\t\thooksExecutionMode: \"parallel\",\n\n\t\t// Response defaults\n\t\tresponseParser: JSON.parse,\n\t\tresponseType: \"json\",\n\t\tresultMode: \"all\",\n\n\t\t// Retry Defaults\n\t\tretryAttempts: 0,\n\t\tretryCondition: () => true,\n\t\tretryDelay: 1000,\n\t\tretryMaxDelay: 10000,\n\t\tretryMethods: [\"GET\", \"POST\"],\n\t\tretryStatusCodes: [],\n\t\tretryStrategy: \"linear\",\n\t} satisfies CallApiExtraOptions)\n);\n\nexport const requestOptionDefaults = Object.freeze(\n\tdefineEnum({\n\t\tmethod: \"GET\",\n\t} satisfies CallApiConfig)\n);\n"],"mappings":"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"}
1
+ {"version":3,"file":"defaults-D5uiLm4M.js","names":[],"sources":["../src/types/type-helpers.ts","../src/utils/guards.ts","../src/auth.ts","../src/constants/common.ts","../src/constants/validation.ts","../src/utils/external/error.ts","../src/validation.ts","../src/url.ts","../src/utils/common.ts","../src/constants/defaults.ts"],"sourcesContent":["// == These two types allows for adding arbitrary literal types, while still provided autocomplete for defaults.\n// == Usually intersection with \"{}\" or \"NonNullable<unknown>\" would make it work fine, but the placeholder with never type is added to make the AnyWhatever type appear last in a given union.\nexport type AnyString = string & NonNullable<unknown>;\nexport type AnyNumber = number & NonNullable<unknown>;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is fine here\nexport type AnyObject = Record<keyof any, any>;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport type AnyFunction<TResult = unknown> = (...args: any[]) => TResult;\n\nexport type Prettify<TObject> = NonNullable<unknown> & { [Key in keyof TObject]: TObject[Key] };\n\ntype WriteableLevel = \"deep\" | \"shallow\";\n\n/**\n * Makes all properties in an object type writeable (removes readonly modifiers).\n * Supports both shallow and deep modes, and handles special cases like arrays, tuples, and unions.\n * @template TObject - The object type to make writeable\n * @template TVariant - The level of writeable transformation (\"shallow\" | \"deep\")\n */\n\ntype ArrayOrObject = Record<number | string | symbol, unknown> | unknown[] | readonly unknown[];\n\nexport type Writeable<TObject, TLevel extends WriteableLevel = \"shallow\"> =\n\tTObject extends ArrayOrObject ?\n\t\t{\n\t\t\t-readonly [Key in keyof TObject]: TLevel extends \"deep\" ?\n\t\t\t\tNonNullable<TObject[Key]> extends ArrayOrObject ?\n\t\t\t\t\tWriteable<TObject[Key], \"deep\">\n\t\t\t\t:\tTObject[Key]\n\t\t\t:\tTObject[Key];\n\t\t}\n\t:\tTObject;\n\nexport const defineEnum = <const TValue extends object>(value: TValue) =>\n\tObject.freeze(value) as Readonly<Writeable<TValue>>;\n\nexport type UnionToIntersection<TUnion> =\n\t(TUnion extends unknown ? (param: TUnion) => void : never) extends (param: infer TParam) => void ?\n\t\tTParam\n\t:\tnever;\n\n// == Using this Immediately Indexed Mapped type helper to help show computed type of anything passed to it instead of just the type name\nexport type UnmaskType<TValue> = { value: TValue }[\"value\"];\n\n/**\n * @description Userland implementation of NoInfer intrinsic type, but this one doesn't show up on hover like the intrinsic one\n *\n * Prevents TypeScript from inferring `TGeneric` at this position by creating a circular dependency.\n * The tuple index `[TGeneric extends unknown ? 0 : never]` depends on `TGeneric`, forcing TS to\n * skip this site for inference and use other arguments or defaults instead.\n */\nexport type NoInferUnMasked<TGeneric> = [TGeneric][TGeneric extends unknown ? 0 : never];\n\ntype RemoveSlashImpl<TUrl extends string, TDirection extends \"leading\" | \"trailing\"> =\n\tTDirection extends \"leading\" ?\n\t\tTUrl extends `/${infer TWithoutLeadingSlash}` ?\n\t\t\tTWithoutLeadingSlash\n\t\t:\tTUrl\n\t: TDirection extends \"trailing\" ?\n\t\tTUrl extends `${infer TWithoutTailingSlash}/` ?\n\t\t\tTWithoutTailingSlash\n\t\t:\tTUrl\n\t:\tnever;\n\nexport type RemoveTrailingSlash<TUrl extends string> = RemoveSlashImpl<TUrl, \"trailing\">;\nexport type RemoveLeadingSlash<TUrl extends string> = RemoveSlashImpl<TUrl, \"leading\">;\n\nexport type Awaitable<TValue> = Promise<TValue> | TValue;\n\n// export type MatchExactObjectType<TActualObject extends TExpectedObject, TExpectedObject> = {\n// \t[Key in keyof TActualObject]: Key extends keyof TExpectedObject ? TActualObject[Key] : never;\n// };\n\nexport type Satisfies<TActualObject extends TExpectedObject, TExpectedObject> = {\n\t[Key in keyof TActualObject]: Key extends keyof TExpectedObject ? TActualObject[Key] : never;\n};\n// export type Satisfies<TActualObject extends TExpectedObject, TExpectedObject> = {\n// \t[Key in keyof TActualObject & keyof TExpectedObject]: TActualObject[Key];\n// };\n\nexport type DistributiveOmit<TObject, TKeysToOmit extends keyof TObject> =\n\tTObject extends unknown ? Omit<TObject, TKeysToOmit> : never;\n\ntype ErrorMessages<TType extends number | string | symbol = never> = Partial<\n\tRecord<\"$all\" | number | symbol | (AnyString | TType), unknown>\n> | null;\n\n/**\n * Type utility that takes two types and allows only the properties of the first type. The properties of the second will be disallowed (typed as `never` by default or a custom message).\n *\n * @template TFirstType The first type. Properties of this type will be required.\n * @template TSecondType The second type. Properties of this type will be disallowed.\n * @template TErrorMessages An object of custom messages to display on the properties of the second type that are disallowed.\n */\ntype AllowOnlyFirst<TFirstType, TSecondType, TErrorMessages extends ErrorMessages = never> = Prettify<\n\tTFirstType & {\n\t\t[Key in keyof Omit<TSecondType, keyof TFirstType>]?: Key extends keyof TErrorMessages ?\n\t\t\tTErrorMessages[Key]\n\t\t: \"$all\" extends keyof TErrorMessages ? TErrorMessages[\"$all\"]\n\t\t: TErrorMessages extends null ? TErrorMessages\n\t\t: never;\n\t}\n>;\n\n/**\n * Merges all types in an array of types into one type.\n *\n * @template TArrayOfTypes Array of types to merge\n * @template TAccumulator Accumulator for the resulting merged type\n */\ntype MergeTypes<TArrayOfTypes extends unknown[], TAccumulator = NonNullable<unknown>> =\n\tTArrayOfTypes extends [infer TFirstType, ...infer TRestOfTypes] ?\n\t\tMergeTypes<\n\t\t\tTRestOfTypes,\n\t\t\t{ [Key in keyof TAccumulator | keyof TFirstType]: (TAccumulator & TFirstType)[Key] }\n\t\t>\n\t:\tTAccumulator;\n\n/**\n * Type utility that extracts discriminated properties from a union of types.\n * Takes an array of types and returns a union of types where each type has unique properties.\n *\n * @template TArrayOfTypes Array of types to process\n * @template TErrorMessages An object of custom messages to display on the properties that are disallowed.\n * @template TAccumulator Accumulator for the resulting union\n * @template TMergedProperties Merged properties from all types\n */\n\nexport type UnionDiscriminator<\n\tTArrayOfTypes extends unknown[],\n\tTErrorMessages extends ErrorMessages<keyof MergeTypes<TArrayOfTypes>> = never,\n\tTAccumulator = never,\n\tTMergedProperties = MergeTypes<TArrayOfTypes>,\n> =\n\tTArrayOfTypes extends [infer TFirstType, ...infer TRestOfTypes] ?\n\t\tUnionDiscriminator<\n\t\t\tTRestOfTypes,\n\t\t\tTErrorMessages,\n\t\t\t// eslint-disable-next-line perfectionist/sort-union-types -- Let TAccumulator be first\n\t\t\tTAccumulator | AllowOnlyFirst<TFirstType, TMergedProperties, TErrorMessages>,\n\t\t\tTMergedProperties\n\t\t>\n\t:\tTAccumulator;\n\nexport type CommonRequestHeaders =\n\t| \"Access-Control-Allow-Credentials\"\n\t| \"Access-Control-Allow-Headers\"\n\t| \"Access-Control-Allow-Methods\"\n\t| \"Access-Control-Allow-Origin\"\n\t| \"Access-Control-Expose-Headers\"\n\t| \"Access-Control-Max-Age\"\n\t| \"Age\"\n\t| \"Allow\"\n\t| \"Cache-Control\"\n\t| \"Clear-Site-Data\"\n\t| \"Content-Disposition\"\n\t| \"Content-Encoding\"\n\t| \"Content-Language\"\n\t| \"Content-Length\"\n\t| \"Content-Location\"\n\t| \"Content-Range\"\n\t| \"Content-Security-Policy-Report-Only\"\n\t| \"Content-Security-Policy\"\n\t| \"Cookie\"\n\t| \"Cross-Origin-Embedder-Policy\"\n\t| \"Cross-Origin-Opener-Policy\"\n\t| \"Cross-Origin-Resource-Policy\"\n\t| \"Date\"\n\t| \"ETag\"\n\t| \"Expires\"\n\t| \"Last-Modified\"\n\t| \"Location\"\n\t| \"Permissions-Policy\"\n\t| \"Pragma\"\n\t| \"Retry-After\"\n\t| \"Save-Data\"\n\t| \"Sec-CH-Prefers-Color-Scheme\"\n\t| \"Sec-CH-Prefers-Reduced-Motion\"\n\t| \"Sec-CH-UA-Arch\"\n\t| \"Sec-CH-UA-Bitness\"\n\t| \"Sec-CH-UA-Form-Factor\"\n\t| \"Sec-CH-UA-Full-Version-List\"\n\t| \"Sec-CH-UA-Full-Version\"\n\t| \"Sec-CH-UA-Mobile\"\n\t| \"Sec-CH-UA-Model\"\n\t| \"Sec-CH-UA-Platform-Version\"\n\t| \"Sec-CH-UA-Platform\"\n\t| \"Sec-CH-UA-WoW64\"\n\t| \"Sec-CH-UA\"\n\t| \"Sec-Fetch-Dest\"\n\t| \"Sec-Fetch-Mode\"\n\t| \"Sec-Fetch-Site\"\n\t| \"Sec-Fetch-User\"\n\t| \"Sec-GPC\"\n\t| \"Server-Timing\"\n\t| \"Server\"\n\t| \"Service-Worker-Navigation-Preload\"\n\t| \"Set-Cookie\"\n\t| \"Strict-Transport-Security\"\n\t| \"Timing-Allow-Origin\"\n\t| \"Trailer\"\n\t| \"Transfer-Encoding\"\n\t| \"Upgrade\"\n\t| \"Vary\"\n\t| \"Warning\"\n\t| \"WWW-Authenticate\"\n\t| \"X-Content-Type-Options\"\n\t| \"X-DNS-Prefetch-Control\"\n\t| \"X-Frame-Options\"\n\t| \"X-Permitted-Cross-Domain-Policies\"\n\t| \"X-Powered-By\"\n\t| \"X-Robots-Tag\"\n\t| \"X-XSS-Protection\"\n\t| AnyString;\n\nexport type CommonAuthorizationHeaders = `${\"Basic\" | \"Bearer\" | \"Token\"} ${string}`;\n\nexport type CommonContentTypes =\n\t| \"application/epub+zip\"\n\t| \"application/gzip\"\n\t| \"application/json\"\n\t| \"application/ld+json\"\n\t| \"application/octet-stream\"\n\t| \"application/ogg\"\n\t| \"application/pdf\"\n\t| \"application/rtf\"\n\t| \"application/vnd.ms-fontobject\"\n\t| \"application/wasm\"\n\t| \"application/xhtml+xml\"\n\t| \"application/xml\"\n\t| \"application/zip\"\n\t| \"audio/aac\"\n\t| \"audio/mpeg\"\n\t| \"audio/ogg\"\n\t| \"audio/opus\"\n\t| \"audio/webm\"\n\t| \"audio/x-midi\"\n\t| \"font/otf\"\n\t| \"font/ttf\"\n\t| \"font/woff\"\n\t| \"font/woff2\"\n\t| \"image/avif\"\n\t| \"image/bmp\"\n\t| \"image/gif\"\n\t| \"image/jpeg\"\n\t| \"image/png\"\n\t| \"image/svg+xml\"\n\t| \"image/tiff\"\n\t| \"image/webp\"\n\t| \"image/x-icon\"\n\t| \"model/gltf-binary\"\n\t| \"model/gltf+json\"\n\t| \"text/calendar\"\n\t| \"text/css\"\n\t| \"text/csv\"\n\t| \"text/html\"\n\t| \"text/javascript\"\n\t| \"text/plain\"\n\t| \"video/3gpp\"\n\t| \"video/3gpp2\"\n\t| \"video/av1\"\n\t| \"video/mp2t\"\n\t| \"video/mp4\"\n\t| \"video/mpeg\"\n\t| \"video/ogg\"\n\t| \"video/webm\"\n\t| \"video/x-msvideo\"\n\t| AnyString;\n","import type { AnyFunction } from \"../types/type-helpers\";\n\nexport const isArray = <TArrayItem>(value: unknown): value is TArrayItem[] => Array.isArray(value);\n\nexport const isBoolean = (value: unknown): value is boolean => typeof value === \"boolean\";\n\nexport const isBlob = (value: unknown): value is Blob => value instanceof Blob;\n\nexport const isObject = <TObject extends object>(value: unknown): value is TObject => {\n\treturn typeof value === \"object\" && value !== null;\n};\n\nconst hasObjectPrototype = (value: unknown) => {\n\treturn Object.prototype.toString.call(value) === \"[object Object]\";\n};\n\n/**\n * @description Copied from TanStack Query's isPlainObject\n * @see https://github.com/TanStack/query/blob/main/packages/query-core/src/utils.ts#L321\n */\nexport const isPlainObject = <TPlainObject extends Record<string, unknown>>(\n\tvalue: unknown\n): value is TPlainObject => {\n\tif (!hasObjectPrototype(value)) {\n\t\treturn false;\n\t}\n\n\t// If has no constructor\n\tconst constructor = (value as object | undefined)?.constructor;\n\tif (constructor === undefined) {\n\t\treturn true;\n\t}\n\n\t// If has modified prototype\n\tconst prototype = constructor.prototype as object;\n\tif (!hasObjectPrototype(prototype)) {\n\t\treturn false;\n\t}\n\n\t// If constructor does not have an Object-specific method\n\tif (!Object.hasOwn(prototype, \"isPrototypeOf\")) {\n\t\treturn false;\n\t}\n\n\t// Handles Objects created by Object.create(<arbitrary prototype>)\n\tif (Object.getPrototypeOf(value) !== Object.prototype) {\n\t\treturn false;\n\t}\n\n\t// It's probably a plain object at this point\n\treturn true;\n};\n\nexport const isValidJsonString = (value: unknown): value is string => {\n\tif (!isString(value)) {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tJSON.parse(value);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n};\n\nexport const isSerializableObject = (value: unknown) => {\n\treturn (\n\t\tisPlainObject(value)\n\t\t|| isArray(value)\n\t\t|| typeof (value as { toJSON: unknown } | undefined)?.toJSON === \"function\"\n\t);\n};\n\nexport const isFunction = <TFunction extends AnyFunction>(value: unknown): value is TFunction =>\n\ttypeof value === \"function\";\n\nexport const isQueryString = (value: unknown): value is string => isString(value) && value.includes(\"=\");\n\nexport const isString = (value: unknown) => typeof value === \"string\";\n\nexport const isPromise = (value: unknown) => value instanceof Promise;\n\nexport const isReadableStream = (value: unknown): value is ReadableStream<unknown> => {\n\treturn value instanceof ReadableStream;\n};\n\n// https://github.com/unjs/ofetch/blob/main/src/utils.ts\nexport const isJSONSerializable = (value: unknown) => {\n\tif (value === undefined) {\n\t\treturn false;\n\t}\n\tconst t = typeof value;\n\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- No time to make this more type-safe\n\tif (t === \"string\" || t === \"number\" || t === \"boolean\" || t === null) {\n\t\treturn true;\n\t}\n\tif (t !== \"object\") {\n\t\treturn false;\n\t}\n\tif (isArray(value)) {\n\t\treturn true;\n\t}\n\tif ((value as Buffer | null)?.buffer) {\n\t\treturn false;\n\t}\n\n\treturn (\n\t\tvalue?.constructor.name === \"Object\"\n\t\t|| typeof (value as { toJSON: () => unknown } | null)?.toJSON === \"function\"\n\t);\n};\n","/* eslint-disable perfectionist/sort-object-types -- Avoid Sorting for now */\n\nimport type { CallApiExtraOptions } from \"./types/common\";\nimport type { Awaitable } from \"./types/type-helpers\";\nimport { isFunction, isObject, isPromise } from \"./utils/guards\";\n\ntype PossibleAuthValue = Awaitable<string | null | undefined>;\n\ntype PossibleAuthValueOrGetter = PossibleAuthValue | (() => PossibleAuthValue);\n\n// export type BearerOrTokenAuth =\n// \t| {\n// \t\t\ttype?: \"Bearer\" | undefined;\n// \t\t\tbearer?: PossibleAuthValueOrGetter;\n// \t\t\ttoken?: never;\n// \t }\n// \t| {\n// \t\t\ttype?: \"Token\";\n// \t\t\tbearer?: never;\n// \t\t\ttoken?: PossibleAuthValueOrGetter;\n// \t };\n\nexport type BearerAuth = {\n\ttype: \"Bearer\";\n\tvalue: PossibleAuthValueOrGetter;\n};\n\nexport type TokenAuth = {\n\ttype: \"Token\";\n\tvalue: PossibleAuthValueOrGetter;\n};\n\nexport type BasicAuth = {\n\ttype: \"Basic\";\n\tusername: PossibleAuthValueOrGetter;\n\tpassword: PossibleAuthValueOrGetter;\n};\n\n/**\n * Custom auth\n *\n * @param prefix - prefix of the header\n * @param authValue - value of the header\n *\n * @example\n * ```ts\n * {\n * type: \"Custom\",\n * prefix: \"Token\",\n * authValue: \"token\"\n * }\n * ```\n */\nexport type CustomAuth = {\n\ttype: \"Custom\";\n\tprefix: PossibleAuthValueOrGetter;\n\tvalue: PossibleAuthValueOrGetter;\n};\n\n// eslint-disable-next-line perfectionist/sort-union-types -- Let the first one be first\nexport type AuthOption = PossibleAuthValueOrGetter | BearerAuth | TokenAuth | BasicAuth | CustomAuth;\n\nconst resolveAuthValue = (value: PossibleAuthValueOrGetter) => (isFunction(value) ? value() : value);\n\ntype AuthHeaderObject = { Authorization: string };\n\nexport const getAuthHeader = async (\n\tauth: CallApiExtraOptions[\"auth\"]\n): Promise<AuthHeaderObject | undefined> => {\n\tif (auth === undefined) return;\n\n\tif (isPromise(auth) || isFunction(auth) || !isObject(auth)) {\n\t\tconst authValue = await resolveAuthValue(auth);\n\n\t\tif (authValue === undefined) return;\n\n\t\treturn {\n\t\t\tAuthorization: `Bearer ${authValue}`,\n\t\t};\n\t}\n\n\tswitch (auth.type) {\n\t\tcase \"Basic\": {\n\t\t\tconst [username, password] = await Promise.all([\n\t\t\t\tresolveAuthValue(auth.username),\n\t\t\t\tresolveAuthValue(auth.password),\n\t\t\t]);\n\n\t\t\tif (username === undefined || password === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `Basic ${globalThis.btoa(`${username}:${password}`)}`,\n\t\t\t};\n\t\t}\n\t\tcase \"Bearer\": {\n\t\t\tconst value = await resolveAuthValue(auth.value);\n\n\t\t\tif (value === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `Bearer ${value}`,\n\t\t\t};\n\t\t}\n\t\tcase \"Custom\": {\n\t\t\tconst [prefix, value] = await Promise.all([\n\t\t\t\tresolveAuthValue(auth.prefix),\n\t\t\t\tresolveAuthValue(auth.value),\n\t\t\t]);\n\n\t\t\tif (value === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `${prefix} ${value}`,\n\t\t\t};\n\t\t}\n\n\t\tcase \"Token\": {\n\t\t\tconst value = await resolveAuthValue(auth.value);\n\n\t\t\tif (value === undefined) return;\n\n\t\t\treturn {\n\t\t\t\tAuthorization: `Token ${value}`,\n\t\t\t};\n\t\t}\n\n\t\tdefault: {\n\t\t\tauth satisfies never;\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// default: {\n\t\t// \tconst [bearer, token] = await Promise.all([\n\t\t// \t\tresolveAuthValue(auth.bearer),\n\t\t// \t\tresolveAuthValue(auth.token),\n\t\t// \t]);\n\n\t\t// \tif (bearer !== undefined) {\n\t\t// \t\treturn { Authorization: `Bearer ${bearer}` };\n\t\t// \t}\n\n\t\t// \tif (token === undefined) return;\n\n\t\t// \treturn { Authorization: `Token ${token}` };\n\t\t// }\n\t}\n};\n","import type { ModifiedRequestInit } from \"../types/common\";\nimport { defineEnum } from \"../types/type-helpers\";\n\nexport const fetchSpecificKeys = defineEnum([\n\t\"body\",\n\t\"integrity\",\n\t\"duplex\",\n\t\"method\",\n\t\"headers\",\n\t\"signal\",\n\t\"cache\",\n\t\"redirect\",\n\t\"window\",\n\t\"credentials\",\n\t\"keepalive\",\n\t\"referrer\",\n\t\"priority\",\n\t\"mode\",\n\t\"referrerPolicy\",\n] satisfies Array<keyof ModifiedRequestInit> as Array<keyof ModifiedRequestInit>);\n","export const fallBackRouteSchemaKey = \"@default\";\n\nexport type FallBackRouteSchemaKey = typeof fallBackRouteSchemaKey;\n","import { extraOptionDefaults } from \"../../constants/defaults\";\nimport type { CallApiExtraOptions } from \"../../types/common\";\nimport type { StandardSchemaV1 } from \"../../types/standard-schema\";\nimport type { CallApiSchema, CallApiSchemaConfig } from \"../../validation\";\nimport { isObject, isString } from \"../guards\";\n\ntype HTTPErrorDetails<TErrorData> = Pick<CallApiExtraOptions, \"defaultHTTPErrorMessage\"> & {\n\terrorData: TErrorData;\n\tresponse: Response;\n};\n\nconst httpErrorSymbol = Symbol(\"HTTPError\");\n\nexport class HTTPError<TErrorData = Record<string, unknown>> extends Error {\n\terrorData: HTTPErrorDetails<TErrorData>[\"errorData\"];\n\n\treadonly httpErrorSymbol = httpErrorSymbol;\n\n\toverride name = \"HTTPError\" as const;\n\n\tresponse: HTTPErrorDetails<TErrorData>[\"response\"];\n\n\tconstructor(errorDetails: HTTPErrorDetails<TErrorData>, errorOptions?: ErrorOptions) {\n\t\tconst { defaultHTTPErrorMessage, errorData, response } = errorDetails;\n\n\t\tconst resolvedDefaultHTTPErrorMessage =\n\t\t\tisString(defaultHTTPErrorMessage) ? defaultHTTPErrorMessage : (\n\t\t\t\tdefaultHTTPErrorMessage?.({ errorData, response })\n\t\t\t);\n\n\t\tconst selectedDefaultErrorMessage =\n\t\t\tresolvedDefaultHTTPErrorMessage\n\t\t\t?? (response.statusText || extraOptionDefaults.defaultHTTPErrorMessage);\n\n\t\tconst message =\n\t\t\t(errorData as { message?: string } | undefined)?.message ?? selectedDefaultErrorMessage;\n\n\t\tsuper(message, errorOptions);\n\n\t\tthis.errorData = errorData;\n\t\tthis.response = response;\n\t}\n\n\t/**\n\t * @description Checks if the given error is an instance of HTTPError\n\t * @param error - The error to check\n\t * @returns true if the error is an instance of HTTPError, false otherwise\n\t */\n\tstatic override isError<TErrorData>(error: unknown): error is HTTPError<TErrorData> {\n\t\tif (!isObject<HTTPError>(error)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (error instanceof HTTPError) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst actualError = error as HTTPError;\n\n\t\treturn (\n\t\t\tactualError.httpErrorSymbol === httpErrorSymbol\n\t\t\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- Allow\n\t\t\t&& actualError.name === \"HTTPError\"\n\t\t);\n\t}\n}\n\nconst prettifyPath = (path: ValidationError[\"errorData\"][number][\"path\"]) => {\n\tif (!path || path.length === 0) {\n\t\treturn \"\";\n\t}\n\n\tconst pathString = path.map((segment) => (isObject(segment) ? segment.key : segment)).join(\".\");\n\n\treturn ` → at ${pathString}`;\n};\n\nconst prettifyValidationIssues = (issues: ValidationError[\"errorData\"]) => {\n\tconst issuesString = issues.map((issue) => `✖ ${issue.message}${prettifyPath(issue.path)}`).join(\" | \");\n\n\treturn issuesString;\n};\n\ntype SafeExtract<TUnion, TKey extends TUnion> = Extract<TUnion, TKey>;\n\ntype ValidationErrorDetails = {\n\t/**\n\t * The cause of the validation error.\n\t *\n\t * It's either the name the schema for which validation failed, or the name of the schema config option that led to the validation error.\n\t */\n\tissueCause:\n\t\t| \"toFormData\"\n\t\t| \"toQueryString\"\n\t\t| \"unknown\"\n\t\t| `schemaConfig-(${SafeExtract<keyof CallApiSchemaConfig, \"strict\">})`\n\t\t| keyof CallApiSchema;\n\n\t/**\n\t * The issues that caused the validation error.\n\t */\n\tissues: readonly StandardSchemaV1.Issue[];\n\n\t/**\n\t * The response from server, if any.\n\t */\n\tresponse: Response | null;\n};\n\nconst validationErrorSymbol = Symbol(\"ValidationErrorSymbol\");\n\nexport class ValidationError extends Error {\n\terrorData: ValidationErrorDetails[\"issues\"];\n\n\tissueCause: ValidationErrorDetails[\"issueCause\"];\n\n\toverride name = \"ValidationError\" as const;\n\n\tresponse: ValidationErrorDetails[\"response\"];\n\n\treadonly validationErrorSymbol = validationErrorSymbol;\n\n\tconstructor(details: ValidationErrorDetails, errorOptions?: ErrorOptions) {\n\t\tconst { issueCause, issues, response } = details;\n\n\t\tconst prettyMessage = prettifyValidationIssues(issues);\n\n\t\tconst message = `(${issueCause.toUpperCase()}) - ${prettyMessage}`;\n\n\t\tsuper(message, errorOptions);\n\n\t\tthis.errorData = issues;\n\t\tthis.response = response;\n\t\tthis.issueCause = issueCause;\n\t}\n\n\t/**\n\t * @description Checks if the given error is an instance of ValidationError\n\t * @param error - The error to check\n\t * @returns true if the error is an instance of ValidationError, false otherwise\n\t */\n\tstatic override isError(error: unknown): error is ValidationError {\n\t\tif (!isObject<ValidationError>(error)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (error instanceof ValidationError) {\n\t\t\treturn true;\n\t\t}\n\n\t\tconst actualError = error as ValidationError;\n\n\t\treturn (\n\t\t\tactualError.validationErrorSymbol === validationErrorSymbol\n\t\t\t// eslint-disable-next-line ts-eslint/no-unnecessary-condition -- Allow\n\t\t\t&& actualError.name === \"ValidationError\"\n\t\t);\n\t}\n}\n","import type { AuthOption } from \"./auth\";\nimport { fallBackRouteSchemaKey, type FallBackRouteSchemaKey } from \"./constants/validation\";\nimport type {\n\tBaseCallApiExtraOptions,\n\tCallApiExtraOptions,\n\tCallApiRequestOptions,\n\tGlobalMeta,\n} from \"./types/common\";\nimport type { Body, HeadersOption, MethodUnion } from \"./types/conditional-types\";\nimport type { StandardSchemaV1 } from \"./types/standard-schema\";\nimport {\n\tdefineEnum,\n\ttype AnyFunction,\n\ttype AnyString,\n\ttype Awaitable,\n\ttype UnionDiscriminator,\n\ttype UnionToIntersection,\n} from \"./types/type-helpers\";\nimport {\n\tatSymbol,\n\textractMethodFromURL,\n\tnormalizeURL,\n\ttype AtSymbol,\n\ttype Params,\n\ttype Query,\n} from \"./url\";\nimport { toArray } from \"./utils/common\";\nimport { ValidationError } from \"./utils/external/error\";\nimport { isFunction, isObject } from \"./utils/guards\";\n\ntype ResultVariant = \"infer-input\" | \"infer-output\";\n\nexport type InferSchemaResult<TSchema, TFallbackResult, TResultVariant extends ResultVariant> =\n\t// == Checking for undefined first and returning fallback to avoid type errors when passing the config around (weird tbh)\n\tundefined extends TSchema ? TFallbackResult\n\t: TSchema extends StandardSchemaV1 ?\n\t\tTResultVariant extends \"infer-input\" ?\n\t\t\tStandardSchemaV1.InferInput<TSchema>\n\t\t:\tStandardSchemaV1.InferOutput<TSchema>\n\t: TSchema extends AnyFunction<infer TResult> ? Awaited<TResult>\n\t: TFallbackResult;\n\nexport type InferSchemaOutput<TSchema, TFallbackResult = unknown> = InferSchemaResult<\n\tTSchema,\n\tTFallbackResult,\n\t\"infer-output\"\n>;\n\nexport type InferSchemaInput<TSchema, TFallbackResult = unknown> = InferSchemaResult<\n\tTSchema,\n\tTFallbackResult,\n\t\"infer-input\"\n>;\n\nconst handleValidatorFunction = <TInput>(\n\tvalidator: AnyFunction,\n\tinputData: TInput\n): Promise<StandardSchemaV1.Result<TInput>> => {\n\tconst result = new Promise((resolve) => resolve(validator(inputData as never)))\n\t\t.then((value) => ({ issues: undefined, value: value as never }))\n\t\t.catch((error) => ({ issues: toArray(error) as never, value: undefined }));\n\n\treturn result;\n};\n\nexport const getValidatedValue = <\n\tTSchema extends AnyFunction | StandardSchemaV1,\n\tTVariant extends \"async\" | \"sync\",\n>(\n\tinputValue: InferSchemaOutput<TSchema>,\n\tschema?: TSchema,\n\t_ignoredOptions?: { variant: TVariant }\n): TVariant extends \"async\" ? Promise<StandardSchemaV1.Result<typeof inputValue>>\n:\tStandardSchemaV1.Result<typeof inputValue> => {\n\tif (!schema) {\n\t\treturn { issues: undefined, value: inputValue } as never;\n\t}\n\n\tconst result =\n\t\tisFunction(schema) ?\n\t\t\thandleValidatorFunction(schema, inputValue)\n\t\t:\tschema[\"~standard\"].validate(inputValue);\n\n\treturn result as never;\n};\n\nconst callApiSchemaParser = async <\n\tTFullSchema extends CallApiSchema,\n\tTSchemaName extends keyof CallApiSchema,\n\tTSchema extends NonNullable<TFullSchema[TSchemaName]>,\n>(\n\tfullSchema: TFullSchema | undefined,\n\tschemaName: TSchemaName,\n\toptions: { inputValue: InferSchemaInput<TSchema>; response?: Response | null }\n): Promise<InferSchemaOutput<TSchema>> => {\n\tconst { inputValue, response } = options;\n\n\tconst schema = fullSchema?.[schemaName];\n\n\tconst result = await getValidatedValue(inputValue, schema);\n\n\tif (result.issues) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: schemaName,\n\t\t\tissues: result.issues,\n\t\t\tresponse: response ?? null,\n\t\t});\n\t}\n\n\treturn result.value as never;\n};\n\ntype BooleanObject = {\n\t[Key in keyof CallApiSchema]: boolean;\n};\n\nexport interface CallApiSchemaConfig {\n\t/**\n\t * The base url of the schema. By default it's the baseURL of the callApi instance.\n\t */\n\tbaseURL?: \"\" | AnyString;\n\n\t/**\n\t * Disables runtime validation for the schema.\n\t */\n\tdisableRuntimeValidation?: boolean | BooleanObject;\n\n\t/**\n\t * If `true`, the original input value will be used instead of the transformed/validated output.\n\t *\n\t * When true, the original input is returned unchanged after validation, ignoring any schema-level\n\t * transformations such as type coercion, default values, or field mapping. Only the validation\n\t * step is executed; the resulting value is discarded in favor of the raw input.\n\t */\n\tdisableRuntimeValidationTransform?: boolean | BooleanObject;\n\n\t/**\n\t * Optional url prefix that will be substituted for the `baseURL` of the schemaConfig at runtime.\n\t *\n\t * Enables a short, stable prefix for routes while keeping the full `baseURL` centralized in config.\n\t * Keeps route definitions concise and shields them from changes to the underlying base URL.\n\t */\n\tprefix?: \"\" | AnyString;\n\n\t/**\n\t * Controls the strictness of API route validation.\n\t *\n\t * When true:\n\t * - Only routes explicitly defined in the schema will be considered valid to typescript and the runtime.\n\t * - Attempting to call routes not defined in the schema will result in both type errors and runtime validation errors.\n\t * - Useful for ensuring API calls conform exactly to your schema definition\n\t *\n\t * When false or undefined (default):\n\t * - All routes will be allowed, whether they are defined in the schema or not\n\t */\n\tstrict?: boolean;\n}\n\nexport type CallApiSchemaType<TInput> =\n\t| StandardSchemaV1<TInput | undefined>\n\t| ((value: TInput) => Awaitable<TInput | undefined>);\n\nexport interface CallApiSchema {\n\tauth?: CallApiSchemaType<AuthOption>;\n\n\t/**\n\t * The schema to use for validating the request body.\n\t */\n\tbody?: CallApiSchemaType<Body>;\n\n\t/**\n\t * The schema to use for validating the response data.\n\t */\n\tdata?: CallApiSchemaType<unknown>;\n\n\t/**\n\t * The schema to use for validating the response error data.\n\t */\n\terrorData?: CallApiSchemaType<unknown>;\n\n\t/**\n\t * The schema to use for validating the request headers.\n\t */\n\theaders?: CallApiSchemaType<HeadersOption>;\n\n\t/**\n\t * The schema to use for validating the meta option.\n\t */\n\tmeta?: CallApiSchemaType<GlobalMeta>;\n\n\t/**\n\t * The schema to use for validating the request method.\n\t */\n\tmethod?: CallApiSchemaType<MethodUnion>;\n\n\t/**\n\t * The schema to use for validating the request url parameters.\n\t */\n\tparams?: CallApiSchemaType<Params>;\n\n\t/**\n\t * The schema to use for validating the request url queries.\n\t */\n\tquery?: CallApiSchemaType<Query>;\n}\n\nexport const routeKeyMethods = defineEnum([\"delete\", \"get\", \"patch\", \"post\", \"put\"]);\n\nexport type RouteKeyMethods = (typeof routeKeyMethods)[number];\n\nexport type RouteKeyMethodsURLUnion = `${AtSymbol}${RouteKeyMethods}/`;\n\nexport type BaseSchemaRouteKeyPrefixes = FallBackRouteSchemaKey | RouteKeyMethodsURLUnion;\n\nexport type BaseCallApiSchemaRoutes = Partial<\n\tRecord<AnyString | BaseSchemaRouteKeyPrefixes, CallApiSchema>\n>;\n\nexport type BaseCallApiSchemaAndConfig = {\n\tconfig?: CallApiSchemaConfig;\n\troutes: BaseCallApiSchemaRoutes;\n};\n\ntype ValidationOptions<\n\tTSchema extends CallApiSchema[keyof CallApiSchema] = CallApiSchema[keyof CallApiSchema],\n> = {\n\tinputValue: InferSchemaInput<TSchema>;\n\tresponse?: Response | null;\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n\tschemaConfig: CallApiSchemaConfig | undefined;\n};\n\nexport const handleSchemaValidation = async <\n\tTFullSchema extends CallApiSchema,\n\tTSchemaName extends keyof CallApiSchema,\n\tTSchema extends NonNullable<TFullSchema[TSchemaName]>,\n>(\n\tfullSchema: TFullSchema | undefined,\n\tschemaName: TSchemaName,\n\tvalidationOptions: ValidationOptions<TSchema>\n): Promise<InferSchemaOutput<TSchema>> => {\n\tconst { inputValue, response, resultMode, schemaConfig } = validationOptions;\n\n\t// == If resultMode is set to `fetchApi`, return the input value as is (which is going to be `null` in this)\n\tif (resultMode === \"fetchApi\" && (schemaName === \"data\" || schemaName === \"errorData\")) {\n\t\treturn inputValue as never;\n\t}\n\n\tconst disableRuntimeValidationBooleanObject =\n\t\tisObject(schemaConfig?.disableRuntimeValidation) ? schemaConfig.disableRuntimeValidation : {};\n\n\tconst shouldDisableRuntimeValidation =\n\t\tschemaConfig?.disableRuntimeValidation === true\n\t\t|| disableRuntimeValidationBooleanObject[schemaName] === true;\n\n\tif (shouldDisableRuntimeValidation) {\n\t\treturn inputValue as never;\n\t}\n\n\tconst validResult = await callApiSchemaParser(fullSchema, schemaName, { inputValue, response });\n\n\tconst disableResultApplicationBooleanObject =\n\t\tisObject(schemaConfig?.disableRuntimeValidationTransform) ?\n\t\t\tschemaConfig.disableRuntimeValidationTransform\n\t\t:\t{};\n\n\tconst shouldDisableResultApplication =\n\t\tschemaConfig?.disableRuntimeValidationTransform === true\n\t\t|| disableResultApplicationBooleanObject[schemaName] === true;\n\n\tif (shouldDisableResultApplication) {\n\t\treturn inputValue as never;\n\t}\n\n\treturn validResult as never;\n};\n\ntype LastOf<TValue> =\n\tUnionToIntersection<TValue extends unknown ? () => TValue : never> extends () => infer R ? R : never;\n\ntype Push<TArray extends unknown[], TArrayItem> = [...TArray, TArrayItem];\n\ntype UnionToTuple<\n\tTUnion,\n\tTComputedLastUnion = LastOf<TUnion>,\n\tTComputedIsUnionEqualToNever = [TUnion] extends [never] ? true : false,\n> =\n\ttrue extends TComputedIsUnionEqualToNever ? []\n\t:\tPush<UnionToTuple<Exclude<TUnion, TComputedLastUnion>>, TComputedLastUnion>;\n\nexport type Tuple<TTuple, TArray extends TTuple[] = []> =\n\tUnionToTuple<TTuple>[\"length\"] extends TArray[\"length\"] ? [...TArray]\n\t:\tTuple<TTuple, [TTuple, ...TArray]>;\n\ntype ExtraOptionsValidationOptions = {\n\toptions: CallApiExtraOptions;\n};\n\nconst extraOptionsToBeValidated = [\"meta\", \"params\", \"query\", \"auth\"] satisfies Tuple<\n\tExtract<keyof CallApiSchema, keyof CallApiExtraOptions>\n>;\n\ntype RequestOptionsValidationOptions = {\n\trequest: CallApiRequestOptions;\n};\n\nconst requestOptionsToBeValidated = [\"body\", \"headers\", \"method\"] satisfies Tuple<\n\tExtract<keyof CallApiSchema, keyof CallApiRequestOptions>\n>;\n\ntype OptionValidationOptions = UnionDiscriminator<\n\t[ExtraOptionsValidationOptions, RequestOptionsValidationOptions]\n> & {\n\tschema: CallApiSchema | undefined;\n\tschemaConfig: CallApiSchemaConfig | undefined;\n};\n\nconst handleOptionsValidation = async <TValidationOptions extends OptionValidationOptions>(\n\tvalidationOptions: TValidationOptions\n): Promise<\n\tundefined extends TValidationOptions[\"options\"] ?\n\t\tPick<CallApiRequestOptions, (typeof requestOptionsToBeValidated)[number]>\n\t:\tPick<CallApiExtraOptions, (typeof extraOptionsToBeValidated)[number]>\n> => {\n\tconst { options, request, schema, schemaConfig } = validationOptions;\n\n\tconst resolvedOptionsToBeValidated = options ? extraOptionsToBeValidated : requestOptionsToBeValidated;\n\n\tconst resolvedOptions = options ?? request;\n\n\tconst validationResultArray = await Promise.all(\n\t\tresolvedOptionsToBeValidated.map((schemaName) =>\n\t\t\thandleSchemaValidation(schema, schemaName, {\n\t\t\t\tinputValue: resolvedOptions[schemaName as keyof typeof resolvedOptions],\n\t\t\t\tresultMode: options?.resultMode,\n\t\t\t\tschemaConfig,\n\t\t\t})\n\t\t)\n\t);\n\n\tconst validatedResultObject: Record<string, unknown> = {};\n\n\tfor (const [index, schemaName] of resolvedOptionsToBeValidated.entries()) {\n\t\tconst validationResult = validationResultArray[index];\n\n\t\tif (validationResult === undefined) continue;\n\n\t\tvalidatedResultObject[schemaName] = validationResult;\n\t}\n\n\treturn validatedResultObject;\n};\n\nexport const handleConfigValidation = async (\n\tvalidationOptions: ExtraOptionsValidationOptions\n\t\t& GetResolvedSchemaContext\n\t\t& RequestOptionsValidationOptions\n) => {\n\tconst { baseExtraOptions, currentRouteSchemaKey, extraOptions, options, request } = validationOptions;\n\n\tconst { currentRouteSchema, resolvedSchema } = getResolvedSchema({\n\t\tbaseExtraOptions,\n\t\tcurrentRouteSchemaKey,\n\t\textraOptions,\n\t});\n\n\tconst resolvedSchemaConfig = getResolvedSchemaConfig({ baseExtraOptions, extraOptions });\n\n\tif (resolvedSchemaConfig?.strict === true && !currentRouteSchema) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: \"schemaConfig-(strict)\",\n\t\t\tissues: [{ message: `Strict Mode - No schema found for route '${currentRouteSchemaKey}' ` }],\n\t\t\tresponse: null,\n\t\t});\n\t}\n\n\tconst [extraOptionsValidationResult, requestOptionsValidationResult] = await Promise.all([\n\t\thandleOptionsValidation({\n\t\t\toptions,\n\t\t\tschema: resolvedSchema,\n\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t}),\n\t\thandleOptionsValidation({\n\t\t\trequest,\n\t\t\tschema: resolvedSchema,\n\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t}),\n\t]);\n\n\treturn {\n\t\textraOptionsValidationResult,\n\t\trequestOptionsValidationResult,\n\t\tresolvedSchema,\n\t\tresolvedSchemaConfig,\n\t};\n};\n\ntype GetResolvedSchemaContext = {\n\tbaseExtraOptions: BaseCallApiExtraOptions;\n\tcurrentRouteSchemaKey: string;\n\textraOptions: CallApiExtraOptions;\n};\n\nexport const getResolvedSchema = (context: GetResolvedSchemaContext) => {\n\tconst { baseExtraOptions, currentRouteSchemaKey, extraOptions } = context;\n\n\tconst fallbackRouteSchema = baseExtraOptions.schema?.routes[fallBackRouteSchemaKey];\n\tconst currentRouteSchema = baseExtraOptions.schema?.routes[currentRouteSchemaKey];\n\n\tconst resolvedRouteSchema = {\n\t\t...fallbackRouteSchema,\n\t\t// == Current route schema takes precedence over fallback route schema\n\t\t...currentRouteSchema,\n\t} satisfies CallApiSchema as CallApiSchema | undefined;\n\n\tconst resolvedSchema =\n\t\tisFunction(extraOptions.schema) ?\n\t\t\textraOptions.schema({\n\t\t\t\tbaseSchemaRoutes: baseExtraOptions.schema?.routes ?? {},\n\t\t\t\tcurrentRouteSchema: resolvedRouteSchema ?? {},\n\t\t\t\tcurrentRouteSchemaKey,\n\t\t\t})\n\t\t:\t(extraOptions.schema ?? resolvedRouteSchema);\n\n\treturn { currentRouteSchema, resolvedSchema };\n};\n\nexport const getResolvedSchemaConfig = (\n\tcontext: Omit<GetResolvedSchemaContext, \"currentRouteSchemaKey\">\n) => {\n\tconst { baseExtraOptions, extraOptions } = context;\n\n\tconst resolvedSchemaConfig =\n\t\tisFunction(extraOptions.schemaConfig) ?\n\t\t\textraOptions.schemaConfig({ baseSchemaConfig: baseExtraOptions.schema?.config ?? {} })\n\t\t:\t(extraOptions.schemaConfig ?? baseExtraOptions.schema?.config);\n\n\treturn resolvedSchemaConfig;\n};\n\nconst removeLeadingSlash = (value: string) => (value.startsWith(\"/\") ? value.slice(1) : value);\n\nconst extractURLParts = (initURL: string) => {\n\treturn {\n\t\tmethodFromURL: extractMethodFromURL(initURL),\n\t\tpathWithoutMethod: normalizeURL(initURL, { retainLeadingSlashForRelativeURLs: false }),\n\t};\n};\n\nconst mergeURLParts = (options: { method: string | undefined; path: string }): string => {\n\tconst { method, path } = options;\n\n\treturn method ? `${atSymbol}${method}/${removeLeadingSlash(path)}` : path;\n};\n\nexport const getCurrentRouteSchemaKeyAndMainInitURL = (\n\tcontext: Pick<GetResolvedSchemaContext, \"baseExtraOptions\" | \"extraOptions\"> & { initURL: string }\n) => {\n\tconst { baseExtraOptions, extraOptions, initURL } = context;\n\n\tconst schemaConfig = getResolvedSchemaConfig({ baseExtraOptions, extraOptions });\n\n\tlet currentRouteSchemaKey = initURL;\n\tlet mainInitURL = initURL;\n\n\tconst { methodFromURL, pathWithoutMethod } = extractURLParts(initURL);\n\n\tconst prefixWithoutLeadingSlash = schemaConfig?.prefix && removeLeadingSlash(schemaConfig.prefix);\n\n\tif (prefixWithoutLeadingSlash && pathWithoutMethod.startsWith(prefixWithoutLeadingSlash)) {\n\t\tconst restOfPathWithoutPrefix = pathWithoutMethod.slice(prefixWithoutLeadingSlash.length);\n\n\t\tcurrentRouteSchemaKey = mergeURLParts({ method: methodFromURL, path: restOfPathWithoutPrefix });\n\n\t\tconst pathWithReplacedPrefix = pathWithoutMethod.replace(\n\t\t\tprefixWithoutLeadingSlash,\n\t\t\tschemaConfig.baseURL ?? \"\"\n\t\t);\n\n\t\tmainInitURL = mergeURLParts({ method: methodFromURL, path: pathWithReplacedPrefix });\n\t}\n\n\tif (schemaConfig?.baseURL && pathWithoutMethod.startsWith(schemaConfig.baseURL)) {\n\t\tconst restOfPathWithoutBaseURL = pathWithoutMethod.slice(schemaConfig.baseURL.length);\n\n\t\tcurrentRouteSchemaKey = mergeURLParts({ method: methodFromURL, path: restOfPathWithoutBaseURL });\n\t}\n\n\treturn { currentRouteSchemaKey, mainInitURL };\n};\n","import type { CallApiExtraOptions } from \"./types/common\";\nimport type { AnyString, UnmaskType } from \"./types/type-helpers\";\nimport { isArray } from \"./utils/guards\";\nimport { routeKeyMethods, type RouteKeyMethodsURLUnion } from \"./validation\";\n\nexport const slash = \"/\";\nconst colon = \":\";\nconst openBrace = \"{\";\nconst closeBrace = \"}\";\n\nconst handleArrayParams = (url: string, params: Extract<CallApiExtraOptions[\"params\"], unknown[]>) => {\n\tlet newUrl = url;\n\n\tconst urlParts = newUrl.split(slash);\n\n\t// == Find all parameters in order (both :param and {param} patterns)\n\tconst matchedParamsArray: string[] = [];\n\n\tfor (const part of urlParts) {\n\t\tconst isMatch = part.startsWith(colon) || (part.startsWith(openBrace) && part.endsWith(closeBrace));\n\n\t\tif (!isMatch) continue;\n\n\t\tmatchedParamsArray.push(part);\n\t}\n\n\tfor (const [paramIndex, matchedParam] of matchedParamsArray.entries()) {\n\t\tconst stringParamValue = String(params[paramIndex]);\n\t\tnewUrl = newUrl.replace(matchedParam, stringParamValue);\n\t}\n\n\treturn newUrl;\n};\n\nconst handleObjectParams = (\n\turl: string,\n\tparams: Extract<CallApiExtraOptions[\"params\"], Record<string, unknown>>\n) => {\n\tlet newUrl = url;\n\n\tfor (const [paramKey, paramValue] of Object.entries(params)) {\n\t\t// == Replace both :param and {param} patterns\n\t\tconst colonPattern = `${colon}${paramKey}` as const;\n\t\tconst bracePattern = `${openBrace}${paramKey}${closeBrace}` as const;\n\n\t\tconst stringValue = String(paramValue);\n\n\t\tnewUrl = newUrl.replace(colonPattern, stringValue);\n\t\tnewUrl = newUrl.replace(bracePattern, stringValue);\n\t}\n\n\treturn newUrl;\n};\n\nconst mergeUrlWithParams = (url: string, params: CallApiExtraOptions[\"params\"]) => {\n\tif (!params) {\n\t\treturn url;\n\t}\n\n\tconst newUrl = isArray(params) ? handleArrayParams(url, params) : handleObjectParams(url, params);\n\n\treturn newUrl;\n};\n\nconst questionMark = \"?\";\nconst ampersand = \"&\";\nconst mergeUrlWithQuery = (url: string, query: CallApiExtraOptions[\"query\"]): string => {\n\tif (!query) {\n\t\treturn url;\n\t}\n\n\tconst queryString = new URLSearchParams(query as Record<string, string> | URLSearchParams).toString();\n\n\tif (queryString.length === 0) {\n\t\treturn url;\n\t}\n\n\tif (url.endsWith(questionMark)) {\n\t\treturn `${url}${queryString}`;\n\t}\n\n\tif (url.includes(questionMark)) {\n\t\treturn `${url}${ampersand}${queryString}`;\n\t}\n\n\treturn `${url}${questionMark}${queryString}`;\n};\n\n/**\n * @description Extracts the HTTP method from method-prefixed route patterns.\n *\n * Analyzes URLs that start with method modifiers (e.g., \"@get/\", \"@post/\") and extracts\n * the HTTP method for use in API requests. This enables method specification directly\n * in route definitions.\n *\n * @param initURL - The URL string to analyze for method modifiers\n * @returns The extracted HTTP method (lowercase) if found, otherwise undefined\n *\n * @example\n * ```typescript\n * extractMethodFromURL(\"@get/users\"); // Returns: \"get\"\n * extractMethodFromURL(\"@post/users\"); // Returns: \"post\"\n * ```\n */\nexport const extractMethodFromURL = (initURL: string | undefined) => {\n\tif (!initURL?.startsWith(\"@\")) return;\n\n\tconst methodFromURL = routeKeyMethods.find((method) =>\n\t\tinitURL.startsWith(`${atSymbol}${method}${slash}`)\n\t);\n\n\tif (!methodFromURL) return;\n\n\treturn methodFromURL;\n};\n\ntype NormalizeURLOptions = {\n\tretainLeadingSlashForRelativeURLs?: boolean;\n};\n\nexport const atSymbol = \"@\";\nexport type AtSymbol = typeof atSymbol;\n\nexport const normalizeURL = (initURL: string, options: NormalizeURLOptions = {}) => {\n\tconst { retainLeadingSlashForRelativeURLs = true } = options;\n\n\tconst methodFromURL = extractMethodFromURL(initURL);\n\n\tif (!methodFromURL) {\n\t\treturn initURL;\n\t}\n\n\tconst normalizedURL =\n\t\tretainLeadingSlashForRelativeURLs && !initURL.includes(\"http\") ?\n\t\t\tinitURL.replace(`${atSymbol}${methodFromURL}`, \"\")\n\t\t:\tinitURL.replace(`${atSymbol}${methodFromURL}${slash}`, \"\");\n\n\treturn normalizedURL;\n};\n\ntype GetFullURLOptions = {\n\t/** Base URL to prepend to relative URLs */\n\tbaseURL: string | undefined;\n\t/** Initial URL pattern that may contain parameters and method modifiers */\n\tinitURL: string;\n\t/** Parameters to substitute into the URL path */\n\tparams: CallApiExtraOptions[\"params\"];\n\t/** Query parameters to append to the URL */\n\tquery: CallApiExtraOptions[\"query\"];\n};\n\nconst getFullURL = (initURL: string, baseURL: string | undefined) => {\n\tif (!baseURL || initURL.startsWith(\"http\")) {\n\t\treturn initURL;\n\t}\n\n\tconst shouldAddSlash = initURL.length > 0 && !initURL.startsWith(slash) && !baseURL.endsWith(slash);\n\n\treturn shouldAddSlash ? `${baseURL}${slash}${initURL}` : `${baseURL}${initURL}`;\n};\n\nexport const getFullAndNormalizedURL = (options: GetFullURLOptions) => {\n\tconst { baseURL, initURL, params, query } = options;\n\n\tconst normalizedInitURL = normalizeURL(initURL);\n\n\tconst initURLWithParams = mergeUrlWithParams(normalizedInitURL, params);\n\n\tconst initURLWithParamsAndQuery = mergeUrlWithQuery(initURLWithParams, query);\n\n\tconst fullURL = getFullURL(initURLWithParamsAndQuery, baseURL);\n\n\tif (!URL.canParse(fullURL)) {\n\t\tconst errorMessage =\n\t\t\t!baseURL ?\n\t\t\t\t`Invalid URL '${initURL}'. Are you passing a relative url to CallApi without setting the 'baseURL' option?`\n\t\t\t:\t`Invalid URL '${fullURL}'. Please validate that you are passing the correct url.`;\n\n\t\tconsole.error(errorMessage);\n\t}\n\n\treturn {\n\t\tfullURL,\n\t\tnormalizedInitURL,\n\t};\n};\n\nexport type AllowedQueryParamValues = UnmaskType<boolean | number | string>;\n\nexport type RecordStyleParams = UnmaskType<Record<string, AllowedQueryParamValues>>;\n\nexport type TupleStyleParams = UnmaskType<AllowedQueryParamValues[]>;\n\nexport type Params = UnmaskType<RecordStyleParams | TupleStyleParams>;\n\nexport type Query = UnmaskType<Record<string, AllowedQueryParamValues> | URLSearchParams>;\n\nexport type InitURLOrURLObject = AnyString | RouteKeyMethodsURLUnion | URL;\n\nexport interface URLOptions {\n\t/**\n\t * Base URL for all API requests. Will only be prepended to relative URLs.\n\t *\n\t * Absolute URLs (starting with http/https) will not be prepended by the baseURL.\n\t *\n\t * @example\n\t * ```ts\n\t * // Set base URL for all requests\n\t * baseURL: \"https://api.example.com/v1\"\n\t *\n\t * // Then use relative URLs in requests\n\t * callApi(\"/users\") // → https://api.example.com/v1/users\n\t * callApi(\"/posts/123\") // → https://api.example.com/v1/posts/123\n\t *\n\t * // Environment-specific base URLs\n\t * baseURL: process.env.NODE_ENV === \"production\"\n\t * ? \"https://api.example.com\"\n\t * : \"http://localhost:3000/api\"\n\t * ```\n\t */\n\tbaseURL?: string;\n\n\t/**\n\t * Resolved request URL after processing baseURL, parameters, and query strings (readonly)\n\t *\n\t * This is the final URL that will be used for the HTTP request, computed from\n\t * baseURL, initURL, params, and query parameters.\n\t *\n\t */\n\treadonly fullURL?: string;\n\n\t/**\n\t * The original URL string passed to the callApi instance (readonly)\n\t *\n\t * This preserves the original URL as provided, including any method modifiers like \"@get/\" or \"@post/\".\n\t *\n\t */\n\treadonly initURL?: string;\n\n\t/**\n\t * The URL string after normalization, with method modifiers removed(readonly)\n\t *\n\t * Method modifiers like \"@get/\", \"@post/\" are stripped to create a clean URL\n\t * for parameter substitution and final URL construction.\n\t *\n\t */\n\treadonly initURLNormalized?: string;\n\n\t/**\n\t * Parameters to be substituted into URL path segments.\n\t *\n\t * Supports both object-style (named parameters) and array-style (positional parameters)\n\t * for flexible URL parameter substitution.\n\t *\n\t * @example\n\t * ```typescript\n\t * // Object-style parameters (recommended)\n\t * const namedParams: URLOptions = {\n\t * initURL: \"/users/:userId/posts/:postId\",\n\t * params: { userId: \"123\", postId: \"456\" }\n\t * };\n\t * // Results in: /users/123/posts/456\n\t *\n\t * // Array-style parameters (positional)\n\t * const positionalParams: URLOptions = {\n\t * initURL: \"/users/:userId/posts/:postId\",\n\t * params: [\"123\", \"456\"] // Maps in order: userId=123, postId=456\n\t * };\n\t * // Results in: /users/123/posts/456\n\t *\n\t * // Single parameter\n\t * const singleParam: URLOptions = {\n\t * initURL: \"/users/:id\",\n\t * params: { id: \"user-123\" }\n\t * };\n\t * // Results in: /users/user-123\n\t * ```\n\t */\n\tparams?: Params;\n\n\t/**\n\t * Query parameters to append to the URL as search parameters.\n\t *\n\t * These will be serialized into the URL query string using standard\n\t * URL encoding practices.\n\t *\n\t * @example\n\t * ```typescript\n\t * // Basic query parameters\n\t * const queryOptions: URLOptions = {\n\t * initURL: \"/users\",\n\t * query: {\n\t * page: 1,\n\t * limit: 10,\n\t * search: \"john doe\",\n\t * active: true\n\t * }\n\t * };\n\t * // Results in: /users?page=1&limit=10&search=john%20doe&active=true\n\t *\n\t * // Filtering and sorting\n\t * const filterOptions: URLOptions = {\n\t * initURL: \"/products\",\n\t * query: {\n\t * category: \"electronics\",\n\t * minPrice: 100,\n\t * maxPrice: 500,\n\t * sortBy: \"price\",\n\t * order: \"asc\"\n\t * }\n\t * };\n\t * // Results in: /products?category=electronics&minPrice=100&maxPrice=500&sortBy=price&order=asc\n\t * ```\n\t */\n\tquery?: Query;\n}\n","import { getAuthHeader } from \"../auth\";\nimport { fetchSpecificKeys } from \"../constants/common\";\nimport { extraOptionDefaults, requestOptionDefaults } from \"../constants/defaults\";\nimport type { RequestContext } from \"../hooks\";\nimport type { Middlewares } from \"../middlewares\";\nimport type { BaseCallApiExtraOptions, CallApiExtraOptions, CallApiRequestOptions } from \"../types/common\";\nimport type { InferHeadersOption } from \"../types/conditional-types\";\nimport type { DistributiveOmit } from \"../types/type-helpers\";\nimport { extractMethodFromURL } from \"../url\";\nimport type { CallApiSchema } from \"../validation\";\nimport {\n\tisArray,\n\tisFunction,\n\tisPlainObject,\n\tisQueryString,\n\tisSerializableObject,\n\tisValidJsonString,\n} from \"./guards\";\n\nexport const omitKeys = <\n\tTObject extends Record<string, unknown>,\n\tconst TOmitArray extends Array<keyof TObject> | ReadonlyArray<keyof TObject>,\n>(\n\tinitialObject: TObject,\n\tkeysToOmit: TOmitArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToOmitSet = new Set(keysToOmit);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (!keysToOmitSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as DistributiveOmit<TObject, TOmitArray[number]>;\n};\n\nexport const pickKeys = <\n\tTObject extends Record<string, unknown>,\n\tconst TPickArray extends Array<keyof TObject> | ReadonlyArray<keyof TObject>,\n>(\n\tinitialObject: TObject,\n\tkeysToPick: TPickArray\n) => {\n\tconst updatedObject = {} as Record<string, unknown>;\n\n\tconst keysToPickSet = new Set(keysToPick);\n\n\tfor (const [key, value] of Object.entries(initialObject)) {\n\t\tif (keysToPickSet.has(key)) {\n\t\t\tupdatedObject[key] = value;\n\t\t}\n\t}\n\n\treturn updatedObject as Pick<TObject, TPickArray[number]>;\n};\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitBaseConfig = (baseConfig: Record<string, any>) =>\n\t[\n\t\tpickKeys(baseConfig, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(baseConfig, fetchSpecificKeys) as BaseCallApiExtraOptions,\n\t] as const;\n\n// eslint-disable-next-line ts-eslint/no-explicit-any -- Any is required here so that one can pass custom function type without type errors\nexport const splitConfig = (config: Record<string, any>) =>\n\t[\n\t\tpickKeys(config, fetchSpecificKeys) as CallApiRequestOptions,\n\t\tomitKeys(config, fetchSpecificKeys) as CallApiExtraOptions,\n\t] as const;\n\nexport const objectifyHeaders = (headers: CallApiRequestOptions[\"headers\"]) => {\n\tif (!headers) {\n\t\treturn {};\n\t}\n\n\tif (isPlainObject(headers)) {\n\t\treturn headers as Record<string, string>;\n\t}\n\n\treturn Object.fromEntries(headers);\n};\n\nexport type GetResolvedHeadersOptions = {\n\tbaseHeaders: CallApiRequestOptions[\"headers\"];\n\theaders: InferHeadersOption<CallApiSchema>[\"headers\"];\n};\n\nexport const getResolvedHeaders = (options: GetResolvedHeadersOptions) => {\n\tconst { baseHeaders, headers } = options;\n\n\tconst resolvedHeaders =\n\t\tisFunction(headers) ?\n\t\t\theaders({ baseHeaders: objectifyHeaders(baseHeaders) })\n\t\t:\t(headers ?? baseHeaders);\n\n\treturn objectifyHeaders(resolvedHeaders);\n};\n\nconst detectContentTypeHeader = (body: CallApiRequestOptions[\"body\"]) => {\n\tif (isQueryString(body)) {\n\t\treturn { \"Content-Type\": \"application/x-www-form-urlencoded\" };\n\t}\n\n\tif (isSerializableObject(body) || isValidJsonString(body)) {\n\t\treturn { Accept: \"application/json\", \"Content-Type\": \"application/json\" };\n\t}\n\n\treturn null;\n};\n\nexport type GetHeadersOptions = {\n\tauth: CallApiExtraOptions[\"auth\"];\n\tbody: CallApiRequestOptions[\"body\"];\n\tresolvedHeaders: CallApiRequestOptions[\"headers\"];\n};\n\nexport const getHeaders = async (options: GetHeadersOptions) => {\n\tconst { auth, body, resolvedHeaders } = options;\n\n\tconst authHeaderObject = await getAuthHeader(auth);\n\n\tconst resolvedHeadersObject = objectifyHeaders(resolvedHeaders);\n\n\tconst hasExistingContentType =\n\t\tObject.hasOwn(resolvedHeadersObject, \"Content-Type\")\n\t\t|| Object.hasOwn(resolvedHeadersObject, \"content-type\");\n\n\tif (!hasExistingContentType) {\n\t\tconst contentTypeHeader = detectContentTypeHeader(body);\n\t\tcontentTypeHeader && Object.assign(resolvedHeadersObject, contentTypeHeader);\n\t}\n\n\tconst headersObject: Record<string, string> = {\n\t\t...authHeaderObject,\n\t\t...resolvedHeadersObject,\n\t};\n\n\treturn headersObject;\n};\n\nexport type GetMethodContext = {\n\t/** The URL string that may contain method modifiers like \"@get/\" or \"@post/\" */\n\tinitURL: string | undefined;\n\t/** Explicitly specified HTTP method */\n\tmethod: CallApiRequestOptions[\"method\"];\n};\n\nexport const getMethod = (ctx: GetMethodContext) => {\n\tconst { initURL, method } = ctx;\n\n\treturn (\n\t\tmethod?.toUpperCase() ?? extractMethodFromURL(initURL)?.toUpperCase() ?? requestOptionDefaults.method\n\t);\n};\n\nexport type GetBodyOptions = Pick<GetHeadersOptions, \"body\" | \"resolvedHeaders\"> & {\n\tbodySerializer: CallApiExtraOptions[\"bodySerializer\"];\n};\n\nexport const getBody = (options: GetBodyOptions) => {\n\tconst { body, bodySerializer, resolvedHeaders } = options;\n\n\tconst headers = new Headers(resolvedHeaders as Record<string, string>);\n\n\tconst existingContentType = headers.get(\"content-type\");\n\n\tif (!existingContentType && isSerializableObject(body)) {\n\t\tconst selectedBodySerializer = bodySerializer ?? extraOptionDefaults.bodySerializer;\n\n\t\treturn selectedBodySerializer(body);\n\t}\n\n\tif (existingContentType === \"application/x-www-form-urlencoded\" && isSerializableObject(body)) {\n\t\treturn new URLSearchParams(body as Record<string, string>).toString();\n\t}\n\n\treturn body;\n};\n\nexport const getInitFetchImpl = (customFetchImpl: CallApiExtraOptions[\"customFetchImpl\"]) => {\n\tif (customFetchImpl) {\n\t\treturn customFetchImpl;\n\t}\n\n\tif (typeof globalThis !== \"undefined\" && isFunction(globalThis.fetch)) {\n\t\treturn globalThis.fetch;\n\t}\n\n\tthrow new Error(\"No fetch implementation found\");\n};\n\nexport const getFetchImpl = (context: {\n\tcustomFetchImpl: CallApiExtraOptions[\"customFetchImpl\"];\n\tfetchMiddleware: Middlewares[\"fetchMiddleware\"];\n\trequestContext: RequestContext;\n}) => {\n\tconst { customFetchImpl, fetchMiddleware, requestContext } = context;\n\n\tconst initFetchImpl = getInitFetchImpl(customFetchImpl);\n\n\tconst resolvedFetchImpl =\n\t\tfetchMiddleware ? fetchMiddleware({ ...requestContext, fetchImpl: initFetchImpl }) : initFetchImpl;\n\n\treturn resolvedFetchImpl;\n};\n\nexport const waitFor = (delay: number) => {\n\tif (delay === 0) return;\n\n\tconst promise = new Promise((resolve) => setTimeout(resolve, delay));\n\n\treturn promise;\n};\n\nexport const createCombinedSignal = (...signals: Array<AbortSignal | null | undefined>) => {\n\tconst combinedSignal = AbortSignal.any(signals.filter((signal) => signal != null));\n\n\treturn combinedSignal;\n};\n\nexport const createTimeoutSignal = (milliseconds: number | null | undefined) => {\n\tif (milliseconds == null) {\n\t\treturn null;\n\t}\n\n\treturn AbortSignal.timeout(milliseconds);\n};\n\nexport const deterministicHashFn = (value: unknown): string => {\n\treturn JSON.stringify(value, (_, val: unknown) => {\n\t\tif (!isPlainObject(val)) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// eslint-disable-next-line unicorn/no-array-sort -- Not necessary here\n\t\tconst sortedKeys = Object.keys(val).sort();\n\n\t\tconst result: Record<string, unknown> = {};\n\n\t\tfor (const key of sortedKeys) {\n\t\t\tresult[key] = val[key];\n\t\t}\n\n\t\treturn result;\n\t});\n};\n\nexport const toArray = (value: unknown) => (isArray(value) ? value : [value]);\n","import type { CallApiConfig, CallApiExtraOptions } from \"../types/common\";\nimport { defineEnum } from \"../types/type-helpers\";\nimport { deterministicHashFn } from \"../utils/common\";\n\nexport const extraOptionDefaults = Object.freeze(\n\tdefineEnum({\n\t\t// Common defaults\n\t\tbodySerializer: JSON.stringify,\n\t\tdefaultHTTPErrorMessage: \"Request failed unexpectedly\",\n\n\t\t// Dedupe defaults\n\t\t/* eslint-disable perfectionist/sort-objects -- Allow */\n\t\tdedupeCacheScope: \"local\",\n\t\tdedupeKey: (ctx) =>\n\t\t\t`${ctx.options.fullURL}-${deterministicHashFn({ options: ctx.options, request: ctx.request })}`,\n\t\tdedupeCacheScopeKey: \"default\",\n\t\tdedupeStrategy: \"cancel\",\n\t\t/* eslint-enable perfectionist/sort-objects -- Allow */\n\n\t\t// Hook defaults\n\t\thooksExecutionMode: \"parallel\",\n\n\t\t// Response defaults\n\t\tresponseParser: JSON.parse,\n\t\tresponseType: \"json\",\n\t\tresultMode: \"all\",\n\n\t\t// Retry Defaults\n\t\tretryAttempts: 0,\n\t\tretryCondition: () => true,\n\t\tretryDelay: 1000,\n\t\tretryMaxDelay: 10000,\n\t\tretryMethods: [\"GET\", \"POST\"],\n\t\tretryStatusCodes: [],\n\t\tretryStrategy: \"linear\",\n\t} satisfies CallApiExtraOptions)\n);\n\nexport const requestOptionDefaults = Object.freeze(\n\tdefineEnum({\n\t\tmethod: \"GET\",\n\t} satisfies CallApiConfig)\n);\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ declare const fetchSpecificKeys: readonly (keyof RequestInit | "duplex")[];
4
4
  //#region src/types/type-helpers.d.ts
5
5
  type AnyString = string & NonNullable<unknown>;
6
6
  type AnyNumber = number & NonNullable<unknown>;
7
- type AnyFunction<TResult$1 = unknown> = (...args: any[]) => TResult$1;
7
+ type AnyFunction<TResult = unknown> = (...args: any[]) => TResult;
8
8
  type Prettify<TObject> = NonNullable<unknown> & { [Key in keyof TObject]: TObject[Key] };
9
9
  type WriteableLevel = "deep" | "shallow";
10
10
  /**
@@ -853,8 +853,7 @@ interface URLOptions {
853
853
  type MakeSchemaOptionRequiredIfDefined<TSchemaOption extends CallApiSchema[keyof CallApiSchema], TObject> = undefined extends InferSchemaOutput<TSchemaOption, undefined> ? TObject : Required<TObject>;
854
854
  type MergeBaseWithRouteKey<TBaseURLOrPrefix extends string | undefined, TRouteKey extends string> = TBaseURLOrPrefix extends string ? TRouteKey extends `${AtSymbol}${infer TMethod extends RouteKeyMethods}/${infer TRestOfRoutKey}` ? `${AtSymbol}${TMethod}/${RemoveLeadingSlash<RemoveTrailingSlash<TBaseURLOrPrefix>>}/${RemoveLeadingSlash<TRestOfRoutKey>}` : `${TBaseURLOrPrefix}${TRouteKey}` : TRouteKey;
855
855
  type ApplyURLBasedConfig<TSchemaConfig extends CallApiSchemaConfig, TSchemaRouteKeys extends string> = TSchemaConfig["prefix"] extends string ? MergeBaseWithRouteKey<TSchemaConfig["prefix"], TSchemaRouteKeys> : TSchemaConfig["baseURL"] extends string ? MergeBaseWithRouteKey<TSchemaConfig["baseURL"], TSchemaRouteKeys> : TSchemaRouteKeys;
856
- type ApplyStrictConfig<TSchemaConfig extends CallApiSchemaConfig, TSchemaRouteKeys extends string> = TSchemaConfig["strict"] extends true ? TSchemaRouteKeys :
857
- // eslint-disable-next-line perfectionist/sort-union-types -- Don't sort union types
856
+ type ApplyStrictConfig<TSchemaConfig extends CallApiSchemaConfig, TSchemaRouteKeys extends string> = TSchemaConfig["strict"] extends true ? TSchemaRouteKeys : // eslint-disable-next-line perfectionist/sort-union-types -- Don't sort union types
858
857
  TSchemaRouteKeys | Exclude<InitURLOrURLObject, RouteKeyMethodsURLUnion>;
859
858
  type ApplySchemaConfiguration<TSchemaConfig extends CallApiSchemaConfig, TSchemaRouteKeys extends string> = ApplyStrictConfig<TSchemaConfig, ApplyURLBasedConfig<TSchemaConfig, TSchemaRouteKeys>>;
860
859
  type InferAllMainRouteKeys<TBaseSchemaRoutes extends BaseCallApiSchemaRoutes, TSchemaConfig extends CallApiSchemaConfig> = ApplySchemaConfiguration<TSchemaConfig, Exclude<Extract<keyof TBaseSchemaRoutes, string>, FallBackRouteSchemaKey>>;
@@ -974,10 +973,10 @@ type EmptyString = "";
974
973
  type EmptyTuple = readonly [];
975
974
  type StringTuple = readonly string[];
976
975
  type PossibleParamNamePatterns = `${string}:${string}` | `${string}{${string}}${"" | AnyString}`;
977
- type ExtractRouteParamNames<TCurrentRoute$1, TParamNamesAccumulator extends StringTuple = EmptyTuple> = TCurrentRoute$1 extends PossibleParamNamePatterns ? TCurrentRoute$1 extends `${infer TRoutePrefix}:${infer TParamAndRemainingRoute}` ? TParamAndRemainingRoute extends `${infer TCurrentParam}/${infer TRemainingRoute}` ? TCurrentParam extends EmptyString ? ExtractRouteParamNames<`${TRoutePrefix}/${TRemainingRoute}`, TParamNamesAccumulator> : ExtractRouteParamNames<`${TRoutePrefix}/${TRemainingRoute}`, [...TParamNamesAccumulator, TCurrentParam]> : TParamAndRemainingRoute extends `${infer TCurrentParam}` ? TCurrentParam extends EmptyString ? ExtractRouteParamNames<TRoutePrefix, TParamNamesAccumulator> : ExtractRouteParamNames<TRoutePrefix, [...TParamNamesAccumulator, TCurrentParam]> : ExtractRouteParamNames<TRoutePrefix, TParamNamesAccumulator> : TCurrentRoute$1 extends `${infer TRoutePrefix}{${infer TCurrentParam}}${infer TRemainingRoute}` ? TCurrentParam extends EmptyString ? ExtractRouteParamNames<`${TRoutePrefix}${TRemainingRoute}`, TParamNamesAccumulator> : ExtractRouteParamNames<`${TRoutePrefix}${TRemainingRoute}`, [...TParamNamesAccumulator, TCurrentParam]> : TParamNamesAccumulator : TParamNamesAccumulator;
976
+ type ExtractRouteParamNames<TCurrentRoute, TParamNamesAccumulator extends StringTuple = EmptyTuple> = TCurrentRoute extends PossibleParamNamePatterns ? TCurrentRoute extends `${infer TRoutePrefix}:${infer TParamAndRemainingRoute}` ? TParamAndRemainingRoute extends `${infer TCurrentParam}/${infer TRemainingRoute}` ? TCurrentParam extends EmptyString ? ExtractRouteParamNames<`${TRoutePrefix}/${TRemainingRoute}`, TParamNamesAccumulator> : ExtractRouteParamNames<`${TRoutePrefix}/${TRemainingRoute}`, [...TParamNamesAccumulator, TCurrentParam]> : TParamAndRemainingRoute extends `${infer TCurrentParam}` ? TCurrentParam extends EmptyString ? ExtractRouteParamNames<TRoutePrefix, TParamNamesAccumulator> : ExtractRouteParamNames<TRoutePrefix, [...TParamNamesAccumulator, TCurrentParam]> : ExtractRouteParamNames<TRoutePrefix, TParamNamesAccumulator> : TCurrentRoute extends `${infer TRoutePrefix}{${infer TCurrentParam}}${infer TRemainingRoute}` ? TCurrentParam extends EmptyString ? ExtractRouteParamNames<`${TRoutePrefix}${TRemainingRoute}`, TParamNamesAccumulator> : ExtractRouteParamNames<`${TRoutePrefix}${TRemainingRoute}`, [...TParamNamesAccumulator, TCurrentParam]> : TParamNamesAccumulator : TParamNamesAccumulator;
978
977
  type ConvertParamNamesToRecord<TParamNames extends StringTuple> = Prettify<TParamNames extends (readonly [infer TFirstParamName extends string, ...infer TRemainingParamNames extends StringTuple]) ? Record<TFirstParamName, AllowedQueryParamValues> & ConvertParamNamesToRecord<TRemainingParamNames> : NonNullable<unknown>>;
979
978
  type ConvertParamNamesToTuple<TParamNames extends StringTuple> = TParamNames extends readonly [string, ...infer TRemainingParamNames extends StringTuple] ? [AllowedQueryParamValues, ...ConvertParamNamesToTuple<TRemainingParamNames>] : [];
980
- type InferParamsFromRoute<TCurrentRoute$1> = ExtractRouteParamNames<TCurrentRoute$1> extends StringTuple ? ExtractRouteParamNames<TCurrentRoute$1> extends EmptyTuple ? Params : ConvertParamNamesToRecord<ExtractRouteParamNames<TCurrentRoute$1>> | ConvertParamNamesToTuple<ExtractRouteParamNames<TCurrentRoute$1>> : Params;
979
+ type InferParamsFromRoute<TCurrentRoute> = ExtractRouteParamNames<TCurrentRoute> extends StringTuple ? ExtractRouteParamNames<TCurrentRoute> extends EmptyTuple ? Params : ConvertParamNamesToRecord<ExtractRouteParamNames<TCurrentRoute>> | ConvertParamNamesToTuple<ExtractRouteParamNames<TCurrentRoute>> : Params;
981
980
  type MakeParamsOptionRequired<TParamsSchemaOption extends CallApiSchema["params"], TBaseSchemaRoutes extends BaseCallApiSchemaRoutes, TCurrentRouteSchemaKey extends string, TObject> = MakeSchemaOptionRequiredIfDefined<TParamsSchemaOption, Params extends InferParamsFromRoute<TCurrentRouteSchemaKey> ? TObject : TCurrentRouteSchemaKey extends Extract<keyof TBaseSchemaRoutes, TCurrentRouteSchemaKey> ? undefined extends InferSchemaOutput<TParamsSchemaOption, null> ? TObject : Required<TObject> : TObject>;
982
981
  type InferParamsOption<TSchema extends CallApiSchema, TBaseSchemaRoutes extends BaseCallApiSchemaRoutes, TCurrentRouteSchemaKey extends string> = MakeParamsOptionRequired<TSchema["params"], TBaseSchemaRoutes, TCurrentRouteSchemaKey, {
983
982
  /**
@@ -1864,4 +1863,4 @@ declare const callApi: <TData = unknown, TErrorData = unknown, TResultMode exten
1864
1863
  }, TSchema, CallApiSchemaConfig, TSchemaConfig, TInitURL, TCurrentRouteSchemaKey, DefaultPluginArray, TPluginArray>) => Promise<TComputedResult>;
1865
1864
  //#endregion
1866
1865
  export { HooksOrHooksArray as $, HTTPError as A, CallApiSchema as B, CallApiRequestOptions as C, GetCallApiContextRequired as D, GetCallApiContext as E, InferInitURL as F, FallBackRouteSchemaKey as G, CallApiSchemaType as H, InferParamsFromRoute as I, FetchMiddlewareContext as J, fallBackRouteSchemaKey as K, URLOptions as L, RetryOptions as M, GetCurrentRouteSchemaKey as N, InstanceContext as O, InferAllMainRouteKeys as P, Hooks as Q, BaseCallApiSchemaRoutes as R, CallApiParameters as S, CallApiResultLoose as T, InferSchemaInput as U, CallApiSchemaConfig as V, InferSchemaOutput as W, DedupeOptions as X, Middlewares as Y, ErrorContext as Z, BaseCallApiConfig as _, CallApiPlugin as a, SuccessContext as at, CallApiExtraOptions as b, PluginSetupContext as c, Writeable as ct, CallApiResultSuccessVariant as d, RequestContext as et, PossibleHTTPError as f, ResultModeType as g, ResponseTypeType as h, DefaultCallApiContext as i, ResponseStreamContext as it, ValidationError as j, Register as k, CallApiResultErrorVariant as l, fetchSpecificKeys as lt, PossibleValidationError as m, createFetchClient as n, ResponseContext as nt, PluginHooks as o, AnyFunction as ot, PossibleJavaScriptError as p, FetchImpl as q, createFetchClientWithContext as r, ResponseErrorContext as rt, PluginMiddlewares as s, Satisfies as st, callApi as t, RequestStreamContext as tt, CallApiResultSuccessOrErrorVariant as u, BaseCallApiExtraOptions as v, CallApiRequestOptionsForHooks as w, CallApiExtraOptionsForHooks as x, CallApiConfig as y, BaseSchemaRouteKeyPrefixes as z };
1867
- //# sourceMappingURL=index-UfuQFNcf.d.ts.map
1866
+ //# sourceMappingURL=index-DCyPkUNR.d.ts.map
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as HooksOrHooksArray, B as CallApiSchema, C as CallApiRequestOptions, D as GetCallApiContextRequired, E as GetCallApiContext, F as InferInitURL, I as InferParamsFromRoute, J as FetchMiddlewareContext, L as URLOptions, M as RetryOptions, N as GetCurrentRouteSchemaKey, O as InstanceContext, P as InferAllMainRouteKeys, Q as Hooks, R as BaseCallApiSchemaRoutes, S as CallApiParameters, T as CallApiResultLoose, U as InferSchemaInput, V as CallApiSchemaConfig, W as InferSchemaOutput, X as DedupeOptions, Y as Middlewares, Z as ErrorContext, _ as BaseCallApiConfig, a as CallApiPlugin, at as SuccessContext, b as CallApiExtraOptions, c as PluginSetupContext, d as CallApiResultSuccessVariant, et as RequestContext, f as PossibleHTTPError, g as ResultModeType, h as ResponseTypeType, i as DefaultCallApiContext, it as ResponseStreamContext, k as Register, l as CallApiResultErrorVariant, m as PossibleValidationError, n as createFetchClient, nt as ResponseContext, o as PluginHooks, p as PossibleJavaScriptError, q as FetchImpl, r as createFetchClientWithContext, rt as ResponseErrorContext, s as PluginMiddlewares, t as callApi, tt as RequestStreamContext, u as CallApiResultSuccessOrErrorVariant, v as BaseCallApiExtraOptions, w as CallApiRequestOptionsForHooks, x as CallApiExtraOptionsForHooks, y as CallApiConfig, z as BaseSchemaRouteKeyPrefixes } from "./index-UfuQFNcf.js";
1
+ import { $ as HooksOrHooksArray, B as CallApiSchema, C as CallApiRequestOptions, D as GetCallApiContextRequired, E as GetCallApiContext, F as InferInitURL, I as InferParamsFromRoute, J as FetchMiddlewareContext, L as URLOptions, M as RetryOptions, N as GetCurrentRouteSchemaKey, O as InstanceContext, P as InferAllMainRouteKeys, Q as Hooks, R as BaseCallApiSchemaRoutes, S as CallApiParameters, T as CallApiResultLoose, U as InferSchemaInput, V as CallApiSchemaConfig, W as InferSchemaOutput, X as DedupeOptions, Y as Middlewares, Z as ErrorContext, _ as BaseCallApiConfig, a as CallApiPlugin, at as SuccessContext, b as CallApiExtraOptions, c as PluginSetupContext, d as CallApiResultSuccessVariant, et as RequestContext, f as PossibleHTTPError, g as ResultModeType, h as ResponseTypeType, i as DefaultCallApiContext, it as ResponseStreamContext, k as Register, l as CallApiResultErrorVariant, m as PossibleValidationError, n as createFetchClient, nt as ResponseContext, o as PluginHooks, p as PossibleJavaScriptError, q as FetchImpl, r as createFetchClientWithContext, rt as ResponseErrorContext, s as PluginMiddlewares, t as callApi, tt as RequestStreamContext, u as CallApiResultSuccessOrErrorVariant, v as BaseCallApiExtraOptions, w as CallApiRequestOptionsForHooks, x as CallApiExtraOptionsForHooks, y as CallApiConfig, z as BaseSchemaRouteKeyPrefixes } from "./index-DCyPkUNR.js";
2
2
  export { BaseCallApiConfig, BaseCallApiExtraOptions, BaseCallApiSchemaRoutes, BaseSchemaRouteKeyPrefixes, CallApiConfig, CallApiExtraOptions, CallApiExtraOptionsForHooks, CallApiParameters, CallApiPlugin, CallApiRequestOptions, CallApiRequestOptionsForHooks, CallApiResultLoose as CallApiResult, CallApiResultErrorVariant, CallApiResultSuccessOrErrorVariant, CallApiResultSuccessVariant, CallApiSchema, CallApiSchemaConfig, DedupeOptions, DefaultCallApiContext, ErrorContext, FetchImpl, FetchMiddlewareContext, GetCallApiContext, GetCallApiContextRequired, GetCurrentRouteSchemaKey, Hooks, HooksOrHooksArray, InferAllMainRouteKeys, InferInitURL, InferParamsFromRoute, InferSchemaInput, InferSchemaOutput, InstanceContext, Middlewares, PluginHooks, PluginMiddlewares, PluginSetupContext, PossibleHTTPError, PossibleJavaScriptError, PossibleValidationError, Register, RequestContext, RequestStreamContext, ResponseContext, ResponseErrorContext, ResponseStreamContext, ResponseTypeType, ResultModeType, RetryOptions, SuccessContext, URLOptions, callApi, createFetchClient, createFetchClientWithContext };
package/dist/index.js CHANGED
@@ -591,9 +591,9 @@ const createRetryManager = (ctx) => {
591
591
  //#region src/createFetchClient.ts
592
592
  const $GlobalRequestInfoCache = /* @__PURE__ */ new Map();
593
593
  const createFetchClientWithContext = () => {
594
- const createFetchClient$1 = (initBaseConfig = {}) => {
594
+ const createFetchClient = (initBaseConfig = {}) => {
595
595
  const $LocalRequestInfoCache = /* @__PURE__ */ new Map();
596
- const callApi$1 = async (initURL, initConfig = {}) => {
596
+ const callApi = async (initURL, initConfig = {}) => {
597
597
  const [fetchOptions, extraOptions] = splitConfig(initConfig);
598
598
  const baseConfig = isFunction(initBaseConfig) ? initBaseConfig({
599
599
  initURL: initURL.toString(),
@@ -756,7 +756,7 @@ const createFetchClientWithContext = () => {
756
756
  shouldThrowOnError
757
757
  };
758
758
  const { handleRetryOrGetErrorResult } = createRetryManager({
759
- callApi: callApi$1,
759
+ callApi,
760
760
  callApiArgs: {
761
761
  config,
762
762
  initURL
@@ -798,9 +798,9 @@ const createFetchClientWithContext = () => {
798
798
  removeDedupeKeyFromCache();
799
799
  }
800
800
  };
801
- return callApi$1;
801
+ return callApi;
802
802
  };
803
- return createFetchClient$1;
803
+ return createFetchClient;
804
804
  };
805
805
  const createFetchClient = createFetchClientWithContext();
806
806
  const callApi = createFetchClient();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["dedupeKey","$GlobalRequestInfoCache","$RequestInfoCache","callApi","createFetchClient","callApi"],"sources":["../src/result.ts","../src/hooks.ts","../src/stream.ts","../src/dedupe.ts","../src/middlewares.ts","../src/plugins.ts","../src/retry.ts","../src/createFetchClient.ts"],"sourcesContent":["import { extraOptionDefaults } from \"./constants/defaults\";\nimport type { CallApiExtraOptions } from \"./types/common\";\nimport type { ThrowOnErrorBoolean } from \"./types/conditional-types\";\nimport type { DefaultDataType, DefaultThrowOnError } from \"./types/default-types\";\nimport type {\n\tAnyString,\n\tAwaitable,\n\tDistributiveOmit,\n\tNoInferUnMasked,\n\tPrettify,\n\tUnmaskType,\n} from \"./types/type-helpers\";\nimport { omitKeys } from \"./utils/common\";\nimport type { HTTPError, ValidationError } from \"./utils/external/error\";\nimport { isHTTPErrorInstance, isValidationErrorInstance } from \"./utils/external/guards\";\n\nexport type ResponseType = \"blob\" | \"json\" | \"text\";\n\nexport type ResponseParser<TData> = (text: string) => Awaitable<TData>;\n\nexport const getResponseType = <TData>(response: Response, responseParser: ResponseParser<TData>) => ({\n\tarrayBuffer: () => response.arrayBuffer(),\n\tblob: () => response.blob(),\n\tformData: () => response.formData(),\n\tjson: async (): Promise<TData> => {\n\t\tconst text = await response.text();\n\t\treturn responseParser(text);\n\t},\n\tstream: () => response.body,\n\ttext: () => response.text(),\n});\n\ntype InitResponseTypeMap<TData = unknown> = ReturnType<typeof getResponseType<TData>>;\n\ntype ResponseTypeUnion = keyof InitResponseTypeMap;\n\ntype ResponseTypePlaceholder = null;\n\nexport type ResponseTypeType = ResponseTypePlaceholder | ResponseTypeUnion;\n\nexport type ResponseTypeMap<TData> = {\n\t[Key in keyof InitResponseTypeMap<TData>]: Awaited<ReturnType<InitResponseTypeMap<TData>[Key]>>;\n};\n\nexport type GetResponseType<\n\tTData,\n\tTResponseType extends ResponseTypeType,\n\tTComputedResponseTypeMap extends ResponseTypeMap<TData> = ResponseTypeMap<TData>,\n> =\n\tnull extends TResponseType ? TComputedResponseTypeMap[\"json\"]\n\t: TResponseType extends NonNullable<ResponseTypeType> ? TComputedResponseTypeMap[TResponseType]\n\t: never;\n\nconst textTypes = new Set([\"image/svg\", \"application/xml\", \"application/xhtml\", \"application/html\"]);\nconst JSON_REGEX = /^application\\/(?:[\\w!#$%&*.^`~-]*\\+)?json(;.+)?$/i;\n\nconst detectResponseType = (response: Response): Extract<ResponseTypeType, \"blob\" | \"json\" | \"text\"> => {\n\tconst initContentType = response.headers.get(\"content-type\");\n\n\tif (!initContentType) {\n\t\treturn extraOptionDefaults.responseType;\n\t}\n\n\tconst contentType = initContentType.split(\";\")[0] ?? \"\";\n\n\tif (JSON_REGEX.test(contentType)) {\n\t\treturn \"json\";\n\t}\n\n\tif (textTypes.has(contentType) || contentType.startsWith(\"text/\")) {\n\t\treturn \"text\";\n\t}\n\n\treturn \"blob\";\n};\n\nexport const resolveResponseData = async (options: {\n\tresponse: Response;\n\tresponseParser: CallApiExtraOptions[\"responseParser\"];\n\tresponseType: CallApiExtraOptions[\"responseType\"];\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n}) => {\n\tconst { response, responseParser, responseType, resultMode } = options;\n\n\t// == If the result mode is set to `fetchApi`, then don't try to resolve the responseData and just return null\n\tif (resultMode === \"fetchApi\") {\n\t\treturn null;\n\t}\n\n\tconst selectedParser = responseParser ?? extraOptionDefaults.responseParser;\n\tconst selectedResponseType = responseType ?? detectResponseType(response);\n\n\tconst RESPONSE_TYPE_LOOKUP = getResponseType(response, selectedParser);\n\n\tif (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, selectedResponseType)) {\n\t\tthrow new Error(`Invalid response type: ${selectedResponseType}`);\n\t}\n\n\treturn RESPONSE_TYPE_LOOKUP[selectedResponseType]();\n};\n\nexport type CallApiResultSuccessVariant<TData> = {\n\tdata: NoInferUnMasked<TData>;\n\terror: null;\n\tresponse: Response;\n};\nexport type PossibleJavaScriptError = UnmaskType<{\n\terrorData: false;\n\tmessage: string;\n\tname: \"AbortError\" | \"Error\" | \"SyntaxError\" | \"TimeoutError\" | \"TypeError\" | AnyString;\n\toriginalError: DOMException | Error | SyntaxError | TypeError;\n}>;\n\nexport type PossibleHTTPError<TErrorData> = UnmaskType<{\n\terrorData: NoInferUnMasked<TErrorData>;\n\tmessage: string;\n\tname: \"HTTPError\";\n\toriginalError: HTTPError;\n}>;\n\nexport type PossibleValidationError = UnmaskType<{\n\terrorData: ValidationError[\"errorData\"];\n\tissueCause: ValidationError[\"issueCause\"];\n\tmessage: string;\n\tname: \"ValidationError\";\n\toriginalError: ValidationError;\n}>;\n\nexport type CallApiResultErrorVariant<TErrorData> =\n\t| {\n\t\t\tdata: null;\n\t\t\terror: PossibleHTTPError<TErrorData>;\n\t\t\tresponse: Response;\n\t }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: PossibleJavaScriptError;\n\t\t\tresponse: Response | null;\n\t }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: PossibleValidationError;\n\t\t\tresponse: Response | null;\n\t };\n\nexport type CallApiResultSuccessOrErrorVariant<TData, TError> =\n\t| CallApiResultErrorVariant<TError>\n\t| CallApiResultSuccessVariant<TData>;\n\ntype GetCallApiResult<\n\tTThrowOnError extends ThrowOnErrorBoolean,\n\tTResultWithException extends CallApiResultSuccessVariant<unknown>,\n\tTResultWithoutException extends CallApiResultSuccessOrErrorVariant<unknown, unknown>,\n> = TThrowOnError extends true ? TResultWithException : TResultWithoutException;\n\nexport type ResultModeMap<\n\tTData = DefaultDataType,\n\tTErrorData = DefaultDataType,\n\tTThrowOnError extends ThrowOnErrorBoolean = DefaultThrowOnError,\n\tTComputedResult extends GetCallApiResult<\n\t\tTThrowOnError,\n\t\tCallApiResultSuccessVariant<TData>,\n\t\tCallApiResultSuccessOrErrorVariant<TData, TErrorData>\n\t> = GetCallApiResult<\n\t\tTThrowOnError,\n\t\tCallApiResultSuccessVariant<TData>,\n\t\tCallApiResultSuccessOrErrorVariant<TData, TErrorData>\n\t>,\n> = UnmaskType<{\n\tall: TComputedResult;\n\tfetchApi: TComputedResult[\"response\"];\n\tonlyData: TComputedResult[\"data\"];\n\tonlyResponse: TComputedResult[\"response\"];\n\twithoutResponse: Prettify<DistributiveOmit<TComputedResult, \"response\">>;\n}>;\n\ntype ResultModePlaceholder = null;\n\ntype ResultModeUnion = keyof ResultModeMap;\n\n// FIXME - Revisit this idea later. Take inspirations from how zod does it with pick({}) and omit({d})\n// type ResultModeObject = { data?: boolean; error?: boolean; response?: boolean };\n\nexport type ResultModeType = ResultModePlaceholder | ResultModeUnion;\n\nexport type InferCallApiResult<\n\tTData,\n\tTErrorData,\n\tTResultMode extends ResultModeType,\n\tTThrowOnError extends ThrowOnErrorBoolean,\n\tTComputedResultModeMapWithException extends ResultModeMap<TData, TErrorData, true> = ResultModeMap<\n\t\tTData,\n\t\tTErrorData,\n\t\ttrue\n\t>,\n\tTComputedResultModeMapWithoutException extends ResultModeMap<TData, TErrorData, TThrowOnError> =\n\t\tResultModeMap<TData, TErrorData, TThrowOnError>,\n> =\n\tTErrorData extends false ? TComputedResultModeMapWithException[\"onlyData\"]\n\t: TErrorData extends false | undefined ? TComputedResultModeMapWithException[\"onlyData\"]\n\t: ResultModePlaceholder extends TResultMode ? TComputedResultModeMapWithoutException[\"all\"]\n\t: TResultMode extends ResultModeUnion ? TComputedResultModeMapWithoutException[TResultMode]\n\t: never;\n\ntype SuccessInfo = Pick<CallApiExtraOptions, \"resultMode\"> & {\n\tresponse: Response;\n};\n\ntype LazyResultModeMap = {\n\t[key in keyof ResultModeMap]: () => ResultModeMap[key];\n};\n\nconst getResultModeMap = (details: ResultModeMap[\"all\"]): LazyResultModeMap => {\n\treturn {\n\t\tall: () => details,\n\t\tfetchApi: () => details.response,\n\t\tonlyData: () => details.data,\n\t\tonlyResponse: () => details.response,\n\t\twithoutResponse: () => omitKeys(details, [\"response\"]),\n\t};\n};\n\ntype SuccessResult = CallApiResultSuccessVariant<unknown> | null;\n\n// The return statement is casted due to a design limitation in ts.\n// LINK - See https://www.zhenghao.io/posts/type-functions for more info\nexport const resolveSuccessResult = (data: unknown, info: SuccessInfo): SuccessResult => {\n\tconst { response, resultMode } = info;\n\n\tconst details = {\n\t\tdata,\n\t\terror: null,\n\t\tresponse,\n\t} satisfies CallApiResultSuccessVariant<unknown>;\n\n\tconst resultModeMap = getResultModeMap(details);\n\n\tconst successResult = resultModeMap[resultMode ?? \"all\"]();\n\n\treturn successResult as SuccessResult;\n};\n\nexport type ErrorInfo = Omit<SuccessInfo, \"response\">\n\t& Pick<CallApiExtraOptions, \"cloneResponse\"> & {\n\t\tmessage?: string;\n\t};\n\nexport type ErrorResult = {\n\terrorDetails: CallApiResultErrorVariant<unknown>;\n\terrorResult: CallApiResultErrorVariant<unknown> | null;\n};\n\nexport const resolveErrorResult = (error: unknown, info: ErrorInfo): ErrorResult => {\n\tconst { cloneResponse, message: customErrorMessage, resultMode } = info;\n\n\tlet errorDetails = {\n\t\tdata: null,\n\t\terror: {\n\t\t\terrorData: false,\n\t\t\tmessage: customErrorMessage ?? (error as Error).message,\n\t\t\tname: (error as Error).name,\n\t\t\toriginalError: error as Error,\n\t\t},\n\t\tresponse: null,\n\t} satisfies CallApiResultErrorVariant<unknown> as CallApiResultErrorVariant<unknown>;\n\n\tif (isValidationErrorInstance(error)) {\n\t\tconst { errorData, message, response } = error;\n\n\t\terrorDetails = {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\terrorData,\n\t\t\t\tissueCause: error.issueCause,\n\t\t\t\tmessage,\n\t\t\t\tname: \"ValidationError\",\n\t\t\t\toriginalError: error,\n\t\t\t},\n\t\t\tresponse,\n\t\t};\n\t}\n\n\tif (isHTTPErrorInstance<never>(error)) {\n\t\tconst { errorData, message, name, response } = error;\n\n\t\terrorDetails = {\n\t\t\tdata: null,\n\t\t\terror: { errorData, message, name, originalError: error },\n\t\t\tresponse: cloneResponse ? response.clone() : response,\n\t\t};\n\t}\n\n\tconst resultModeMap = getResultModeMap(errorDetails);\n\n\tconst errorResult = resultModeMap[resultMode ?? \"all\"]() as never;\n\n\treturn { errorDetails, errorResult };\n};\n\nexport const getCustomizedErrorResult = (\n\terrorResult: ErrorResult[\"errorResult\"],\n\tcustomErrorInfo: { message: string | undefined }\n): ErrorResult[\"errorResult\"] => {\n\tif (!errorResult) {\n\t\treturn null;\n\t}\n\n\tconst { message = errorResult.error.message } = customErrorInfo;\n\n\treturn {\n\t\t...errorResult,\n\t\terror: {\n\t\t\t...errorResult.error,\n\t\t\tmessage,\n\t\t} satisfies NonNullable<ErrorResult[\"errorResult\"]>[\"error\"] as never,\n\t};\n};\n","import {\n\tresolveErrorResult,\n\ttype CallApiResultErrorVariant,\n\ttype CallApiResultSuccessVariant,\n\ttype ErrorInfo,\n\ttype PossibleHTTPError,\n\ttype PossibleJavaScriptError,\n\ttype PossibleValidationError,\n} from \"./result\";\nimport type { StreamProgressEvent } from \"./stream\";\nimport type {\n\tBaseCallApiConfig,\n\tCallApiConfig,\n\tCallApiContext,\n\tCallApiExtraOptionsForHooks,\n\tCallApiRequestOptionsForHooks,\n} from \"./types/common\";\nimport type { DefaultCallApiContext } from \"./types/default-types\";\nimport type { AnyFunction, Awaitable, DistributiveOmit, Prettify } from \"./types/type-helpers\";\n\nexport interface Hooks<TCallApiContext extends CallApiContext = DefaultCallApiContext> {\n\t/**\n\t * Hook called when any error occurs within the request/response lifecycle.\n\t *\n\t * This is a unified error handler that catches both request errors (network failures,\n\t * timeouts, etc.) and response errors (HTTP error status codes). It's essentially\n\t * a combination of `onRequestError` and `onResponseError` hooks.\n\t *\n\t * @param context - Error context containing error details, request info, and response (if available)\n\t * @returns Promise or void - Hook can be async or sync\n\t */\n\tonError?: (context: ErrorContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called before the HTTP request is sent and before any internal processing of the request object begins.\n\t *\n\t * This is the ideal place to modify request headers, add authentication,\n\t * implement request logging, or perform any setup before the network call.\n\t *\n\t * @param context - Request context with mutable request object and configuration\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonRequest?: (context: RequestContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when an error occurs during the fetch request itself.\n\t *\n\t * This handles network-level errors like connection failures, timeouts,\n\t * DNS resolution errors, or other issues that prevent getting an HTTP response.\n\t * Note that HTTP error status codes (4xx, 5xx) are handled by `onResponseError`.\n\t *\n\t * @param context - Request error context with error details and null response\n\t * @returns Promise or void - Hook can be async or sync\n\t */\n\tonRequestError?: (context: RequestErrorContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called just before the HTTP request is sent and after the request has been processed.\n\t *\n\t * @param context - Request context with mutable request object and configuration\n\t */\n\tonRequestReady?: (context: RequestContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called during upload stream progress tracking.\n\t *\n\t * This hook is triggered when uploading data (like file uploads) and provides\n\t * progress information about the upload. Useful for implementing progress bars\n\t * or upload status indicators.\n\t *\n\t * @param context - Request stream context with progress event and request instance\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonRequestStream?: (context: RequestStreamContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when any HTTP response is received from the API.\n\t *\n\t * This hook is triggered for both successful (2xx) and error (4xx, 5xx) responses.\n\t * It's useful for response logging, metrics collection, or any processing that\n\t * should happen regardless of response status.\n\t *\n\t * @param context - Response context with either success data or error information\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonResponse?: (context: ResponseContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when an HTTP error response (4xx, 5xx) is received from the API.\n\t *\n\t * This handles server-side errors where an HTTP response was successfully received\n\t * but indicates an error condition. Different from `onRequestError` which handles\n\t * network-level failures.\n\t *\n\t * @param context - Response error context with HTTP error details and response\n\t * @returns Promise or void - Hook can be async or sync\n\t */\n\tonResponseError?: (context: ResponseErrorContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called during download stream progress tracking.\n\t *\n\t * This hook is triggered when downloading data (like file downloads) and provides\n\t * progress information about the download. Useful for implementing progress bars\n\t * or download status indicators.\n\t *\n\t * @param context - Response stream context with progress event and response\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonResponseStream?: (context: ResponseStreamContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when a request is being retried.\n\t *\n\t * This hook is triggered before each retry attempt, providing information about\n\t * the previous failure and the current retry attempt number. Useful for implementing\n\t * custom retry logic, exponential backoff, or retry logging.\n\t *\n\t * @param context - Retry context with error details and retry attempt count\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonRetry?: (response: RetryContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when a successful response (2xx status) is received from the API.\n\t *\n\t * This hook is triggered only for successful responses and provides access to\n\t * the parsed response data. Ideal for success logging, caching, or post-processing\n\t * of successful API responses.\n\t *\n\t * @param context - Success context with parsed response data and response object\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonSuccess?: (context: SuccessContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when a validation error occurs.\n\t *\n\t * This hook is triggered when request or response data fails validation against\n\t * a defined schema. It provides access to the validation error details and can\n\t * be used for custom error handling, logging, or fallback behavior.\n\t *\n\t * @param context - Validation error context with error details and response (if available)\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonValidationError?: (context: ValidationErrorContext<TCallApiContext>) => Awaitable<unknown>;\n}\n\nexport type HooksOrHooksArray<TCallApiContext extends NoInfer<CallApiContext> = DefaultCallApiContext> = {\n\t[Key in keyof Hooks<TCallApiContext>]:\n\t\t| Hooks<TCallApiContext>[Key]\n\t\t// eslint-disable-next-line perfectionist/sort-union-types -- I need arrays to be last\n\t\t| Array<Hooks<TCallApiContext>[Key]>;\n};\n\nexport interface HookConfigOptions {\n\t/**\n\t * Controls the execution mode of all composed hooks (main + plugin hooks).\n\t *\n\t * - **\"parallel\"**: All hooks execute simultaneously via Promise.all() for better performance\n\t * - **\"sequential\"**: All hooks execute one by one in registration order via await in a loop\n\t *\n\t * This affects how ALL hooks execute together, regardless of their source (main or plugin).\n\t *\n\t * @default \"parallel\"\n\t */\n\thooksExecutionMode?: \"parallel\" | \"sequential\";\n}\n\nexport type RequestContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = {\n\t/**\n\t * Base configuration object passed to createFetchClient.\n\t *\n\t * Contains the foundational configuration that applies to all requests\n\t * made by this client instance, such as baseURL, default headers, and\n\t * global options.\n\t */\n\tbaseConfig: Exclude<BaseCallApiConfig, AnyFunction>;\n\n\t/**\n\t * Instance-specific configuration object passed to the callApi instance.\n\t *\n\t * Contains configuration specific to this particular API call, which\n\t * can override or extend the base configuration.\n\t */\n\tconfig: CallApiConfig;\n\n\t/**\n\t * Merged options combining base config, instance config, and default options.\n\t *\n\t * This is the final resolved configuration that will be used for the request,\n\t * with proper precedence applied (instance > base > defaults).\n\t */\n\toptions: CallApiExtraOptionsForHooks<TCallApiContext>;\n\n\t/**\n\t * Merged request object ready to be sent.\n\t *\n\t * Contains the final request configuration including URL, method, headers,\n\t * body, and other fetch options. This object can be modified in onRequest\n\t * hooks to customize the outgoing request.\n\t */\n\trequest: CallApiRequestOptionsForHooks;\n};\n\nexport type ValidationErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = DistributiveOmit<\n\tExtract<CallApiResultErrorVariant<unknown>, { error: PossibleValidationError }>,\n\t\"data\"\n>\n\t& RequestContext<TCallApiContext>;\n\nexport type SuccessContext<\n\tTCallApiContext extends Pick<CallApiContext, \"Data\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = DistributiveOmit<CallApiResultSuccessVariant<TCallApiContext[\"Data\"]>, \"error\">\n\t& RequestContext<TCallApiContext>;\n\nexport type ResponseContext<\n\tTCallApiContext extends Pick<CallApiContext, \"Data\" | \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = RequestContext<TCallApiContext>\n\t& (\n\t\t| Prettify<CallApiResultSuccessVariant<TCallApiContext[\"Data\"]>>\n\t\t| Prettify<\n\t\t\t\tExtract<\n\t\t\t\t\tCallApiResultErrorVariant<TCallApiContext[\"ErrorData\"]>,\n\t\t\t\t\t{ error: PossibleHTTPError<TCallApiContext[\"ErrorData\"]> }\n\t\t\t\t>\n\t\t >\n\t);\n\nexport type RequestErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = DistributiveOmit<\n\tExtract<CallApiResultErrorVariant<unknown>, { error: PossibleJavaScriptError }>,\n\t\"data\"\n>\n\t& RequestContext<TCallApiContext>;\n\nexport type ErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = DistributiveOmit<CallApiResultErrorVariant<TCallApiContext[\"ErrorData\"]>, \"data\">\n\t& RequestContext<TCallApiContext>;\n\nexport type ResponseErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = Extract<ErrorContext<TCallApiContext>, { error: PossibleHTTPError<TCallApiContext[\"ErrorData\"]> }>\n\t& RequestContext<TCallApiContext>;\n\nexport type RetryContext<\n\tTCallApiContext extends Pick<CallApiContext, \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = ErrorContext<TCallApiContext> & {\n\tretryAttemptCount: number;\n};\n\nexport type RequestStreamContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = RequestContext<TCallApiContext> & {\n\tevent: StreamProgressEvent;\n\trequestInstance: Request;\n};\n\nexport type ResponseStreamContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = RequestContext<TCallApiContext> & {\n\tevent: StreamProgressEvent;\n\tresponse: Response;\n};\n\ntype HookRegistries = Required<{\n\t[Key in keyof Hooks]: Set<Hooks[Key]>;\n}>;\n\nexport const getHookRegistriesAndKeys = () => {\n\tconst hookRegistries: HookRegistries = {\n\t\tonError: new Set(),\n\t\tonRequest: new Set(),\n\t\tonRequestError: new Set(),\n\t\tonRequestReady: new Set(),\n\t\tonRequestStream: new Set(),\n\t\tonResponse: new Set(),\n\t\tonResponseError: new Set(),\n\t\tonResponseStream: new Set(),\n\t\tonRetry: new Set(),\n\t\tonSuccess: new Set(),\n\t\tonValidationError: new Set(),\n\t};\n\n\tconst hookRegistryKeys = Object.keys(hookRegistries) as Array<keyof Hooks>;\n\n\treturn { hookRegistries, hookRegistryKeys };\n};\n\nexport const composeHooksFromArray = (\n\thooksArray: Array<Hooks[keyof Hooks] | undefined>,\n\thooksExecutionMode: NonNullable<CallApiExtraOptionsForHooks[\"hooksExecutionMode\"]>\n) => {\n\tconst composedHook = async (ctx: unknown) => {\n\t\tswitch (hooksExecutionMode) {\n\t\t\tcase \"parallel\": {\n\t\t\t\tawait Promise.all(hooksArray.map((hook) => hook?.(ctx as never)));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"sequential\": {\n\t\t\t\tfor (const hook of hooksArray) {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop -- This is necessary in this case\n\t\t\t\t\tawait hook?.(ctx as never);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\thooksExecutionMode satisfies never;\n\t\t\t}\n\t\t}\n\t};\n\n\treturn composedHook;\n};\n\nexport const executeHooks = async (...hookResultsOrPromise: Array<Awaitable<unknown>>) => {\n\tawait Promise.all(hookResultsOrPromise);\n};\n\nexport type ExecuteHookInfo = {\n\terrorInfo: ErrorInfo;\n\tshouldThrowOnError: boolean | undefined;\n};\n\nexport const executeHooksInCatchBlock = async (\n\thookResultsOrPromise: Array<Awaitable<unknown>>,\n\thookInfo: ExecuteHookInfo\n) => {\n\tconst { errorInfo, shouldThrowOnError } = hookInfo;\n\n\ttry {\n\t\tawait Promise.all(hookResultsOrPromise);\n\n\t\treturn null;\n\t} catch (hookError) {\n\t\tif (shouldThrowOnError) {\n\t\t\tthrow hookError;\n\t\t}\n\n\t\tconst { errorResult } = resolveErrorResult(hookError, errorInfo);\n\n\t\treturn errorResult;\n\t}\n};\n","import {\n\texecuteHooks,\n\ttype RequestContext,\n\ttype RequestStreamContext,\n\ttype ResponseStreamContext,\n} from \"./hooks\";\nimport { isReadableStream } from \"./utils/guards\";\n\nexport type StreamProgressEvent = {\n\t/**\n\t * Current chunk of data being streamed\n\t */\n\tchunk: Uint8Array;\n\t/**\n\t * Progress in percentage\n\t */\n\tprogress: number;\n\t/**\n\t * Total size of data in bytes\n\t */\n\ttotalBytes: number;\n\t/**\n\t * Amount of data transferred so far\n\t */\n\ttransferredBytes: number;\n};\n\nconst createProgressEvent = (options: {\n\tchunk: Uint8Array;\n\ttotalBytes: number;\n\ttransferredBytes: number;\n}): StreamProgressEvent => {\n\tconst { chunk, totalBytes, transferredBytes } = options;\n\n\treturn {\n\t\tchunk,\n\t\tprogress: Math.round((transferredBytes / totalBytes) * 100) || 0,\n\t\ttotalBytes,\n\t\ttransferredBytes,\n\t};\n};\n\nconst calculateTotalBytesFromBody = async (\n\trequestBody: Request[\"body\"] | null,\n\texistingTotalBytes: number\n) => {\n\tlet totalBytes = existingTotalBytes;\n\n\tif (!requestBody) {\n\t\treturn totalBytes;\n\t}\n\n\tfor await (const chunk of requestBody) {\n\t\ttotalBytes += chunk.byteLength;\n\t}\n\n\treturn totalBytes;\n};\n\ntype ToStreamableRequestContext = RequestContext;\n\nexport const toStreamableRequest = async (\n\tcontext: ToStreamableRequestContext\n): Promise<Request | RequestInit> => {\n\tconst { baseConfig, config, options, request } = context;\n\n\tif (!options.onRequestStream || !isReadableStream(request.body)) {\n\t\treturn request as RequestInit;\n\t}\n\n\tconst requestInstance = new Request(\n\t\toptions.fullURL as NonNullable<typeof options.fullURL>,\n\t\t{ ...request, duplex: \"half\" } as RequestInit\n\t);\n\n\tconst contentLength = requestInstance.headers.get(\"content-length\");\n\n\tlet totalBytes = Number(contentLength ?? 0);\n\n\t// == If no content length is present, we read the total bytes from the body\n\tif (!contentLength && options.forcefullyCalculateRequestStreamSize) {\n\t\ttotalBytes = await calculateTotalBytesFromBody(requestInstance.clone().body, totalBytes);\n\t}\n\n\tlet transferredBytes = 0;\n\n\tconst stream = new ReadableStream({\n\t\tstart: async (controller) => {\n\t\t\tconst body = requestInstance.body;\n\n\t\t\tif (!body) return;\n\n\t\t\tconst requestStreamContext = {\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tevent: createProgressEvent({ chunk: new Uint8Array(), totalBytes, transferredBytes }),\n\t\t\t\toptions,\n\t\t\t\trequest,\n\t\t\t\trequestInstance,\n\t\t\t} satisfies RequestStreamContext;\n\n\t\t\tawait executeHooks(options.onRequestStream?.(requestStreamContext));\n\n\t\t\tfor await (const chunk of body) {\n\t\t\t\ttransferredBytes += chunk.byteLength;\n\n\t\t\t\ttotalBytes = Math.max(totalBytes, transferredBytes);\n\n\t\t\t\tawait executeHooks(\n\t\t\t\t\toptions.onRequestStream?.({\n\t\t\t\t\t\t...requestStreamContext,\n\t\t\t\t\t\tevent: createProgressEvent({ chunk, totalBytes, transferredBytes }),\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\treturn new Request(requestInstance, { body: stream, duplex: \"half\" } as RequestInit);\n};\n\ntype StreamableResponseContext = RequestContext & { response: Response };\n\nexport const toStreamableResponse = (context: StreamableResponseContext): Response => {\n\tconst { baseConfig, config, options, request, response } = context;\n\n\tif (!options.onResponseStream || !response.body) {\n\t\treturn response;\n\t}\n\n\tconst contentLength = response.headers.get(\"content-length\");\n\n\tlet totalBytes = Number(contentLength ?? 0);\n\n\tlet transferredBytes = 0;\n\n\tconst stream = new ReadableStream({\n\t\tstart: async (controller) => {\n\t\t\tconst body = response.body;\n\n\t\t\tif (!body) return;\n\n\t\t\tconst responseStreamContext = {\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tevent: createProgressEvent({ chunk: new Uint8Array(), totalBytes, transferredBytes }),\n\t\t\t\toptions,\n\t\t\t\trequest,\n\t\t\t\tresponse,\n\t\t\t} satisfies ResponseStreamContext;\n\n\t\t\tawait executeHooks(options.onResponseStream?.(responseStreamContext));\n\n\t\t\tfor await (const chunk of body) {\n\t\t\t\ttransferredBytes += chunk.byteLength;\n\n\t\t\t\ttotalBytes = Math.max(totalBytes, transferredBytes);\n\n\t\t\t\tawait executeHooks(\n\t\t\t\t\toptions.onResponseStream?.({\n\t\t\t\t\t\t...responseStreamContext,\n\t\t\t\t\t\tevent: createProgressEvent({ chunk, totalBytes, transferredBytes }),\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\treturn new Response(stream, response);\n};\n","import { extraOptionDefaults } from \"./constants/defaults\";\nimport type { RequestContext } from \"./hooks\";\nimport { toStreamableRequest, toStreamableResponse } from \"./stream\";\nimport type { AnyString, UnmaskType } from \"./types/type-helpers\";\nimport { waitFor } from \"./utils/common\";\nimport { isFunction } from \"./utils/guards\";\n\ntype RequestInfo = {\n\tcontroller: AbortController;\n\tresponsePromise: Promise<Response>;\n};\n\n/**\n * Cache that stores active request information for deduplication within a specific scope.\n *\n * Maps deduplication keys to their corresponding request information, including the abort controller\n * and response promise. A `null` key represents requests that don't participate in deduplication.\n *\n * **Internal Usage:**\n * This type is primarily used internally by the deduplication system. You typically won't need to\n * interact with it directly unless you're building custom deduplication logic or debugging.\n *\n * @example\n * ```ts\n * // This is handled internally, but conceptually:\n * const cache: RequestInfoCache = new Map([\n * [\"user-123\", { controller: abortController, responsePromise: fetchPromise }],\n * [\"config\", { controller: abortController2, responsePromise: fetchPromise2 }],\n * ]);\n * ```\n */\nexport type RequestInfoCache = Map<string | null, RequestInfo>;\n\n/**\n * Global cache that manages multiple request info caches, organized by scope keys.\n *\n * This enables the global deduplication feature by maintaining separate cache namespaces\n * for different scope keys. Each scope key gets its own `RequestInfoCache` instance.\n *\n * **Cache Lifecycle:**\n * - Caches are created on-demand when first accessed\n * - Automatic cleanup occurs when no references remain\n * - Each scope key maintains independent deduplication state\n *\n * **Memory Considerations:**\n * - Each scope key creates a separate cache instance\n * - Consider the number of different scope keys in your application\n * - Caches are cleaned up automatically when clients are garbage collected\n *\n * @example\n * ```ts\n * // This is managed internally, but conceptually:\n * const globalCache: GlobalRequestInfoCache = new Map([\n * [\"user-service\", new Map([...])], // Cache for user service requests\n * [\"analytics\", new Map([...])], // Cache for analytics requests\n * [\"default\", new Map([...])] // Default cache scope\n * ]);\n * ```\n */\nexport type GlobalRequestInfoCache = Map<DedupeOptions[\"dedupeCacheScopeKey\"], RequestInfoCache>;\n\ntype DedupeContext = RequestContext & {\n\t$GlobalRequestInfoCache: GlobalRequestInfoCache;\n\t$LocalRequestInfoCache: RequestInfoCache;\n\tnewFetchController: AbortController;\n};\n\nexport const createDedupeStrategy = async (context: DedupeContext) => {\n\tconst {\n\t\t$GlobalRequestInfoCache,\n\t\t$LocalRequestInfoCache,\n\t\tbaseConfig,\n\t\tconfig,\n\t\tnewFetchController,\n\t\toptions: globalOptions,\n\t} = context;\n\n\tconst dedupeStrategy = globalOptions.dedupeStrategy ?? extraOptionDefaults.dedupeStrategy;\n\n\tconst resolvedDedupeStrategy = isFunction(dedupeStrategy) ? dedupeStrategy(context) : dedupeStrategy;\n\n\tconst getDedupeKey = () => {\n\t\tconst shouldHaveDedupeKey =\n\t\t\tresolvedDedupeStrategy === \"cancel\" || resolvedDedupeStrategy === \"defer\";\n\n\t\tif (!shouldHaveDedupeKey) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst dedupeKey = globalOptions.dedupeKey ?? extraOptionDefaults.dedupeKey;\n\n\t\tconst resolvedDedupeKey = isFunction(dedupeKey) ? dedupeKey(context) : dedupeKey;\n\n\t\treturn resolvedDedupeKey;\n\t};\n\n\tconst getDedupeCacheScopeKey = () => {\n\t\tconst dedupeCacheScopeKey =\n\t\t\tglobalOptions.dedupeCacheScopeKey ?? extraOptionDefaults.dedupeCacheScopeKey;\n\n\t\tconst resolvedDedupeCacheScopeKey =\n\t\t\tisFunction(dedupeCacheScopeKey) ? dedupeCacheScopeKey(context) : dedupeCacheScopeKey;\n\n\t\treturn resolvedDedupeCacheScopeKey;\n\t};\n\n\tconst dedupeKey = getDedupeKey();\n\n\tconst getRequestInfoCache = () => {\n\t\tif (!dedupeKey) return;\n\n\t\tconst dedupeCacheScope = globalOptions.dedupeCacheScope ?? extraOptionDefaults.dedupeCacheScope;\n\n\t\tconst dedupeCacheScopeKey = getDedupeCacheScopeKey();\n\n\t\tif (dedupeCacheScope === \"global\" && !$GlobalRequestInfoCache.has(dedupeCacheScopeKey)) {\n\t\t\t$GlobalRequestInfoCache.set(dedupeCacheScopeKey, new Map());\n\t\t}\n\n\t\tconst $RequestInfoCache =\n\t\t\tdedupeCacheScope === \"global\" ?\n\t\t\t\t$GlobalRequestInfoCache.get(dedupeCacheScopeKey)\n\t\t\t:\t$LocalRequestInfoCache;\n\n\t\treturn {\n\t\t\tdelete: () => $RequestInfoCache?.delete(dedupeKey),\n\t\t\tget: () => $RequestInfoCache?.get(dedupeKey),\n\t\t\tset: (value: RequestInfo) => $RequestInfoCache?.set(dedupeKey, value),\n\t\t};\n\t};\n\n\tconst $RequestInfoCache = getRequestInfoCache();\n\n\t/**\n\t * Force sequential execution of parallel requests to enable proper cache-based deduplication.\n\t *\n\t * Problem: When Promise.all([callApi(url), callApi(url)]) executes, both requests\n\t * start synchronously and reach this point before either can populate the cache.\n\t *\n\t * Why `await Promise.resolve()` fails:\n\t * - All microtasks in a batch resolve together at the next microtask checkpoint\n\t * - Both requests resume execution simultaneously after the await\n\t * - Both check `prevRequestInfo` at the same time → both see empty cache\n\t * - Both proceed to populate cache → deduplication fails\n\t *\n\t * Why `wait new Promise(()=> setTimeout(resolve, number))` works:\n\t * - Each setTimeout creates a separate task in the task queue\n\t * - Tasks execute sequentially, not simultaneously\n\t * - Request 1's task runs first: checks cache (empty) → continues → populates cache\n\t * - Request 2's task runs after: checks cache (populated) → uses cached promise\n\t * - Deduplication succeeds\n\t *\n\t * IMPORTANT: The delay must be non-zero. setTimeout(fn, 0) fails because JavaScript engines\n\t * may optimize zero-delay timers by batching them together, causing all requests to resume\n\t * simultaneously (same problem as microtasks). Any non-zero value (even 0.0000000001) forces\n\t * proper sequential task queue scheduling, ensuring each request gets its own task slot.\n\t */\n\tif (dedupeKey !== null) {\n\t\tawait waitFor(0.001);\n\t}\n\n\tconst prevRequestInfo = $RequestInfoCache?.get();\n\n\tconst getAbortErrorMessage = () => {\n\t\tif (globalOptions.dedupeKey) {\n\t\t\treturn `Duplicate request detected - Aborted previous request with key '${dedupeKey}'`;\n\t\t}\n\n\t\treturn `Duplicate request detected - Aborted previous request to '${globalOptions.fullURL}'`;\n\t};\n\n\tconst handleRequestCancelStrategy = () => {\n\t\tconst shouldCancelRequest = prevRequestInfo && resolvedDedupeStrategy === \"cancel\";\n\n\t\tif (!shouldCancelRequest) return;\n\n\t\tconst message = getAbortErrorMessage();\n\n\t\tconst reason = new DOMException(message, \"AbortError\");\n\n\t\tprevRequestInfo.controller.abort(reason);\n\t};\n\n\tconst handleRequestDeferStrategy = async (deferContext: {\n\t\tfetchApi: NonNullable<DedupeContext[\"options\"][\"customFetchImpl\"]>;\n\t\toptions: DedupeContext[\"options\"];\n\t\trequest: DedupeContext[\"request\"];\n\t}) => {\n\t\t// == Local options and request are needed so that transformations are applied can be applied to both from call site\n\t\tconst { fetchApi, options: localOptions, request: localRequest } = deferContext;\n\n\t\tconst shouldUsePromiseFromCache = prevRequestInfo && resolvedDedupeStrategy === \"defer\";\n\n\t\tconst streamableContext = {\n\t\t\tbaseConfig,\n\t\t\tconfig,\n\t\t\toptions: localOptions,\n\t\t\trequest: localRequest,\n\t\t} satisfies RequestContext;\n\n\t\tconst streamableRequest = await toStreamableRequest(streamableContext);\n\n\t\tconst responsePromise =\n\t\t\tshouldUsePromiseFromCache ?\n\t\t\t\tprevRequestInfo.responsePromise\n\t\t\t:\tfetchApi(localOptions.fullURL as NonNullable<typeof localOptions.fullURL>, streamableRequest);\n\n\t\t$RequestInfoCache?.set({ controller: newFetchController, responsePromise });\n\n\t\treturn toStreamableResponse({ ...streamableContext, response: await responsePromise });\n\t};\n\n\tconst removeDedupeKeyFromCache = () => {\n\t\t$RequestInfoCache?.delete();\n\t};\n\n\treturn {\n\t\tgetAbortErrorMessage,\n\t\thandleRequestCancelStrategy,\n\t\thandleRequestDeferStrategy,\n\t\tremoveDedupeKeyFromCache,\n\t\tresolvedDedupeStrategy,\n\t};\n};\n\ntype DedupeStrategyUnion = UnmaskType<\"cancel\" | \"defer\" | \"none\">;\n\nexport type DedupeOptions = {\n\t/**\n\t * Controls the scope of request deduplication caching.\n\t *\n\t * - `\"global\"`: Shares deduplication cache across all `createFetchClient` instances with the same `dedupeCacheScopeKey`.\n\t * Useful for applications with multiple API clients that should share deduplication state.\n\t * - `\"local\"`: Limits deduplication to requests within the same `createFetchClient` instance.\n\t * Provides better isolation and is recommended for most use cases.\n\t *\n\t *\n\t * **Real-world Scenarios:**\n\t * - Use `\"global\"` when you have multiple API clients (user service, auth service, etc.) that might make overlapping requests\n\t * - Use `\"local\"` (default) for single-purpose clients or when you want strict isolation between different parts of your app\n\t *\n\t * @example\n\t * ```ts\n\t * // Local scope - each client has its own deduplication cache\n\t * const userClient = createFetchClient({ baseURL: \"/api/users\" });\n\t * const postClient = createFetchClient({ baseURL: \"/api/posts\" });\n\t * // These clients won't share deduplication state\n\t *\n\t * // Global scope - share cache across related clients\n\t * const userClient = createFetchClient({\n\t * baseURL: \"/api/users\",\n\t * dedupeCacheScope: \"global\",\n\t * });\n\t * const postClient = createFetchClient({\n\t * baseURL: \"/api/posts\",\n\t * dedupeCacheScope: \"global\",\n\t * });\n\t * // These clients will share deduplication state\n\t * ```\n\t *\n\t * @default \"local\"\n\t */\n\tdedupeCacheScope?: \"global\" | \"local\";\n\n\t/**\n\t * Unique namespace for the global deduplication cache when using `dedupeCacheScope: \"global\"`.\n\t *\n\t * This creates logical groupings of deduplication caches. All instances with the same key\n\t * will share the same cache namespace, allowing fine-grained control over which clients\n\t * share deduplication state.\n\t *\n\t * **Best Practices:**\n\t * - Use descriptive names that reflect the logical grouping (e.g., \"user-service\", \"analytics-api\")\n\t * - Keep scope keys consistent across related API clients\n\t * - Consider using different scope keys for different environments (dev, staging, prod)\n\t * - Avoid overly broad scope keys that might cause unintended cache sharing\n\t *\n\t * **Cache Management:**\n\t * - Each scope key maintains its own independent cache\n\t * - Caches are automatically cleaned up when no references remain\n\t * - Consider the memory implications of multiple global scopes\n\t *\n\t * @example\n\t * ```ts\n\t * // Group related API clients together\n\t * const userClient = createFetchClient({\n\t * baseURL: \"/api/users\",\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: \"user-service\"\n\t * });\n\t * const profileClient = createFetchClient({\n\t * baseURL: \"/api/profiles\",\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: \"user-service\" // Same scope - will share cache\n\t * });\n\t *\n\t * // Separate analytics client with its own cache\n\t * const analyticsClient = createFetchClient({\n\t * baseURL: \"/api/analytics\",\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: \"analytics-service\" // Different scope\n\t * });\n\t *\n\t * // Environment-specific scoping\n\t * const apiClient = createFetchClient({\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: `api-${process.env.NODE_ENV}` // \"api-development\", \"api-production\", etc.\n\t * });\n\t * ```\n\t *\n\t * @default \"default\"\n\t */\n\tdedupeCacheScopeKey?: \"default\" | AnyString | ((context: RequestContext) => string | undefined);\n\n\t/**\n\t * Custom key generator for request deduplication.\n\t *\n\t * Override the default key generation strategy to control exactly which requests\n\t * are considered duplicates. The default key combines URL, method, body, and\n\t * relevant headers (excluding volatile ones like 'Date', 'Authorization', etc.).\n\t *\n\t * **Default Key Generation:**\n\t * The auto-generated key includes:\n\t * - Full request URL (including query parameters)\n\t * - HTTP method (GET, POST, etc.)\n\t * - Request body (for POST/PUT/PATCH requests)\n\t * - Stable headers (excludes Date, Authorization, User-Agent, etc.)\n\t *\n\t * **Custom Key Best Practices:**\n\t * - Include only the parts of the request that should affect deduplication\n\t * - Avoid including volatile data (timestamps, random IDs, etc.)\n\t * - Consider performance - simpler keys are faster to compute and compare\n\t * - Ensure keys are deterministic for the same logical request\n\t * - Use consistent key formats across your application\n\t *\n\t * **Performance Considerations:**\n\t * - Function-based keys are computed on every request - keep them lightweight\n\t * - String keys are fastest but least flexible\n\t * - Consider caching expensive key computations if needed\n\t *\n\t * @example\n\t * ```ts\n\t * import { callApi } from \"@zayne-labs/callapi\";\n\t *\n\t * // Simple static key - useful for singleton requests\n\t * const config = callApi(\"/api/config\", {\n\t * dedupeKey: \"app-config\",\n\t * dedupeStrategy: \"defer\" // Share the same config across all requests\n\t * });\n\t *\n\t * // URL and method only - ignore headers and body\n\t * const userData = callApi(\"/api/user/123\", {\n\t * dedupeKey: (context) => `${context.options.method}:${context.options.fullURL}`\n\t * });\n\t *\n\t * // Include specific headers in deduplication\n\t * const apiCall = callApi(\"/api/data\", {\n\t * dedupeKey: (context) => {\n\t * const authHeader = context.request.headers.get(\"Authorization\");\n\t * return `${context.options.fullURL}-${authHeader}`;\n\t * }\n\t * });\n\t *\n\t * // User-specific deduplication\n\t * const userSpecificCall = callApi(\"/api/dashboard\", {\n\t * dedupeKey: (context) => {\n\t * const userId = context.options.fullURL.match(/user\\/(\\d+)/)?.[1];\n\t * return `dashboard-${userId}`;\n\t * }\n\t * });\n\t *\n\t * // Ignore certain query parameters\n\t * const searchCall = callApi(\"/api/search?q=test&timestamp=123456\", {\n\t * dedupeKey: (context) => {\n\t * const url = new URL(context.options.fullURL);\n\t * url.searchParams.delete(\"timestamp\"); // Remove volatile param\n\t * return `search:${url.toString()}`;\n\t * }\n\t * });\n\t * ```\n\t *\n\t * @default Auto-generated from request details\n\t */\n\tdedupeKey?: string | ((context: RequestContext) => string | undefined);\n\n\t/**\n\t * Strategy for handling duplicate requests. Can be a static string or callback function.\n\t *\n\t * **Available Strategies:**\n\t * - `\"cancel\"`: Cancel previous request when new one starts (good for search)\n\t * - `\"defer\"`: Share response between duplicate requests (good for config loading)\n\t * - `\"none\"`: No deduplication, all requests execute independently\n\t *\n\t * @example\n\t * ```ts\n\t * // Static strategies\n\t * const searchClient = createFetchClient({\n\t * dedupeStrategy: \"cancel\" // Cancel previous searches\n\t * });\n\t *\n\t * const configClient = createFetchClient({\n\t * dedupeStrategy: \"defer\" // Share config across components\n\t * });\n\t *\n\t * // Dynamic strategy based on request\n\t * const smartClient = createFetchClient({\n\t * dedupeStrategy: (context) => {\n\t * return context.options.method === \"GET\" ? \"defer\" : \"cancel\";\n\t * }\n\t * });\n\t *\n\t * // Search-as-you-type with cancel strategy\n\t * const handleSearch = async (query: string) => {\n\t * try {\n\t * const { data } = await callApi(\"/api/search\", {\n\t * method: \"POST\",\n\t * body: { query },\n\t * dedupeStrategy: \"cancel\",\n\t * dedupeKey: \"search\" // Cancel previous searches, only latest one goes through\n\t * });\n\t *\n\t * updateSearchResults(data);\n\t * } catch (error) {\n\t * if (error.name === \"AbortError\") {\n\t * // Previous search cancelled - (expected behavior)\n\t * return;\n\t * }\n\t * console.error(\"Search failed:\", error);\n\t * }\n\t * };\n\t *\n\t * ```\n\t *\n\t * @default \"cancel\"\n\t */\n\tdedupeStrategy?: DedupeStrategyUnion | ((context: RequestContext) => DedupeStrategyUnion);\n};\n","import type { RequestContext } from \"./hooks\";\nimport type { CallApiContext } from \"./types/common\";\nimport type { DefaultCallApiContext } from \"./types/default-types\";\nimport type { UnmaskType } from \"./types/type-helpers\";\n\nexport type FetchImpl = UnmaskType<\n\t(input: string | Request | URL, init?: RequestInit) => Promise<Response>\n>;\n\nexport type FetchMiddlewareContext<TCallApiContext extends CallApiContext> =\n\tRequestContext<TCallApiContext> & {\n\t\tfetchImpl: FetchImpl;\n\t};\n\nexport interface Middlewares<TCallApiContext extends NoInfer<CallApiContext> = DefaultCallApiContext> {\n\t/**\n\t * Wraps the fetch implementation to intercept requests at the network layer.\n\t *\n\t * Takes a context object containing the current fetch function and returns a new fetch function.\n\t * Use it to cache responses, add logging, handle offline mode, or short-circuit requests etc.\n\t * Multiple middleware compose in order: plugins → base config → per-request.\n\t *\n\t * Unlike `customFetchImpl`, middleware can call through to the original fetch.\n\t *\n\t * @example\n\t * ```ts\n\t * // Cache responses\n\t * const cache = new Map();\n\t *\n\t * fetchMiddleware: (ctx) => async (input, init) => {\n\t * const key = input.toString();\n\t *\n\t * const cachedResponse = cache.get(key);\n\t *\n\t * if (cachedResponse) {\n\t *\t return cachedResponse.clone();\n\t * }\n\t *\n\t * const response = await ctx.fetchImpl(input, init);\n\t * cache.set(key, response.clone());\n\t *\n\t * return response;\n\t * }\n\t *\n\t * // Handle offline\n\t * fetchMiddleware: (ctx) => async (...parameters) => {\n\t * if (!navigator.onLine) {\n\t * return new Response('{\"error\": \"offline\"}', { status: 503 });\n\t * }\n\t *\n\t * return ctx.fetchImpl(...parameters);\n\t * }\n\t * ```\n\t */\n\tfetchMiddleware?: (context: FetchMiddlewareContext<TCallApiContext>) => FetchImpl;\n}\n\ntype MiddlewareRegistries = Required<{\n\t[Key in keyof Middlewares]: Set<Middlewares[Key]>;\n}>;\n\nexport const getMiddlewareRegistriesAndKeys = () => {\n\tconst middlewareRegistries: MiddlewareRegistries = {\n\t\tfetchMiddleware: new Set(),\n\t};\n\n\tconst middlewareRegistryKeys = Object.keys(middlewareRegistries) as Array<keyof Middlewares>;\n\n\treturn { middlewareRegistries, middlewareRegistryKeys };\n};\n\nexport const composeMiddlewaresFromArray = (\n\tmiddlewareArray: Array<Middlewares[keyof Middlewares] | undefined>\n) => {\n\tlet composedMiddleware: Middlewares[keyof Middlewares];\n\n\tfor (const currentMiddleware of middlewareArray) {\n\t\tif (!currentMiddleware) continue;\n\n\t\tconst previousMiddleware = composedMiddleware;\n\n\t\tif (!previousMiddleware) {\n\t\t\tcomposedMiddleware = currentMiddleware;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcomposedMiddleware = (context) => {\n\t\t\tconst prevFetchImpl = previousMiddleware(context);\n\t\t\tconst fetchImpl = currentMiddleware({ ...context, fetchImpl: prevFetchImpl });\n\n\t\t\treturn fetchImpl;\n\t\t};\n\t}\n\n\treturn composedMiddleware;\n};\n","import { extraOptionDefaults } from \"./constants/defaults\";\nimport {\n\tcomposeHooksFromArray,\n\tgetHookRegistriesAndKeys,\n\ttype Hooks,\n\ttype HooksOrHooksArray,\n\ttype RequestContext,\n} from \"./hooks\";\nimport {\n\tcomposeMiddlewaresFromArray,\n\tgetMiddlewareRegistriesAndKeys,\n\ttype Middlewares,\n} from \"./middlewares\";\nimport type { CallApiContext, CallApiRequestOptions, OverrideCallApiContext } from \"./types/common\";\nimport type { DefaultCallApiContext, DefaultDataType } from \"./types/default-types\";\nimport type { AnyFunction, Awaitable, UnionToIntersection } from \"./types/type-helpers\";\nimport type { InitURLOrURLObject } from \"./url\";\nimport { getMethod, getResolvedHeaders } from \"./utils/common\";\nimport { isArray, isFunction, isString } from \"./utils/guards\";\nimport {\n\tgetCurrentRouteSchemaKeyAndMainInitURL,\n\ttype BaseCallApiSchemaAndConfig,\n\ttype InferSchemaOutput,\n} from \"./validation\";\n\nexport type PluginSetupContext<TCallApiContext extends CallApiContext = DefaultCallApiContext> =\n\tRequestContext<TCallApiContext> & { initURL: string };\n\nexport type PluginInitResult<TCallApiContext extends CallApiContext = DefaultCallApiContext> = Partial<\n\tOmit<PluginSetupContext<TCallApiContext>, \"initURL\" | \"request\"> & {\n\t\tinitURL: InitURLOrURLObject;\n\t\trequest: CallApiRequestOptions;\n\t}\n>;\n\ntype GetDefaultDataTypeForPlugins<TData> = DefaultDataType extends TData ? never : TData;\n\nexport type PluginHooks<TCallApiContext extends CallApiContext = DefaultCallApiContext> =\n\tHooksOrHooksArray<\n\t\tOverrideCallApiContext<\n\t\t\tTCallApiContext,\n\t\t\t{\n\t\t\t\tData: GetDefaultDataTypeForPlugins<TCallApiContext[\"Data\"]>;\n\t\t\t\tErrorData: GetDefaultDataTypeForPlugins<TCallApiContext[\"ErrorData\"]>;\n\t\t\t}\n\t\t>\n\t>;\n\nexport type PluginMiddlewares<TCallApiContext extends CallApiContext = DefaultCallApiContext> =\n\tMiddlewares<\n\t\tOverrideCallApiContext<\n\t\t\tTCallApiContext,\n\t\t\t{\n\t\t\t\tData: GetDefaultDataTypeForPlugins<TCallApiContext[\"Data\"]>;\n\t\t\t\tErrorData: GetDefaultDataTypeForPlugins<TCallApiContext[\"ErrorData\"]>;\n\t\t\t}\n\t\t>\n\t>;\n\nexport interface CallApiPlugin<TCallApiContext extends CallApiContext = DefaultCallApiContext> {\n\t/**\n\t * Defines additional options that can be passed to callApi\n\t */\n\tdefineExtraOptions?: () => TCallApiContext[\"InferredExtraOptions\"];\n\n\t/**\n\t * A description for the plugin\n\t */\n\tdescription?: string;\n\n\t/**\n\t * Hooks for the plugin\n\t */\n\thooks?:\n\t\t| PluginHooks<TCallApiContext>\n\t\t| ((\n\t\t\t\tcontext: PluginSetupContext<TCallApiContext>\n\t\t ) => Awaitable<PluginHooks<TCallApiContext>> | Awaitable<void>);\n\n\t/**\n\t * A unique id for the plugin\n\t */\n\tid: string;\n\n\t/**\n\t * Middlewares that for the plugin\n\t */\n\tmiddlewares?:\n\t\t| PluginMiddlewares<TCallApiContext>\n\t\t| ((\n\t\t\t\tcontext: PluginSetupContext<TCallApiContext>\n\t\t ) => Awaitable<PluginMiddlewares<TCallApiContext>> | Awaitable<void>);\n\n\t/**\n\t * A name for the plugin\n\t */\n\tname: string;\n\n\t/**\n\t * Base schema for the client.\n\t */\n\tschema?: BaseCallApiSchemaAndConfig;\n\n\t/**\n\t * A function that will be called when the plugin is initialized. This will be called before the any of the other internal functions.\n\t */\n\tsetup?: (\n\t\tcontext: PluginSetupContext<TCallApiContext>\n\t) => Awaitable<PluginInitResult<TCallApiContext>> | Awaitable<void>;\n\n\t/**\n\t * A version for the plugin\n\t */\n\tversion?: string;\n}\n\nexport type InferPluginExtraOptions<TPluginArray extends CallApiPlugin[]> = UnionToIntersection<\n\tTPluginArray extends Array<infer TPlugin> ?\n\t\tTPlugin extends CallApiPlugin ?\n\t\t\tTPlugin[\"defineExtraOptions\"] extends AnyFunction<infer TResult> ?\n\t\t\t\tInferSchemaOutput<TResult, TResult>\n\t\t\t:\tnever\n\t\t:\tnever\n\t:\tnever\n>;\n\nexport const getResolvedPlugins = (context: Pick<RequestContext, \"baseConfig\" | \"options\">) => {\n\tconst { baseConfig, options } = context;\n\n\tconst resolvedPlugins =\n\t\tisFunction(options.plugins) ?\n\t\t\toptions.plugins({ basePlugins: baseConfig.plugins ?? [] })\n\t\t:\t(options.plugins ?? []);\n\n\treturn resolvedPlugins;\n};\n\nexport const initializePlugins = async (setupContext: PluginSetupContext) => {\n\tconst { baseConfig, config, initURL, options, request } = setupContext;\n\n\tconst {\n\t\taddMainHooks,\n\t\taddMainMiddlewares,\n\t\taddPluginHooks,\n\t\taddPluginMiddlewares,\n\t\tgetResolvedHooks,\n\t\tgetResolvedMiddlewares,\n\t} = setupHooksAndMiddlewares({ baseConfig, config, options });\n\n\tconst initURLResult = getCurrentRouteSchemaKeyAndMainInitURL({\n\t\tbaseExtraOptions: baseConfig,\n\t\textraOptions: config,\n\t\tinitURL,\n\t});\n\n\tlet resolvedCurrentRouteSchemaKey = initURLResult.currentRouteSchemaKey;\n\tlet resolvedInitURL = initURLResult.mainInitURL;\n\tconst resolvedOptions = options;\n\tconst resolvedRequest = Object.assign(request, {\n\t\theaders: getResolvedHeaders({ baseHeaders: baseConfig.headers, headers: config.headers }),\n\t\tmethod: getMethod({ initURL: resolvedInitURL, method: request.method }),\n\t});\n\n\tconst executePluginSetupFn = async (pluginSetup: CallApiPlugin[\"setup\"]) => {\n\t\tif (!pluginSetup) return;\n\n\t\tconst initResult = await pluginSetup(setupContext);\n\n\t\tif (!initResult) return;\n\n\t\tconst urlString = initResult.initURL?.toString();\n\n\t\tif (isString(urlString)) {\n\t\t\tconst newURLResult = getCurrentRouteSchemaKeyAndMainInitURL({\n\t\t\t\tbaseExtraOptions: baseConfig,\n\t\t\t\textraOptions: config,\n\t\t\t\tinitURL: urlString,\n\t\t\t});\n\n\t\t\tresolvedCurrentRouteSchemaKey = newURLResult.currentRouteSchemaKey;\n\t\t\tresolvedInitURL = newURLResult.mainInitURL;\n\t\t}\n\n\t\tif (initResult.request) {\n\t\t\tObject.assign(resolvedRequest, initResult.request);\n\t\t}\n\n\t\tif (initResult.options) {\n\t\t\tObject.assign(resolvedOptions, initResult.options);\n\t\t}\n\t};\n\n\tconst resolvedPlugins = getResolvedPlugins({ baseConfig, options });\n\n\tfor (const plugin of resolvedPlugins) {\n\t\t// eslint-disable-next-line no-await-in-loop -- Await is necessary in this case.\n\t\tconst [, pluginHooks, pluginMiddlewares] = await Promise.all([\n\t\t\texecutePluginSetupFn(plugin.setup),\n\t\t\tisFunction(plugin.hooks) ? plugin.hooks(setupContext) : plugin.hooks,\n\t\t\tisFunction(plugin.middlewares) ? plugin.middlewares(setupContext) : plugin.middlewares,\n\t\t]);\n\n\t\tpluginHooks && addPluginHooks(pluginHooks);\n\t\tpluginMiddlewares && addPluginMiddlewares(pluginMiddlewares);\n\t}\n\n\taddMainHooks();\n\n\taddMainMiddlewares();\n\n\tconst resolvedHooks = getResolvedHooks();\n\n\tconst resolvedMiddlewares = getResolvedMiddlewares();\n\n\treturn {\n\t\tresolvedCurrentRouteSchemaKey,\n\t\tresolvedHooks,\n\t\tresolvedInitURL,\n\t\tresolvedMiddlewares,\n\t\tresolvedOptions,\n\t\tresolvedRequest,\n\t};\n};\n\nconst setupHooksAndMiddlewares = (\n\tcontext: Pick<PluginSetupContext, \"baseConfig\" | \"config\" | \"options\">\n) => {\n\tconst { baseConfig, config, options } = context;\n\n\tconst { hookRegistries, hookRegistryKeys } = getHookRegistriesAndKeys();\n\n\tconst { middlewareRegistries, middlewareRegistryKeys } = getMiddlewareRegistriesAndKeys();\n\n\tconst addMainHooks = () => {\n\t\tfor (const hookName of hookRegistryKeys) {\n\t\t\tconst overriddenHook = options[hookName];\n\t\t\tconst baseHook = baseConfig[hookName];\n\t\t\tconst instanceHook = config[hookName];\n\n\t\t\tconst shouldMergeBaseAndInstanceHooks = isArray(baseHook) && instanceHook;\n\n\t\t\tconst mainHook =\n\t\t\t\tshouldMergeBaseAndInstanceHooks ? [baseHook, instanceHook].flat() : overriddenHook;\n\n\t\t\tmainHook && hookRegistries[hookName].add(mainHook as never);\n\t\t}\n\t};\n\n\tconst addPluginHooks = (pluginHooks: PluginHooks) => {\n\t\tfor (const hookName of hookRegistryKeys) {\n\t\t\tconst pluginHook = pluginHooks[hookName];\n\n\t\t\tpluginHook && hookRegistries[hookName].add(pluginHook as never);\n\t\t}\n\t};\n\n\tconst addMainMiddlewares = () => {\n\t\tfor (const middlewareName of middlewareRegistryKeys) {\n\t\t\tconst baseMiddleware = baseConfig[middlewareName];\n\t\t\tconst instanceMiddleware = config[middlewareName];\n\n\t\t\tbaseMiddleware && middlewareRegistries[middlewareName].add(baseMiddleware);\n\n\t\t\tinstanceMiddleware && middlewareRegistries[middlewareName].add(instanceMiddleware);\n\t\t}\n\t};\n\n\tconst addPluginMiddlewares = (pluginMiddlewares: PluginMiddlewares) => {\n\t\tfor (const middlewareName of middlewareRegistryKeys) {\n\t\t\tconst pluginMiddleware = pluginMiddlewares[middlewareName];\n\n\t\t\tif (!pluginMiddleware) continue;\n\n\t\t\tmiddlewareRegistries[middlewareName].add(pluginMiddleware);\n\t\t}\n\t};\n\n\tconst getResolvedHooks = () => {\n\t\tconst resolvedHooks: Hooks = {};\n\n\t\tfor (const [hookName, hookRegistry] of Object.entries(hookRegistries)) {\n\t\t\tif (hookRegistry.size === 0) continue;\n\n\t\t\t// == Flatten the hook registry to remove any nested arrays, incase an array of hooks is passed to any of the hooks\n\t\t\tconst flattenedHookArray = [...hookRegistry].flat();\n\n\t\t\tif (flattenedHookArray.length === 0) continue;\n\n\t\t\tconst hooksExecutionMode = options.hooksExecutionMode ?? extraOptionDefaults.hooksExecutionMode;\n\n\t\t\tconst composedHook = composeHooksFromArray(flattenedHookArray, hooksExecutionMode);\n\n\t\t\tresolvedHooks[hookName as keyof Hooks] = composedHook;\n\t\t}\n\n\t\treturn resolvedHooks;\n\t};\n\n\tconst getResolvedMiddlewares = () => {\n\t\tconst resolvedMiddlewares: Middlewares = {};\n\n\t\tfor (const [middlewareName, middlewareRegistry] of Object.entries(middlewareRegistries)) {\n\t\t\tif (middlewareRegistry.size === 0) continue;\n\n\t\t\tconst middlewareArray = [...middlewareRegistry];\n\n\t\t\tif (middlewareArray.length === 0) continue;\n\n\t\t\tconst composedMiddleware = composeMiddlewaresFromArray(middlewareArray);\n\n\t\t\tresolvedMiddlewares[middlewareName as keyof Middlewares] = composedMiddleware;\n\t\t}\n\n\t\treturn resolvedMiddlewares;\n\t};\n\n\treturn {\n\t\taddMainHooks,\n\t\taddMainMiddlewares,\n\t\taddPluginHooks,\n\t\taddPluginMiddlewares,\n\t\tgetResolvedHooks,\n\t\tgetResolvedMiddlewares,\n\t};\n};\n","import { extraOptionDefaults } from \"./constants/defaults\";\nimport {\n\texecuteHooksInCatchBlock,\n\ttype ErrorContext,\n\ttype ExecuteHookInfo,\n\ttype RetryContext,\n} from \"./hooks\";\nimport type { CallApiResultErrorVariant } from \"./result\";\nimport type { CallApiConfig } from \"./types/common\";\nimport type { MethodUnion } from \"./types/conditional-types\";\nimport { defineEnum, type AnyNumber, type Awaitable, type UnmaskType } from \"./types/type-helpers\";\nimport type { InitURLOrURLObject } from \"./url\";\nimport { waitFor } from \"./utils/common\";\nimport { isBoolean, isFunction, isString } from \"./utils/guards\";\n\n// eslint-disable-next-line ts-eslint/no-unused-vars -- Ignore\nconst defaultRetryStatusCodesLookup = () =>\n\tdefineEnum({\n\t\t408: \"Request Timeout\",\n\t\t409: \"Conflict\",\n\t\t425: \"Too Early\",\n\t\t429: \"Too Many Requests\",\n\t\t500: \"Internal Server Error\",\n\t\t502: \"Bad Gateway\",\n\t\t503: \"Service Unavailable\",\n\t\t504: \"Gateway Timeout\",\n\t});\n\ntype RetryStatusCodes = UnmaskType<AnyNumber | keyof ReturnType<typeof defaultRetryStatusCodesLookup>>;\n\ntype RetryCondition<TErrorData> = (context: ErrorContext<{ ErrorData: TErrorData }>) => Awaitable<boolean>;\n\nexport interface RetryOptions<TErrorData> {\n\t/**\n\t * Keeps track of the number of times the request has already been retried\n\t * @internal\n\t * @deprecated **NOTE**: This property is used internally to track retries. Please abstain from modifying it.\n\t */\n\treadonly [\"~retryAttemptCount\"]?: number;\n\n\t/**\n\t * Number of allowed retry attempts on HTTP errors\n\t * @default 0\n\t */\n\tretryAttempts?: number;\n\n\t/**\n\t * Callback whose return value determines if a request should be retried or not\n\t */\n\tretryCondition?: RetryCondition<TErrorData>;\n\n\t/**\n\t * Delay between retries in milliseconds\n\t * @default 1000\n\t */\n\tretryDelay?: number | ((currentAttemptCount: number) => number);\n\n\t/**\n\t * Maximum delay in milliseconds. Only applies to exponential strategy\n\t * @default 10000\n\t */\n\tretryMaxDelay?: number;\n\n\t/**\n\t * HTTP methods that are allowed to retry\n\t * @default [\"GET\", \"POST\"]\n\t */\n\tretryMethods?: MethodUnion[];\n\n\t/**\n\t * HTTP status codes that trigger a retry\n\t */\n\tretryStatusCodes?: RetryStatusCodes[];\n\n\t/**\n\t * Strategy to use when retrying\n\t * @default \"linear\"\n\t */\n\tretryStrategy?: \"exponential\" | \"linear\";\n}\n\nconst getLinearDelay = (currentAttemptCount: number, options: RetryOptions<unknown>) => {\n\tconst retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;\n\n\tconst resolveRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;\n\n\treturn resolveRetryDelay;\n};\n\nconst getExponentialDelay = (currentAttemptCount: number, options: RetryOptions<unknown>) => {\n\tconst retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;\n\n\tconst resolvedRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;\n\n\tconst maxDelay = options.retryMaxDelay ?? extraOptionDefaults.retryMaxDelay;\n\n\tconst exponentialDelay = resolvedRetryDelay * 2 ** currentAttemptCount;\n\n\treturn Math.min(exponentialDelay, maxDelay);\n};\n\ntype CallApiImpl = (initURL: never, init?: CallApiConfig) => Promise<CallApiResultErrorVariant<unknown>>;\n\nexport const createRetryManager = <TCallApi extends CallApiImpl>(ctx: {\n\tcallApi: TCallApi;\n\tcallApiArgs: { config: CallApiConfig; initURL: InitURLOrURLObject };\n\terror: unknown;\n\terrorContext: ErrorContext;\n\terrorResult: CallApiResultErrorVariant<unknown> | null;\n\thookInfo: ExecuteHookInfo;\n}) => {\n\tconst { callApi, callApiArgs, error, errorContext, errorResult, hookInfo } = ctx;\n\n\tconst { options, request } = errorContext;\n\n\t// eslint-disable-next-line ts-eslint/no-deprecated -- Allowed for internal use\n\tconst currentAttemptCount = options[\"~retryAttemptCount\"] ?? 1;\n\n\tconst retryStrategy = options.retryStrategy ?? extraOptionDefaults.retryStrategy;\n\n\tconst getDelay = () => {\n\t\tswitch (retryStrategy) {\n\t\t\tcase \"exponential\": {\n\t\t\t\treturn getExponentialDelay(currentAttemptCount, options);\n\t\t\t}\n\t\t\tcase \"linear\": {\n\t\t\t\treturn getLinearDelay(currentAttemptCount, options);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Invalid retry strategy: ${String(retryStrategy)}`);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst shouldAttemptRetry = async () => {\n\t\tif (isBoolean(request.signal) && request.signal.aborted) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst retryCondition = options.retryCondition ?? extraOptionDefaults.retryCondition;\n\n\t\tconst maximumRetryAttempts = options.retryAttempts ?? extraOptionDefaults.retryAttempts;\n\n\t\tconst customRetryCondition = await retryCondition(errorContext);\n\n\t\tconst baseShouldRetry = currentAttemptCount <= maximumRetryAttempts && customRetryCondition;\n\n\t\tif (!baseShouldRetry) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst retryMethods = new Set(options.retryMethods ?? extraOptionDefaults.retryMethods);\n\n\t\tconst includesMethod =\n\t\t\tisString(request.method) && retryMethods.size > 0 ? retryMethods.has(request.method) : true;\n\n\t\tconst retryStatusCodes = new Set(options.retryStatusCodes ?? extraOptionDefaults.retryStatusCodes);\n\n\t\tconst includesStatusCodes =\n\t\t\terrorContext.response != null && retryStatusCodes.size > 0 ?\n\t\t\t\tretryStatusCodes.has(errorContext.response.status)\n\t\t\t:\ttrue;\n\n\t\tconst shouldRetry = includesMethod && includesStatusCodes;\n\n\t\treturn shouldRetry;\n\t};\n\n\tconst handleRetry = async () => {\n\t\tconst retryContext = {\n\t\t\t...errorContext,\n\t\t\tretryAttemptCount: currentAttemptCount,\n\t\t} satisfies RetryContext<{ ErrorData: unknown }>;\n\n\t\tconst hookError = await executeHooksInCatchBlock([options.onRetry?.(retryContext)], hookInfo);\n\n\t\tif (hookError) {\n\t\t\treturn hookError;\n\t\t}\n\n\t\tawait waitFor(getDelay());\n\n\t\tconst updatedConfig = {\n\t\t\t...callApiArgs.config,\n\t\t\t\"~retryAttemptCount\": currentAttemptCount + 1,\n\t\t} satisfies CallApiConfig;\n\n\t\treturn callApi(callApiArgs.initURL as never, updatedConfig);\n\t};\n\n\tconst handleRetryOrGetErrorResult = async () => {\n\t\tconst shouldRetry = await shouldAttemptRetry();\n\n\t\tif (shouldRetry) {\n\t\t\tconst callApiRetryResult = handleRetry();\n\n\t\t\treturn callApiRetryResult;\n\t\t}\n\n\t\tif (hookInfo.shouldThrowOnError) {\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn errorResult;\n\t};\n\n\treturn {\n\t\thandleRetryOrGetErrorResult,\n\t};\n};\n","import { createDedupeStrategy, type GlobalRequestInfoCache, type RequestInfoCache } from \"./dedupe\";\nimport {\n\texecuteHooks,\n\texecuteHooksInCatchBlock,\n\ttype ErrorContext,\n\ttype ExecuteHookInfo,\n\ttype RequestContext,\n\ttype ResponseContext,\n\ttype SuccessContext,\n} from \"./hooks\";\nimport { initializePlugins, type CallApiPlugin } from \"./plugins\";\nimport {\n\tgetCustomizedErrorResult,\n\tresolveErrorResult,\n\tresolveResponseData,\n\tresolveSuccessResult,\n\ttype ErrorInfo,\n\ttype GetResponseType,\n\ttype ResponseTypeType,\n\ttype ResultModeType,\n} from \"./result\";\nimport { createRetryManager } from \"./retry\";\nimport type {\n\tBaseCallApiConfig,\n\tCallApiConfig,\n\tCallApiContext,\n\tCallApiExtraOptionsForHooks,\n\tCallApiRequestOptions,\n\tCallApiRequestOptionsForHooks,\n\tCallApiResult,\n\tGetBaseSchemaConfig,\n\tGetBaseSchemaRoutes,\n} from \"./types/common\";\nimport type {\n\tGetCurrentRouteSchema,\n\tGetCurrentRouteSchemaKey,\n\tInferInitURL,\n\tThrowOnErrorBoolean,\n} from \"./types/conditional-types\";\nimport type {\n\tDefaultCallApiContext,\n\tDefaultPluginArray,\n\tDefaultThrowOnError,\n} from \"./types/default-types\";\nimport type { AnyFunction } from \"./types/type-helpers\";\nimport { getFullAndNormalizedURL } from \"./url\";\nimport {\n\tcreateCombinedSignal,\n\tcreateTimeoutSignal,\n\tgetBody,\n\tgetFetchImpl,\n\tgetHeaders,\n\tgetMethod,\n\tsplitBaseConfig,\n\tsplitConfig,\n} from \"./utils/common\";\nimport { HTTPError } from \"./utils/external/error\";\nimport { isHTTPErrorInstance, isValidationErrorInstance } from \"./utils/external/guards\";\nimport { isFunction } from \"./utils/guards\";\nimport {\n\thandleConfigValidation,\n\thandleSchemaValidation,\n\ttype BaseCallApiSchemaAndConfig,\n\ttype BaseCallApiSchemaRoutes,\n\ttype CallApiSchema,\n\ttype CallApiSchemaConfig,\n\ttype InferSchemaOutput,\n} from \"./validation\";\n\nconst $GlobalRequestInfoCache: GlobalRequestInfoCache = new Map();\n\nexport const createFetchClientWithContext = <\n\tTOuterCallApiContext extends CallApiContext = DefaultCallApiContext,\n>() => {\n\tconst createFetchClient = <\n\t\tTBaseCallApiContext extends CallApiContext = TOuterCallApiContext,\n\t\tTBaseData = TBaseCallApiContext[\"Data\"],\n\t\tTBaseErrorData = TBaseCallApiContext[\"ErrorData\"],\n\t\tTBaseResultMode extends ResultModeType = TBaseCallApiContext[\"ResultMode\"] extends ResultModeType ?\n\t\t\tTBaseCallApiContext[\"ResultMode\"]\n\t\t:\tDefaultCallApiContext[\"ResultMode\"],\n\t\tTBaseThrowOnError extends ThrowOnErrorBoolean = DefaultThrowOnError,\n\t\tTBaseResponseType extends ResponseTypeType = ResponseTypeType,\n\t\tconst TBaseSchemaAndConfig extends BaseCallApiSchemaAndConfig = BaseCallApiSchemaAndConfig,\n\t\tconst TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray,\n\t\tTComputedBaseSchemaConfig extends CallApiSchemaConfig = GetBaseSchemaConfig<TBaseSchemaAndConfig>,\n\t\tTComputedBaseSchemaRoutes extends BaseCallApiSchemaRoutes =\n\t\t\tGetBaseSchemaRoutes<TBaseSchemaAndConfig>,\n\t>(\n\t\tinitBaseConfig: BaseCallApiConfig<\n\t\t\tTBaseCallApiContext,\n\t\t\tTBaseData,\n\t\t\tTBaseErrorData,\n\t\t\tTBaseResultMode,\n\t\t\tTBaseThrowOnError,\n\t\t\tTBaseResponseType,\n\t\t\tTBaseSchemaAndConfig,\n\t\t\tTBasePluginArray\n\t\t> = {} as never\n\t) => {\n\t\tconst $LocalRequestInfoCache: RequestInfoCache = new Map();\n\n\t\tconst callApi = async <\n\t\t\tTData = TBaseData,\n\t\t\tTErrorData = TBaseErrorData,\n\t\t\tTResultMode extends ResultModeType = TBaseResultMode,\n\t\t\tTCallApiContext extends CallApiContext = TBaseCallApiContext,\n\t\t\tTThrowOnError extends ThrowOnErrorBoolean = TBaseThrowOnError,\n\t\t\tTResponseType extends ResponseTypeType = TBaseResponseType,\n\t\t\tconst TSchemaConfig extends CallApiSchemaConfig = TComputedBaseSchemaConfig,\n\t\t\tTInitURL extends InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig> = InferInitURL<\n\t\t\t\tTComputedBaseSchemaRoutes,\n\t\t\t\tTSchemaConfig\n\t\t\t>,\n\t\t\tTCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> =\n\t\t\t\tGetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>,\n\t\t\tconst TSchema extends CallApiSchema = GetCurrentRouteSchema<\n\t\t\t\tTComputedBaseSchemaRoutes,\n\t\t\t\tTCurrentRouteSchemaKey\n\t\t\t>,\n\t\t\tconst TPluginArray extends CallApiPlugin[] = TBasePluginArray,\n\t\t\tTComputedData = InferSchemaOutput<TSchema[\"data\"], GetResponseType<TData, TResponseType>>,\n\t\t\tTComputedErrorData = InferSchemaOutput<\n\t\t\t\tTSchema[\"errorData\"],\n\t\t\t\tGetResponseType<TErrorData, TResponseType>\n\t\t\t>,\n\t\t\tTComputedResult = CallApiResult<TComputedData, TComputedErrorData, TResultMode, TThrowOnError>,\n\t\t>(\n\t\t\tinitURL: TInitURL,\n\t\t\tinitConfig: CallApiConfig<\n\t\t\t\tTCallApiContext,\n\t\t\t\tTComputedData,\n\t\t\t\tTComputedErrorData,\n\t\t\t\tTResultMode,\n\t\t\t\tTThrowOnError,\n\t\t\t\tTResponseType,\n\t\t\t\tTComputedBaseSchemaRoutes,\n\t\t\t\tTSchema,\n\t\t\t\tTComputedBaseSchemaConfig,\n\t\t\t\tTSchemaConfig,\n\t\t\t\tTInitURL,\n\t\t\t\tTCurrentRouteSchemaKey,\n\t\t\t\tTBasePluginArray,\n\t\t\t\tTPluginArray\n\t\t\t> = {} as never\n\t\t): Promise<TComputedResult> => {\n\t\t\tconst [fetchOptions, extraOptions] = splitConfig(initConfig);\n\n\t\t\tconst resolvedBaseConfig =\n\t\t\t\tisFunction(initBaseConfig) ?\n\t\t\t\t\tinitBaseConfig({\n\t\t\t\t\t\tinitURL: initURL.toString(),\n\t\t\t\t\t\toptions: extraOptions,\n\t\t\t\t\t\trequest: fetchOptions,\n\t\t\t\t\t})\n\t\t\t\t:\tinitBaseConfig;\n\n\t\t\tconst baseConfig = resolvedBaseConfig as Exclude<BaseCallApiConfig, AnyFunction>;\n\t\t\tconst config = initConfig as CallApiConfig;\n\n\t\t\tconst [baseFetchOptions, baseExtraOptions] = splitBaseConfig(baseConfig);\n\n\t\t\tconst shouldSkipAutoMergeForOptions =\n\t\t\t\tbaseExtraOptions.skipAutoMergeFor === \"all\" || baseExtraOptions.skipAutoMergeFor === \"options\";\n\n\t\t\tconst shouldSkipAutoMergeForRequest =\n\t\t\t\tbaseExtraOptions.skipAutoMergeFor === \"all\" || baseExtraOptions.skipAutoMergeFor === \"request\";\n\n\t\t\t// == Merged Extra Options\n\t\t\tconst mergedExtraOptions = {\n\t\t\t\t...baseExtraOptions,\n\t\t\t\t...(!shouldSkipAutoMergeForOptions && extraOptions),\n\t\t\t};\n\n\t\t\t// == Merged Request Options\n\t\t\tconst mergedRequestOptions = {\n\t\t\t\t...baseFetchOptions,\n\t\t\t\t...(!shouldSkipAutoMergeForRequest && fetchOptions),\n\t\t\t} satisfies CallApiRequestOptions;\n\n\t\t\tconst {\n\t\t\t\tresolvedCurrentRouteSchemaKey,\n\t\t\t\tresolvedHooks,\n\t\t\t\tresolvedInitURL,\n\t\t\t\tresolvedMiddlewares,\n\t\t\t\tresolvedOptions,\n\t\t\t\tresolvedRequest,\n\t\t\t} = await initializePlugins({\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tinitURL: initURL.toString(),\n\t\t\t\toptions: mergedExtraOptions as CallApiExtraOptionsForHooks,\n\t\t\t\trequest: mergedRequestOptions as CallApiRequestOptionsForHooks,\n\t\t\t});\n\n\t\t\tconst { fullURL, normalizedInitURL } = getFullAndNormalizedURL({\n\t\t\t\tbaseURL: resolvedOptions.baseURL,\n\t\t\t\tinitURL: resolvedInitURL,\n\t\t\t\tparams: resolvedOptions.params,\n\t\t\t\tquery: resolvedOptions.query,\n\t\t\t});\n\n\t\t\tconst options = {\n\t\t\t\t...resolvedOptions,\n\t\t\t\t...resolvedHooks,\n\t\t\t\t...resolvedMiddlewares,\n\n\t\t\t\tfullURL,\n\t\t\t\tinitURL: resolvedInitURL,\n\t\t\t\tinitURLNormalized: normalizedInitURL,\n\t\t\t} satisfies CallApiExtraOptionsForHooks;\n\n\t\t\tconst newFetchController = new AbortController();\n\n\t\t\tconst timeoutSignal = createTimeoutSignal(options.timeout);\n\n\t\t\tconst combinedSignal = createCombinedSignal(\n\t\t\t\ttimeoutSignal,\n\t\t\t\tresolvedRequest.signal,\n\t\t\t\tnewFetchController.signal\n\t\t\t);\n\n\t\t\tconst request = {\n\t\t\t\t...resolvedRequest,\n\n\t\t\t\tsignal: combinedSignal,\n\t\t\t} satisfies CallApiRequestOptionsForHooks;\n\n\t\t\tconst {\n\t\t\t\tgetAbortErrorMessage,\n\t\t\t\thandleRequestCancelStrategy,\n\t\t\t\thandleRequestDeferStrategy,\n\t\t\t\tremoveDedupeKeyFromCache,\n\t\t\t\tresolvedDedupeStrategy,\n\t\t\t} = await createDedupeStrategy({\n\t\t\t\t$GlobalRequestInfoCache,\n\t\t\t\t$LocalRequestInfoCache,\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tnewFetchController,\n\t\t\t\toptions,\n\t\t\t\trequest,\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\thandleRequestCancelStrategy();\n\n\t\t\t\tawait executeHooks(options.onRequest?.({ baseConfig, config, options, request }));\n\n\t\t\t\tconst {\n\t\t\t\t\textraOptionsValidationResult,\n\t\t\t\t\trequestOptionsValidationResult,\n\t\t\t\t\tresolvedSchema,\n\t\t\t\t\tresolvedSchemaConfig,\n\t\t\t\t} = await handleConfigValidation({\n\t\t\t\t\tbaseExtraOptions,\n\t\t\t\t\tcurrentRouteSchemaKey: resolvedCurrentRouteSchemaKey,\n\t\t\t\t\textraOptions,\n\t\t\t\t\toptions,\n\t\t\t\t\trequest,\n\t\t\t\t});\n\n\t\t\t\t// == Apply Schema Output for Extra Options\n\n\t\t\t\tObject.assign(options, extraOptionsValidationResult);\n\n\t\t\t\t// == Apply Schema Output for Request Options\n\t\t\t\tObject.assign(request, {\n\t\t\t\t\tbody: getBody({\n\t\t\t\t\t\tbody: requestOptionsValidationResult.body,\n\t\t\t\t\t\tbodySerializer: options.bodySerializer,\n\t\t\t\t\t\tresolvedHeaders: requestOptionsValidationResult.headers,\n\t\t\t\t\t}),\n\t\t\t\t\theaders: await getHeaders({\n\t\t\t\t\t\tauth: options.auth,\n\t\t\t\t\t\tbody: requestOptionsValidationResult.body,\n\t\t\t\t\t\tresolvedHeaders: requestOptionsValidationResult.headers,\n\t\t\t\t\t}),\n\t\t\t\t\tmethod: getMethod({\n\t\t\t\t\t\tinitURL: resolvedInitURL,\n\t\t\t\t\t\tmethod: requestOptionsValidationResult.method,\n\t\t\t\t\t}),\n\t\t\t\t});\n\n\t\t\t\tconst readyRequestContext = { baseConfig, config, options, request } satisfies RequestContext;\n\n\t\t\t\tawait executeHooks(options.onRequestReady?.(readyRequestContext));\n\n\t\t\t\tconst fetchApi = getFetchImpl({\n\t\t\t\t\tcustomFetchImpl: options.customFetchImpl,\n\t\t\t\t\tfetchMiddleware: options.fetchMiddleware,\n\t\t\t\t\trequestContext: readyRequestContext,\n\t\t\t\t});\n\n\t\t\t\tconst response = await handleRequestDeferStrategy({ fetchApi, options, request });\n\n\t\t\t\t// == Also clone response when dedupeStrategy is set to \"defer\" to avoid error thrown from reading response.(whatever) more than once\n\t\t\t\tconst shouldCloneResponse = Boolean(\n\t\t\t\t\tresolvedDedupeStrategy === \"defer\" || options.cloneResponse\n\t\t\t\t);\n\n\t\t\t\tconst responseData = await resolveResponseData({\n\t\t\t\t\tresponse: shouldCloneResponse ? response.clone() : response,\n\t\t\t\t\tresponseParser: options.responseParser,\n\t\t\t\t\tresponseType: options.responseType,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t});\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tconst validErrorData = await handleSchemaValidation(resolvedSchema, \"errorData\", {\n\t\t\t\t\t\tinputValue: responseData,\n\t\t\t\t\t\tresponse,\n\t\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t\t\t\t});\n\n\t\t\t\t\t// == Push all error handling responsibilities to the catch block if not retrying\n\t\t\t\t\tthrow new HTTPError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdefaultHTTPErrorMessage: options.defaultHTTPErrorMessage,\n\t\t\t\t\t\t\terrorData: validErrorData,\n\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ cause: validErrorData }\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst validSuccessData = await handleSchemaValidation(resolvedSchema, \"data\", {\n\t\t\t\t\tinputValue: responseData,\n\t\t\t\t\tresponse,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t\t\t});\n\n\t\t\t\tconst successContext = {\n\t\t\t\t\tbaseConfig,\n\t\t\t\t\tconfig,\n\t\t\t\t\tdata: validSuccessData,\n\t\t\t\t\toptions,\n\t\t\t\t\trequest,\n\t\t\t\t\tresponse,\n\t\t\t\t} satisfies SuccessContext;\n\n\t\t\t\tawait executeHooks(\n\t\t\t\t\toptions.onSuccess?.(successContext),\n\t\t\t\t\toptions.onResponse?.({ ...successContext, error: null })\n\t\t\t\t);\n\n\t\t\t\tconst successResult = resolveSuccessResult(successContext.data, {\n\t\t\t\t\tresponse: successContext.response,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t});\n\n\t\t\t\treturn successResult as never;\n\n\t\t\t\t// == Exhaustive Error handling\n\t\t\t} catch (error) {\n\t\t\t\tconst errorInfo = {\n\t\t\t\t\tcloneResponse: options.cloneResponse,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t} satisfies ErrorInfo;\n\n\t\t\t\tconst { errorDetails, errorResult } = resolveErrorResult(error, errorInfo);\n\n\t\t\t\tconst errorContext = {\n\t\t\t\t\tbaseConfig,\n\t\t\t\t\tconfig,\n\t\t\t\t\terror: errorDetails.error as never,\n\t\t\t\t\toptions,\n\t\t\t\t\trequest,\n\t\t\t\t\tresponse: errorDetails.response as never,\n\t\t\t\t} satisfies ErrorContext;\n\n\t\t\t\tconst shouldThrowOnError = Boolean(\n\t\t\t\t\tisFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError\n\t\t\t\t);\n\n\t\t\t\tconst hookInfo = {\n\t\t\t\t\terrorInfo,\n\t\t\t\t\tshouldThrowOnError,\n\t\t\t\t} satisfies ExecuteHookInfo;\n\n\t\t\t\tconst { handleRetryOrGetErrorResult } = createRetryManager({\n\t\t\t\t\tcallApi,\n\t\t\t\t\tcallApiArgs: { config, initURL },\n\t\t\t\t\terror,\n\t\t\t\t\terrorContext,\n\t\t\t\t\terrorResult,\n\t\t\t\t\thookInfo,\n\t\t\t\t});\n\n\t\t\t\tconst responseContext: ResponseContext | null =\n\t\t\t\t\t(errorContext.response as typeof errorDetails.response) ?\n\t\t\t\t\t\t{ ...errorContext, data: null }\n\t\t\t\t\t:\tnull;\n\n\t\t\t\tif (isValidationErrorInstance(error)) {\n\t\t\t\t\tconst hookError = await executeHooksInCatchBlock(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tresponseContext && options.onResponse?.(responseContext),\n\t\t\t\t\t\t\toptions.onValidationError?.(errorContext),\n\t\t\t\t\t\t\toptions.onError?.(errorContext),\n\t\t\t\t\t\t],\n\t\t\t\t\t\thookInfo\n\t\t\t\t\t);\n\n\t\t\t\t\treturn (hookError ?? (await handleRetryOrGetErrorResult())) as never;\n\t\t\t\t}\n\n\t\t\t\tif (isHTTPErrorInstance<TErrorData>(error)) {\n\t\t\t\t\tconst hookError = await executeHooksInCatchBlock(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tresponseContext && options.onResponse?.(responseContext),\n\t\t\t\t\t\t\toptions.onResponseError?.(errorContext),\n\t\t\t\t\t\t\toptions.onError?.(errorContext),\n\t\t\t\t\t\t],\n\t\t\t\t\t\thookInfo\n\t\t\t\t\t);\n\n\t\t\t\t\treturn (hookError ?? (await handleRetryOrGetErrorResult())) as never;\n\t\t\t\t}\n\n\t\t\t\tlet message = (error as Error | undefined)?.message;\n\n\t\t\t\tif (error instanceof DOMException && error.name === \"AbortError\") {\n\t\t\t\t\tmessage = getAbortErrorMessage();\n\n\t\t\t\t\t!shouldThrowOnError && console.error(`${error.name}:`, message);\n\t\t\t\t}\n\n\t\t\t\tif (error instanceof DOMException && error.name === \"TimeoutError\") {\n\t\t\t\t\tmessage = `Request timed out after ${options.timeout}ms`;\n\n\t\t\t\t\t!shouldThrowOnError && console.error(`${error.name}:`, message);\n\t\t\t\t}\n\n\t\t\t\tconst hookError = await executeHooksInCatchBlock(\n\t\t\t\t\t[\n\t\t\t\t\t\tresponseContext && options.onResponse?.(responseContext),\n\t\t\t\t\t\toptions.onRequestError?.(errorContext),\n\t\t\t\t\t\toptions.onError?.(errorContext),\n\t\t\t\t\t],\n\t\t\t\t\thookInfo\n\t\t\t\t);\n\n\t\t\t\treturn (hookError\n\t\t\t\t\t?? getCustomizedErrorResult(await handleRetryOrGetErrorResult(), { message })) as never;\n\n\t\t\t\t// == Removing the now unneeded AbortController from store\n\t\t\t} finally {\n\t\t\t\tremoveDedupeKeyFromCache();\n\t\t\t}\n\t\t};\n\n\t\treturn callApi;\n\t};\n\n\treturn createFetchClient;\n};\n\nexport const createFetchClient = createFetchClientWithContext();\n\nexport const callApi = createFetchClient();\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["dedupeKey","$GlobalRequestInfoCache","$RequestInfoCache","callApi"],"sources":["../src/result.ts","../src/hooks.ts","../src/stream.ts","../src/dedupe.ts","../src/middlewares.ts","../src/plugins.ts","../src/retry.ts","../src/createFetchClient.ts"],"sourcesContent":["import { extraOptionDefaults } from \"./constants/defaults\";\nimport type { CallApiExtraOptions } from \"./types/common\";\nimport type { ThrowOnErrorBoolean } from \"./types/conditional-types\";\nimport type { DefaultDataType, DefaultThrowOnError } from \"./types/default-types\";\nimport type {\n\tAnyString,\n\tAwaitable,\n\tDistributiveOmit,\n\tNoInferUnMasked,\n\tPrettify,\n\tUnmaskType,\n} from \"./types/type-helpers\";\nimport { omitKeys } from \"./utils/common\";\nimport type { HTTPError, ValidationError } from \"./utils/external/error\";\nimport { isHTTPErrorInstance, isValidationErrorInstance } from \"./utils/external/guards\";\n\nexport type ResponseType = \"blob\" | \"json\" | \"text\";\n\nexport type ResponseParser<TData> = (text: string) => Awaitable<TData>;\n\nexport const getResponseType = <TData>(response: Response, responseParser: ResponseParser<TData>) => ({\n\tarrayBuffer: () => response.arrayBuffer(),\n\tblob: () => response.blob(),\n\tformData: () => response.formData(),\n\tjson: async (): Promise<TData> => {\n\t\tconst text = await response.text();\n\t\treturn responseParser(text);\n\t},\n\tstream: () => response.body,\n\ttext: () => response.text(),\n});\n\ntype InitResponseTypeMap<TData = unknown> = ReturnType<typeof getResponseType<TData>>;\n\ntype ResponseTypeUnion = keyof InitResponseTypeMap;\n\ntype ResponseTypePlaceholder = null;\n\nexport type ResponseTypeType = ResponseTypePlaceholder | ResponseTypeUnion;\n\nexport type ResponseTypeMap<TData> = {\n\t[Key in keyof InitResponseTypeMap<TData>]: Awaited<ReturnType<InitResponseTypeMap<TData>[Key]>>;\n};\n\nexport type GetResponseType<\n\tTData,\n\tTResponseType extends ResponseTypeType,\n\tTComputedResponseTypeMap extends ResponseTypeMap<TData> = ResponseTypeMap<TData>,\n> =\n\tnull extends TResponseType ? TComputedResponseTypeMap[\"json\"]\n\t: TResponseType extends NonNullable<ResponseTypeType> ? TComputedResponseTypeMap[TResponseType]\n\t: never;\n\nconst textTypes = new Set([\"image/svg\", \"application/xml\", \"application/xhtml\", \"application/html\"]);\nconst JSON_REGEX = /^application\\/(?:[\\w!#$%&*.^`~-]*\\+)?json(;.+)?$/i;\n\nconst detectResponseType = (response: Response): Extract<ResponseTypeType, \"blob\" | \"json\" | \"text\"> => {\n\tconst initContentType = response.headers.get(\"content-type\");\n\n\tif (!initContentType) {\n\t\treturn extraOptionDefaults.responseType;\n\t}\n\n\tconst contentType = initContentType.split(\";\")[0] ?? \"\";\n\n\tif (JSON_REGEX.test(contentType)) {\n\t\treturn \"json\";\n\t}\n\n\tif (textTypes.has(contentType) || contentType.startsWith(\"text/\")) {\n\t\treturn \"text\";\n\t}\n\n\treturn \"blob\";\n};\n\nexport const resolveResponseData = async (options: {\n\tresponse: Response;\n\tresponseParser: CallApiExtraOptions[\"responseParser\"];\n\tresponseType: CallApiExtraOptions[\"responseType\"];\n\tresultMode: CallApiExtraOptions[\"resultMode\"];\n}) => {\n\tconst { response, responseParser, responseType, resultMode } = options;\n\n\t// == If the result mode is set to `fetchApi`, then don't try to resolve the responseData and just return null\n\tif (resultMode === \"fetchApi\") {\n\t\treturn null;\n\t}\n\n\tconst selectedParser = responseParser ?? extraOptionDefaults.responseParser;\n\tconst selectedResponseType = responseType ?? detectResponseType(response);\n\n\tconst RESPONSE_TYPE_LOOKUP = getResponseType(response, selectedParser);\n\n\tif (!Object.hasOwn(RESPONSE_TYPE_LOOKUP, selectedResponseType)) {\n\t\tthrow new Error(`Invalid response type: ${selectedResponseType}`);\n\t}\n\n\treturn RESPONSE_TYPE_LOOKUP[selectedResponseType]();\n};\n\nexport type CallApiResultSuccessVariant<TData> = {\n\tdata: NoInferUnMasked<TData>;\n\terror: null;\n\tresponse: Response;\n};\nexport type PossibleJavaScriptError = UnmaskType<{\n\terrorData: false;\n\tmessage: string;\n\tname: \"AbortError\" | \"Error\" | \"SyntaxError\" | \"TimeoutError\" | \"TypeError\" | AnyString;\n\toriginalError: DOMException | Error | SyntaxError | TypeError;\n}>;\n\nexport type PossibleHTTPError<TErrorData> = UnmaskType<{\n\terrorData: NoInferUnMasked<TErrorData>;\n\tmessage: string;\n\tname: \"HTTPError\";\n\toriginalError: HTTPError;\n}>;\n\nexport type PossibleValidationError = UnmaskType<{\n\terrorData: ValidationError[\"errorData\"];\n\tissueCause: ValidationError[\"issueCause\"];\n\tmessage: string;\n\tname: \"ValidationError\";\n\toriginalError: ValidationError;\n}>;\n\nexport type CallApiResultErrorVariant<TErrorData> =\n\t| {\n\t\t\tdata: null;\n\t\t\terror: PossibleHTTPError<TErrorData>;\n\t\t\tresponse: Response;\n\t }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: PossibleJavaScriptError;\n\t\t\tresponse: Response | null;\n\t }\n\t| {\n\t\t\tdata: null;\n\t\t\terror: PossibleValidationError;\n\t\t\tresponse: Response | null;\n\t };\n\nexport type CallApiResultSuccessOrErrorVariant<TData, TError> =\n\t| CallApiResultErrorVariant<TError>\n\t| CallApiResultSuccessVariant<TData>;\n\ntype GetCallApiResult<\n\tTThrowOnError extends ThrowOnErrorBoolean,\n\tTResultWithException extends CallApiResultSuccessVariant<unknown>,\n\tTResultWithoutException extends CallApiResultSuccessOrErrorVariant<unknown, unknown>,\n> = TThrowOnError extends true ? TResultWithException : TResultWithoutException;\n\nexport type ResultModeMap<\n\tTData = DefaultDataType,\n\tTErrorData = DefaultDataType,\n\tTThrowOnError extends ThrowOnErrorBoolean = DefaultThrowOnError,\n\tTComputedResult extends GetCallApiResult<\n\t\tTThrowOnError,\n\t\tCallApiResultSuccessVariant<TData>,\n\t\tCallApiResultSuccessOrErrorVariant<TData, TErrorData>\n\t> = GetCallApiResult<\n\t\tTThrowOnError,\n\t\tCallApiResultSuccessVariant<TData>,\n\t\tCallApiResultSuccessOrErrorVariant<TData, TErrorData>\n\t>,\n> = UnmaskType<{\n\tall: TComputedResult;\n\tfetchApi: TComputedResult[\"response\"];\n\tonlyData: TComputedResult[\"data\"];\n\tonlyResponse: TComputedResult[\"response\"];\n\twithoutResponse: Prettify<DistributiveOmit<TComputedResult, \"response\">>;\n}>;\n\ntype ResultModePlaceholder = null;\n\ntype ResultModeUnion = keyof ResultModeMap;\n\n// FIXME - Revisit this idea later. Take inspirations from how zod does it with pick({}) and omit({d})\n// type ResultModeObject = { data?: boolean; error?: boolean; response?: boolean };\n\nexport type ResultModeType = ResultModePlaceholder | ResultModeUnion;\n\nexport type InferCallApiResult<\n\tTData,\n\tTErrorData,\n\tTResultMode extends ResultModeType,\n\tTThrowOnError extends ThrowOnErrorBoolean,\n\tTComputedResultModeMapWithException extends ResultModeMap<TData, TErrorData, true> = ResultModeMap<\n\t\tTData,\n\t\tTErrorData,\n\t\ttrue\n\t>,\n\tTComputedResultModeMapWithoutException extends ResultModeMap<TData, TErrorData, TThrowOnError> =\n\t\tResultModeMap<TData, TErrorData, TThrowOnError>,\n> =\n\tTErrorData extends false ? TComputedResultModeMapWithException[\"onlyData\"]\n\t: TErrorData extends false | undefined ? TComputedResultModeMapWithException[\"onlyData\"]\n\t: ResultModePlaceholder extends TResultMode ? TComputedResultModeMapWithoutException[\"all\"]\n\t: TResultMode extends ResultModeUnion ? TComputedResultModeMapWithoutException[TResultMode]\n\t: never;\n\ntype SuccessInfo = Pick<CallApiExtraOptions, \"resultMode\"> & {\n\tresponse: Response;\n};\n\ntype LazyResultModeMap = {\n\t[key in keyof ResultModeMap]: () => ResultModeMap[key];\n};\n\nconst getResultModeMap = (details: ResultModeMap[\"all\"]): LazyResultModeMap => {\n\treturn {\n\t\tall: () => details,\n\t\tfetchApi: () => details.response,\n\t\tonlyData: () => details.data,\n\t\tonlyResponse: () => details.response,\n\t\twithoutResponse: () => omitKeys(details, [\"response\"]),\n\t};\n};\n\ntype SuccessResult = CallApiResultSuccessVariant<unknown> | null;\n\n// The return statement is casted due to a design limitation in ts.\n// LINK - See https://www.zhenghao.io/posts/type-functions for more info\nexport const resolveSuccessResult = (data: unknown, info: SuccessInfo): SuccessResult => {\n\tconst { response, resultMode } = info;\n\n\tconst details = {\n\t\tdata,\n\t\terror: null,\n\t\tresponse,\n\t} satisfies CallApiResultSuccessVariant<unknown>;\n\n\tconst resultModeMap = getResultModeMap(details);\n\n\tconst successResult = resultModeMap[resultMode ?? \"all\"]();\n\n\treturn successResult as SuccessResult;\n};\n\nexport type ErrorInfo = Omit<SuccessInfo, \"response\">\n\t& Pick<CallApiExtraOptions, \"cloneResponse\"> & {\n\t\tmessage?: string;\n\t};\n\nexport type ErrorResult = {\n\terrorDetails: CallApiResultErrorVariant<unknown>;\n\terrorResult: CallApiResultErrorVariant<unknown> | null;\n};\n\nexport const resolveErrorResult = (error: unknown, info: ErrorInfo): ErrorResult => {\n\tconst { cloneResponse, message: customErrorMessage, resultMode } = info;\n\n\tlet errorDetails = {\n\t\tdata: null,\n\t\terror: {\n\t\t\terrorData: false,\n\t\t\tmessage: customErrorMessage ?? (error as Error).message,\n\t\t\tname: (error as Error).name,\n\t\t\toriginalError: error as Error,\n\t\t},\n\t\tresponse: null,\n\t} satisfies CallApiResultErrorVariant<unknown> as CallApiResultErrorVariant<unknown>;\n\n\tif (isValidationErrorInstance(error)) {\n\t\tconst { errorData, message, response } = error;\n\n\t\terrorDetails = {\n\t\t\tdata: null,\n\t\t\terror: {\n\t\t\t\terrorData,\n\t\t\t\tissueCause: error.issueCause,\n\t\t\t\tmessage,\n\t\t\t\tname: \"ValidationError\",\n\t\t\t\toriginalError: error,\n\t\t\t},\n\t\t\tresponse,\n\t\t};\n\t}\n\n\tif (isHTTPErrorInstance<never>(error)) {\n\t\tconst { errorData, message, name, response } = error;\n\n\t\terrorDetails = {\n\t\t\tdata: null,\n\t\t\terror: { errorData, message, name, originalError: error },\n\t\t\tresponse: cloneResponse ? response.clone() : response,\n\t\t};\n\t}\n\n\tconst resultModeMap = getResultModeMap(errorDetails);\n\n\tconst errorResult = resultModeMap[resultMode ?? \"all\"]() as never;\n\n\treturn { errorDetails, errorResult };\n};\n\nexport const getCustomizedErrorResult = (\n\terrorResult: ErrorResult[\"errorResult\"],\n\tcustomErrorInfo: { message: string | undefined }\n): ErrorResult[\"errorResult\"] => {\n\tif (!errorResult) {\n\t\treturn null;\n\t}\n\n\tconst { message = errorResult.error.message } = customErrorInfo;\n\n\treturn {\n\t\t...errorResult,\n\t\terror: {\n\t\t\t...errorResult.error,\n\t\t\tmessage,\n\t\t} satisfies NonNullable<ErrorResult[\"errorResult\"]>[\"error\"] as never,\n\t};\n};\n","import {\n\tresolveErrorResult,\n\ttype CallApiResultErrorVariant,\n\ttype CallApiResultSuccessVariant,\n\ttype ErrorInfo,\n\ttype PossibleHTTPError,\n\ttype PossibleJavaScriptError,\n\ttype PossibleValidationError,\n} from \"./result\";\nimport type { StreamProgressEvent } from \"./stream\";\nimport type {\n\tBaseCallApiConfig,\n\tCallApiConfig,\n\tCallApiContext,\n\tCallApiExtraOptionsForHooks,\n\tCallApiRequestOptionsForHooks,\n} from \"./types/common\";\nimport type { DefaultCallApiContext } from \"./types/default-types\";\nimport type { AnyFunction, Awaitable, DistributiveOmit, Prettify } from \"./types/type-helpers\";\n\nexport interface Hooks<TCallApiContext extends CallApiContext = DefaultCallApiContext> {\n\t/**\n\t * Hook called when any error occurs within the request/response lifecycle.\n\t *\n\t * This is a unified error handler that catches both request errors (network failures,\n\t * timeouts, etc.) and response errors (HTTP error status codes). It's essentially\n\t * a combination of `onRequestError` and `onResponseError` hooks.\n\t *\n\t * @param context - Error context containing error details, request info, and response (if available)\n\t * @returns Promise or void - Hook can be async or sync\n\t */\n\tonError?: (context: ErrorContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called before the HTTP request is sent and before any internal processing of the request object begins.\n\t *\n\t * This is the ideal place to modify request headers, add authentication,\n\t * implement request logging, or perform any setup before the network call.\n\t *\n\t * @param context - Request context with mutable request object and configuration\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonRequest?: (context: RequestContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when an error occurs during the fetch request itself.\n\t *\n\t * This handles network-level errors like connection failures, timeouts,\n\t * DNS resolution errors, or other issues that prevent getting an HTTP response.\n\t * Note that HTTP error status codes (4xx, 5xx) are handled by `onResponseError`.\n\t *\n\t * @param context - Request error context with error details and null response\n\t * @returns Promise or void - Hook can be async or sync\n\t */\n\tonRequestError?: (context: RequestErrorContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called just before the HTTP request is sent and after the request has been processed.\n\t *\n\t * @param context - Request context with mutable request object and configuration\n\t */\n\tonRequestReady?: (context: RequestContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called during upload stream progress tracking.\n\t *\n\t * This hook is triggered when uploading data (like file uploads) and provides\n\t * progress information about the upload. Useful for implementing progress bars\n\t * or upload status indicators.\n\t *\n\t * @param context - Request stream context with progress event and request instance\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonRequestStream?: (context: RequestStreamContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when any HTTP response is received from the API.\n\t *\n\t * This hook is triggered for both successful (2xx) and error (4xx, 5xx) responses.\n\t * It's useful for response logging, metrics collection, or any processing that\n\t * should happen regardless of response status.\n\t *\n\t * @param context - Response context with either success data or error information\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonResponse?: (context: ResponseContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when an HTTP error response (4xx, 5xx) is received from the API.\n\t *\n\t * This handles server-side errors where an HTTP response was successfully received\n\t * but indicates an error condition. Different from `onRequestError` which handles\n\t * network-level failures.\n\t *\n\t * @param context - Response error context with HTTP error details and response\n\t * @returns Promise or void - Hook can be async or sync\n\t */\n\tonResponseError?: (context: ResponseErrorContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called during download stream progress tracking.\n\t *\n\t * This hook is triggered when downloading data (like file downloads) and provides\n\t * progress information about the download. Useful for implementing progress bars\n\t * or download status indicators.\n\t *\n\t * @param context - Response stream context with progress event and response\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonResponseStream?: (context: ResponseStreamContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when a request is being retried.\n\t *\n\t * This hook is triggered before each retry attempt, providing information about\n\t * the previous failure and the current retry attempt number. Useful for implementing\n\t * custom retry logic, exponential backoff, or retry logging.\n\t *\n\t * @param context - Retry context with error details and retry attempt count\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonRetry?: (response: RetryContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when a successful response (2xx status) is received from the API.\n\t *\n\t * This hook is triggered only for successful responses and provides access to\n\t * the parsed response data. Ideal for success logging, caching, or post-processing\n\t * of successful API responses.\n\t *\n\t * @param context - Success context with parsed response data and response object\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonSuccess?: (context: SuccessContext<TCallApiContext>) => Awaitable<unknown>;\n\n\t/**\n\t * Hook called when a validation error occurs.\n\t *\n\t * This hook is triggered when request or response data fails validation against\n\t * a defined schema. It provides access to the validation error details and can\n\t * be used for custom error handling, logging, or fallback behavior.\n\t *\n\t * @param context - Validation error context with error details and response (if available)\n\t * @returns Promise or void - Hook can be async or sync\n\t *\n\t */\n\tonValidationError?: (context: ValidationErrorContext<TCallApiContext>) => Awaitable<unknown>;\n}\n\nexport type HooksOrHooksArray<TCallApiContext extends NoInfer<CallApiContext> = DefaultCallApiContext> = {\n\t[Key in keyof Hooks<TCallApiContext>]:\n\t\t| Hooks<TCallApiContext>[Key]\n\t\t// eslint-disable-next-line perfectionist/sort-union-types -- I need arrays to be last\n\t\t| Array<Hooks<TCallApiContext>[Key]>;\n};\n\nexport interface HookConfigOptions {\n\t/**\n\t * Controls the execution mode of all composed hooks (main + plugin hooks).\n\t *\n\t * - **\"parallel\"**: All hooks execute simultaneously via Promise.all() for better performance\n\t * - **\"sequential\"**: All hooks execute one by one in registration order via await in a loop\n\t *\n\t * This affects how ALL hooks execute together, regardless of their source (main or plugin).\n\t *\n\t * @default \"parallel\"\n\t */\n\thooksExecutionMode?: \"parallel\" | \"sequential\";\n}\n\nexport type RequestContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = {\n\t/**\n\t * Base configuration object passed to createFetchClient.\n\t *\n\t * Contains the foundational configuration that applies to all requests\n\t * made by this client instance, such as baseURL, default headers, and\n\t * global options.\n\t */\n\tbaseConfig: Exclude<BaseCallApiConfig, AnyFunction>;\n\n\t/**\n\t * Instance-specific configuration object passed to the callApi instance.\n\t *\n\t * Contains configuration specific to this particular API call, which\n\t * can override or extend the base configuration.\n\t */\n\tconfig: CallApiConfig;\n\n\t/**\n\t * Merged options combining base config, instance config, and default options.\n\t *\n\t * This is the final resolved configuration that will be used for the request,\n\t * with proper precedence applied (instance > base > defaults).\n\t */\n\toptions: CallApiExtraOptionsForHooks<TCallApiContext>;\n\n\t/**\n\t * Merged request object ready to be sent.\n\t *\n\t * Contains the final request configuration including URL, method, headers,\n\t * body, and other fetch options. This object can be modified in onRequest\n\t * hooks to customize the outgoing request.\n\t */\n\trequest: CallApiRequestOptionsForHooks;\n};\n\nexport type ValidationErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = DistributiveOmit<\n\tExtract<CallApiResultErrorVariant<unknown>, { error: PossibleValidationError }>,\n\t\"data\"\n>\n\t& RequestContext<TCallApiContext>;\n\nexport type SuccessContext<\n\tTCallApiContext extends Pick<CallApiContext, \"Data\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = DistributiveOmit<CallApiResultSuccessVariant<TCallApiContext[\"Data\"]>, \"error\">\n\t& RequestContext<TCallApiContext>;\n\nexport type ResponseContext<\n\tTCallApiContext extends Pick<CallApiContext, \"Data\" | \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = RequestContext<TCallApiContext>\n\t& (\n\t\t| Prettify<CallApiResultSuccessVariant<TCallApiContext[\"Data\"]>>\n\t\t| Prettify<\n\t\t\t\tExtract<\n\t\t\t\t\tCallApiResultErrorVariant<TCallApiContext[\"ErrorData\"]>,\n\t\t\t\t\t{ error: PossibleHTTPError<TCallApiContext[\"ErrorData\"]> }\n\t\t\t\t>\n\t\t >\n\t);\n\nexport type RequestErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = DistributiveOmit<\n\tExtract<CallApiResultErrorVariant<unknown>, { error: PossibleJavaScriptError }>,\n\t\"data\"\n>\n\t& RequestContext<TCallApiContext>;\n\nexport type ErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = DistributiveOmit<CallApiResultErrorVariant<TCallApiContext[\"ErrorData\"]>, \"data\">\n\t& RequestContext<TCallApiContext>;\n\nexport type ResponseErrorContext<\n\tTCallApiContext extends Pick<CallApiContext, \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = Extract<ErrorContext<TCallApiContext>, { error: PossibleHTTPError<TCallApiContext[\"ErrorData\"]> }>\n\t& RequestContext<TCallApiContext>;\n\nexport type RetryContext<\n\tTCallApiContext extends Pick<CallApiContext, \"ErrorData\" | \"InferredExtraOptions\" | \"Meta\"> =\n\t\tDefaultCallApiContext,\n> = ErrorContext<TCallApiContext> & {\n\tretryAttemptCount: number;\n};\n\nexport type RequestStreamContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = RequestContext<TCallApiContext> & {\n\tevent: StreamProgressEvent;\n\trequestInstance: Request;\n};\n\nexport type ResponseStreamContext<\n\tTCallApiContext extends Pick<CallApiContext, \"InferredExtraOptions\" | \"Meta\"> = DefaultCallApiContext,\n> = RequestContext<TCallApiContext> & {\n\tevent: StreamProgressEvent;\n\tresponse: Response;\n};\n\ntype HookRegistries = Required<{\n\t[Key in keyof Hooks]: Set<Hooks[Key]>;\n}>;\n\nexport const getHookRegistriesAndKeys = () => {\n\tconst hookRegistries: HookRegistries = {\n\t\tonError: new Set(),\n\t\tonRequest: new Set(),\n\t\tonRequestError: new Set(),\n\t\tonRequestReady: new Set(),\n\t\tonRequestStream: new Set(),\n\t\tonResponse: new Set(),\n\t\tonResponseError: new Set(),\n\t\tonResponseStream: new Set(),\n\t\tonRetry: new Set(),\n\t\tonSuccess: new Set(),\n\t\tonValidationError: new Set(),\n\t};\n\n\tconst hookRegistryKeys = Object.keys(hookRegistries) as Array<keyof Hooks>;\n\n\treturn { hookRegistries, hookRegistryKeys };\n};\n\nexport const composeHooksFromArray = (\n\thooksArray: Array<Hooks[keyof Hooks] | undefined>,\n\thooksExecutionMode: NonNullable<CallApiExtraOptionsForHooks[\"hooksExecutionMode\"]>\n) => {\n\tconst composedHook = async (ctx: unknown) => {\n\t\tswitch (hooksExecutionMode) {\n\t\t\tcase \"parallel\": {\n\t\t\t\tawait Promise.all(hooksArray.map((hook) => hook?.(ctx as never)));\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"sequential\": {\n\t\t\t\tfor (const hook of hooksArray) {\n\t\t\t\t\t// eslint-disable-next-line no-await-in-loop -- This is necessary in this case\n\t\t\t\t\tawait hook?.(ctx as never);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\thooksExecutionMode satisfies never;\n\t\t\t}\n\t\t}\n\t};\n\n\treturn composedHook;\n};\n\nexport const executeHooks = async (...hookResultsOrPromise: Array<Awaitable<unknown>>) => {\n\tawait Promise.all(hookResultsOrPromise);\n};\n\nexport type ExecuteHookInfo = {\n\terrorInfo: ErrorInfo;\n\tshouldThrowOnError: boolean | undefined;\n};\n\nexport const executeHooksInCatchBlock = async (\n\thookResultsOrPromise: Array<Awaitable<unknown>>,\n\thookInfo: ExecuteHookInfo\n) => {\n\tconst { errorInfo, shouldThrowOnError } = hookInfo;\n\n\ttry {\n\t\tawait Promise.all(hookResultsOrPromise);\n\n\t\treturn null;\n\t} catch (hookError) {\n\t\tif (shouldThrowOnError) {\n\t\t\tthrow hookError;\n\t\t}\n\n\t\tconst { errorResult } = resolveErrorResult(hookError, errorInfo);\n\n\t\treturn errorResult;\n\t}\n};\n","import {\n\texecuteHooks,\n\ttype RequestContext,\n\ttype RequestStreamContext,\n\ttype ResponseStreamContext,\n} from \"./hooks\";\nimport { isReadableStream } from \"./utils/guards\";\n\nexport type StreamProgressEvent = {\n\t/**\n\t * Current chunk of data being streamed\n\t */\n\tchunk: Uint8Array;\n\t/**\n\t * Progress in percentage\n\t */\n\tprogress: number;\n\t/**\n\t * Total size of data in bytes\n\t */\n\ttotalBytes: number;\n\t/**\n\t * Amount of data transferred so far\n\t */\n\ttransferredBytes: number;\n};\n\nconst createProgressEvent = (options: {\n\tchunk: Uint8Array;\n\ttotalBytes: number;\n\ttransferredBytes: number;\n}): StreamProgressEvent => {\n\tconst { chunk, totalBytes, transferredBytes } = options;\n\n\treturn {\n\t\tchunk,\n\t\tprogress: Math.round((transferredBytes / totalBytes) * 100) || 0,\n\t\ttotalBytes,\n\t\ttransferredBytes,\n\t};\n};\n\nconst calculateTotalBytesFromBody = async (\n\trequestBody: Request[\"body\"] | null,\n\texistingTotalBytes: number\n) => {\n\tlet totalBytes = existingTotalBytes;\n\n\tif (!requestBody) {\n\t\treturn totalBytes;\n\t}\n\n\tfor await (const chunk of requestBody) {\n\t\ttotalBytes += chunk.byteLength;\n\t}\n\n\treturn totalBytes;\n};\n\ntype ToStreamableRequestContext = RequestContext;\n\nexport const toStreamableRequest = async (\n\tcontext: ToStreamableRequestContext\n): Promise<Request | RequestInit> => {\n\tconst { baseConfig, config, options, request } = context;\n\n\tif (!options.onRequestStream || !isReadableStream(request.body)) {\n\t\treturn request as RequestInit;\n\t}\n\n\tconst requestInstance = new Request(\n\t\toptions.fullURL as NonNullable<typeof options.fullURL>,\n\t\t{ ...request, duplex: \"half\" } as RequestInit\n\t);\n\n\tconst contentLength = requestInstance.headers.get(\"content-length\");\n\n\tlet totalBytes = Number(contentLength ?? 0);\n\n\t// == If no content length is present, we read the total bytes from the body\n\tif (!contentLength && options.forcefullyCalculateRequestStreamSize) {\n\t\ttotalBytes = await calculateTotalBytesFromBody(requestInstance.clone().body, totalBytes);\n\t}\n\n\tlet transferredBytes = 0;\n\n\tconst stream = new ReadableStream({\n\t\tstart: async (controller) => {\n\t\t\tconst body = requestInstance.body;\n\n\t\t\tif (!body) return;\n\n\t\t\tconst requestStreamContext = {\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tevent: createProgressEvent({ chunk: new Uint8Array(), totalBytes, transferredBytes }),\n\t\t\t\toptions,\n\t\t\t\trequest,\n\t\t\t\trequestInstance,\n\t\t\t} satisfies RequestStreamContext;\n\n\t\t\tawait executeHooks(options.onRequestStream?.(requestStreamContext));\n\n\t\t\tfor await (const chunk of body) {\n\t\t\t\ttransferredBytes += chunk.byteLength;\n\n\t\t\t\ttotalBytes = Math.max(totalBytes, transferredBytes);\n\n\t\t\t\tawait executeHooks(\n\t\t\t\t\toptions.onRequestStream?.({\n\t\t\t\t\t\t...requestStreamContext,\n\t\t\t\t\t\tevent: createProgressEvent({ chunk, totalBytes, transferredBytes }),\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\treturn new Request(requestInstance, { body: stream, duplex: \"half\" } as RequestInit);\n};\n\ntype StreamableResponseContext = RequestContext & { response: Response };\n\nexport const toStreamableResponse = (context: StreamableResponseContext): Response => {\n\tconst { baseConfig, config, options, request, response } = context;\n\n\tif (!options.onResponseStream || !response.body) {\n\t\treturn response;\n\t}\n\n\tconst contentLength = response.headers.get(\"content-length\");\n\n\tlet totalBytes = Number(contentLength ?? 0);\n\n\tlet transferredBytes = 0;\n\n\tconst stream = new ReadableStream({\n\t\tstart: async (controller) => {\n\t\t\tconst body = response.body;\n\n\t\t\tif (!body) return;\n\n\t\t\tconst responseStreamContext = {\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tevent: createProgressEvent({ chunk: new Uint8Array(), totalBytes, transferredBytes }),\n\t\t\t\toptions,\n\t\t\t\trequest,\n\t\t\t\tresponse,\n\t\t\t} satisfies ResponseStreamContext;\n\n\t\t\tawait executeHooks(options.onResponseStream?.(responseStreamContext));\n\n\t\t\tfor await (const chunk of body) {\n\t\t\t\ttransferredBytes += chunk.byteLength;\n\n\t\t\t\ttotalBytes = Math.max(totalBytes, transferredBytes);\n\n\t\t\t\tawait executeHooks(\n\t\t\t\t\toptions.onResponseStream?.({\n\t\t\t\t\t\t...responseStreamContext,\n\t\t\t\t\t\tevent: createProgressEvent({ chunk, totalBytes, transferredBytes }),\n\t\t\t\t\t})\n\t\t\t\t);\n\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t}\n\n\t\t\tcontroller.close();\n\t\t},\n\t});\n\n\treturn new Response(stream, response);\n};\n","import { extraOptionDefaults } from \"./constants/defaults\";\nimport type { RequestContext } from \"./hooks\";\nimport { toStreamableRequest, toStreamableResponse } from \"./stream\";\nimport type { AnyString, UnmaskType } from \"./types/type-helpers\";\nimport { waitFor } from \"./utils/common\";\nimport { isFunction } from \"./utils/guards\";\n\ntype RequestInfo = {\n\tcontroller: AbortController;\n\tresponsePromise: Promise<Response>;\n};\n\n/**\n * Cache that stores active request information for deduplication within a specific scope.\n *\n * Maps deduplication keys to their corresponding request information, including the abort controller\n * and response promise. A `null` key represents requests that don't participate in deduplication.\n *\n * **Internal Usage:**\n * This type is primarily used internally by the deduplication system. You typically won't need to\n * interact with it directly unless you're building custom deduplication logic or debugging.\n *\n * @example\n * ```ts\n * // This is handled internally, but conceptually:\n * const cache: RequestInfoCache = new Map([\n * [\"user-123\", { controller: abortController, responsePromise: fetchPromise }],\n * [\"config\", { controller: abortController2, responsePromise: fetchPromise2 }],\n * ]);\n * ```\n */\nexport type RequestInfoCache = Map<string | null, RequestInfo>;\n\n/**\n * Global cache that manages multiple request info caches, organized by scope keys.\n *\n * This enables the global deduplication feature by maintaining separate cache namespaces\n * for different scope keys. Each scope key gets its own `RequestInfoCache` instance.\n *\n * **Cache Lifecycle:**\n * - Caches are created on-demand when first accessed\n * - Automatic cleanup occurs when no references remain\n * - Each scope key maintains independent deduplication state\n *\n * **Memory Considerations:**\n * - Each scope key creates a separate cache instance\n * - Consider the number of different scope keys in your application\n * - Caches are cleaned up automatically when clients are garbage collected\n *\n * @example\n * ```ts\n * // This is managed internally, but conceptually:\n * const globalCache: GlobalRequestInfoCache = new Map([\n * [\"user-service\", new Map([...])], // Cache for user service requests\n * [\"analytics\", new Map([...])], // Cache for analytics requests\n * [\"default\", new Map([...])] // Default cache scope\n * ]);\n * ```\n */\nexport type GlobalRequestInfoCache = Map<DedupeOptions[\"dedupeCacheScopeKey\"], RequestInfoCache>;\n\ntype DedupeContext = RequestContext & {\n\t$GlobalRequestInfoCache: GlobalRequestInfoCache;\n\t$LocalRequestInfoCache: RequestInfoCache;\n\tnewFetchController: AbortController;\n};\n\nexport const createDedupeStrategy = async (context: DedupeContext) => {\n\tconst {\n\t\t$GlobalRequestInfoCache,\n\t\t$LocalRequestInfoCache,\n\t\tbaseConfig,\n\t\tconfig,\n\t\tnewFetchController,\n\t\toptions: globalOptions,\n\t} = context;\n\n\tconst dedupeStrategy = globalOptions.dedupeStrategy ?? extraOptionDefaults.dedupeStrategy;\n\n\tconst resolvedDedupeStrategy = isFunction(dedupeStrategy) ? dedupeStrategy(context) : dedupeStrategy;\n\n\tconst getDedupeKey = () => {\n\t\tconst shouldHaveDedupeKey =\n\t\t\tresolvedDedupeStrategy === \"cancel\" || resolvedDedupeStrategy === \"defer\";\n\n\t\tif (!shouldHaveDedupeKey) {\n\t\t\treturn null;\n\t\t}\n\n\t\tconst dedupeKey = globalOptions.dedupeKey ?? extraOptionDefaults.dedupeKey;\n\n\t\tconst resolvedDedupeKey = isFunction(dedupeKey) ? dedupeKey(context) : dedupeKey;\n\n\t\treturn resolvedDedupeKey;\n\t};\n\n\tconst getDedupeCacheScopeKey = () => {\n\t\tconst dedupeCacheScopeKey =\n\t\t\tglobalOptions.dedupeCacheScopeKey ?? extraOptionDefaults.dedupeCacheScopeKey;\n\n\t\tconst resolvedDedupeCacheScopeKey =\n\t\t\tisFunction(dedupeCacheScopeKey) ? dedupeCacheScopeKey(context) : dedupeCacheScopeKey;\n\n\t\treturn resolvedDedupeCacheScopeKey;\n\t};\n\n\tconst dedupeKey = getDedupeKey();\n\n\tconst getRequestInfoCache = () => {\n\t\tif (!dedupeKey) return;\n\n\t\tconst dedupeCacheScope = globalOptions.dedupeCacheScope ?? extraOptionDefaults.dedupeCacheScope;\n\n\t\tconst dedupeCacheScopeKey = getDedupeCacheScopeKey();\n\n\t\tif (dedupeCacheScope === \"global\" && !$GlobalRequestInfoCache.has(dedupeCacheScopeKey)) {\n\t\t\t$GlobalRequestInfoCache.set(dedupeCacheScopeKey, new Map());\n\t\t}\n\n\t\tconst $RequestInfoCache =\n\t\t\tdedupeCacheScope === \"global\" ?\n\t\t\t\t$GlobalRequestInfoCache.get(dedupeCacheScopeKey)\n\t\t\t:\t$LocalRequestInfoCache;\n\n\t\treturn {\n\t\t\tdelete: () => $RequestInfoCache?.delete(dedupeKey),\n\t\t\tget: () => $RequestInfoCache?.get(dedupeKey),\n\t\t\tset: (value: RequestInfo) => $RequestInfoCache?.set(dedupeKey, value),\n\t\t};\n\t};\n\n\tconst $RequestInfoCache = getRequestInfoCache();\n\n\t/**\n\t * Force sequential execution of parallel requests to enable proper cache-based deduplication.\n\t *\n\t * Problem: When Promise.all([callApi(url), callApi(url)]) executes, both requests\n\t * start synchronously and reach this point before either can populate the cache.\n\t *\n\t * Why `await Promise.resolve()` fails:\n\t * - All microtasks in a batch resolve together at the next microtask checkpoint\n\t * - Both requests resume execution simultaneously after the await\n\t * - Both check `prevRequestInfo` at the same time → both see empty cache\n\t * - Both proceed to populate cache → deduplication fails\n\t *\n\t * Why `wait new Promise(()=> setTimeout(resolve, number))` works:\n\t * - Each setTimeout creates a separate task in the task queue\n\t * - Tasks execute sequentially, not simultaneously\n\t * - Request 1's task runs first: checks cache (empty) → continues → populates cache\n\t * - Request 2's task runs after: checks cache (populated) → uses cached promise\n\t * - Deduplication succeeds\n\t *\n\t * IMPORTANT: The delay must be non-zero. setTimeout(fn, 0) fails because JavaScript engines\n\t * may optimize zero-delay timers by batching them together, causing all requests to resume\n\t * simultaneously (same problem as microtasks). Any non-zero value (even 0.0000000001) forces\n\t * proper sequential task queue scheduling, ensuring each request gets its own task slot.\n\t */\n\tif (dedupeKey !== null) {\n\t\tawait waitFor(0.001);\n\t}\n\n\tconst prevRequestInfo = $RequestInfoCache?.get();\n\n\tconst getAbortErrorMessage = () => {\n\t\tif (globalOptions.dedupeKey) {\n\t\t\treturn `Duplicate request detected - Aborted previous request with key '${dedupeKey}'`;\n\t\t}\n\n\t\treturn `Duplicate request detected - Aborted previous request to '${globalOptions.fullURL}'`;\n\t};\n\n\tconst handleRequestCancelStrategy = () => {\n\t\tconst shouldCancelRequest = prevRequestInfo && resolvedDedupeStrategy === \"cancel\";\n\n\t\tif (!shouldCancelRequest) return;\n\n\t\tconst message = getAbortErrorMessage();\n\n\t\tconst reason = new DOMException(message, \"AbortError\");\n\n\t\tprevRequestInfo.controller.abort(reason);\n\t};\n\n\tconst handleRequestDeferStrategy = async (deferContext: {\n\t\tfetchApi: NonNullable<DedupeContext[\"options\"][\"customFetchImpl\"]>;\n\t\toptions: DedupeContext[\"options\"];\n\t\trequest: DedupeContext[\"request\"];\n\t}) => {\n\t\t// == Local options and request are needed so that transformations are applied can be applied to both from call site\n\t\tconst { fetchApi, options: localOptions, request: localRequest } = deferContext;\n\n\t\tconst shouldUsePromiseFromCache = prevRequestInfo && resolvedDedupeStrategy === \"defer\";\n\n\t\tconst streamableContext = {\n\t\t\tbaseConfig,\n\t\t\tconfig,\n\t\t\toptions: localOptions,\n\t\t\trequest: localRequest,\n\t\t} satisfies RequestContext;\n\n\t\tconst streamableRequest = await toStreamableRequest(streamableContext);\n\n\t\tconst responsePromise =\n\t\t\tshouldUsePromiseFromCache ?\n\t\t\t\tprevRequestInfo.responsePromise\n\t\t\t:\tfetchApi(localOptions.fullURL as NonNullable<typeof localOptions.fullURL>, streamableRequest);\n\n\t\t$RequestInfoCache?.set({ controller: newFetchController, responsePromise });\n\n\t\treturn toStreamableResponse({ ...streamableContext, response: await responsePromise });\n\t};\n\n\tconst removeDedupeKeyFromCache = () => {\n\t\t$RequestInfoCache?.delete();\n\t};\n\n\treturn {\n\t\tgetAbortErrorMessage,\n\t\thandleRequestCancelStrategy,\n\t\thandleRequestDeferStrategy,\n\t\tremoveDedupeKeyFromCache,\n\t\tresolvedDedupeStrategy,\n\t};\n};\n\ntype DedupeStrategyUnion = UnmaskType<\"cancel\" | \"defer\" | \"none\">;\n\nexport type DedupeOptions = {\n\t/**\n\t * Controls the scope of request deduplication caching.\n\t *\n\t * - `\"global\"`: Shares deduplication cache across all `createFetchClient` instances with the same `dedupeCacheScopeKey`.\n\t * Useful for applications with multiple API clients that should share deduplication state.\n\t * - `\"local\"`: Limits deduplication to requests within the same `createFetchClient` instance.\n\t * Provides better isolation and is recommended for most use cases.\n\t *\n\t *\n\t * **Real-world Scenarios:**\n\t * - Use `\"global\"` when you have multiple API clients (user service, auth service, etc.) that might make overlapping requests\n\t * - Use `\"local\"` (default) for single-purpose clients or when you want strict isolation between different parts of your app\n\t *\n\t * @example\n\t * ```ts\n\t * // Local scope - each client has its own deduplication cache\n\t * const userClient = createFetchClient({ baseURL: \"/api/users\" });\n\t * const postClient = createFetchClient({ baseURL: \"/api/posts\" });\n\t * // These clients won't share deduplication state\n\t *\n\t * // Global scope - share cache across related clients\n\t * const userClient = createFetchClient({\n\t * baseURL: \"/api/users\",\n\t * dedupeCacheScope: \"global\",\n\t * });\n\t * const postClient = createFetchClient({\n\t * baseURL: \"/api/posts\",\n\t * dedupeCacheScope: \"global\",\n\t * });\n\t * // These clients will share deduplication state\n\t * ```\n\t *\n\t * @default \"local\"\n\t */\n\tdedupeCacheScope?: \"global\" | \"local\";\n\n\t/**\n\t * Unique namespace for the global deduplication cache when using `dedupeCacheScope: \"global\"`.\n\t *\n\t * This creates logical groupings of deduplication caches. All instances with the same key\n\t * will share the same cache namespace, allowing fine-grained control over which clients\n\t * share deduplication state.\n\t *\n\t * **Best Practices:**\n\t * - Use descriptive names that reflect the logical grouping (e.g., \"user-service\", \"analytics-api\")\n\t * - Keep scope keys consistent across related API clients\n\t * - Consider using different scope keys for different environments (dev, staging, prod)\n\t * - Avoid overly broad scope keys that might cause unintended cache sharing\n\t *\n\t * **Cache Management:**\n\t * - Each scope key maintains its own independent cache\n\t * - Caches are automatically cleaned up when no references remain\n\t * - Consider the memory implications of multiple global scopes\n\t *\n\t * @example\n\t * ```ts\n\t * // Group related API clients together\n\t * const userClient = createFetchClient({\n\t * baseURL: \"/api/users\",\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: \"user-service\"\n\t * });\n\t * const profileClient = createFetchClient({\n\t * baseURL: \"/api/profiles\",\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: \"user-service\" // Same scope - will share cache\n\t * });\n\t *\n\t * // Separate analytics client with its own cache\n\t * const analyticsClient = createFetchClient({\n\t * baseURL: \"/api/analytics\",\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: \"analytics-service\" // Different scope\n\t * });\n\t *\n\t * // Environment-specific scoping\n\t * const apiClient = createFetchClient({\n\t * dedupeCacheScope: \"global\",\n\t * dedupeCacheScopeKey: `api-${process.env.NODE_ENV}` // \"api-development\", \"api-production\", etc.\n\t * });\n\t * ```\n\t *\n\t * @default \"default\"\n\t */\n\tdedupeCacheScopeKey?: \"default\" | AnyString | ((context: RequestContext) => string | undefined);\n\n\t/**\n\t * Custom key generator for request deduplication.\n\t *\n\t * Override the default key generation strategy to control exactly which requests\n\t * are considered duplicates. The default key combines URL, method, body, and\n\t * relevant headers (excluding volatile ones like 'Date', 'Authorization', etc.).\n\t *\n\t * **Default Key Generation:**\n\t * The auto-generated key includes:\n\t * - Full request URL (including query parameters)\n\t * - HTTP method (GET, POST, etc.)\n\t * - Request body (for POST/PUT/PATCH requests)\n\t * - Stable headers (excludes Date, Authorization, User-Agent, etc.)\n\t *\n\t * **Custom Key Best Practices:**\n\t * - Include only the parts of the request that should affect deduplication\n\t * - Avoid including volatile data (timestamps, random IDs, etc.)\n\t * - Consider performance - simpler keys are faster to compute and compare\n\t * - Ensure keys are deterministic for the same logical request\n\t * - Use consistent key formats across your application\n\t *\n\t * **Performance Considerations:**\n\t * - Function-based keys are computed on every request - keep them lightweight\n\t * - String keys are fastest but least flexible\n\t * - Consider caching expensive key computations if needed\n\t *\n\t * @example\n\t * ```ts\n\t * import { callApi } from \"@zayne-labs/callapi\";\n\t *\n\t * // Simple static key - useful for singleton requests\n\t * const config = callApi(\"/api/config\", {\n\t * dedupeKey: \"app-config\",\n\t * dedupeStrategy: \"defer\" // Share the same config across all requests\n\t * });\n\t *\n\t * // URL and method only - ignore headers and body\n\t * const userData = callApi(\"/api/user/123\", {\n\t * dedupeKey: (context) => `${context.options.method}:${context.options.fullURL}`\n\t * });\n\t *\n\t * // Include specific headers in deduplication\n\t * const apiCall = callApi(\"/api/data\", {\n\t * dedupeKey: (context) => {\n\t * const authHeader = context.request.headers.get(\"Authorization\");\n\t * return `${context.options.fullURL}-${authHeader}`;\n\t * }\n\t * });\n\t *\n\t * // User-specific deduplication\n\t * const userSpecificCall = callApi(\"/api/dashboard\", {\n\t * dedupeKey: (context) => {\n\t * const userId = context.options.fullURL.match(/user\\/(\\d+)/)?.[1];\n\t * return `dashboard-${userId}`;\n\t * }\n\t * });\n\t *\n\t * // Ignore certain query parameters\n\t * const searchCall = callApi(\"/api/search?q=test&timestamp=123456\", {\n\t * dedupeKey: (context) => {\n\t * const url = new URL(context.options.fullURL);\n\t * url.searchParams.delete(\"timestamp\"); // Remove volatile param\n\t * return `search:${url.toString()}`;\n\t * }\n\t * });\n\t * ```\n\t *\n\t * @default Auto-generated from request details\n\t */\n\tdedupeKey?: string | ((context: RequestContext) => string | undefined);\n\n\t/**\n\t * Strategy for handling duplicate requests. Can be a static string or callback function.\n\t *\n\t * **Available Strategies:**\n\t * - `\"cancel\"`: Cancel previous request when new one starts (good for search)\n\t * - `\"defer\"`: Share response between duplicate requests (good for config loading)\n\t * - `\"none\"`: No deduplication, all requests execute independently\n\t *\n\t * @example\n\t * ```ts\n\t * // Static strategies\n\t * const searchClient = createFetchClient({\n\t * dedupeStrategy: \"cancel\" // Cancel previous searches\n\t * });\n\t *\n\t * const configClient = createFetchClient({\n\t * dedupeStrategy: \"defer\" // Share config across components\n\t * });\n\t *\n\t * // Dynamic strategy based on request\n\t * const smartClient = createFetchClient({\n\t * dedupeStrategy: (context) => {\n\t * return context.options.method === \"GET\" ? \"defer\" : \"cancel\";\n\t * }\n\t * });\n\t *\n\t * // Search-as-you-type with cancel strategy\n\t * const handleSearch = async (query: string) => {\n\t * try {\n\t * const { data } = await callApi(\"/api/search\", {\n\t * method: \"POST\",\n\t * body: { query },\n\t * dedupeStrategy: \"cancel\",\n\t * dedupeKey: \"search\" // Cancel previous searches, only latest one goes through\n\t * });\n\t *\n\t * updateSearchResults(data);\n\t * } catch (error) {\n\t * if (error.name === \"AbortError\") {\n\t * // Previous search cancelled - (expected behavior)\n\t * return;\n\t * }\n\t * console.error(\"Search failed:\", error);\n\t * }\n\t * };\n\t *\n\t * ```\n\t *\n\t * @default \"cancel\"\n\t */\n\tdedupeStrategy?: DedupeStrategyUnion | ((context: RequestContext) => DedupeStrategyUnion);\n};\n","import type { RequestContext } from \"./hooks\";\nimport type { CallApiContext } from \"./types/common\";\nimport type { DefaultCallApiContext } from \"./types/default-types\";\nimport type { UnmaskType } from \"./types/type-helpers\";\n\nexport type FetchImpl = UnmaskType<\n\t(input: string | Request | URL, init?: RequestInit) => Promise<Response>\n>;\n\nexport type FetchMiddlewareContext<TCallApiContext extends CallApiContext> =\n\tRequestContext<TCallApiContext> & {\n\t\tfetchImpl: FetchImpl;\n\t};\n\nexport interface Middlewares<TCallApiContext extends NoInfer<CallApiContext> = DefaultCallApiContext> {\n\t/**\n\t * Wraps the fetch implementation to intercept requests at the network layer.\n\t *\n\t * Takes a context object containing the current fetch function and returns a new fetch function.\n\t * Use it to cache responses, add logging, handle offline mode, or short-circuit requests etc.\n\t * Multiple middleware compose in order: plugins → base config → per-request.\n\t *\n\t * Unlike `customFetchImpl`, middleware can call through to the original fetch.\n\t *\n\t * @example\n\t * ```ts\n\t * // Cache responses\n\t * const cache = new Map();\n\t *\n\t * fetchMiddleware: (ctx) => async (input, init) => {\n\t * const key = input.toString();\n\t *\n\t * const cachedResponse = cache.get(key);\n\t *\n\t * if (cachedResponse) {\n\t *\t return cachedResponse.clone();\n\t * }\n\t *\n\t * const response = await ctx.fetchImpl(input, init);\n\t * cache.set(key, response.clone());\n\t *\n\t * return response;\n\t * }\n\t *\n\t * // Handle offline\n\t * fetchMiddleware: (ctx) => async (...parameters) => {\n\t * if (!navigator.onLine) {\n\t * return new Response('{\"error\": \"offline\"}', { status: 503 });\n\t * }\n\t *\n\t * return ctx.fetchImpl(...parameters);\n\t * }\n\t * ```\n\t */\n\tfetchMiddleware?: (context: FetchMiddlewareContext<TCallApiContext>) => FetchImpl;\n}\n\ntype MiddlewareRegistries = Required<{\n\t[Key in keyof Middlewares]: Set<Middlewares[Key]>;\n}>;\n\nexport const getMiddlewareRegistriesAndKeys = () => {\n\tconst middlewareRegistries: MiddlewareRegistries = {\n\t\tfetchMiddleware: new Set(),\n\t};\n\n\tconst middlewareRegistryKeys = Object.keys(middlewareRegistries) as Array<keyof Middlewares>;\n\n\treturn { middlewareRegistries, middlewareRegistryKeys };\n};\n\nexport const composeMiddlewaresFromArray = (\n\tmiddlewareArray: Array<Middlewares[keyof Middlewares] | undefined>\n) => {\n\tlet composedMiddleware: Middlewares[keyof Middlewares];\n\n\tfor (const currentMiddleware of middlewareArray) {\n\t\tif (!currentMiddleware) continue;\n\n\t\tconst previousMiddleware = composedMiddleware;\n\n\t\tif (!previousMiddleware) {\n\t\t\tcomposedMiddleware = currentMiddleware;\n\t\t\tcontinue;\n\t\t}\n\n\t\tcomposedMiddleware = (context) => {\n\t\t\tconst prevFetchImpl = previousMiddleware(context);\n\t\t\tconst fetchImpl = currentMiddleware({ ...context, fetchImpl: prevFetchImpl });\n\n\t\t\treturn fetchImpl;\n\t\t};\n\t}\n\n\treturn composedMiddleware;\n};\n","import { extraOptionDefaults } from \"./constants/defaults\";\nimport {\n\tcomposeHooksFromArray,\n\tgetHookRegistriesAndKeys,\n\ttype Hooks,\n\ttype HooksOrHooksArray,\n\ttype RequestContext,\n} from \"./hooks\";\nimport {\n\tcomposeMiddlewaresFromArray,\n\tgetMiddlewareRegistriesAndKeys,\n\ttype Middlewares,\n} from \"./middlewares\";\nimport type { CallApiContext, CallApiRequestOptions, OverrideCallApiContext } from \"./types/common\";\nimport type { DefaultCallApiContext, DefaultDataType } from \"./types/default-types\";\nimport type { AnyFunction, Awaitable, UnionToIntersection } from \"./types/type-helpers\";\nimport type { InitURLOrURLObject } from \"./url\";\nimport { getMethod, getResolvedHeaders } from \"./utils/common\";\nimport { isArray, isFunction, isString } from \"./utils/guards\";\nimport {\n\tgetCurrentRouteSchemaKeyAndMainInitURL,\n\ttype BaseCallApiSchemaAndConfig,\n\ttype InferSchemaOutput,\n} from \"./validation\";\n\nexport type PluginSetupContext<TCallApiContext extends CallApiContext = DefaultCallApiContext> =\n\tRequestContext<TCallApiContext> & { initURL: string };\n\nexport type PluginInitResult<TCallApiContext extends CallApiContext = DefaultCallApiContext> = Partial<\n\tOmit<PluginSetupContext<TCallApiContext>, \"initURL\" | \"request\"> & {\n\t\tinitURL: InitURLOrURLObject;\n\t\trequest: CallApiRequestOptions;\n\t}\n>;\n\ntype GetDefaultDataTypeForPlugins<TData> = DefaultDataType extends TData ? never : TData;\n\nexport type PluginHooks<TCallApiContext extends CallApiContext = DefaultCallApiContext> =\n\tHooksOrHooksArray<\n\t\tOverrideCallApiContext<\n\t\t\tTCallApiContext,\n\t\t\t{\n\t\t\t\tData: GetDefaultDataTypeForPlugins<TCallApiContext[\"Data\"]>;\n\t\t\t\tErrorData: GetDefaultDataTypeForPlugins<TCallApiContext[\"ErrorData\"]>;\n\t\t\t}\n\t\t>\n\t>;\n\nexport type PluginMiddlewares<TCallApiContext extends CallApiContext = DefaultCallApiContext> =\n\tMiddlewares<\n\t\tOverrideCallApiContext<\n\t\t\tTCallApiContext,\n\t\t\t{\n\t\t\t\tData: GetDefaultDataTypeForPlugins<TCallApiContext[\"Data\"]>;\n\t\t\t\tErrorData: GetDefaultDataTypeForPlugins<TCallApiContext[\"ErrorData\"]>;\n\t\t\t}\n\t\t>\n\t>;\n\nexport interface CallApiPlugin<TCallApiContext extends CallApiContext = DefaultCallApiContext> {\n\t/**\n\t * Defines additional options that can be passed to callApi\n\t */\n\tdefineExtraOptions?: () => TCallApiContext[\"InferredExtraOptions\"];\n\n\t/**\n\t * A description for the plugin\n\t */\n\tdescription?: string;\n\n\t/**\n\t * Hooks for the plugin\n\t */\n\thooks?:\n\t\t| PluginHooks<TCallApiContext>\n\t\t| ((\n\t\t\t\tcontext: PluginSetupContext<TCallApiContext>\n\t\t ) => Awaitable<PluginHooks<TCallApiContext>> | Awaitable<void>);\n\n\t/**\n\t * A unique id for the plugin\n\t */\n\tid: string;\n\n\t/**\n\t * Middlewares that for the plugin\n\t */\n\tmiddlewares?:\n\t\t| PluginMiddlewares<TCallApiContext>\n\t\t| ((\n\t\t\t\tcontext: PluginSetupContext<TCallApiContext>\n\t\t ) => Awaitable<PluginMiddlewares<TCallApiContext>> | Awaitable<void>);\n\n\t/**\n\t * A name for the plugin\n\t */\n\tname: string;\n\n\t/**\n\t * Base schema for the client.\n\t */\n\tschema?: BaseCallApiSchemaAndConfig;\n\n\t/**\n\t * A function that will be called when the plugin is initialized. This will be called before the any of the other internal functions.\n\t */\n\tsetup?: (\n\t\tcontext: PluginSetupContext<TCallApiContext>\n\t) => Awaitable<PluginInitResult<TCallApiContext>> | Awaitable<void>;\n\n\t/**\n\t * A version for the plugin\n\t */\n\tversion?: string;\n}\n\nexport type InferPluginExtraOptions<TPluginArray extends CallApiPlugin[]> = UnionToIntersection<\n\tTPluginArray extends Array<infer TPlugin> ?\n\t\tTPlugin extends CallApiPlugin ?\n\t\t\tTPlugin[\"defineExtraOptions\"] extends AnyFunction<infer TResult> ?\n\t\t\t\tInferSchemaOutput<TResult, TResult>\n\t\t\t:\tnever\n\t\t:\tnever\n\t:\tnever\n>;\n\nexport const getResolvedPlugins = (context: Pick<RequestContext, \"baseConfig\" | \"options\">) => {\n\tconst { baseConfig, options } = context;\n\n\tconst resolvedPlugins =\n\t\tisFunction(options.plugins) ?\n\t\t\toptions.plugins({ basePlugins: baseConfig.plugins ?? [] })\n\t\t:\t(options.plugins ?? []);\n\n\treturn resolvedPlugins;\n};\n\nexport const initializePlugins = async (setupContext: PluginSetupContext) => {\n\tconst { baseConfig, config, initURL, options, request } = setupContext;\n\n\tconst {\n\t\taddMainHooks,\n\t\taddMainMiddlewares,\n\t\taddPluginHooks,\n\t\taddPluginMiddlewares,\n\t\tgetResolvedHooks,\n\t\tgetResolvedMiddlewares,\n\t} = setupHooksAndMiddlewares({ baseConfig, config, options });\n\n\tconst initURLResult = getCurrentRouteSchemaKeyAndMainInitURL({\n\t\tbaseExtraOptions: baseConfig,\n\t\textraOptions: config,\n\t\tinitURL,\n\t});\n\n\tlet resolvedCurrentRouteSchemaKey = initURLResult.currentRouteSchemaKey;\n\tlet resolvedInitURL = initURLResult.mainInitURL;\n\tconst resolvedOptions = options;\n\tconst resolvedRequest = Object.assign(request, {\n\t\theaders: getResolvedHeaders({ baseHeaders: baseConfig.headers, headers: config.headers }),\n\t\tmethod: getMethod({ initURL: resolvedInitURL, method: request.method }),\n\t});\n\n\tconst executePluginSetupFn = async (pluginSetup: CallApiPlugin[\"setup\"]) => {\n\t\tif (!pluginSetup) return;\n\n\t\tconst initResult = await pluginSetup(setupContext);\n\n\t\tif (!initResult) return;\n\n\t\tconst urlString = initResult.initURL?.toString();\n\n\t\tif (isString(urlString)) {\n\t\t\tconst newURLResult = getCurrentRouteSchemaKeyAndMainInitURL({\n\t\t\t\tbaseExtraOptions: baseConfig,\n\t\t\t\textraOptions: config,\n\t\t\t\tinitURL: urlString,\n\t\t\t});\n\n\t\t\tresolvedCurrentRouteSchemaKey = newURLResult.currentRouteSchemaKey;\n\t\t\tresolvedInitURL = newURLResult.mainInitURL;\n\t\t}\n\n\t\tif (initResult.request) {\n\t\t\tObject.assign(resolvedRequest, initResult.request);\n\t\t}\n\n\t\tif (initResult.options) {\n\t\t\tObject.assign(resolvedOptions, initResult.options);\n\t\t}\n\t};\n\n\tconst resolvedPlugins = getResolvedPlugins({ baseConfig, options });\n\n\tfor (const plugin of resolvedPlugins) {\n\t\t// eslint-disable-next-line no-await-in-loop -- Await is necessary in this case.\n\t\tconst [, pluginHooks, pluginMiddlewares] = await Promise.all([\n\t\t\texecutePluginSetupFn(plugin.setup),\n\t\t\tisFunction(plugin.hooks) ? plugin.hooks(setupContext) : plugin.hooks,\n\t\t\tisFunction(plugin.middlewares) ? plugin.middlewares(setupContext) : plugin.middlewares,\n\t\t]);\n\n\t\tpluginHooks && addPluginHooks(pluginHooks);\n\t\tpluginMiddlewares && addPluginMiddlewares(pluginMiddlewares);\n\t}\n\n\taddMainHooks();\n\n\taddMainMiddlewares();\n\n\tconst resolvedHooks = getResolvedHooks();\n\n\tconst resolvedMiddlewares = getResolvedMiddlewares();\n\n\treturn {\n\t\tresolvedCurrentRouteSchemaKey,\n\t\tresolvedHooks,\n\t\tresolvedInitURL,\n\t\tresolvedMiddlewares,\n\t\tresolvedOptions,\n\t\tresolvedRequest,\n\t};\n};\n\nconst setupHooksAndMiddlewares = (\n\tcontext: Pick<PluginSetupContext, \"baseConfig\" | \"config\" | \"options\">\n) => {\n\tconst { baseConfig, config, options } = context;\n\n\tconst { hookRegistries, hookRegistryKeys } = getHookRegistriesAndKeys();\n\n\tconst { middlewareRegistries, middlewareRegistryKeys } = getMiddlewareRegistriesAndKeys();\n\n\tconst addMainHooks = () => {\n\t\tfor (const hookName of hookRegistryKeys) {\n\t\t\tconst overriddenHook = options[hookName];\n\t\t\tconst baseHook = baseConfig[hookName];\n\t\t\tconst instanceHook = config[hookName];\n\n\t\t\tconst shouldMergeBaseAndInstanceHooks = isArray(baseHook) && instanceHook;\n\n\t\t\tconst mainHook =\n\t\t\t\tshouldMergeBaseAndInstanceHooks ? [baseHook, instanceHook].flat() : overriddenHook;\n\n\t\t\tmainHook && hookRegistries[hookName].add(mainHook as never);\n\t\t}\n\t};\n\n\tconst addPluginHooks = (pluginHooks: PluginHooks) => {\n\t\tfor (const hookName of hookRegistryKeys) {\n\t\t\tconst pluginHook = pluginHooks[hookName];\n\n\t\t\tpluginHook && hookRegistries[hookName].add(pluginHook as never);\n\t\t}\n\t};\n\n\tconst addMainMiddlewares = () => {\n\t\tfor (const middlewareName of middlewareRegistryKeys) {\n\t\t\tconst baseMiddleware = baseConfig[middlewareName];\n\t\t\tconst instanceMiddleware = config[middlewareName];\n\n\t\t\tbaseMiddleware && middlewareRegistries[middlewareName].add(baseMiddleware);\n\n\t\t\tinstanceMiddleware && middlewareRegistries[middlewareName].add(instanceMiddleware);\n\t\t}\n\t};\n\n\tconst addPluginMiddlewares = (pluginMiddlewares: PluginMiddlewares) => {\n\t\tfor (const middlewareName of middlewareRegistryKeys) {\n\t\t\tconst pluginMiddleware = pluginMiddlewares[middlewareName];\n\n\t\t\tif (!pluginMiddleware) continue;\n\n\t\t\tmiddlewareRegistries[middlewareName].add(pluginMiddleware);\n\t\t}\n\t};\n\n\tconst getResolvedHooks = () => {\n\t\tconst resolvedHooks: Hooks = {};\n\n\t\tfor (const [hookName, hookRegistry] of Object.entries(hookRegistries)) {\n\t\t\tif (hookRegistry.size === 0) continue;\n\n\t\t\t// == Flatten the hook registry to remove any nested arrays, incase an array of hooks is passed to any of the hooks\n\t\t\tconst flattenedHookArray = [...hookRegistry].flat();\n\n\t\t\tif (flattenedHookArray.length === 0) continue;\n\n\t\t\tconst hooksExecutionMode = options.hooksExecutionMode ?? extraOptionDefaults.hooksExecutionMode;\n\n\t\t\tconst composedHook = composeHooksFromArray(flattenedHookArray, hooksExecutionMode);\n\n\t\t\tresolvedHooks[hookName as keyof Hooks] = composedHook;\n\t\t}\n\n\t\treturn resolvedHooks;\n\t};\n\n\tconst getResolvedMiddlewares = () => {\n\t\tconst resolvedMiddlewares: Middlewares = {};\n\n\t\tfor (const [middlewareName, middlewareRegistry] of Object.entries(middlewareRegistries)) {\n\t\t\tif (middlewareRegistry.size === 0) continue;\n\n\t\t\tconst middlewareArray = [...middlewareRegistry];\n\n\t\t\tif (middlewareArray.length === 0) continue;\n\n\t\t\tconst composedMiddleware = composeMiddlewaresFromArray(middlewareArray);\n\n\t\t\tresolvedMiddlewares[middlewareName as keyof Middlewares] = composedMiddleware;\n\t\t}\n\n\t\treturn resolvedMiddlewares;\n\t};\n\n\treturn {\n\t\taddMainHooks,\n\t\taddMainMiddlewares,\n\t\taddPluginHooks,\n\t\taddPluginMiddlewares,\n\t\tgetResolvedHooks,\n\t\tgetResolvedMiddlewares,\n\t};\n};\n","import { extraOptionDefaults } from \"./constants/defaults\";\nimport {\n\texecuteHooksInCatchBlock,\n\ttype ErrorContext,\n\ttype ExecuteHookInfo,\n\ttype RetryContext,\n} from \"./hooks\";\nimport type { CallApiResultErrorVariant } from \"./result\";\nimport type { CallApiConfig } from \"./types/common\";\nimport type { MethodUnion } from \"./types/conditional-types\";\nimport { defineEnum, type AnyNumber, type Awaitable, type UnmaskType } from \"./types/type-helpers\";\nimport type { InitURLOrURLObject } from \"./url\";\nimport { waitFor } from \"./utils/common\";\nimport { isBoolean, isFunction, isString } from \"./utils/guards\";\n\n// eslint-disable-next-line ts-eslint/no-unused-vars -- Ignore\nconst defaultRetryStatusCodesLookup = () =>\n\tdefineEnum({\n\t\t408: \"Request Timeout\",\n\t\t409: \"Conflict\",\n\t\t425: \"Too Early\",\n\t\t429: \"Too Many Requests\",\n\t\t500: \"Internal Server Error\",\n\t\t502: \"Bad Gateway\",\n\t\t503: \"Service Unavailable\",\n\t\t504: \"Gateway Timeout\",\n\t});\n\ntype RetryStatusCodes = UnmaskType<AnyNumber | keyof ReturnType<typeof defaultRetryStatusCodesLookup>>;\n\ntype RetryCondition<TErrorData> = (context: ErrorContext<{ ErrorData: TErrorData }>) => Awaitable<boolean>;\n\nexport interface RetryOptions<TErrorData> {\n\t/**\n\t * Keeps track of the number of times the request has already been retried\n\t * @internal\n\t * @deprecated **NOTE**: This property is used internally to track retries. Please abstain from modifying it.\n\t */\n\treadonly [\"~retryAttemptCount\"]?: number;\n\n\t/**\n\t * Number of allowed retry attempts on HTTP errors\n\t * @default 0\n\t */\n\tretryAttempts?: number;\n\n\t/**\n\t * Callback whose return value determines if a request should be retried or not\n\t */\n\tretryCondition?: RetryCondition<TErrorData>;\n\n\t/**\n\t * Delay between retries in milliseconds\n\t * @default 1000\n\t */\n\tretryDelay?: number | ((currentAttemptCount: number) => number);\n\n\t/**\n\t * Maximum delay in milliseconds. Only applies to exponential strategy\n\t * @default 10000\n\t */\n\tretryMaxDelay?: number;\n\n\t/**\n\t * HTTP methods that are allowed to retry\n\t * @default [\"GET\", \"POST\"]\n\t */\n\tretryMethods?: MethodUnion[];\n\n\t/**\n\t * HTTP status codes that trigger a retry\n\t */\n\tretryStatusCodes?: RetryStatusCodes[];\n\n\t/**\n\t * Strategy to use when retrying\n\t * @default \"linear\"\n\t */\n\tretryStrategy?: \"exponential\" | \"linear\";\n}\n\nconst getLinearDelay = (currentAttemptCount: number, options: RetryOptions<unknown>) => {\n\tconst retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;\n\n\tconst resolveRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;\n\n\treturn resolveRetryDelay;\n};\n\nconst getExponentialDelay = (currentAttemptCount: number, options: RetryOptions<unknown>) => {\n\tconst retryDelay = options.retryDelay ?? extraOptionDefaults.retryDelay;\n\n\tconst resolvedRetryDelay = isFunction(retryDelay) ? retryDelay(currentAttemptCount) : retryDelay;\n\n\tconst maxDelay = options.retryMaxDelay ?? extraOptionDefaults.retryMaxDelay;\n\n\tconst exponentialDelay = resolvedRetryDelay * 2 ** currentAttemptCount;\n\n\treturn Math.min(exponentialDelay, maxDelay);\n};\n\ntype CallApiImpl = (initURL: never, init?: CallApiConfig) => Promise<CallApiResultErrorVariant<unknown>>;\n\nexport const createRetryManager = <TCallApi extends CallApiImpl>(ctx: {\n\tcallApi: TCallApi;\n\tcallApiArgs: { config: CallApiConfig; initURL: InitURLOrURLObject };\n\terror: unknown;\n\terrorContext: ErrorContext;\n\terrorResult: CallApiResultErrorVariant<unknown> | null;\n\thookInfo: ExecuteHookInfo;\n}) => {\n\tconst { callApi, callApiArgs, error, errorContext, errorResult, hookInfo } = ctx;\n\n\tconst { options, request } = errorContext;\n\n\t// eslint-disable-next-line ts-eslint/no-deprecated -- Allowed for internal use\n\tconst currentAttemptCount = options[\"~retryAttemptCount\"] ?? 1;\n\n\tconst retryStrategy = options.retryStrategy ?? extraOptionDefaults.retryStrategy;\n\n\tconst getDelay = () => {\n\t\tswitch (retryStrategy) {\n\t\t\tcase \"exponential\": {\n\t\t\t\treturn getExponentialDelay(currentAttemptCount, options);\n\t\t\t}\n\t\t\tcase \"linear\": {\n\t\t\t\treturn getLinearDelay(currentAttemptCount, options);\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new Error(`Invalid retry strategy: ${String(retryStrategy)}`);\n\t\t\t}\n\t\t}\n\t};\n\n\tconst shouldAttemptRetry = async () => {\n\t\tif (isBoolean(request.signal) && request.signal.aborted) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst retryCondition = options.retryCondition ?? extraOptionDefaults.retryCondition;\n\n\t\tconst maximumRetryAttempts = options.retryAttempts ?? extraOptionDefaults.retryAttempts;\n\n\t\tconst customRetryCondition = await retryCondition(errorContext);\n\n\t\tconst baseShouldRetry = currentAttemptCount <= maximumRetryAttempts && customRetryCondition;\n\n\t\tif (!baseShouldRetry) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst retryMethods = new Set(options.retryMethods ?? extraOptionDefaults.retryMethods);\n\n\t\tconst includesMethod =\n\t\t\tisString(request.method) && retryMethods.size > 0 ? retryMethods.has(request.method) : true;\n\n\t\tconst retryStatusCodes = new Set(options.retryStatusCodes ?? extraOptionDefaults.retryStatusCodes);\n\n\t\tconst includesStatusCodes =\n\t\t\terrorContext.response != null && retryStatusCodes.size > 0 ?\n\t\t\t\tretryStatusCodes.has(errorContext.response.status)\n\t\t\t:\ttrue;\n\n\t\tconst shouldRetry = includesMethod && includesStatusCodes;\n\n\t\treturn shouldRetry;\n\t};\n\n\tconst handleRetry = async () => {\n\t\tconst retryContext = {\n\t\t\t...errorContext,\n\t\t\tretryAttemptCount: currentAttemptCount,\n\t\t} satisfies RetryContext<{ ErrorData: unknown }>;\n\n\t\tconst hookError = await executeHooksInCatchBlock([options.onRetry?.(retryContext)], hookInfo);\n\n\t\tif (hookError) {\n\t\t\treturn hookError;\n\t\t}\n\n\t\tawait waitFor(getDelay());\n\n\t\tconst updatedConfig = {\n\t\t\t...callApiArgs.config,\n\t\t\t\"~retryAttemptCount\": currentAttemptCount + 1,\n\t\t} satisfies CallApiConfig;\n\n\t\treturn callApi(callApiArgs.initURL as never, updatedConfig);\n\t};\n\n\tconst handleRetryOrGetErrorResult = async () => {\n\t\tconst shouldRetry = await shouldAttemptRetry();\n\n\t\tif (shouldRetry) {\n\t\t\tconst callApiRetryResult = handleRetry();\n\n\t\t\treturn callApiRetryResult;\n\t\t}\n\n\t\tif (hookInfo.shouldThrowOnError) {\n\t\t\tthrow error;\n\t\t}\n\n\t\treturn errorResult;\n\t};\n\n\treturn {\n\t\thandleRetryOrGetErrorResult,\n\t};\n};\n","import { createDedupeStrategy, type GlobalRequestInfoCache, type RequestInfoCache } from \"./dedupe\";\nimport {\n\texecuteHooks,\n\texecuteHooksInCatchBlock,\n\ttype ErrorContext,\n\ttype ExecuteHookInfo,\n\ttype RequestContext,\n\ttype ResponseContext,\n\ttype SuccessContext,\n} from \"./hooks\";\nimport { initializePlugins, type CallApiPlugin } from \"./plugins\";\nimport {\n\tgetCustomizedErrorResult,\n\tresolveErrorResult,\n\tresolveResponseData,\n\tresolveSuccessResult,\n\ttype ErrorInfo,\n\ttype GetResponseType,\n\ttype ResponseTypeType,\n\ttype ResultModeType,\n} from \"./result\";\nimport { createRetryManager } from \"./retry\";\nimport type {\n\tBaseCallApiConfig,\n\tCallApiConfig,\n\tCallApiContext,\n\tCallApiExtraOptionsForHooks,\n\tCallApiRequestOptions,\n\tCallApiRequestOptionsForHooks,\n\tCallApiResult,\n\tGetBaseSchemaConfig,\n\tGetBaseSchemaRoutes,\n} from \"./types/common\";\nimport type {\n\tGetCurrentRouteSchema,\n\tGetCurrentRouteSchemaKey,\n\tInferInitURL,\n\tThrowOnErrorBoolean,\n} from \"./types/conditional-types\";\nimport type {\n\tDefaultCallApiContext,\n\tDefaultPluginArray,\n\tDefaultThrowOnError,\n} from \"./types/default-types\";\nimport type { AnyFunction } from \"./types/type-helpers\";\nimport { getFullAndNormalizedURL } from \"./url\";\nimport {\n\tcreateCombinedSignal,\n\tcreateTimeoutSignal,\n\tgetBody,\n\tgetFetchImpl,\n\tgetHeaders,\n\tgetMethod,\n\tsplitBaseConfig,\n\tsplitConfig,\n} from \"./utils/common\";\nimport { HTTPError } from \"./utils/external/error\";\nimport { isHTTPErrorInstance, isValidationErrorInstance } from \"./utils/external/guards\";\nimport { isFunction } from \"./utils/guards\";\nimport {\n\thandleConfigValidation,\n\thandleSchemaValidation,\n\ttype BaseCallApiSchemaAndConfig,\n\ttype BaseCallApiSchemaRoutes,\n\ttype CallApiSchema,\n\ttype CallApiSchemaConfig,\n\ttype InferSchemaOutput,\n} from \"./validation\";\n\nconst $GlobalRequestInfoCache: GlobalRequestInfoCache = new Map();\n\nexport const createFetchClientWithContext = <\n\tTOuterCallApiContext extends CallApiContext = DefaultCallApiContext,\n>() => {\n\tconst createFetchClient = <\n\t\tTBaseCallApiContext extends CallApiContext = TOuterCallApiContext,\n\t\tTBaseData = TBaseCallApiContext[\"Data\"],\n\t\tTBaseErrorData = TBaseCallApiContext[\"ErrorData\"],\n\t\tTBaseResultMode extends ResultModeType = TBaseCallApiContext[\"ResultMode\"] extends ResultModeType ?\n\t\t\tTBaseCallApiContext[\"ResultMode\"]\n\t\t:\tDefaultCallApiContext[\"ResultMode\"],\n\t\tTBaseThrowOnError extends ThrowOnErrorBoolean = DefaultThrowOnError,\n\t\tTBaseResponseType extends ResponseTypeType = ResponseTypeType,\n\t\tconst TBaseSchemaAndConfig extends BaseCallApiSchemaAndConfig = BaseCallApiSchemaAndConfig,\n\t\tconst TBasePluginArray extends CallApiPlugin[] = DefaultPluginArray,\n\t\tTComputedBaseSchemaConfig extends CallApiSchemaConfig = GetBaseSchemaConfig<TBaseSchemaAndConfig>,\n\t\tTComputedBaseSchemaRoutes extends BaseCallApiSchemaRoutes =\n\t\t\tGetBaseSchemaRoutes<TBaseSchemaAndConfig>,\n\t>(\n\t\tinitBaseConfig: BaseCallApiConfig<\n\t\t\tTBaseCallApiContext,\n\t\t\tTBaseData,\n\t\t\tTBaseErrorData,\n\t\t\tTBaseResultMode,\n\t\t\tTBaseThrowOnError,\n\t\t\tTBaseResponseType,\n\t\t\tTBaseSchemaAndConfig,\n\t\t\tTBasePluginArray\n\t\t> = {} as never\n\t) => {\n\t\tconst $LocalRequestInfoCache: RequestInfoCache = new Map();\n\n\t\tconst callApi = async <\n\t\t\tTData = TBaseData,\n\t\t\tTErrorData = TBaseErrorData,\n\t\t\tTResultMode extends ResultModeType = TBaseResultMode,\n\t\t\tTCallApiContext extends CallApiContext = TBaseCallApiContext,\n\t\t\tTThrowOnError extends ThrowOnErrorBoolean = TBaseThrowOnError,\n\t\t\tTResponseType extends ResponseTypeType = TBaseResponseType,\n\t\t\tconst TSchemaConfig extends CallApiSchemaConfig = TComputedBaseSchemaConfig,\n\t\t\tTInitURL extends InferInitURL<TComputedBaseSchemaRoutes, TSchemaConfig> = InferInitURL<\n\t\t\t\tTComputedBaseSchemaRoutes,\n\t\t\t\tTSchemaConfig\n\t\t\t>,\n\t\t\tTCurrentRouteSchemaKey extends GetCurrentRouteSchemaKey<TSchemaConfig, TInitURL> =\n\t\t\t\tGetCurrentRouteSchemaKey<TSchemaConfig, TInitURL>,\n\t\t\tconst TSchema extends CallApiSchema = GetCurrentRouteSchema<\n\t\t\t\tTComputedBaseSchemaRoutes,\n\t\t\t\tTCurrentRouteSchemaKey\n\t\t\t>,\n\t\t\tconst TPluginArray extends CallApiPlugin[] = TBasePluginArray,\n\t\t\tTComputedData = InferSchemaOutput<TSchema[\"data\"], GetResponseType<TData, TResponseType>>,\n\t\t\tTComputedErrorData = InferSchemaOutput<\n\t\t\t\tTSchema[\"errorData\"],\n\t\t\t\tGetResponseType<TErrorData, TResponseType>\n\t\t\t>,\n\t\t\tTComputedResult = CallApiResult<TComputedData, TComputedErrorData, TResultMode, TThrowOnError>,\n\t\t>(\n\t\t\tinitURL: TInitURL,\n\t\t\tinitConfig: CallApiConfig<\n\t\t\t\tTCallApiContext,\n\t\t\t\tTComputedData,\n\t\t\t\tTComputedErrorData,\n\t\t\t\tTResultMode,\n\t\t\t\tTThrowOnError,\n\t\t\t\tTResponseType,\n\t\t\t\tTComputedBaseSchemaRoutes,\n\t\t\t\tTSchema,\n\t\t\t\tTComputedBaseSchemaConfig,\n\t\t\t\tTSchemaConfig,\n\t\t\t\tTInitURL,\n\t\t\t\tTCurrentRouteSchemaKey,\n\t\t\t\tTBasePluginArray,\n\t\t\t\tTPluginArray\n\t\t\t> = {} as never\n\t\t): Promise<TComputedResult> => {\n\t\t\tconst [fetchOptions, extraOptions] = splitConfig(initConfig);\n\n\t\t\tconst resolvedBaseConfig =\n\t\t\t\tisFunction(initBaseConfig) ?\n\t\t\t\t\tinitBaseConfig({\n\t\t\t\t\t\tinitURL: initURL.toString(),\n\t\t\t\t\t\toptions: extraOptions,\n\t\t\t\t\t\trequest: fetchOptions,\n\t\t\t\t\t})\n\t\t\t\t:\tinitBaseConfig;\n\n\t\t\tconst baseConfig = resolvedBaseConfig as Exclude<BaseCallApiConfig, AnyFunction>;\n\t\t\tconst config = initConfig as CallApiConfig;\n\n\t\t\tconst [baseFetchOptions, baseExtraOptions] = splitBaseConfig(baseConfig);\n\n\t\t\tconst shouldSkipAutoMergeForOptions =\n\t\t\t\tbaseExtraOptions.skipAutoMergeFor === \"all\" || baseExtraOptions.skipAutoMergeFor === \"options\";\n\n\t\t\tconst shouldSkipAutoMergeForRequest =\n\t\t\t\tbaseExtraOptions.skipAutoMergeFor === \"all\" || baseExtraOptions.skipAutoMergeFor === \"request\";\n\n\t\t\t// == Merged Extra Options\n\t\t\tconst mergedExtraOptions = {\n\t\t\t\t...baseExtraOptions,\n\t\t\t\t...(!shouldSkipAutoMergeForOptions && extraOptions),\n\t\t\t};\n\n\t\t\t// == Merged Request Options\n\t\t\tconst mergedRequestOptions = {\n\t\t\t\t...baseFetchOptions,\n\t\t\t\t...(!shouldSkipAutoMergeForRequest && fetchOptions),\n\t\t\t} satisfies CallApiRequestOptions;\n\n\t\t\tconst {\n\t\t\t\tresolvedCurrentRouteSchemaKey,\n\t\t\t\tresolvedHooks,\n\t\t\t\tresolvedInitURL,\n\t\t\t\tresolvedMiddlewares,\n\t\t\t\tresolvedOptions,\n\t\t\t\tresolvedRequest,\n\t\t\t} = await initializePlugins({\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tinitURL: initURL.toString(),\n\t\t\t\toptions: mergedExtraOptions as CallApiExtraOptionsForHooks,\n\t\t\t\trequest: mergedRequestOptions as CallApiRequestOptionsForHooks,\n\t\t\t});\n\n\t\t\tconst { fullURL, normalizedInitURL } = getFullAndNormalizedURL({\n\t\t\t\tbaseURL: resolvedOptions.baseURL,\n\t\t\t\tinitURL: resolvedInitURL,\n\t\t\t\tparams: resolvedOptions.params,\n\t\t\t\tquery: resolvedOptions.query,\n\t\t\t});\n\n\t\t\tconst options = {\n\t\t\t\t...resolvedOptions,\n\t\t\t\t...resolvedHooks,\n\t\t\t\t...resolvedMiddlewares,\n\n\t\t\t\tfullURL,\n\t\t\t\tinitURL: resolvedInitURL,\n\t\t\t\tinitURLNormalized: normalizedInitURL,\n\t\t\t} satisfies CallApiExtraOptionsForHooks;\n\n\t\t\tconst newFetchController = new AbortController();\n\n\t\t\tconst timeoutSignal = createTimeoutSignal(options.timeout);\n\n\t\t\tconst combinedSignal = createCombinedSignal(\n\t\t\t\ttimeoutSignal,\n\t\t\t\tresolvedRequest.signal,\n\t\t\t\tnewFetchController.signal\n\t\t\t);\n\n\t\t\tconst request = {\n\t\t\t\t...resolvedRequest,\n\n\t\t\t\tsignal: combinedSignal,\n\t\t\t} satisfies CallApiRequestOptionsForHooks;\n\n\t\t\tconst {\n\t\t\t\tgetAbortErrorMessage,\n\t\t\t\thandleRequestCancelStrategy,\n\t\t\t\thandleRequestDeferStrategy,\n\t\t\t\tremoveDedupeKeyFromCache,\n\t\t\t\tresolvedDedupeStrategy,\n\t\t\t} = await createDedupeStrategy({\n\t\t\t\t$GlobalRequestInfoCache,\n\t\t\t\t$LocalRequestInfoCache,\n\t\t\t\tbaseConfig,\n\t\t\t\tconfig,\n\t\t\t\tnewFetchController,\n\t\t\t\toptions,\n\t\t\t\trequest,\n\t\t\t});\n\n\t\t\ttry {\n\t\t\t\thandleRequestCancelStrategy();\n\n\t\t\t\tawait executeHooks(options.onRequest?.({ baseConfig, config, options, request }));\n\n\t\t\t\tconst {\n\t\t\t\t\textraOptionsValidationResult,\n\t\t\t\t\trequestOptionsValidationResult,\n\t\t\t\t\tresolvedSchema,\n\t\t\t\t\tresolvedSchemaConfig,\n\t\t\t\t} = await handleConfigValidation({\n\t\t\t\t\tbaseExtraOptions,\n\t\t\t\t\tcurrentRouteSchemaKey: resolvedCurrentRouteSchemaKey,\n\t\t\t\t\textraOptions,\n\t\t\t\t\toptions,\n\t\t\t\t\trequest,\n\t\t\t\t});\n\n\t\t\t\t// == Apply Schema Output for Extra Options\n\n\t\t\t\tObject.assign(options, extraOptionsValidationResult);\n\n\t\t\t\t// == Apply Schema Output for Request Options\n\t\t\t\tObject.assign(request, {\n\t\t\t\t\tbody: getBody({\n\t\t\t\t\t\tbody: requestOptionsValidationResult.body,\n\t\t\t\t\t\tbodySerializer: options.bodySerializer,\n\t\t\t\t\t\tresolvedHeaders: requestOptionsValidationResult.headers,\n\t\t\t\t\t}),\n\t\t\t\t\theaders: await getHeaders({\n\t\t\t\t\t\tauth: options.auth,\n\t\t\t\t\t\tbody: requestOptionsValidationResult.body,\n\t\t\t\t\t\tresolvedHeaders: requestOptionsValidationResult.headers,\n\t\t\t\t\t}),\n\t\t\t\t\tmethod: getMethod({\n\t\t\t\t\t\tinitURL: resolvedInitURL,\n\t\t\t\t\t\tmethod: requestOptionsValidationResult.method,\n\t\t\t\t\t}),\n\t\t\t\t});\n\n\t\t\t\tconst readyRequestContext = { baseConfig, config, options, request } satisfies RequestContext;\n\n\t\t\t\tawait executeHooks(options.onRequestReady?.(readyRequestContext));\n\n\t\t\t\tconst fetchApi = getFetchImpl({\n\t\t\t\t\tcustomFetchImpl: options.customFetchImpl,\n\t\t\t\t\tfetchMiddleware: options.fetchMiddleware,\n\t\t\t\t\trequestContext: readyRequestContext,\n\t\t\t\t});\n\n\t\t\t\tconst response = await handleRequestDeferStrategy({ fetchApi, options, request });\n\n\t\t\t\t// == Also clone response when dedupeStrategy is set to \"defer\" to avoid error thrown from reading response.(whatever) more than once\n\t\t\t\tconst shouldCloneResponse = Boolean(\n\t\t\t\t\tresolvedDedupeStrategy === \"defer\" || options.cloneResponse\n\t\t\t\t);\n\n\t\t\t\tconst responseData = await resolveResponseData({\n\t\t\t\t\tresponse: shouldCloneResponse ? response.clone() : response,\n\t\t\t\t\tresponseParser: options.responseParser,\n\t\t\t\t\tresponseType: options.responseType,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t});\n\n\t\t\t\tif (!response.ok) {\n\t\t\t\t\tconst validErrorData = await handleSchemaValidation(resolvedSchema, \"errorData\", {\n\t\t\t\t\t\tinputValue: responseData,\n\t\t\t\t\t\tresponse,\n\t\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t\t\t\t});\n\n\t\t\t\t\t// == Push all error handling responsibilities to the catch block if not retrying\n\t\t\t\t\tthrow new HTTPError(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdefaultHTTPErrorMessage: options.defaultHTTPErrorMessage,\n\t\t\t\t\t\t\terrorData: validErrorData,\n\t\t\t\t\t\t\tresponse,\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ cause: validErrorData }\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst validSuccessData = await handleSchemaValidation(resolvedSchema, \"data\", {\n\t\t\t\t\tinputValue: responseData,\n\t\t\t\t\tresponse,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t\tschemaConfig: resolvedSchemaConfig,\n\t\t\t\t});\n\n\t\t\t\tconst successContext = {\n\t\t\t\t\tbaseConfig,\n\t\t\t\t\tconfig,\n\t\t\t\t\tdata: validSuccessData,\n\t\t\t\t\toptions,\n\t\t\t\t\trequest,\n\t\t\t\t\tresponse,\n\t\t\t\t} satisfies SuccessContext;\n\n\t\t\t\tawait executeHooks(\n\t\t\t\t\toptions.onSuccess?.(successContext),\n\t\t\t\t\toptions.onResponse?.({ ...successContext, error: null })\n\t\t\t\t);\n\n\t\t\t\tconst successResult = resolveSuccessResult(successContext.data, {\n\t\t\t\t\tresponse: successContext.response,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t});\n\n\t\t\t\treturn successResult as never;\n\n\t\t\t\t// == Exhaustive Error handling\n\t\t\t} catch (error) {\n\t\t\t\tconst errorInfo = {\n\t\t\t\t\tcloneResponse: options.cloneResponse,\n\t\t\t\t\tresultMode: options.resultMode,\n\t\t\t\t} satisfies ErrorInfo;\n\n\t\t\t\tconst { errorDetails, errorResult } = resolveErrorResult(error, errorInfo);\n\n\t\t\t\tconst errorContext = {\n\t\t\t\t\tbaseConfig,\n\t\t\t\t\tconfig,\n\t\t\t\t\terror: errorDetails.error as never,\n\t\t\t\t\toptions,\n\t\t\t\t\trequest,\n\t\t\t\t\tresponse: errorDetails.response as never,\n\t\t\t\t} satisfies ErrorContext;\n\n\t\t\t\tconst shouldThrowOnError = Boolean(\n\t\t\t\t\tisFunction(options.throwOnError) ? options.throwOnError(errorContext) : options.throwOnError\n\t\t\t\t);\n\n\t\t\t\tconst hookInfo = {\n\t\t\t\t\terrorInfo,\n\t\t\t\t\tshouldThrowOnError,\n\t\t\t\t} satisfies ExecuteHookInfo;\n\n\t\t\t\tconst { handleRetryOrGetErrorResult } = createRetryManager({\n\t\t\t\t\tcallApi,\n\t\t\t\t\tcallApiArgs: { config, initURL },\n\t\t\t\t\terror,\n\t\t\t\t\terrorContext,\n\t\t\t\t\terrorResult,\n\t\t\t\t\thookInfo,\n\t\t\t\t});\n\n\t\t\t\tconst responseContext: ResponseContext | null =\n\t\t\t\t\t(errorContext.response as typeof errorDetails.response) ?\n\t\t\t\t\t\t{ ...errorContext, data: null }\n\t\t\t\t\t:\tnull;\n\n\t\t\t\tif (isValidationErrorInstance(error)) {\n\t\t\t\t\tconst hookError = await executeHooksInCatchBlock(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tresponseContext && options.onResponse?.(responseContext),\n\t\t\t\t\t\t\toptions.onValidationError?.(errorContext),\n\t\t\t\t\t\t\toptions.onError?.(errorContext),\n\t\t\t\t\t\t],\n\t\t\t\t\t\thookInfo\n\t\t\t\t\t);\n\n\t\t\t\t\treturn (hookError ?? (await handleRetryOrGetErrorResult())) as never;\n\t\t\t\t}\n\n\t\t\t\tif (isHTTPErrorInstance<TErrorData>(error)) {\n\t\t\t\t\tconst hookError = await executeHooksInCatchBlock(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tresponseContext && options.onResponse?.(responseContext),\n\t\t\t\t\t\t\toptions.onResponseError?.(errorContext),\n\t\t\t\t\t\t\toptions.onError?.(errorContext),\n\t\t\t\t\t\t],\n\t\t\t\t\t\thookInfo\n\t\t\t\t\t);\n\n\t\t\t\t\treturn (hookError ?? (await handleRetryOrGetErrorResult())) as never;\n\t\t\t\t}\n\n\t\t\t\tlet message = (error as Error | undefined)?.message;\n\n\t\t\t\tif (error instanceof DOMException && error.name === \"AbortError\") {\n\t\t\t\t\tmessage = getAbortErrorMessage();\n\n\t\t\t\t\t!shouldThrowOnError && console.error(`${error.name}:`, message);\n\t\t\t\t}\n\n\t\t\t\tif (error instanceof DOMException && error.name === \"TimeoutError\") {\n\t\t\t\t\tmessage = `Request timed out after ${options.timeout}ms`;\n\n\t\t\t\t\t!shouldThrowOnError && console.error(`${error.name}:`, message);\n\t\t\t\t}\n\n\t\t\t\tconst hookError = await executeHooksInCatchBlock(\n\t\t\t\t\t[\n\t\t\t\t\t\tresponseContext && options.onResponse?.(responseContext),\n\t\t\t\t\t\toptions.onRequestError?.(errorContext),\n\t\t\t\t\t\toptions.onError?.(errorContext),\n\t\t\t\t\t],\n\t\t\t\t\thookInfo\n\t\t\t\t);\n\n\t\t\t\treturn (hookError\n\t\t\t\t\t?? getCustomizedErrorResult(await handleRetryOrGetErrorResult(), { message })) as never;\n\n\t\t\t\t// == Removing the now unneeded AbortController from store\n\t\t\t} finally {\n\t\t\t\tremoveDedupeKeyFromCache();\n\t\t\t}\n\t\t};\n\n\t\treturn callApi;\n\t};\n\n\treturn createFetchClient;\n};\n\nexport const createFetchClient = createFetchClientWithContext();\n\nexport const callApi = createFetchClient();\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { A as HTTPError, B as CallApiSchema, C as CallApiRequestOptions, H as CallApiSchemaType, R as BaseCallApiSchemaRoutes, V as CallApiSchemaConfig, W as InferSchemaOutput, _ as BaseCallApiConfig, a as CallApiPlugin, ct as Writeable, f as PossibleHTTPError, j as ValidationError, l as CallApiResultErrorVariant, m as PossibleValidationError, ot as AnyFunction, p as PossibleJavaScriptError, st as Satisfies, y as CallApiConfig } from "../../index-UfuQFNcf.js";
1
+ import { A as HTTPError, B as CallApiSchema, C as CallApiRequestOptions, H as CallApiSchemaType, R as BaseCallApiSchemaRoutes, V as CallApiSchemaConfig, W as InferSchemaOutput, _ as BaseCallApiConfig, a as CallApiPlugin, ct as Writeable, f as PossibleHTTPError, j as ValidationError, l as CallApiResultErrorVariant, m as PossibleValidationError, ot as AnyFunction, p as PossibleJavaScriptError, st as Satisfies, y as CallApiConfig } from "../../index-DCyPkUNR.js";
2
2
 
3
3
  //#region src/utils/external/body.d.ts
4
4
  type BodyType = NonNullable<CallApiRequestOptions["body"]>;
@@ -55,7 +55,7 @@ type BaseConfigObject = Exclude<BaseCallApiConfig, AnyFunction>;
55
55
  type BaseConfigFn = Extract<BaseCallApiConfig, AnyFunction>;
56
56
  type DefineBaseConfig = {
57
57
  <const TBaseConfig extends BaseConfigObject>(baseConfig: Satisfies<TBaseConfig, BaseConfigObject>): Writeable<typeof baseConfig, "deep">;
58
- <TBaseConfigFn extends BaseConfigFn>(baseConfig: TBaseConfigFn): TBaseConfigFn;
58
+ <TBaseConfigFn extends BaseConfigFn>(baseConfig: TBaseConfigFn): (...parameters: Parameters<TBaseConfigFn>) => Writeable<ReturnType<TBaseConfigFn>, "deep">;
59
59
  };
60
60
  declare const defineBaseConfig: DefineBaseConfig;
61
61
  declare const defineInstanceConfig: <const TInstanceConfig extends CallApiConfig>(config: TInstanceConfig) => Writeable<typeof config, "deep">;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/external/body.ts","../../../src/utils/external/define.ts"],"sourcesContent":["import type { CallApiRequestOptions } from \"../../types/common\";\nimport { getValidatedValue, type CallApiSchemaType, type InferSchemaOutput } from \"../../validation\";\nimport { isArray, isBlob, isObject, isString } from \"../guards\";\nimport { ValidationError } from \"./error\";\n\nconst toStringOrStringify = (value: unknown): string => {\n\treturn isString(value) ? value : JSON.stringify(value);\n};\n\ntype BodyType = NonNullable<CallApiRequestOptions[\"body\"]>;\n\nexport const toSearchParams = <TSchema extends CallApiSchemaType<BodyType>>(\n\tdata: InferSchemaOutput<TSchema>,\n\tschema?: TSchema\n) => {\n\tconst result = getValidatedValue(data, schema, { variant: \"sync\" });\n\n\tif (result.issues) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: \"toQueryString\",\n\t\t\tissues: result.issues,\n\t\t\tresponse: null,\n\t\t});\n\t}\n\n\tconst searchParams = new URLSearchParams();\n\n\tfor (const [key, value] of Object.entries(result.value as Record<string, unknown>)) {\n\t\tif (value == null) continue;\n\n\t\tif (isArray(value)) {\n\t\t\t// eslint-disable-next-line max-depth -- Allow\n\t\t\tfor (const innerValue of value) {\n\t\t\t\tsearchParams.append(key, toStringOrStringify(innerValue));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tsearchParams.set(key, toStringOrStringify(value));\n\t}\n\n\treturn searchParams;\n};\n\nexport const toQueryString = <TSchema extends CallApiSchemaType<BodyType>>(\n\t...parameters: Parameters<typeof toSearchParams<TSchema>>\n) => {\n\tconst searchParams = toSearchParams(...parameters);\n\n\treturn searchParams.toString();\n};\n\nconst toBlobOrString = (value: unknown): string | Blob => {\n\treturn isBlob(value) ? value : String(value);\n};\n\n/**\n * @description Converts a plain object to FormData.\n *\n * Handles various data types:\n * - **Primitives** (string, number, boolean): Converted to strings\n * - **Blobs/Files**: Added directly to FormData\n * - **Arrays**: Each item is appended (allows multiple values for same key)\n * - **Objects**: JSON stringified before adding to FormData\n *\n * @example\n * ```ts\n * // Basic usage\n * const formData = toFormData({\n * name: \"John\",\n * age: 30,\n * active: true\n * });\n *\n * // With arrays\n * const formData = toFormData({\n * tags: [\"javascript\", \"typescript\"],\n * name: \"John\"\n * });\n *\n * // With files\n * const formData = toFormData({\n * avatar: fileBlob,\n * name: \"John\"\n * });\n *\n * // With nested objects (one level only)\n * const formData = toFormData({\n * user: { name: \"John\", age: 30 },\n * settings: { theme: \"dark\" }\n * });\n */\nexport const toFormData = <TSchema extends CallApiSchemaType<BodyType>>(\n\tdata: InferSchemaOutput<TSchema>,\n\tschema?: TSchema\n) => {\n\tconst formData = new FormData();\n\n\tconst result = getValidatedValue(data, schema, { variant: \"sync\" });\n\n\tif (result.issues) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: \"toFormData\",\n\t\t\tissues: result.issues,\n\t\t\tresponse: null,\n\t\t});\n\t}\n\n\tfor (const [key, value] of Object.entries(result.value as Record<string, unknown>)) {\n\t\tif (isArray(value)) {\n\t\t\t// eslint-disable-next-line max-depth -- Allow for now\n\t\t\tfor (const innerValue of value) {\n\t\t\t\tformData.append(key, toBlobOrString(innerValue));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isObject(value) && !isBlob(value)) {\n\t\t\tformData.set(key, JSON.stringify(value));\n\t\t\tcontinue;\n\t\t}\n\n\t\tformData.set(key, toBlobOrString(value));\n\t}\n\n\treturn formData;\n};\n","import type { CallApiPlugin } from \"../../plugins\";\nimport type { BaseCallApiConfig, CallApiConfig } from \"../../types/common\";\nimport type { AnyFunction, Satisfies, Writeable } from \"../../types/type-helpers\";\nimport type {\n\tBaseCallApiSchemaAndConfig,\n\tBaseCallApiSchemaRoutes,\n\tCallApiSchema,\n\tCallApiSchemaConfig,\n} from \"../../validation\";\n\nexport const defineSchema = <\n\tconst TBaseSchemaRoutes extends BaseCallApiSchemaRoutes,\n\tconst TSchemaConfig extends CallApiSchemaConfig,\n>(\n\troutes: TBaseSchemaRoutes,\n\tconfig?: Satisfies<TSchemaConfig, CallApiSchemaConfig>\n) => {\n\treturn {\n\t\tconfig: defineSchemaConfig(config as NonNullable<typeof config>),\n\t\troutes: defineSchemaRoutes(routes),\n\t} satisfies BaseCallApiSchemaAndConfig;\n};\n\nexport const defineSchemaRoutes = <const TSchemaRoutes extends BaseCallApiSchemaRoutes>(\n\troutes: TSchemaRoutes\n) => {\n\treturn routes as Writeable<typeof routes, \"deep\">;\n};\n\nexport const defineMainSchema = <const TSchema extends CallApiSchema>(\n\tmainSchema: Satisfies<TSchema, CallApiSchema>\n) => {\n\treturn mainSchema as Writeable<typeof mainSchema, \"deep\">;\n};\n\nexport const defineSchemaConfig = <const TSchemaConfig extends CallApiSchemaConfig>(\n\tconfig: Satisfies<TSchemaConfig, CallApiSchemaConfig>\n) => {\n\treturn config as Writeable<typeof config, \"deep\">;\n};\n\nexport const definePlugin = <const TPlugin extends CallApiPlugin>(plugin: TPlugin) => {\n\treturn plugin as Writeable<typeof plugin, \"deep\">;\n};\n\ntype BaseConfigObject = Exclude<BaseCallApiConfig, AnyFunction>;\n\ntype BaseConfigFn = Extract<BaseCallApiConfig, AnyFunction>;\n\ntype DefineBaseConfig = {\n\t<const TBaseConfig extends BaseConfigObject>(\n\t\tbaseConfig: Satisfies<TBaseConfig, BaseConfigObject>\n\t): Writeable<typeof baseConfig, \"deep\">;\n\t<TBaseConfigFn extends BaseConfigFn>(baseConfig: TBaseConfigFn): TBaseConfigFn;\n};\n\nexport const defineBaseConfig: DefineBaseConfig = <const TBaseConfig extends BaseCallApiConfig>(\n\tbaseConfig: TBaseConfig\n) => {\n\treturn baseConfig;\n};\n\nexport const defineInstanceConfig = <const TInstanceConfig extends CallApiConfig>(\n\tconfig: TInstanceConfig\n) => {\n\treturn config as Writeable<typeof config, \"deep\">;\n};\n"],"mappings":";;;;AAKA,MAAM,uBAAuB,UAA2B;AACvD,QAAO,SAAS,MAAM,GAAG,QAAQ,KAAK,UAAU,MAAM;;AAKvD,MAAa,kBACZ,MACA,WACI;CACJ,MAAM,SAAS,kBAAkB,MAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC;AAEnE,KAAI,OAAO,OACV,OAAM,IAAI,gBAAgB;EACzB,YAAY;EACZ,QAAQ,OAAO;EACf,UAAU;EACV,CAAC;CAGH,MAAM,eAAe,IAAI,iBAAiB;AAE1C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,MAAiC,EAAE;AACnF,MAAI,SAAS,KAAM;AAEnB,MAAI,QAAQ,MAAM,EAAE;AAEnB,QAAK,MAAM,cAAc,MACxB,cAAa,OAAO,KAAK,oBAAoB,WAAW,CAAC;AAE1D;;AAGD,eAAa,IAAI,KAAK,oBAAoB,MAAM,CAAC;;AAGlD,QAAO;;AAGR,MAAa,iBACZ,GAAG,eACC;AAGJ,QAFqB,eAAe,GAAG,WAAW,CAE9B,UAAU;;AAG/B,MAAM,kBAAkB,UAAkC;AACzD,QAAO,OAAO,MAAM,GAAG,QAAQ,OAAO,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuC7C,MAAa,cACZ,MACA,WACI;CACJ,MAAM,WAAW,IAAI,UAAU;CAE/B,MAAM,SAAS,kBAAkB,MAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC;AAEnE,KAAI,OAAO,OACV,OAAM,IAAI,gBAAgB;EACzB,YAAY;EACZ,QAAQ,OAAO;EACf,UAAU;EACV,CAAC;AAGH,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,MAAiC,EAAE;AACnF,MAAI,QAAQ,MAAM,EAAE;AAEnB,QAAK,MAAM,cAAc,MACxB,UAAS,OAAO,KAAK,eAAe,WAAW,CAAC;AAEjD;;AAGD,MAAI,SAAS,MAAM,IAAI,CAAC,OAAO,MAAM,EAAE;AACtC,YAAS,IAAI,KAAK,KAAK,UAAU,MAAM,CAAC;AACxC;;AAGD,WAAS,IAAI,KAAK,eAAe,MAAM,CAAC;;AAGzC,QAAO;;;;;ACnHR,MAAa,gBAIZ,QACA,WACI;AACJ,QAAO;EACN,QAAQ,mBAAmB,OAAqC;EAChE,QAAQ,mBAAmB,OAAO;EAClC;;AAGF,MAAa,sBACZ,WACI;AACJ,QAAO;;AAGR,MAAa,oBACZ,eACI;AACJ,QAAO;;AAGR,MAAa,sBACZ,WACI;AACJ,QAAO;;AAGR,MAAa,gBAAqD,WAAoB;AACrF,QAAO;;AAcR,MAAa,oBACZ,eACI;AACJ,QAAO;;AAGR,MAAa,wBACZ,WACI;AACJ,QAAO"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/utils/external/body.ts","../../../src/utils/external/define.ts"],"sourcesContent":["import type { CallApiRequestOptions } from \"../../types/common\";\nimport { getValidatedValue, type CallApiSchemaType, type InferSchemaOutput } from \"../../validation\";\nimport { isArray, isBlob, isObject, isString } from \"../guards\";\nimport { ValidationError } from \"./error\";\n\nconst toStringOrStringify = (value: unknown): string => {\n\treturn isString(value) ? value : JSON.stringify(value);\n};\n\ntype BodyType = NonNullable<CallApiRequestOptions[\"body\"]>;\n\nexport const toSearchParams = <TSchema extends CallApiSchemaType<BodyType>>(\n\tdata: InferSchemaOutput<TSchema>,\n\tschema?: TSchema\n) => {\n\tconst result = getValidatedValue(data, schema, { variant: \"sync\" });\n\n\tif (result.issues) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: \"toQueryString\",\n\t\t\tissues: result.issues,\n\t\t\tresponse: null,\n\t\t});\n\t}\n\n\tconst searchParams = new URLSearchParams();\n\n\tfor (const [key, value] of Object.entries(result.value as Record<string, unknown>)) {\n\t\tif (value == null) continue;\n\n\t\tif (isArray(value)) {\n\t\t\t// eslint-disable-next-line max-depth -- Allow\n\t\t\tfor (const innerValue of value) {\n\t\t\t\tsearchParams.append(key, toStringOrStringify(innerValue));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tsearchParams.set(key, toStringOrStringify(value));\n\t}\n\n\treturn searchParams;\n};\n\nexport const toQueryString = <TSchema extends CallApiSchemaType<BodyType>>(\n\t...parameters: Parameters<typeof toSearchParams<TSchema>>\n) => {\n\tconst searchParams = toSearchParams(...parameters);\n\n\treturn searchParams.toString();\n};\n\nconst toBlobOrString = (value: unknown): string | Blob => {\n\treturn isBlob(value) ? value : String(value);\n};\n\n/**\n * @description Converts a plain object to FormData.\n *\n * Handles various data types:\n * - **Primitives** (string, number, boolean): Converted to strings\n * - **Blobs/Files**: Added directly to FormData\n * - **Arrays**: Each item is appended (allows multiple values for same key)\n * - **Objects**: JSON stringified before adding to FormData\n *\n * @example\n * ```ts\n * // Basic usage\n * const formData = toFormData({\n * name: \"John\",\n * age: 30,\n * active: true\n * });\n *\n * // With arrays\n * const formData = toFormData({\n * tags: [\"javascript\", \"typescript\"],\n * name: \"John\"\n * });\n *\n * // With files\n * const formData = toFormData({\n * avatar: fileBlob,\n * name: \"John\"\n * });\n *\n * // With nested objects (one level only)\n * const formData = toFormData({\n * user: { name: \"John\", age: 30 },\n * settings: { theme: \"dark\" }\n * });\n */\nexport const toFormData = <TSchema extends CallApiSchemaType<BodyType>>(\n\tdata: InferSchemaOutput<TSchema>,\n\tschema?: TSchema\n) => {\n\tconst formData = new FormData();\n\n\tconst result = getValidatedValue(data, schema, { variant: \"sync\" });\n\n\tif (result.issues) {\n\t\tthrow new ValidationError({\n\t\t\tissueCause: \"toFormData\",\n\t\t\tissues: result.issues,\n\t\t\tresponse: null,\n\t\t});\n\t}\n\n\tfor (const [key, value] of Object.entries(result.value as Record<string, unknown>)) {\n\t\tif (isArray(value)) {\n\t\t\t// eslint-disable-next-line max-depth -- Allow for now\n\t\t\tfor (const innerValue of value) {\n\t\t\t\tformData.append(key, toBlobOrString(innerValue));\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isObject(value) && !isBlob(value)) {\n\t\t\tformData.set(key, JSON.stringify(value));\n\t\t\tcontinue;\n\t\t}\n\n\t\tformData.set(key, toBlobOrString(value));\n\t}\n\n\treturn formData;\n};\n","import type { CallApiPlugin } from \"../../plugins\";\nimport type { BaseCallApiConfig, CallApiConfig } from \"../../types/common\";\nimport type { AnyFunction, Satisfies, Writeable } from \"../../types/type-helpers\";\nimport type {\n\tBaseCallApiSchemaAndConfig,\n\tBaseCallApiSchemaRoutes,\n\tCallApiSchema,\n\tCallApiSchemaConfig,\n} from \"../../validation\";\n\nexport const defineSchema = <\n\tconst TBaseSchemaRoutes extends BaseCallApiSchemaRoutes,\n\tconst TSchemaConfig extends CallApiSchemaConfig,\n>(\n\troutes: TBaseSchemaRoutes,\n\tconfig?: Satisfies<TSchemaConfig, CallApiSchemaConfig>\n) => {\n\treturn {\n\t\tconfig: defineSchemaConfig(config as NonNullable<typeof config>),\n\t\troutes: defineSchemaRoutes(routes),\n\t} satisfies BaseCallApiSchemaAndConfig;\n};\n\nexport const defineSchemaRoutes = <const TSchemaRoutes extends BaseCallApiSchemaRoutes>(\n\troutes: TSchemaRoutes\n) => {\n\treturn routes as Writeable<typeof routes, \"deep\">;\n};\n\nexport const defineMainSchema = <const TSchema extends CallApiSchema>(\n\tmainSchema: Satisfies<TSchema, CallApiSchema>\n) => {\n\treturn mainSchema as Writeable<typeof mainSchema, \"deep\">;\n};\n\nexport const defineSchemaConfig = <const TSchemaConfig extends CallApiSchemaConfig>(\n\tconfig: Satisfies<TSchemaConfig, CallApiSchemaConfig>\n) => {\n\treturn config as Writeable<typeof config, \"deep\">;\n};\n\nexport const definePlugin = <const TPlugin extends CallApiPlugin>(plugin: TPlugin) => {\n\treturn plugin as Writeable<typeof plugin, \"deep\">;\n};\n\ntype BaseConfigObject = Exclude<BaseCallApiConfig, AnyFunction>;\n\ntype BaseConfigFn = Extract<BaseCallApiConfig, AnyFunction>;\n\ntype DefineBaseConfig = {\n\t<const TBaseConfig extends BaseConfigObject>(\n\t\tbaseConfig: Satisfies<TBaseConfig, BaseConfigObject>\n\t): Writeable<typeof baseConfig, \"deep\">;\n\t<TBaseConfigFn extends BaseConfigFn>(\n\t\tbaseConfig: TBaseConfigFn\n\t): (...parameters: Parameters<TBaseConfigFn>) => Writeable<ReturnType<TBaseConfigFn>, \"deep\">;\n};\n\nexport const defineBaseConfig: DefineBaseConfig = <const TBaseConfig extends BaseCallApiConfig>(\n\tbaseConfig: TBaseConfig\n) => {\n\treturn baseConfig;\n};\n\nexport const defineInstanceConfig = <const TInstanceConfig extends CallApiConfig>(\n\tconfig: TInstanceConfig\n) => {\n\treturn config as Writeable<typeof config, \"deep\">;\n};\n"],"mappings":";;;;AAKA,MAAM,uBAAuB,UAA2B;AACvD,QAAO,SAAS,MAAM,GAAG,QAAQ,KAAK,UAAU,MAAM;;AAKvD,MAAa,kBACZ,MACA,WACI;CACJ,MAAM,SAAS,kBAAkB,MAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC;AAEnE,KAAI,OAAO,OACV,OAAM,IAAI,gBAAgB;EACzB,YAAY;EACZ,QAAQ,OAAO;EACf,UAAU;EACV,CAAC;CAGH,MAAM,eAAe,IAAI,iBAAiB;AAE1C,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,MAAiC,EAAE;AACnF,MAAI,SAAS,KAAM;AAEnB,MAAI,QAAQ,MAAM,EAAE;AAEnB,QAAK,MAAM,cAAc,MACxB,cAAa,OAAO,KAAK,oBAAoB,WAAW,CAAC;AAE1D;;AAGD,eAAa,IAAI,KAAK,oBAAoB,MAAM,CAAC;;AAGlD,QAAO;;AAGR,MAAa,iBACZ,GAAG,eACC;AAGJ,QAFqB,eAAe,GAAG,WAAW,CAE9B,UAAU;;AAG/B,MAAM,kBAAkB,UAAkC;AACzD,QAAO,OAAO,MAAM,GAAG,QAAQ,OAAO,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuC7C,MAAa,cACZ,MACA,WACI;CACJ,MAAM,WAAW,IAAI,UAAU;CAE/B,MAAM,SAAS,kBAAkB,MAAM,QAAQ,EAAE,SAAS,QAAQ,CAAC;AAEnE,KAAI,OAAO,OACV,OAAM,IAAI,gBAAgB;EACzB,YAAY;EACZ,QAAQ,OAAO;EACf,UAAU;EACV,CAAC;AAGH,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,MAAiC,EAAE;AACnF,MAAI,QAAQ,MAAM,EAAE;AAEnB,QAAK,MAAM,cAAc,MACxB,UAAS,OAAO,KAAK,eAAe,WAAW,CAAC;AAEjD;;AAGD,MAAI,SAAS,MAAM,IAAI,CAAC,OAAO,MAAM,EAAE;AACtC,YAAS,IAAI,KAAK,KAAK,UAAU,MAAM,CAAC;AACxC;;AAGD,WAAS,IAAI,KAAK,eAAe,MAAM,CAAC;;AAGzC,QAAO;;;;;ACnHR,MAAa,gBAIZ,QACA,WACI;AACJ,QAAO;EACN,QAAQ,mBAAmB,OAAqC;EAChE,QAAQ,mBAAmB,OAAO;EAClC;;AAGF,MAAa,sBACZ,WACI;AACJ,QAAO;;AAGR,MAAa,oBACZ,eACI;AACJ,QAAO;;AAGR,MAAa,sBACZ,WACI;AACJ,QAAO;;AAGR,MAAa,gBAAqD,WAAoB;AACrF,QAAO;;AAgBR,MAAa,oBACZ,eACI;AACJ,QAAO;;AAGR,MAAa,wBACZ,WACI;AACJ,QAAO"}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@zayne-labs/callapi",
3
3
  "type": "module",
4
- "version": "1.11.43",
4
+ "version": "1.11.44",
5
5
  "description": "A lightweight wrapper over fetch with quality of life improvements like built-in request cancellation, retries, interceptors and more",
6
6
  "author": "Ryan Zayne",
7
7
  "license": "MIT",
8
- "homepage": "https://github.com/zayne-labs/callapi#readme",
8
+ "homepage": "https://zayne-labs-callapi.vercel.app",
9
9
  "repository": {
10
10
  "type": "git",
11
- "url": "git+https://github.com/zayne-labs/callapi.git"
11
+ "url": "git+https://github.com/zayne-labs/callapi.git",
12
+ "directory": "packages/callapi"
12
13
  },
13
14
  "bugs": {
14
15
  "url": "https://github.com/zayne-labs/callapi/issues"
@@ -39,19 +40,19 @@
39
40
  "@size-limit/esbuild-why": "12.0.0",
40
41
  "@size-limit/preset-small-lib": "12.0.0",
41
42
  "@total-typescript/ts-reset": "0.6.1",
42
- "@vitest/browser": "4.0.16",
43
- "@vitest/browser-playwright": "4.0.16",
44
- "@vitest/coverage-v8": "4.0.16",
45
- "@zayne-labs/prettier-config": "^0.11.16",
46
- "@zayne-labs/tsconfig": "0.11.16",
43
+ "@vitest/browser": "4.0.17",
44
+ "@vitest/browser-playwright": "4.0.17",
45
+ "@vitest/coverage-v8": "4.0.17",
46
+ "@zayne-labs/prettier-config": "^0.11.21",
47
+ "@zayne-labs/tsconfig": "0.11.21",
47
48
  "concurrently": "^9.2.1",
48
49
  "cross-env": "^10.1.0",
49
50
  "playwright": "^1.57.0",
50
- "publint": "^0.3.16",
51
+ "publint": "^0.3.17",
51
52
  "size-limit": "12.0.0",
52
- "tsdown": "0.19.0-beta.3",
53
+ "tsdown": "0.20.0-beta.4",
53
54
  "typescript": "5.9.3",
54
- "vitest": "^4.0.16",
55
+ "vitest": "^4.0.17",
55
56
  "zod": "^4.3.5"
56
57
  },
57
58
  "publishConfig": {