@tahanabavi/typefetch 1.5.7 → 1.6.0

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 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/middlewares/logging.ts","../src/middlewares/retry.ts","../src/middlewares/auth.ts","../src/middlewares/cache.ts","../src/middlewares/encryption.ts","../src/utils/make-request-schema.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n Contracts,\n EndpointDef,\n EndpointDefZ,\n Middleware,\n ErrorLike,\n EndpointMethods,\n TokenProvider,\n RequestOptions,\n MiddlewareContext,\n} from \"./types\";\n\nexport class RichError extends Error implements ErrorLike {\n status?: number;\n code?: string;\n title?: string;\n detail?: string;\n errors?: Record<string, string[]>;\n\n constructor(error: Partial<ErrorLike> & { message: string }) {\n super(error.message);\n Object.assign(this, error);\n }\n}\n\ntype ParsedRequestParts = {\n path?: Record<string, any>;\n query?: Record<string, any>;\n body?: any;\n headers: Record<string, string>;\n isStructured: boolean;\n};\n\nconst REQUEST_PART_KEYS = new Set([\n \"path\",\n \"query\",\n \"body\",\n \"headers\",\n \"header\",\n]);\n\nexport class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {\n private middlewares: Array<{ fn: Middleware; options?: any }> = [];\n private errorHandler?: (error: E) => void;\n private responseTransform: (data: any) => any = (d) => d;\n private useMockData = false;\n private mockDelay = { min: 100, max: 1000 };\n private responseWrapper?: (successResponse: z.ZodTypeAny) => z.ZodTypeAny;\n private tokenProvider?: TokenProvider;\n\n private retryConfig?: {\n maxRetries: number;\n backoff: \"fixed\" | \"linear\" | \"exponential\";\n retryCondition?: (error: RichError, attempt: number) => boolean;\n };\n\n private _modules!: { [M in keyof C]: EndpointMethods<C[M]> };\n\n constructor(\n private config: {\n baseUrl: string;\n token?: string;\n tokenProvider?: TokenProvider;\n useMockData?: boolean;\n mockDelay?: { min: number; max: number };\n },\n private contracts: C,\n ) {\n this.useMockData = config.useMockData || false;\n this.mockDelay = config.mockDelay || { min: 100, max: 1000 };\n this.tokenProvider = config.tokenProvider;\n }\n\n init() {\n const modules = {} as { [M in keyof C]: EndpointMethods<C[M]> };\n\n for (const moduleName in this.contracts) {\n const module = this.contracts[moduleName];\n (modules as any)[moduleName] = {} as EndpointMethods<typeof module>;\n\n for (const endpointName in module) {\n const endpoint = module[endpointName] as EndpointDefZ;\n\n (modules as any)[moduleName][endpointName] = (\n input: any,\n options?: RequestOptions,\n ) => this.request(endpoint as any, input, options);\n }\n }\n\n this._modules = modules;\n }\n\n get modules() {\n return this._modules;\n }\n\n use<T>(middleware: Middleware<any, any, T>, options?: T) {\n this.middlewares.push({ fn: middleware, options });\n }\n\n onError(handler: (error: E) => void) {\n this.errorHandler = handler;\n }\n\n useResponseTransform(fn: (data: any) => any) {\n this.responseTransform = fn;\n }\n\n setRetryConfig(config: ApiClient<C>[\"retryConfig\"]) {\n this.retryConfig = config;\n }\n\n setTokenProvider(provider: TokenProvider) {\n this.tokenProvider = provider;\n }\n\n setMockMode(enabled: boolean, delay?: { min: number; max: number }) {\n this.useMockData = enabled;\n if (delay) this.mockDelay = delay;\n }\n\n setResponseWrapper(wrapper: (successResponse: z.ZodTypeAny) => z.ZodTypeAny) {\n this.responseWrapper = wrapper;\n }\n\n async getCurrentToken(): Promise<string | undefined> {\n if (this.tokenProvider) return await this.tokenProvider();\n return this.config.token;\n }\n\n private async request<TReq extends z.ZodTypeAny, TRes extends z.ZodTypeAny>(\n endpoint: EndpointDef<TReq, TRes>,\n input: z.infer<TReq>,\n options?: RequestOptions,\n ): Promise<z.infer<TRes>> {\n const parsedInput = endpoint.request.parse(input);\n\n if (this.useMockData && endpoint.mockData) {\n return this.handleMockRequest(endpoint);\n }\n\n const built = this.buildUrlAndBody(endpoint as EndpointDefZ, parsedInput);\n\n return this.performRequestLogic(\n endpoint,\n parsedInput,\n built.url,\n built.body,\n built.headers,\n built.parts,\n options,\n );\n }\n\n private async performRequestLogic<\n TReq extends z.ZodTypeAny,\n TRes extends z.ZodTypeAny,\n >(\n endpoint: EndpointDef<TReq, TRes>,\n parsedInput: z.infer<TReq>,\n url: string,\n body: BodyInit | undefined,\n requestHeaders: Record<string, string>,\n requestParts: ParsedRequestParts,\n options?: RequestOptions,\n ): Promise<z.infer<TRes>> {\n const headers: Record<string, string> = {};\n\n if (endpoint.bodyType !== \"form-data\") {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const endpointHeaders =\n typeof endpoint.headers === \"function\"\n ? endpoint.headers(parsedInput)\n : endpoint.headers;\n\n Object.assign(\n headers,\n this.normalizeHeaders(endpointHeaders),\n requestHeaders,\n );\n\n if (endpoint.auth) {\n const token = await this.getCurrentToken();\n\n if (!token) {\n const error = this.createError({\n message: `Missing token for ${endpoint.path}`,\n status: 401,\n code: \"NO_TOKEN\",\n });\n this.errorHandler?.(error as any);\n throw error;\n }\n\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const ctx = {\n url,\n init: { method: endpoint.method, headers, body } as RequestInit,\n endpoint: endpoint as never,\n request: {\n ...requestParts,\n rawInput: parsedInput,\n },\n } satisfies MiddlewareContext;\n\n let controller: AbortController | undefined;\n let timeoutId: any;\n\n if (options?.timeout) {\n controller = new AbortController();\n timeoutId = setTimeout(() => controller!.abort(), options.timeout);\n }\n\n if (options?.signal || controller) {\n ctx.init.signal = options?.signal || controller?.signal;\n }\n\n const runner = this.middlewares.reduceRight(\n (next, mw) => () => mw.fn(ctx, next, mw.options),\n () => fetch(ctx.url, ctx.init),\n );\n\n const execute = async () => {\n const res = await runner();\n const json = await res.json();\n let responseData = json;\n\n if (this.responseWrapper) {\n const wrappedSchema = this.responseWrapper(endpoint.response);\n const parsedWrapped = wrappedSchema.parse(json) as any;\n\n if (parsedWrapped.success === false) {\n const error = this.createError({\n message:\n parsedWrapped.message || parsedWrapped.error || \"Request failed\",\n status: parsedWrapped.code || res.status,\n code: parsedWrapped.code\n ? `API_ERROR_${parsedWrapped.code}`\n : \"API_ERROR\",\n });\n\n this.errorHandler?.(error as any);\n throw error;\n }\n\n responseData = parsedWrapped.data;\n }\n\n if (!res.ok) {\n const error = this.createError({\n message: json.message || res.statusText,\n status: res.status,\n code: json.code,\n title: json.title,\n detail: json.detail,\n errors: json.errors,\n });\n this.errorHandler?.(error as any);\n throw error;\n }\n\n const parsed = endpoint.response.parse(responseData);\n return this.responseTransform(parsed);\n };\n\n try {\n const result = await this.executeWithRetry(execute);\n if (timeoutId) clearTimeout(timeoutId);\n return result;\n } catch (err: any) {\n if (timeoutId) clearTimeout(timeoutId);\n const error = this.normalizeError(err);\n this.errorHandler?.(error as any);\n throw error;\n }\n }\n\n private async executeWithRetry(fn: () => Promise<any>): Promise<any> {\n if (!this.retryConfig) return fn();\n\n const { maxRetries, backoff, retryCondition } = this.retryConfig;\n let attempt = 0;\n\n while (true) {\n try {\n return await fn();\n } catch (err: any) {\n attempt++;\n const error = this.normalizeError(err);\n\n const shouldRetry =\n attempt <= maxRetries &&\n (retryCondition?.(error, attempt) ??\n (error.status !== undefined && error.status >= 500));\n\n if (!shouldRetry) throw error;\n\n const delay = this.getBackoffDelay(backoff, attempt);\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n\n private getBackoffDelay(\n type: \"fixed\" | \"linear\" | \"exponential\",\n attempt: number,\n ) {\n const base = 300;\n switch (type) {\n case \"fixed\":\n return base;\n case \"linear\":\n return base * attempt;\n case \"exponential\":\n return base * Math.pow(2, attempt - 1);\n }\n }\n\n private buildUrlAndBody(endpoint: EndpointDefZ, input: any) {\n const parts = this.extractRequestParts(input);\n\n let url = this.config.baseUrl + endpoint.path;\n url = this.applyPathParams(url, parts.path);\n url = this.appendQueryParams(url, parts.query);\n\n let body: BodyInit | undefined;\n const payload = parts.isStructured ? parts.body : input;\n\n if (endpoint.method !== \"GET\" && payload !== undefined) {\n if (endpoint.bodyType === \"form-data\") {\n if (typeof FormData !== \"undefined\" && payload instanceof FormData) {\n body = payload;\n } else {\n const form = new FormData();\n\n if (this.isObjectRecord(payload)) {\n for (const [key, value] of Object.entries(payload)) {\n this.appendFormValue(form, key, value);\n }\n } else if (payload != null) {\n form.append(\"value\", String(payload));\n }\n\n body = form;\n }\n } else {\n body = JSON.stringify(payload);\n }\n }\n\n return { url, body, headers: parts.headers, parts };\n }\n\n private extractRequestParts(input: any): ParsedRequestParts {\n if (this.isStructuredRequestInput(input)) {\n return {\n path: this.isObjectRecord(input.path) ? input.path : undefined,\n query: this.isObjectRecord(input.query) ? input.query : undefined,\n body: input.body,\n headers: this.normalizeHeaders(input.headers ?? input.header),\n isStructured: true,\n };\n }\n\n return {\n body: input,\n headers: {},\n isStructured: false,\n };\n }\n\n private isStructuredRequestInput(\n input: unknown,\n ): input is Record<string, any> {\n if (!this.isObjectRecord(input)) return false;\n\n const keys = Object.keys(input);\n if (keys.length === 0) return false;\n\n return (\n keys.some((key) => REQUEST_PART_KEYS.has(key)) &&\n keys.every((key) => REQUEST_PART_KEYS.has(key))\n );\n }\n\n private isObjectRecord(value: unknown): value is Record<string, any> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n }\n\n private applyPathParams(\n fullUrl: string,\n pathParams?: Record<string, any>,\n ): string {\n const url = new URL(fullUrl);\n\n const replacedPathname = url.pathname.replace(\n /:([A-Za-z0-9_]+)/g,\n (_, key: string) => {\n const value = pathParams?.[key];\n\n if (value === undefined || value === null) {\n throw this.createError({\n message: `Missing path param \"${key}\"`,\n code: \"MISSING_PATH_PARAM\",\n });\n }\n\n return encodeURIComponent(String(value));\n },\n );\n\n return `${url.origin}${replacedPathname}${url.search}${url.hash}`;\n }\n\n private appendQueryParams(url: string, query?: Record<string, any>): string {\n if (!query) return url;\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n this.appendQueryValue(params, key, value);\n }\n\n const queryString = params.toString();\n if (!queryString) return url;\n\n return `${url}${url.includes(\"?\") ? \"&\" : \"?\"}${queryString}`;\n }\n\n private appendQueryValue(params: URLSearchParams, key: string, value: any) {\n if (value === undefined || value === null) return;\n\n if (Array.isArray(value)) {\n for (const item of value) this.appendQueryValue(params, key, item);\n return;\n }\n\n if (value instanceof Date) {\n params.append(key, value.toISOString());\n return;\n }\n\n if (typeof value === \"object\") {\n params.append(key, JSON.stringify(value));\n return;\n }\n\n params.append(key, String(value));\n }\n\n private appendFormValue(form: FormData, key: string, value: any) {\n if (value === undefined || value === null) return;\n\n if (Array.isArray(value)) {\n for (const item of value) this.appendFormValue(form, key, item);\n return;\n }\n\n if (value instanceof Date) {\n form.append(key, value.toISOString());\n return;\n }\n\n const isBlob = typeof Blob !== \"undefined\" && value instanceof Blob;\n\n if (typeof value === \"object\" && !isBlob) {\n form.append(key, JSON.stringify(value));\n return;\n }\n\n form.append(key, value as any);\n }\n\n private normalizeHeaders(headers: unknown): Record<string, string> {\n if (!this.isObjectRecord(headers)) return {};\n\n const normalized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined || value === null) continue;\n normalized[key] = String(value);\n }\n\n return normalized;\n }\n\n private createError(error: Partial<RichError> & { message: string }) {\n return new RichError(error);\n }\n\n private normalizeError(err: any) {\n if (err instanceof RichError) return err;\n if (err instanceof z.ZodError) {\n return this.createError({\n message: `Validation error: ${err.issues.map((e) => e.message).join(\", \")}`,\n code: \"VALIDATION_ERROR\",\n });\n }\n return this.createError({ message: err.message || \"Unknown error\" });\n }\n\n private async handleMockRequest(endpoint: any) {\n const delay =\n Math.floor(\n Math.random() * (this.mockDelay.max - this.mockDelay.min + 1),\n ) + this.mockDelay.min;\n\n await new Promise((r) => setTimeout(r, delay));\n\n const data =\n typeof endpoint.mockData === \"function\"\n ? endpoint.mockData()\n : endpoint.mockData;\n\n return this.responseTransform(endpoint.response.parse(data));\n }\n}\n","import { Middleware } from \"@/types\";\nimport z from \"zod\";\n\nexport type LoggingOptions = {\n logRequest?: boolean;\n logResponse?: boolean;\n debug?: boolean;\n};\n\nexport const loggingMiddleware: Middleware<\n z.ZodTypeAny,\n z.ZodTypeAny,\n LoggingOptions\n> = async (ctx, next, options) => {\n const { logRequest = true, logResponse = true, debug = true } = options || {};\n\n if (debug && logRequest) console.log(\"➡️ Request:\", ctx.url, ctx.init);\n\n const res = await next();\n\n if (debug && logResponse) console.log(\"⬅️ Response:\", res.status);\n\n return res;\n};\n","import { Middleware } from \"@/types\";\n\n\nexport type RetryOptions = {\n maxRetries?: number;\n delay?: number; // ms\n};\n\nexport const retryMiddleware = (options?: RetryOptions): Middleware => {\n const { maxRetries = 3, delay = 500 } = options || {};\n\n const middleware: Middleware = async (ctx, next) => {\n let attempt = 0;\n while (true) {\n try {\n return await next();\n } catch (err) {\n if (attempt >= maxRetries) throw err;\n attempt++;\n await new Promise((r) => setTimeout(r, delay * 2 ** attempt));\n }\n }\n };\n\n return middleware;\n};\n","import { Middleware } from \"@/types\";\nimport z from \"zod\";\n\n/**\n * TokenManagementOptions\n * ======================\n * Configuration structure for supplying credentials to the authentication layer.\n *\n * @property refreshToken A required asynchronous function responsible for\n * obtaining a current, valid access token string. This allows\n * for token fetching from storage or re-issuance upon expiry.\n */\nexport type AuthOptions = {\n refreshToken?: () => Promise<string>;\n};\n\n/**\n * AuthenticationInjectorMiddleware\n * ==================================\n * This middleware operates early in the request pipeline to ensure every\n * outgoing request is properly authorized by prepending an Authorization header.\n *\n * Core Logic:\n * -----------\n * 1. It checks if an explicit `refreshToken` supplier was configured in its options.\n * 2. If present, it synchronously calls this supplier to obtain the latest token.\n * 3. The resulting token is formatted as a standard 'Bearer' token and merged\n * into the request's `init.headers`.\n * 4. The request context (`ctx`) is then passed downstream.\n *\n * Note on Error Handling:\n * -----------------------\n * Any failure during the token retrieval process (e.g., if `refreshToken` throws)\n * results in the error being caught, and the request proceeds **without** an\n * Authorization header. This design defers failure response handling to\n * subsequent middleware or the final network fetcher.\n *\n * @param ctx The current request context object, including mutable `init` properties.\n * @param next The function to execute the rest of the middleware chain.\n * @param options The specific configuration passed to this middleware instance.\n *\n * @returns The final `Response` object after the network call completes.\n *\n * @example\n * // Assuming token retrieval logic is defined elsewhere\n * const tokenSupplier = () => fetchTokenFromSecureStorage();\n *\n * client.addInterceptor(\n * authMiddleware({ refreshToken: tokenSupplier })\n * );\n */\nexport const authMiddleware: Middleware<\n z.ZodTypeAny,\n z.ZodTypeAny,\n AuthOptions\n> = async (ctx, next, options) => {\n // Step 1 & 2: Check for and execute the token provider\n if (options?.refreshToken) {\n try {\n const newToken = await options.refreshToken();\n\n // Step 3: Mutate the context's request initialization object\n ctx.init.headers = {\n ...ctx.init.headers, // Preserve any headers set by prior middleware\n Authorization: `Bearer ${newToken}`,\n };\n } catch (error) {\n // Step 4: Fail silently for header injection purposes\n // The request will proceed unauthenticated if the token failed to load\n console.warn(\n \"Authentication token refresh failed, proceeding without authorization header.\",\n error,\n );\n }\n }\n\n // Step 5: Pass control to the next step in the request pipeline\n return next();\n};\n","import { MiddlewareContext, MiddlewareNext } from \"@/types\";\n\n/**\n * CacheOptions\n * ============\n * Options for configuring the cache middleware.\n * - `ttl` (Time To Live): Duration (in milliseconds) to keep cached GET responses.\n * After this time, cached data expires and a fresh network call is performed.\n */\nexport type CacheOptions = { ttl?: number };\n\n/**\n * cacheMiddleware\n * ===============\n * A generic caching middleware for GET requests in the ApiClient.\n * It stores successful responses in memory based on URL and method,\n * returning cached data for subsequent identical requests until the TTL expires.\n *\n * Purpose:\n * --------\n * - Reduces redundant network calls\n * - Improves performance for frequently fetched resources\n * - Useful for lightweight front-end caching (not suitable for sensitive data)\n *\n * Behavior:\n * ---------\n * 1. Only applies to `GET` requests; all other HTTP methods bypass caching.\n * 2. Caches the parsed JSON response in a simple in-memory Map.\n * 3. On subsequent requests:\n * - If the cache entry exists and hasn’t expired, returns a synthetic\n * `Response` object built from cached JSON.\n * - Otherwise performs the network call and refreshes the cache.\n *\n * @param options - Optional cache configuration (TTL in ms)\n *\n * @returns Middleware function compatible with the ApiClient pipeline.\n *\n * @example\n * client.use(\n * cacheMiddleware({ ttl: 120000 }) // cache GET results for 2 minutes\n * );\n *\n * @note Each middleware instance maintains its own internal cache\n * and is memory-scoped (not persistent between reloads).\n */\nexport const cacheMiddleware = (options: CacheOptions = {}) => {\n // Default TTL = 60 seconds, unless overridden\n const { ttl = 60000 } = options;\n\n /**\n * Internal cache store.\n * Keys are composed as `\"METHOD:URL\"`.\n * Values include cached response data and expiration timestamp.\n */\n const cache = new Map<string, { data: any; expires: number }>();\n\n // Return an asynchronous middleware function conforming to the standard signature\n return async (ctx: MiddlewareContext, next: MiddlewareNext) => {\n // Caching only applies to GET requests\n if (ctx.init.method === \"GET\") {\n const key = `${ctx.init.method}:${ctx.url}`;\n const cached = cache.get(key);\n const now = Date.now();\n\n // Check if valid cached response exists and hasn't expired\n if (cached && cached.expires > now) {\n // Return a new synthetic Response containing cached data\n return new Response(JSON.stringify(cached.data), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n // Perform the actual network request via the next middleware/fetcher\n const res = await next();\n\n // Attempt to read JSON data from the response (clone avoids stream lock)\n const data = await res\n .clone()\n .json()\n .catch(() => null);\n\n // Store parsed data with expiration if successfully obtained\n if (data) {\n cache.set(key, { data, expires: now + ttl });\n }\n\n // Return original response to caller\n return res;\n }\n\n // For all non‑GET requests, just forward the call with no caching logic\n return next();\n };\n};\n","import type { Middleware, DeepEncryptionMap, EncryptionMethod } from \"@/types\";\nimport CryptoJS from \"crypto-js\";\nimport forge from \"node-forge\";\nimport { z } from \"zod\";\n\ntype SymmetricKeyMaterial = {\n type: \"symmetric\";\n key: string;\n};\n\ntype RSAKeyMaterial = {\n type: \"rsa\";\n publicKey: string;\n privateKey: string;\n};\n\ntype KeyMaterial = SymmetricKeyMaterial | RSAKeyMaterial;\n\ntype CustomHandlers = {\n encrypt: (value: string, key: KeyMaterial) => string | Promise<string>;\n decrypt: (value: string, key: KeyMaterial) => string | Promise<string>;\n};\n\nexport interface EncryptionOptions {\n keyProvider: () => KeyMaterial | Promise<KeyMaterial>;\n customHandlers?: CustomHandlers;\n\n /**\n * true = throw when encryption/decryption fails, which avoids leaking plaintext.\n * false = log and continue/fallback to the original response.\n * Default: true\n */\n failClosed?: boolean;\n}\n\nfunction safeJsonParse(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === \"[object Object]\"\n );\n}\n\nfunction hasKey(value: unknown, key: string): value is Record<string, unknown> {\n return (\n isPlainObject(value) && Object.prototype.hasOwnProperty.call(value, key)\n );\n}\n\nfunction toMiddlewareError(message: string, error: unknown): Error {\n const err = new Error(\n `${message}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n (err as any).cause = error;\n return err;\n}\n\nfunction encryptWithAES(value: string, key: string): string {\n return CryptoJS.AES.encrypt(value, key).toString();\n}\n\nfunction decryptWithAES(value: string, key: string): string {\n const bytes = CryptoJS.AES.decrypt(value, key);\n return bytes.toString(CryptoJS.enc.Utf8);\n}\n\nfunction encryptWithDES(value: string, key: string): string {\n return CryptoJS.DES.encrypt(value, key).toString();\n}\n\nfunction decryptWithDES(value: string, key: string): string {\n const bytes = CryptoJS.DES.decrypt(value, key);\n return bytes.toString(CryptoJS.enc.Utf8);\n}\n\nfunction encodeWithBase64(value: string): string {\n return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(value));\n}\n\nfunction decodeWithBase64(value: string): string {\n return CryptoJS.enc.Base64.parse(value).toString(CryptoJS.enc.Utf8);\n}\n\nfunction encryptWithRSA(value: string, publicKey: string): string {\n const publicKeyObject = forge.pki.publicKeyFromPem(publicKey);\n const encrypted = publicKeyObject.encrypt(\n forge.util.encodeUtf8(value),\n \"RSA-OAEP\",\n );\n return forge.util.encode64(encrypted);\n}\n\nfunction decryptWithRSA(value: string, privateKey: string): string {\n const privateKeyObject = forge.pki.privateKeyFromPem(privateKey);\n const decrypted = privateKeyObject.decrypt(\n forge.util.decode64(value),\n \"RSA-OAEP\",\n );\n return forge.util.decodeUtf8(decrypted);\n}\n\nasync function encryptValue(\n value: string,\n method: EncryptionMethod,\n keyMaterial: KeyMaterial,\n customHandlers?: CustomHandlers,\n): Promise<string> {\n switch (method) {\n case \"AES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"AES encryption requires symmetric key material.\");\n }\n return encryptWithAES(value, keyMaterial.key);\n }\n\n case \"DES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"DES encryption requires symmetric key material.\");\n }\n return encryptWithDES(value, keyMaterial.key);\n }\n\n case \"Base64\": {\n return encodeWithBase64(value);\n }\n\n case \"RSA\": {\n if (keyMaterial.type !== \"rsa\") {\n throw new Error(\"RSA encryption requires RSA key material.\");\n }\n return encryptWithRSA(value, keyMaterial.publicKey);\n }\n\n case \"Custom\": {\n if (!customHandlers) {\n throw new Error(\"Custom encryption requires custom handlers.\");\n }\n return await customHandlers.encrypt(value, keyMaterial);\n }\n\n default: {\n const exhaustiveCheck: never = method;\n throw new Error(`Unsupported encryption method: ${exhaustiveCheck}`);\n }\n }\n}\n\nasync function decryptValue(\n value: string,\n method: EncryptionMethod,\n keyMaterial: KeyMaterial,\n customHandlers?: CustomHandlers,\n): Promise<string> {\n switch (method) {\n case \"AES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"AES decryption requires symmetric key material.\");\n }\n return decryptWithAES(value, keyMaterial.key);\n }\n\n case \"DES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"DES decryption requires symmetric key material.\");\n }\n return decryptWithDES(value, keyMaterial.key);\n }\n\n case \"Base64\": {\n return decodeWithBase64(value);\n }\n\n case \"RSA\": {\n if (keyMaterial.type !== \"rsa\") {\n throw new Error(\"RSA decryption requires RSA key material.\");\n }\n return decryptWithRSA(value, keyMaterial.privateKey);\n }\n\n case \"Custom\": {\n if (!customHandlers) {\n throw new Error(\"Custom decryption requires custom handlers.\");\n }\n return await customHandlers.decrypt(value, keyMaterial);\n }\n\n default: {\n const exhaustiveCheck: never = method;\n throw new Error(`Unsupported decryption method: ${exhaustiveCheck}`);\n }\n }\n}\n\nexport async function processDeep<T = unknown>(\n data: unknown,\n map: DeepEncryptionMap | null | undefined,\n defaultMethod: EncryptionMethod,\n transform: (value: unknown, method: EncryptionMethod) => Promise<unknown>,\n): Promise<T> {\n if (data == null || map == null) return data as T;\n\n if (typeof map === \"string\") return (await transform(data, map)) as T;\n\n if (typeof map === \"boolean\") {\n return (map ? await transform(data, defaultMethod) : data) as T;\n }\n\n if (Array.isArray(data)) {\n if (!Array.isArray(map)) {\n return Promise.all(\n data.map((item) => processDeep(item, map, defaultMethod, transform)),\n ) as Promise<T>;\n }\n\n return Promise.all(\n data.map((item, idx) =>\n processDeep(item, map[idx] ?? map[0], defaultMethod, transform),\n ),\n ) as Promise<T>;\n }\n\n if (isPlainObject(data) && isPlainObject(map)) {\n const result: Record<string, unknown> = { ...data };\n\n for (const key of Object.keys(map)) {\n const childMap = (map as Record<string, DeepEncryptionMap>)[key];\n if (childMap == null) continue;\n\n const currentVal = result[key];\n if (currentVal !== undefined) {\n result[key] = await processDeep(\n currentVal,\n childMap,\n defaultMethod,\n transform,\n );\n }\n }\n\n return result as T;\n }\n\n return data as T;\n}\n\nfunction getRequestBodyMap(map: DeepEncryptionMap): DeepEncryptionMap {\n // Supports both styles:\n // encryption.request: { password: true }\n // encryption.request: { body: { password: true } }\n if (hasKey(map, \"body\")) {\n return map.body as DeepEncryptionMap;\n }\n\n return map;\n}\n\nexport const encryptionMiddleware: Middleware<\n z.ZodTypeAny,\n z.ZodTypeAny,\n EncryptionOptions\n> = async (ctx, next, options) => {\n if (!options) {\n throw new Error(\"Encryption middleware options were not provided.\");\n }\n\n const { keyProvider, customHandlers } = options;\n const failClosed = options.failClosed ?? true;\n const encryption = ctx.endpoint.encryption;\n\n if (!encryption || (!encryption.request && !encryption.response)) {\n return next();\n }\n\n const requestMethod: EncryptionMethod =\n typeof encryption.method === \"string\"\n ? encryption.method\n : (encryption.method?.request ?? \"AES\");\n\n const responseMethod: EncryptionMethod =\n typeof encryption.method === \"string\"\n ? encryption.method\n : (encryption.method?.response ?? \"AES\");\n\n const keyMaterial = await keyProvider();\n\n if (\n encryption.request &&\n typeof ctx.init.body === \"string\" &&\n ctx.init.body.length > 0\n ) {\n try {\n const parsedBody = JSON.parse(ctx.init.body);\n const bodyMap = getRequestBodyMap(encryption.request);\n\n const encryptedBody = await processDeep(\n parsedBody,\n bodyMap,\n requestMethod,\n async (value, method) => {\n const serialized =\n typeof value === \"string\" ? value : JSON.stringify(value);\n\n return encryptValue(serialized, method, keyMaterial, customHandlers);\n },\n );\n\n ctx.init.body = JSON.stringify(encryptedBody);\n\n if (ctx.request) {\n ctx.request.body = encryptedBody;\n }\n } catch (error) {\n if (failClosed) {\n throw toMiddlewareError(\n \"Encryption middleware request encryption failed\",\n error,\n );\n }\n\n console.error(\"Encryption middleware request encryption failed.\", error);\n }\n }\n\n const response = await next();\n\n if (!encryption.response) {\n return response;\n }\n\n try {\n const text = await response.clone().text();\n if (!text) return response;\n\n const parsedResponse = JSON.parse(text);\n\n const decryptedPayload = await processDeep(\n parsedResponse,\n encryption.response,\n responseMethod,\n async (value, method) => {\n if (typeof value !== \"string\") return value;\n\n const decrypted = await decryptValue(\n value,\n method,\n keyMaterial,\n customHandlers,\n );\n\n return safeJsonParse(decrypted);\n },\n );\n\n return new Response(JSON.stringify(decryptedPayload), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n } catch (error) {\n if (failClosed) {\n throw toMiddlewareError(\n \"Encryption middleware response decryption failed\",\n error,\n );\n }\n\n console.error(\"Encryption middleware response decryption failed.\", error);\n return response;\n }\n};\n","import { z } from \"zod\";\n\ntype OptionalUndefinedBody<T extends z.ZodTypeAny> = T extends z.ZodUndefined\n ? z.ZodOptional<T>\n : T;\n\nexport const makeRequestSchema =\n <\n TPath extends z.ZodRawShape = {},\n TQuery extends z.ZodRawShape = {},\n TBody extends z.ZodTypeAny = z.ZodUndefined,\n THeaders extends z.ZodTypeAny = z.ZodOptional<\n z.ZodRecord<z.ZodString, z.ZodString>\n >,\n >() =>\n (\n defs: {\n path?: z.ZodObject<TPath>;\n query?: z.ZodObject<TQuery>;\n body?: TBody;\n headers?: THeaders;\n } = {},\n ) => {\n const pathSchema = (defs.path ??\n z.object({})) as unknown as z.ZodObject<TPath>;\n\n const querySchema = (defs.query ??\n z.object({})) as unknown as z.ZodObject<TQuery>;\n\n const rawBodySchema = (defs.body ?? z.undefined()) as TBody;\n\n const bodySchema = (\n defs.body ? rawBodySchema : rawBodySchema.optional()\n ) as OptionalUndefinedBody<TBody>;\n\n const headersSchema = (defs.headers ??\n z.record(z.string(), z.string()).optional()) as THeaders;\n\n return z.object({\n path: pathSchema.optional(),\n query: querySchema.optional(),\n body: bodySchema,\n headers: headersSchema,\n });\n };\n"],"mappings":"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","names":["z"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/middlewares/logging.ts","../src/middlewares/retry.ts","../src/middlewares/auth.ts","../src/middlewares/cache.ts","../src/middlewares/encryption.ts","../src/utils/make-request-schema.ts","../src/modules/tester/context.ts","../src/modules/tester/generate-input.ts","../src/modules/tester/reporter.ts","../src/modules/tester/runner.ts","../src/cli/config.ts"],"sourcesContent":["import { z } from \"zod\";\nimport {\n Contracts,\n EndpointDef,\n EndpointDefZ,\n Middleware,\n ErrorLike,\n EndpointMethods,\n TokenProvider,\n RequestOptions,\n MiddlewareContext,\n} from \"./types\";\n\nexport class RichError extends Error implements ErrorLike {\n status?: number;\n code?: string;\n title?: string;\n detail?: string;\n errors?: Record<string, string[]>;\n\n constructor(error: Partial<ErrorLike> & { message: string }) {\n super(error.message);\n Object.assign(this, error);\n }\n}\n\ntype ParsedRequestParts = {\n path?: Record<string, any>;\n query?: Record<string, any>;\n body?: any;\n headers: Record<string, string>;\n isStructured: boolean;\n};\n\nconst REQUEST_PART_KEYS = new Set([\n \"path\",\n \"query\",\n \"body\",\n \"headers\",\n \"header\",\n]);\n\nexport class ApiClient<C extends Contracts, E extends ErrorLike = RichError> {\n private middlewares: Array<{ fn: Middleware; options?: any }> = [];\n private errorHandler?: (error: E) => void;\n private responseTransform: (data: any) => any = (d) => d;\n private useMockData = false;\n private mockDelay = { min: 100, max: 1000 };\n private responseWrapper?: (successResponse: z.ZodTypeAny) => z.ZodTypeAny;\n private tokenProvider?: TokenProvider;\n\n private retryConfig?: {\n maxRetries: number;\n backoff: \"fixed\" | \"linear\" | \"exponential\";\n retryCondition?: (error: RichError, attempt: number) => boolean;\n };\n\n private _modules!: { [M in keyof C]: EndpointMethods<C[M]> };\n\n constructor(\n private config: {\n baseUrl: string;\n token?: string;\n tokenProvider?: TokenProvider;\n useMockData?: boolean;\n mockDelay?: { min: number; max: number };\n },\n private contracts: C,\n ) {\n this.useMockData = config.useMockData || false;\n this.mockDelay = config.mockDelay || { min: 100, max: 1000 };\n this.tokenProvider = config.tokenProvider;\n }\n\n init() {\n const modules = {} as { [M in keyof C]: EndpointMethods<C[M]> };\n\n for (const moduleName in this.contracts) {\n const module = this.contracts[moduleName];\n (modules as any)[moduleName] = {} as EndpointMethods<typeof module>;\n\n for (const endpointName in module) {\n const endpoint = module[endpointName] as EndpointDefZ;\n\n (modules as any)[moduleName][endpointName] = (\n input: any,\n options?: RequestOptions,\n ) => this.request(endpoint as any, input, options);\n }\n }\n\n this._modules = modules;\n }\n\n get modules() {\n return this._modules;\n }\n\n use<T>(middleware: Middleware<any, any, T>, options?: T) {\n this.middlewares.push({ fn: middleware, options });\n }\n\n onError(handler: (error: E) => void) {\n this.errorHandler = handler;\n }\n\n useResponseTransform(fn: (data: any) => any) {\n this.responseTransform = fn;\n }\n\n setRetryConfig(config: ApiClient<C>[\"retryConfig\"]) {\n this.retryConfig = config;\n }\n\n setTokenProvider(provider: TokenProvider) {\n this.tokenProvider = provider;\n }\n\n setMockMode(enabled: boolean, delay?: { min: number; max: number }) {\n this.useMockData = enabled;\n if (delay) this.mockDelay = delay;\n }\n\n setResponseWrapper(wrapper: (successResponse: z.ZodTypeAny) => z.ZodTypeAny) {\n this.responseWrapper = wrapper;\n }\n\n async getCurrentToken(): Promise<string | undefined> {\n if (this.tokenProvider) return await this.tokenProvider();\n return this.config.token;\n }\n\n private async request<TReq extends z.ZodTypeAny, TRes extends z.ZodTypeAny>(\n endpoint: EndpointDef<TReq, TRes>,\n input: z.infer<TReq>,\n options?: RequestOptions,\n ): Promise<z.infer<TRes>> {\n const parsedInput = endpoint.request.parse(input);\n\n if (this.useMockData && endpoint.mockData) {\n return this.handleMockRequest(endpoint);\n }\n\n const built = this.buildUrlAndBody(endpoint as EndpointDefZ, parsedInput);\n\n return this.performRequestLogic(\n endpoint,\n parsedInput,\n built.url,\n built.body,\n built.headers,\n built.parts,\n options,\n );\n }\n\n private async performRequestLogic<\n TReq extends z.ZodTypeAny,\n TRes extends z.ZodTypeAny,\n >(\n endpoint: EndpointDef<TReq, TRes>,\n parsedInput: z.infer<TReq>,\n url: string,\n body: BodyInit | undefined,\n requestHeaders: Record<string, string>,\n requestParts: ParsedRequestParts,\n options?: RequestOptions,\n ): Promise<z.infer<TRes>> {\n const headers: Record<string, string> = {};\n\n if (endpoint.bodyType !== \"form-data\") {\n headers[\"Content-Type\"] = \"application/json\";\n }\n\n const endpointHeaders =\n typeof endpoint.headers === \"function\"\n ? endpoint.headers(parsedInput)\n : endpoint.headers;\n\n Object.assign(\n headers,\n this.normalizeHeaders(endpointHeaders),\n requestHeaders,\n );\n\n if (endpoint.auth) {\n const token = await this.getCurrentToken();\n\n if (!token) {\n const error = this.createError({\n message: `Missing token for ${endpoint.path}`,\n status: 401,\n code: \"NO_TOKEN\",\n });\n this.errorHandler?.(error as any);\n throw error;\n }\n\n headers[\"Authorization\"] = `Bearer ${token}`;\n }\n\n const ctx = {\n url,\n init: { method: endpoint.method, headers, body } as RequestInit,\n endpoint: endpoint as never,\n request: {\n ...requestParts,\n rawInput: parsedInput,\n },\n } satisfies MiddlewareContext;\n\n let controller: AbortController | undefined;\n let timeoutId: any;\n\n if (options?.timeout) {\n controller = new AbortController();\n timeoutId = setTimeout(() => controller!.abort(), options.timeout);\n }\n\n if (options?.signal || controller) {\n ctx.init.signal = options?.signal || controller?.signal;\n }\n\n const runner = this.middlewares.reduceRight(\n (next, mw) => () => mw.fn(ctx, next, mw.options),\n () => fetch(ctx.url, ctx.init),\n );\n\n const execute = async () => {\n const res = await runner();\n const json = await res.json();\n let responseData = json;\n\n if (this.responseWrapper) {\n const wrappedSchema = this.responseWrapper(endpoint.response);\n const parsedWrapped = wrappedSchema.parse(json) as any;\n\n if (parsedWrapped.success === false) {\n const error = this.createError({\n message:\n parsedWrapped.message || parsedWrapped.error || \"Request failed\",\n status: parsedWrapped.code || res.status,\n code: parsedWrapped.code\n ? `API_ERROR_${parsedWrapped.code}`\n : \"API_ERROR\",\n });\n\n this.errorHandler?.(error as any);\n throw error;\n }\n\n responseData = parsedWrapped.data;\n }\n\n if (!res.ok) {\n const error = this.createError({\n message: json.message || res.statusText,\n status: res.status,\n code: json.code,\n title: json.title,\n detail: json.detail,\n errors: json.errors,\n });\n this.errorHandler?.(error as any);\n throw error;\n }\n\n const parsed = endpoint.response.parse(responseData);\n return this.responseTransform(parsed);\n };\n\n try {\n const result = await this.executeWithRetry(execute);\n if (timeoutId) clearTimeout(timeoutId);\n return result;\n } catch (err: any) {\n if (timeoutId) clearTimeout(timeoutId);\n const error = this.normalizeError(err);\n this.errorHandler?.(error as any);\n throw error;\n }\n }\n\n private async executeWithRetry(fn: () => Promise<any>): Promise<any> {\n if (!this.retryConfig) return fn();\n\n const { maxRetries, backoff, retryCondition } = this.retryConfig;\n let attempt = 0;\n\n while (true) {\n try {\n return await fn();\n } catch (err: any) {\n attempt++;\n const error = this.normalizeError(err);\n\n const shouldRetry =\n attempt <= maxRetries &&\n (retryCondition?.(error, attempt) ??\n (error.status !== undefined && error.status >= 500));\n\n if (!shouldRetry) throw error;\n\n const delay = this.getBackoffDelay(backoff, attempt);\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n }\n\n private getBackoffDelay(\n type: \"fixed\" | \"linear\" | \"exponential\",\n attempt: number,\n ) {\n const base = 300;\n switch (type) {\n case \"fixed\":\n return base;\n case \"linear\":\n return base * attempt;\n case \"exponential\":\n return base * Math.pow(2, attempt - 1);\n }\n }\n\n private buildUrlAndBody(endpoint: EndpointDefZ, input: any) {\n const parts = this.extractRequestParts(input);\n\n let url = this.config.baseUrl + endpoint.path;\n url = this.applyPathParams(url, parts.path);\n url = this.appendQueryParams(url, parts.query);\n\n let body: BodyInit | undefined;\n const payload = parts.isStructured ? parts.body : input;\n\n if (endpoint.method !== \"GET\" && payload !== undefined) {\n if (endpoint.bodyType === \"form-data\") {\n if (typeof FormData !== \"undefined\" && payload instanceof FormData) {\n body = payload;\n } else {\n const form = new FormData();\n\n if (this.isObjectRecord(payload)) {\n for (const [key, value] of Object.entries(payload)) {\n this.appendFormValue(form, key, value);\n }\n } else if (payload != null) {\n form.append(\"value\", String(payload));\n }\n\n body = form;\n }\n } else {\n body = JSON.stringify(payload);\n }\n }\n\n return { url, body, headers: parts.headers, parts };\n }\n\n private extractRequestParts(input: any): ParsedRequestParts {\n if (this.isStructuredRequestInput(input)) {\n return {\n path: this.isObjectRecord(input.path) ? input.path : undefined,\n query: this.isObjectRecord(input.query) ? input.query : undefined,\n body: input.body,\n headers: this.normalizeHeaders(input.headers ?? input.header),\n isStructured: true,\n };\n }\n\n return {\n body: input,\n headers: {},\n isStructured: false,\n };\n }\n\n private isStructuredRequestInput(\n input: unknown,\n ): input is Record<string, any> {\n if (!this.isObjectRecord(input)) return false;\n\n const keys = Object.keys(input);\n if (keys.length === 0) return false;\n\n return (\n keys.some((key) => REQUEST_PART_KEYS.has(key)) &&\n keys.every((key) => REQUEST_PART_KEYS.has(key))\n );\n }\n\n private isObjectRecord(value: unknown): value is Record<string, any> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n }\n\n private applyPathParams(\n fullUrl: string,\n pathParams?: Record<string, any>,\n ): string {\n const url = new URL(fullUrl);\n\n const replacedPathname = url.pathname.replace(\n /:([A-Za-z0-9_]+)/g,\n (_, key: string) => {\n const value = pathParams?.[key];\n\n if (value === undefined || value === null) {\n throw this.createError({\n message: `Missing path param \"${key}\"`,\n code: \"MISSING_PATH_PARAM\",\n });\n }\n\n return encodeURIComponent(String(value));\n },\n );\n\n return `${url.origin}${replacedPathname}${url.search}${url.hash}`;\n }\n\n private appendQueryParams(url: string, query?: Record<string, any>): string {\n if (!query) return url;\n\n const params = new URLSearchParams();\n\n for (const [key, value] of Object.entries(query)) {\n this.appendQueryValue(params, key, value);\n }\n\n const queryString = params.toString();\n if (!queryString) return url;\n\n return `${url}${url.includes(\"?\") ? \"&\" : \"?\"}${queryString}`;\n }\n\n private appendQueryValue(params: URLSearchParams, key: string, value: any) {\n if (value === undefined || value === null) return;\n\n if (Array.isArray(value)) {\n for (const item of value) this.appendQueryValue(params, key, item);\n return;\n }\n\n if (value instanceof Date) {\n params.append(key, value.toISOString());\n return;\n }\n\n if (typeof value === \"object\") {\n params.append(key, JSON.stringify(value));\n return;\n }\n\n params.append(key, String(value));\n }\n\n private appendFormValue(form: FormData, key: string, value: any) {\n if (value === undefined || value === null) return;\n\n if (Array.isArray(value)) {\n for (const item of value) this.appendFormValue(form, key, item);\n return;\n }\n\n if (value instanceof Date) {\n form.append(key, value.toISOString());\n return;\n }\n\n const isBlob = typeof Blob !== \"undefined\" && value instanceof Blob;\n\n if (typeof value === \"object\" && !isBlob) {\n form.append(key, JSON.stringify(value));\n return;\n }\n\n form.append(key, value as any);\n }\n\n private normalizeHeaders(headers: unknown): Record<string, string> {\n if (!this.isObjectRecord(headers)) return {};\n\n const normalized: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined || value === null) continue;\n normalized[key] = String(value);\n }\n\n return normalized;\n }\n\n private createError(error: Partial<RichError> & { message: string }) {\n return new RichError(error);\n }\n\n private normalizeError(err: any) {\n if (err instanceof RichError) return err;\n if (err instanceof z.ZodError) {\n return this.createError({\n message: `Validation error: ${err.issues.map((e) => e.message).join(\", \")}`,\n code: \"VALIDATION_ERROR\",\n });\n }\n return this.createError({ message: err.message || \"Unknown error\" });\n }\n\n private async handleMockRequest(endpoint: any) {\n const delay =\n Math.floor(\n Math.random() * (this.mockDelay.max - this.mockDelay.min + 1),\n ) + this.mockDelay.min;\n\n await new Promise((r) => setTimeout(r, delay));\n\n const data =\n typeof endpoint.mockData === \"function\"\n ? endpoint.mockData()\n : endpoint.mockData;\n\n return this.responseTransform(endpoint.response.parse(data));\n }\n}\n","import { Middleware } from \"@/types\";\nimport z from \"zod\";\n\nexport type LoggingOptions = {\n logRequest?: boolean;\n logResponse?: boolean;\n debug?: boolean;\n};\n\nexport const loggingMiddleware: Middleware<\n z.ZodTypeAny,\n z.ZodTypeAny,\n LoggingOptions\n> = async (ctx, next, options) => {\n const { logRequest = true, logResponse = true, debug = true } = options || {};\n\n if (debug && logRequest) console.log(\"➡️ Request:\", ctx.url, ctx.init);\n\n const res = await next();\n\n if (debug && logResponse) console.log(\"⬅️ Response:\", res.status);\n\n return res;\n};\n","import { Middleware } from \"@/types\";\n\n\nexport type RetryOptions = {\n maxRetries?: number;\n delay?: number; // ms\n};\n\nexport const retryMiddleware = (options?: RetryOptions): Middleware => {\n const { maxRetries = 3, delay = 500 } = options || {};\n\n const middleware: Middleware = async (ctx, next) => {\n let attempt = 0;\n while (true) {\n try {\n return await next();\n } catch (err) {\n if (attempt >= maxRetries) throw err;\n attempt++;\n await new Promise((r) => setTimeout(r, delay * 2 ** attempt));\n }\n }\n };\n\n return middleware;\n};\n","import { Middleware } from \"@/types\";\nimport z from \"zod\";\n\n/**\n * TokenManagementOptions\n * ======================\n * Configuration structure for supplying credentials to the authentication layer.\n *\n * @property refreshToken A required asynchronous function responsible for\n * obtaining a current, valid access token string. This allows\n * for token fetching from storage or re-issuance upon expiry.\n */\nexport type AuthOptions = {\n refreshToken?: () => Promise<string>;\n};\n\n/**\n * AuthenticationInjectorMiddleware\n * ==================================\n * This middleware operates early in the request pipeline to ensure every\n * outgoing request is properly authorized by prepending an Authorization header.\n *\n * Core Logic:\n * -----------\n * 1. It checks if an explicit `refreshToken` supplier was configured in its options.\n * 2. If present, it synchronously calls this supplier to obtain the latest token.\n * 3. The resulting token is formatted as a standard 'Bearer' token and merged\n * into the request's `init.headers`.\n * 4. The request context (`ctx`) is then passed downstream.\n *\n * Note on Error Handling:\n * -----------------------\n * Any failure during the token retrieval process (e.g., if `refreshToken` throws)\n * results in the error being caught, and the request proceeds **without** an\n * Authorization header. This design defers failure response handling to\n * subsequent middleware or the final network fetcher.\n *\n * @param ctx The current request context object, including mutable `init` properties.\n * @param next The function to execute the rest of the middleware chain.\n * @param options The specific configuration passed to this middleware instance.\n *\n * @returns The final `Response` object after the network call completes.\n *\n * @example\n * // Assuming token retrieval logic is defined elsewhere\n * const tokenSupplier = () => fetchTokenFromSecureStorage();\n *\n * client.addInterceptor(\n * authMiddleware({ refreshToken: tokenSupplier })\n * );\n */\nexport const authMiddleware: Middleware<\n z.ZodTypeAny,\n z.ZodTypeAny,\n AuthOptions\n> = async (ctx, next, options) => {\n // Step 1 & 2: Check for and execute the token provider\n if (options?.refreshToken) {\n try {\n const newToken = await options.refreshToken();\n\n // Step 3: Mutate the context's request initialization object\n ctx.init.headers = {\n ...ctx.init.headers, // Preserve any headers set by prior middleware\n Authorization: `Bearer ${newToken}`,\n };\n } catch (error) {\n // Step 4: Fail silently for header injection purposes\n // The request will proceed unauthenticated if the token failed to load\n console.warn(\n \"Authentication token refresh failed, proceeding without authorization header.\",\n error,\n );\n }\n }\n\n // Step 5: Pass control to the next step in the request pipeline\n return next();\n};\n","import { MiddlewareContext, MiddlewareNext } from \"@/types\";\n\n/**\n * CacheOptions\n * ============\n * Options for configuring the cache middleware.\n * - `ttl` (Time To Live): Duration (in milliseconds) to keep cached GET responses.\n * After this time, cached data expires and a fresh network call is performed.\n */\nexport type CacheOptions = { ttl?: number };\n\n/**\n * cacheMiddleware\n * ===============\n * A generic caching middleware for GET requests in the ApiClient.\n * It stores successful responses in memory based on URL and method,\n * returning cached data for subsequent identical requests until the TTL expires.\n *\n * Purpose:\n * --------\n * - Reduces redundant network calls\n * - Improves performance for frequently fetched resources\n * - Useful for lightweight front-end caching (not suitable for sensitive data)\n *\n * Behavior:\n * ---------\n * 1. Only applies to `GET` requests; all other HTTP methods bypass caching.\n * 2. Caches the parsed JSON response in a simple in-memory Map.\n * 3. On subsequent requests:\n * - If the cache entry exists and hasn’t expired, returns a synthetic\n * `Response` object built from cached JSON.\n * - Otherwise performs the network call and refreshes the cache.\n *\n * @param options - Optional cache configuration (TTL in ms)\n *\n * @returns Middleware function compatible with the ApiClient pipeline.\n *\n * @example\n * client.use(\n * cacheMiddleware({ ttl: 120000 }) // cache GET results for 2 minutes\n * );\n *\n * @note Each middleware instance maintains its own internal cache\n * and is memory-scoped (not persistent between reloads).\n */\nexport const cacheMiddleware = (options: CacheOptions = {}) => {\n // Default TTL = 60 seconds, unless overridden\n const { ttl = 60000 } = options;\n\n /**\n * Internal cache store.\n * Keys are composed as `\"METHOD:URL\"`.\n * Values include cached response data and expiration timestamp.\n */\n const cache = new Map<string, { data: any; expires: number }>();\n\n // Return an asynchronous middleware function conforming to the standard signature\n return async (ctx: MiddlewareContext, next: MiddlewareNext) => {\n // Caching only applies to GET requests\n if (ctx.init.method === \"GET\") {\n const key = `${ctx.init.method}:${ctx.url}`;\n const cached = cache.get(key);\n const now = Date.now();\n\n // Check if valid cached response exists and hasn't expired\n if (cached && cached.expires > now) {\n // Return a new synthetic Response containing cached data\n return new Response(JSON.stringify(cached.data), {\n headers: { \"Content-Type\": \"application/json\" },\n });\n }\n\n // Perform the actual network request via the next middleware/fetcher\n const res = await next();\n\n // Attempt to read JSON data from the response (clone avoids stream lock)\n const data = await res\n .clone()\n .json()\n .catch(() => null);\n\n // Store parsed data with expiration if successfully obtained\n if (data) {\n cache.set(key, { data, expires: now + ttl });\n }\n\n // Return original response to caller\n return res;\n }\n\n // For all non‑GET requests, just forward the call with no caching logic\n return next();\n };\n};\n","import type { Middleware, DeepEncryptionMap, EncryptionMethod } from \"@/types\";\nimport CryptoJS from \"crypto-js\";\nimport forge from \"node-forge\";\nimport { z } from \"zod\";\n\ntype SymmetricKeyMaterial = {\n type: \"symmetric\";\n key: string;\n};\n\ntype RSAKeyMaterial = {\n type: \"rsa\";\n publicKey: string;\n privateKey: string;\n};\n\ntype KeyMaterial = SymmetricKeyMaterial | RSAKeyMaterial;\n\ntype CustomHandlers = {\n encrypt: (value: string, key: KeyMaterial) => string | Promise<string>;\n decrypt: (value: string, key: KeyMaterial) => string | Promise<string>;\n};\n\nexport interface EncryptionOptions {\n keyProvider: () => KeyMaterial | Promise<KeyMaterial>;\n customHandlers?: CustomHandlers;\n\n /**\n * true = throw when encryption/decryption fails, which avoids leaking plaintext.\n * false = log and continue/fallback to the original response.\n * Default: true\n */\n failClosed?: boolean;\n}\n\nfunction safeJsonParse(value: string): unknown {\n try {\n return JSON.parse(value);\n } catch {\n return value;\n }\n}\n\nfunction isPlainObject(value: unknown): value is Record<string, unknown> {\n return (\n typeof value === \"object\" &&\n value !== null &&\n !Array.isArray(value) &&\n Object.prototype.toString.call(value) === \"[object Object]\"\n );\n}\n\nfunction hasKey(value: unknown, key: string): value is Record<string, unknown> {\n return (\n isPlainObject(value) && Object.prototype.hasOwnProperty.call(value, key)\n );\n}\n\nfunction toMiddlewareError(message: string, error: unknown): Error {\n const err = new Error(\n `${message}: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n );\n (err as any).cause = error;\n return err;\n}\n\nfunction encryptWithAES(value: string, key: string): string {\n return CryptoJS.AES.encrypt(value, key).toString();\n}\n\nfunction decryptWithAES(value: string, key: string): string {\n const bytes = CryptoJS.AES.decrypt(value, key);\n return bytes.toString(CryptoJS.enc.Utf8);\n}\n\nfunction encryptWithDES(value: string, key: string): string {\n return CryptoJS.DES.encrypt(value, key).toString();\n}\n\nfunction decryptWithDES(value: string, key: string): string {\n const bytes = CryptoJS.DES.decrypt(value, key);\n return bytes.toString(CryptoJS.enc.Utf8);\n}\n\nfunction encodeWithBase64(value: string): string {\n return CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(value));\n}\n\nfunction decodeWithBase64(value: string): string {\n return CryptoJS.enc.Base64.parse(value).toString(CryptoJS.enc.Utf8);\n}\n\nfunction encryptWithRSA(value: string, publicKey: string): string {\n const publicKeyObject = forge.pki.publicKeyFromPem(publicKey);\n const encrypted = publicKeyObject.encrypt(\n forge.util.encodeUtf8(value),\n \"RSA-OAEP\",\n );\n return forge.util.encode64(encrypted);\n}\n\nfunction decryptWithRSA(value: string, privateKey: string): string {\n const privateKeyObject = forge.pki.privateKeyFromPem(privateKey);\n const decrypted = privateKeyObject.decrypt(\n forge.util.decode64(value),\n \"RSA-OAEP\",\n );\n return forge.util.decodeUtf8(decrypted);\n}\n\nasync function encryptValue(\n value: string,\n method: EncryptionMethod,\n keyMaterial: KeyMaterial,\n customHandlers?: CustomHandlers,\n): Promise<string> {\n switch (method) {\n case \"AES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"AES encryption requires symmetric key material.\");\n }\n return encryptWithAES(value, keyMaterial.key);\n }\n\n case \"DES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"DES encryption requires symmetric key material.\");\n }\n return encryptWithDES(value, keyMaterial.key);\n }\n\n case \"Base64\": {\n return encodeWithBase64(value);\n }\n\n case \"RSA\": {\n if (keyMaterial.type !== \"rsa\") {\n throw new Error(\"RSA encryption requires RSA key material.\");\n }\n return encryptWithRSA(value, keyMaterial.publicKey);\n }\n\n case \"Custom\": {\n if (!customHandlers) {\n throw new Error(\"Custom encryption requires custom handlers.\");\n }\n return await customHandlers.encrypt(value, keyMaterial);\n }\n\n default: {\n const exhaustiveCheck: never = method;\n throw new Error(`Unsupported encryption method: ${exhaustiveCheck}`);\n }\n }\n}\n\nasync function decryptValue(\n value: string,\n method: EncryptionMethod,\n keyMaterial: KeyMaterial,\n customHandlers?: CustomHandlers,\n): Promise<string> {\n switch (method) {\n case \"AES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"AES decryption requires symmetric key material.\");\n }\n return decryptWithAES(value, keyMaterial.key);\n }\n\n case \"DES\": {\n if (keyMaterial.type !== \"symmetric\") {\n throw new Error(\"DES decryption requires symmetric key material.\");\n }\n return decryptWithDES(value, keyMaterial.key);\n }\n\n case \"Base64\": {\n return decodeWithBase64(value);\n }\n\n case \"RSA\": {\n if (keyMaterial.type !== \"rsa\") {\n throw new Error(\"RSA decryption requires RSA key material.\");\n }\n return decryptWithRSA(value, keyMaterial.privateKey);\n }\n\n case \"Custom\": {\n if (!customHandlers) {\n throw new Error(\"Custom decryption requires custom handlers.\");\n }\n return await customHandlers.decrypt(value, keyMaterial);\n }\n\n default: {\n const exhaustiveCheck: never = method;\n throw new Error(`Unsupported decryption method: ${exhaustiveCheck}`);\n }\n }\n}\n\nexport async function processDeep<T = unknown>(\n data: unknown,\n map: DeepEncryptionMap | null | undefined,\n defaultMethod: EncryptionMethod,\n transform: (value: unknown, method: EncryptionMethod) => Promise<unknown>,\n): Promise<T> {\n if (data == null || map == null) return data as T;\n\n if (typeof map === \"string\") return (await transform(data, map)) as T;\n\n if (typeof map === \"boolean\") {\n return (map ? await transform(data, defaultMethod) : data) as T;\n }\n\n if (Array.isArray(data)) {\n if (!Array.isArray(map)) {\n return Promise.all(\n data.map((item) => processDeep(item, map, defaultMethod, transform)),\n ) as Promise<T>;\n }\n\n return Promise.all(\n data.map((item, idx) =>\n processDeep(item, map[idx] ?? map[0], defaultMethod, transform),\n ),\n ) as Promise<T>;\n }\n\n if (isPlainObject(data) && isPlainObject(map)) {\n const result: Record<string, unknown> = { ...data };\n\n for (const key of Object.keys(map)) {\n const childMap = (map as Record<string, DeepEncryptionMap>)[key];\n if (childMap == null) continue;\n\n const currentVal = result[key];\n if (currentVal !== undefined) {\n result[key] = await processDeep(\n currentVal,\n childMap,\n defaultMethod,\n transform,\n );\n }\n }\n\n return result as T;\n }\n\n return data as T;\n}\n\nfunction getRequestBodyMap(map: DeepEncryptionMap): DeepEncryptionMap {\n // Supports both styles:\n // encryption.request: { password: true }\n // encryption.request: { body: { password: true } }\n if (hasKey(map, \"body\")) {\n return map.body as DeepEncryptionMap;\n }\n\n return map;\n}\n\nexport const encryptionMiddleware: Middleware<\n z.ZodTypeAny,\n z.ZodTypeAny,\n EncryptionOptions\n> = async (ctx, next, options) => {\n if (!options) {\n throw new Error(\"Encryption middleware options were not provided.\");\n }\n\n const { keyProvider, customHandlers } = options;\n const failClosed = options.failClosed ?? true;\n const encryption = ctx.endpoint.encryption;\n\n if (!encryption || (!encryption.request && !encryption.response)) {\n return next();\n }\n\n const requestMethod: EncryptionMethod =\n typeof encryption.method === \"string\"\n ? encryption.method\n : (encryption.method?.request ?? \"AES\");\n\n const responseMethod: EncryptionMethod =\n typeof encryption.method === \"string\"\n ? encryption.method\n : (encryption.method?.response ?? \"AES\");\n\n const keyMaterial = await keyProvider();\n\n if (\n encryption.request &&\n typeof ctx.init.body === \"string\" &&\n ctx.init.body.length > 0\n ) {\n try {\n const parsedBody = JSON.parse(ctx.init.body);\n const bodyMap = getRequestBodyMap(encryption.request);\n\n const encryptedBody = await processDeep(\n parsedBody,\n bodyMap,\n requestMethod,\n async (value, method) => {\n const serialized =\n typeof value === \"string\" ? value : JSON.stringify(value);\n\n return encryptValue(serialized, method, keyMaterial, customHandlers);\n },\n );\n\n ctx.init.body = JSON.stringify(encryptedBody);\n\n if (ctx.request) {\n ctx.request.body = encryptedBody;\n }\n } catch (error) {\n if (failClosed) {\n throw toMiddlewareError(\n \"Encryption middleware request encryption failed\",\n error,\n );\n }\n\n console.error(\"Encryption middleware request encryption failed.\", error);\n }\n }\n\n const response = await next();\n\n if (!encryption.response) {\n return response;\n }\n\n try {\n const text = await response.clone().text();\n if (!text) return response;\n\n const parsedResponse = JSON.parse(text);\n\n const decryptedPayload = await processDeep(\n parsedResponse,\n encryption.response,\n responseMethod,\n async (value, method) => {\n if (typeof value !== \"string\") return value;\n\n const decrypted = await decryptValue(\n value,\n method,\n keyMaterial,\n customHandlers,\n );\n\n return safeJsonParse(decrypted);\n },\n );\n\n return new Response(JSON.stringify(decryptedPayload), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n } catch (error) {\n if (failClosed) {\n throw toMiddlewareError(\n \"Encryption middleware response decryption failed\",\n error,\n );\n }\n\n console.error(\"Encryption middleware response decryption failed.\", error);\n return response;\n }\n};\n","import { z } from \"zod\";\n\ntype OptionalUndefinedBody<T extends z.ZodTypeAny> = T extends z.ZodUndefined\n ? z.ZodOptional<T>\n : T;\n\nexport const makeRequestSchema =\n <\n TPath extends z.ZodRawShape = {},\n TQuery extends z.ZodRawShape = {},\n TBody extends z.ZodTypeAny = z.ZodUndefined,\n THeaders extends z.ZodTypeAny = z.ZodOptional<\n z.ZodRecord<z.ZodString, z.ZodString>\n >,\n >() =>\n (\n defs: {\n path?: z.ZodObject<TPath>;\n query?: z.ZodObject<TQuery>;\n body?: TBody;\n headers?: THeaders;\n } = {},\n ) => {\n const pathSchema = (defs.path ??\n z.object({})) as unknown as z.ZodObject<TPath>;\n\n const querySchema = (defs.query ??\n z.object({})) as unknown as z.ZodObject<TQuery>;\n\n const rawBodySchema = (defs.body ?? z.undefined()) as TBody;\n\n const bodySchema = (\n defs.body ? rawBodySchema : rawBodySchema.optional()\n ) as OptionalUndefinedBody<TBody>;\n\n const headersSchema = (defs.headers ??\n z.record(z.string(), z.string()).optional()) as THeaders;\n\n return z.object({\n path: pathSchema.optional(),\n query: querySchema.optional(),\n body: bodySchema,\n headers: headersSchema,\n });\n };\n","import type { EndpointTestContext } from \"@/types\";\n\nexport class TypeFetchTestContext implements EndpointTestContext {\n data: Record<string, unknown>;\n\n constructor(initialData: Record<string, unknown> = {}) {\n this.data = { ...initialData };\n }\n\n get<T = unknown>(key: string): T | undefined {\n return this.data[key] as T | undefined;\n }\n\n set<T = unknown>(key: string, value: T): void {\n this.data[key] = value;\n }\n\n has(key: string): boolean {\n return Object.prototype.hasOwnProperty.call(this.data, key);\n }\n}\n","import { z } from \"zod\";\nimport type { AutoInputOptions, SchemaLike } from \"./types\";\n\nconst DEFAULT_MAX_DEPTH = 5;\n\nexport function generateInput(\n schema: z.ZodTypeAny,\n options: AutoInputOptions = {},\n): unknown {\n return generateValue(schema as SchemaLike, options, [], 0);\n}\n\nfunction generateValue(\n schema: SchemaLike,\n options: AutoInputOptions,\n path: string[],\n depth: number,\n): unknown {\n const override = resolveOverride(options, path);\n if (override.exists) return override.value;\n\n const maxDepth = options.maxDepth ?? DEFAULT_MAX_DEPTH;\n if (depth > maxDepth) return null;\n\n const kind = getKind(schema);\n const def = getDef(schema);\n\n switch (kind) {\n case \"optional\":\n if (options.includeOptional === false) return undefined;\n return generateValue(getInnerType(schema, def), options, path, depth + 1);\n\n case \"nullable\":\n return generateValue(getInnerType(schema, def), options, path, depth + 1);\n\n case \"default\":\n return (\n getDefaultValue(def) ??\n generateValue(getInnerType(schema, def), options, path, depth + 1)\n );\n\n case \"catch\":\n case \"readonly\":\n case \"branded\":\n case \"promise\":\n return generateValue(getInnerType(schema, def), options, path, depth + 1);\n\n case \"effects\":\n case \"pipeline\":\n case \"pipe\":\n return generateValue(\n (def.schema ?? def.in ?? def.out) as SchemaLike,\n options,\n path,\n depth + 1,\n );\n\n case \"object\":\n return generateObject(schema, options, path, depth);\n\n case \"array\": {\n if (options.includeArrayItems === false) return [];\n const itemSchema = (def.type ?? def.element ?? def.innerType) as\n | SchemaLike\n | undefined;\n return itemSchema\n ? [generateValue(itemSchema, options, path.concat(\"0\"), depth + 1)]\n : [];\n }\n\n case \"tuple\": {\n const items = (def.items ?? []) as SchemaLike[];\n return items.map((item, index) =>\n generateValue(item, options, path.concat(String(index)), depth + 1),\n );\n }\n\n case \"record\": {\n const valueType = (def.valueType ?? def.valueSchema ?? def.value) as\n | SchemaLike\n | undefined;\n return {\n key: valueType\n ? generateValue(valueType, options, path.concat(\"key\"), depth + 1)\n : \"value\",\n };\n }\n\n case \"union\": {\n const optionsList = (def.options ?? []) as SchemaLike[];\n return optionsList.length\n ? generateValue(optionsList[0], options, path, depth + 1)\n : null;\n }\n\n case \"discriminatedunion\":\n case \"discriminated_union\": {\n const optionsMap = def.optionsMap as Map<string, SchemaLike> | undefined;\n const first =\n optionsMap?.values().next().value ??\n (def.options?.[0] as SchemaLike | undefined);\n return first ? generateValue(first, options, path, depth + 1) : null;\n }\n\n case \"intersection\": {\n const left = generateValue(def.left, options, path, depth + 1);\n const right = generateValue(def.right, options, path, depth + 1);\n if (isObject(left) && isObject(right)) return { ...left, ...right };\n return right ?? left;\n }\n\n case \"literal\": {\n const values = def.values ?? (\"value\" in def ? [def.value] : undefined);\n return Array.isArray(values)\n ? values[0]\n : values?.values?.().next?.().value;\n }\n\n case \"enum\":\n case \"nativeenum\":\n case \"native_enum\": {\n const values = getEnumValues(schema, def);\n return values[0] ?? \"value\";\n }\n\n case \"string\":\n return generateString(path, def, options);\n\n case \"number\":\n return generateNumber(def);\n\n case \"bigint\":\n return BigInt(1);\n\n case \"boolean\":\n return true;\n\n case \"date\":\n return new Date(\"2026-01-01T00:00:00.000Z\");\n\n case \"null\":\n return null;\n\n case \"undefined\":\n case \"void\":\n return undefined;\n\n case \"nan\":\n return Number.NaN;\n\n case \"any\":\n case \"unknown\":\n return guessByPath(path, options);\n\n case \"never\":\n throw new Error(\n `Cannot generate input for never schema at ${path.join(\".\") || \"root\"}`,\n );\n\n default:\n return guessByPath(path, options);\n }\n}\n\nfunction generateObject(\n schema: SchemaLike,\n options: AutoInputOptions,\n path: string[],\n depth: number,\n): Record<string, unknown> {\n const shape = getShape(schema);\n const output: Record<string, unknown> = {};\n\n for (const [key, childSchema] of Object.entries(shape)) {\n const value = generateValue(\n childSchema as SchemaLike,\n options,\n path.concat(key),\n depth + 1,\n );\n if (value !== undefined || options.includeOptional !== false)\n output[key] = value;\n }\n\n return output;\n}\n\nfunction generateString(\n path: string[],\n def: any,\n options: AutoInputOptions,\n): string | unknown {\n const key = path[path.length - 1]?.toLowerCase() ?? \"\";\n const fullPath = path.join(\".\").toLowerCase();\n const minLength = getStringMinLength(def);\n const ensureMinLength = (value: string) =>\n minLength && value.length < minLength\n ? value.padEnd(minLength, \"x\")\n : value;\n\n if (isFileField(key, fullPath))\n return options.fileFactory?.() ?? defaultFileValue();\n\n if (key.includes(\"email\")) {\n const base = \"test@example.com\";\n if (!minLength || base.length >= minLength) return base;\n\n return `test${\"x\".repeat(minLength - base.length)}@example.com`;\n }\n\n if (key.includes(\"url\") || key.includes(\"website\")) {\n const base = \"https://example.com\";\n if (!minLength || base.length >= minLength) return base;\n\n return `${base}/${\"x\".repeat(minLength - base.length)}`;\n }\n\n if (key === \"uuid\" || key.endsWith(\"uuid\")) {\n return \"550e8400-e29b-41d4-a716-446655440000\";\n }\n\n if (key === \"id\" || key.endsWith(\"id\") || fullPath.endsWith(\".path.id\")) {\n return ensureMinLength(\"1\");\n }\n\n if (key.includes(\"phone\")) return ensureMinLength(\"+10000000000\");\n if (key.includes(\"name\")) return ensureMinLength(\"Test Name\");\n if (key.includes(\"password\")) return ensureMinLength(\"StrongPass123!\");\n if (key.includes(\"token\")) return ensureMinLength(\"test-token\");\n\n return ensureMinLength(\"test-string\");\n}\n\nfunction generateNumber(def: any): number {\n const min = getNumberMin(def);\n if (typeof min === \"number\") return min;\n return 1;\n}\n\nfunction guessByPath(path: string[], options: AutoInputOptions): unknown {\n const key = path[path.length - 1]?.toLowerCase() ?? \"\";\n const fullPath = path.join(\".\").toLowerCase();\n\n if (isFileField(key, fullPath))\n return options.fileFactory?.() ?? defaultFileValue();\n if (key.includes(\"count\") || key.includes(\"page\") || key.includes(\"limit\"))\n return 1;\n if (key.startsWith(\"is\") || key.startsWith(\"has\") || key.includes(\"active\"))\n return true;\n return \"test-value\";\n}\n\nfunction resolveOverride(options: AutoInputOptions, path: string[]) {\n const values = options.values ?? {};\n const candidates = [\n path.join(\".\"),\n path.slice(-2).join(\".\"),\n path[path.length - 1] ?? \"\",\n ];\n\n for (const key of candidates) {\n if (key && Object.prototype.hasOwnProperty.call(values, key)) {\n const raw = values[key];\n return {\n exists: true,\n value: typeof raw === \"function\" ? raw(path.join(\".\")) : raw,\n };\n }\n }\n\n return { exists: false, value: undefined };\n}\n\nfunction getDef(schema: SchemaLike): any {\n return schema._def ?? schema.def ?? {};\n}\n\nfunction getKind(schema: SchemaLike): string {\n const def = getDef(schema);\n const raw = def.typeName ?? def.type ?? schema.constructor?.name ?? \"unknown\";\n return String(raw).replace(/^Zod/, \"\").replace(/-/g, \"_\").toLowerCase();\n}\n\nfunction getInnerType(schema: SchemaLike, def = getDef(schema)): SchemaLike {\n return (schema.unwrap?.() ??\n def.innerType ??\n def.schema ??\n def.type) as SchemaLike;\n}\n\nfunction getShape(schema: SchemaLike): Record<string, z.ZodTypeAny> {\n const def = getDef(schema);\n const shape = schema.shape ?? def.shape;\n return typeof shape === \"function\" ? shape() : (shape ?? {});\n}\n\nfunction getDefaultValue(def: any): unknown {\n const value = def.defaultValue;\n return typeof value === \"function\" ? value() : value;\n}\n\nfunction getEnumValues(schema: SchemaLike, def: any): unknown[] {\n if (Array.isArray((schema as any).options)) return (schema as any).options;\n if (Array.isArray(def.values)) return def.values;\n if (def.entries && typeof def.entries === \"object\")\n return Object.values(def.entries);\n if (def.values && typeof def.values === \"object\")\n return Object.values(def.values);\n return [];\n}\n\nfunction getStringMinLength(def: any): number | undefined {\n for (const check of def.checks ?? []) {\n const c = check?._zod?.def ?? check;\n if (\n (c.kind === \"min\" || c.check === \"min_length\" || c.type === \"min\") &&\n typeof c.value === \"number\"\n )\n return c.value;\n if (typeof c.minimum === \"number\") return c.minimum;\n }\n return undefined;\n}\n\nfunction getNumberMin(def: any): number | undefined {\n for (const check of def.checks ?? []) {\n const c = check?._zod?.def ?? check;\n if (\n (c.kind === \"min\" || c.check === \"greater_than\" || c.type === \"min\") &&\n typeof c.value === \"number\"\n )\n return c.value;\n if (typeof c.minimum === \"number\") return c.minimum;\n }\n return undefined;\n}\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isFileField(key: string, fullPath: string): boolean {\n return (\n key === \"file\" ||\n key.endsWith(\"file\") ||\n key.includes(\"avatar\") ||\n fullPath.includes(\"formdata\")\n );\n}\n\nfunction defaultFileValue(): unknown {\n if (typeof Blob !== \"undefined\") {\n return new Blob([\"typefetch-test-file\"], { type: \"text/plain\" });\n }\n return \"typefetch-test-file\";\n}\n","import type { ApiTestReport } from \"./types\";\n\nexport function createMarkdownReport(report: ApiTestReport): string {\n const lines: string[] = [];\n\n lines.push(\"# TypeFetch API Test Report\");\n lines.push(\"\");\n lines.push(`Generated at: ${report.generatedAt}`);\n lines.push(`Mode: ${report.mode}`);\n lines.push(\"\");\n lines.push(\"## Summary\");\n lines.push(\"\");\n lines.push(\"| Total | Passed | Failed | Skipped | Duration |\");\n lines.push(\"|---:|---:|---:|---:|---:|\");\n lines.push(\n `| ${report.summary.total} | ${report.summary.passed} | ${report.summary.failed} | ${report.summary.skipped} | ${formatMs(report.summary.durationMs)} |`,\n );\n lines.push(\"\");\n\n const failed = report.results.filter((item) => item.status === \"failed\");\n if (failed.length) {\n lines.push(\"## Failed Endpoints\");\n lines.push(\"\");\n for (const item of failed) {\n lines.push(`### ${item.module}.${item.endpoint} — ${item.caseName}`);\n lines.push(\"\");\n lines.push(`- Phase: ${item.phase}`);\n lines.push(`- Method: ${item.method}`);\n lines.push(`- Path: ${item.path}`);\n lines.push(`- Duration: ${formatMs(item.durationMs)}`);\n if (item.error?.status) lines.push(`- HTTP Status: ${item.error.status}`);\n if (item.error?.code) lines.push(`- Code: ${item.error.code}`);\n lines.push(`- Error: ${escapeMarkdown(item.error?.message ?? \"Unknown error\")}`);\n if (item.error?.issues) {\n lines.push(\"\");\n lines.push(\"```json\");\n lines.push(JSON.stringify(item.error.issues, null, 2));\n lines.push(\"```\");\n }\n lines.push(\"\");\n }\n }\n\n lines.push(\"## All Results\");\n lines.push(\"\");\n lines.push(\"| Status | Endpoint | Case | Phase | Method | Path | Duration |\");\n lines.push(\"|---|---|---|---|---|---|---:|\");\n\n for (const item of report.results) {\n lines.push(\n `| ${item.status} | ${item.module}.${item.endpoint} | ${escapeTable(item.caseName)} | ${item.phase} | ${item.method} | ${escapeTable(item.path)} | ${formatMs(item.durationMs)} |`,\n );\n }\n\n lines.push(\"\");\n return lines.join(\"\\n\");\n}\n\nexport function createHtmlReport(report: ApiTestReport): string {\n const rows = report.results\n .map(\n (item) => `\n <tr class=\"${item.status}\">\n <td>${escapeHtml(item.status)}</td>\n <td>${escapeHtml(`${item.module}.${item.endpoint}`)}</td>\n <td>${escapeHtml(item.caseName)}</td>\n <td>${escapeHtml(item.phase)}</td>\n <td>${escapeHtml(item.method)}</td>\n <td>${escapeHtml(item.path)}</td>\n <td>${formatMs(item.durationMs)}</td>\n <td>${escapeHtml(item.error?.message ?? \"\")}</td>\n </tr>`,\n )\n .join(\"\\n\");\n\n return `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>TypeFetch API Test Report</title>\n <style>\n body { font-family: Inter, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif; margin: 32px; background: #0f1115; color: #f4f4f5; }\n .cards { display: flex; gap: 12px; flex-wrap: wrap; margin: 24px 0; }\n .card { background: #181b22; border: 1px solid #2a2f3a; border-radius: 14px; padding: 16px 18px; min-width: 120px; }\n .card strong { display: block; font-size: 24px; margin-top: 6px; }\n table { width: 100%; border-collapse: collapse; background: #181b22; border-radius: 14px; overflow: hidden; }\n th, td { padding: 11px 12px; border-bottom: 1px solid #2a2f3a; text-align: left; vertical-align: top; }\n th { color: #a1a1aa; font-size: 13px; }\n tr.passed td:first-child { color: #34d399; }\n tr.failed td:first-child { color: #fb7185; }\n tr.skipped td:first-child { color: #fbbf24; }\n code { background: #272b35; padding: 2px 5px; border-radius: 6px; }\n </style>\n</head>\n<body>\n <h1>TypeFetch API Test Report</h1>\n <p>Generated at: <code>${escapeHtml(report.generatedAt)}</code> · Mode: <code>${escapeHtml(report.mode)}</code></p>\n <section class=\"cards\">\n <div class=\"card\">Total<strong>${report.summary.total}</strong></div>\n <div class=\"card\">Passed<strong>${report.summary.passed}</strong></div>\n <div class=\"card\">Failed<strong>${report.summary.failed}</strong></div>\n <div class=\"card\">Skipped<strong>${report.summary.skipped}</strong></div>\n <div class=\"card\">Duration<strong>${formatMs(report.summary.durationMs)}</strong></div>\n </section>\n <table>\n <thead>\n <tr><th>Status</th><th>Endpoint</th><th>Case</th><th>Phase</th><th>Method</th><th>Path</th><th>Duration</th><th>Error</th></tr>\n </thead>\n <tbody>${rows}</tbody>\n </table>\n</body>\n</html>`;\n}\n\nfunction formatMs(ms: number): string {\n return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(2)}s`;\n}\n\nfunction escapeTable(value: string): string {\n return value.replace(/\\|/g, \"\\\\|\");\n}\n\nfunction escapeMarkdown(value: string): string {\n return value.replace(/`/g, \"\\\\`\");\n}\n\nfunction escapeHtml(value: string): string {\n return value\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n}\n","import { z } from \"zod\";\nimport type {\n Contracts,\n EndpointDefZ,\n EndpointTestCase,\n EndpointTestConfig,\n RequestOptions,\n} from \"@/types\";\nimport { TypeFetchTestContext } from \"./context\";\nimport { generateInput } from \"./generate-input\";\nimport type {\n ApiTestMode,\n ApiTestReport,\n ApiTestResult,\n ApiTestRunnerConfig,\n ApiTestRunnerOptions,\n DiscoveredEndpoint,\n} from \"./types\";\n\nconst DEFAULT_OPTIONS: Required<Pick<ApiTestRunnerOptions, \"mode\" | \"timeout\" | \"concurrency\" | \"stopOnFail\" | \"includeDestructive\">> = {\n mode: \"live\",\n timeout: 10_000,\n concurrency: 1,\n stopOnFail: false,\n includeDestructive: false,\n};\n\nexport function createApiTestRunner<C extends Contracts>(\n config: ApiTestRunnerConfig<C>,\n): ApiTestRunner<C> {\n return new ApiTestRunner(config);\n}\n\nexport class ApiTestRunner<C extends Contracts> {\n private readonly ctx: TypeFetchTestContext;\n private readonly options: ApiTestRunnerOptions & typeof DEFAULT_OPTIONS;\n\n constructor(private readonly config: ApiTestRunnerConfig<C>) {\n this.ctx = new TypeFetchTestContext(config.context);\n this.options = {\n ...DEFAULT_OPTIONS,\n ...(config.options ?? {}),\n };\n }\n\n async run(): Promise<ApiTestReport> {\n const startedAt = Date.now();\n const endpoints = this.discoverEndpoints();\n const results: ApiTestResult[] = [];\n\n for (const item of endpoints) {\n const endpointResults = await this.runEndpoint(item);\n results.push(...endpointResults);\n\n if (this.options.stopOnFail && endpointResults.some((result) => result.status === \"failed\")) {\n break;\n }\n }\n\n const durationMs = Date.now() - startedAt;\n return {\n generatedAt: new Date().toISOString(),\n mode: this.options.mode,\n summary: {\n total: results.length,\n passed: results.filter((item) => item.status === \"passed\").length,\n failed: results.filter((item) => item.status === \"failed\").length,\n skipped: results.filter((item) => item.status === \"skipped\").length,\n durationMs,\n },\n results,\n };\n }\n\n private discoverEndpoints(): DiscoveredEndpoint[] {\n const endpoints: DiscoveredEndpoint[] = [];\n\n for (const moduleName of Object.keys(this.config.contracts)) {\n const module = this.config.contracts[moduleName];\n for (const endpointName of Object.keys(module)) {\n endpoints.push({\n moduleName,\n endpointName,\n endpoint: module[endpointName] as EndpointDefZ,\n });\n }\n }\n\n return endpoints;\n }\n\n private async runEndpoint(item: DiscoveredEndpoint): Promise<ApiTestResult[]> {\n const { endpoint } = item;\n const testConfig = endpoint.test as EndpointTestConfig<any, any> | undefined;\n const tags = [...(testConfig?.tags ?? [])];\n const destructive = Boolean(testConfig?.destructive);\n\n const baseMeta = {\n module: item.moduleName,\n endpoint: item.endpointName,\n method: endpoint.method,\n path: endpoint.path,\n tags,\n destructive,\n };\n\n const skipReason = this.getEndpointSkipReason(testConfig);\n if (skipReason) {\n return [\n {\n ...baseMeta,\n caseName: \"default\",\n phase: this.options.mode,\n status: \"skipped\",\n durationMs: 0,\n skipReason,\n },\n ];\n }\n\n try {\n await testConfig?.setup?.(this.ctx);\n } catch (error) {\n return [\n {\n ...baseMeta,\n caseName: \"setup\",\n phase: this.options.mode,\n status: \"failed\",\n durationMs: 0,\n error: normalizeError(error),\n },\n ];\n }\n\n const cases = this.getCases(endpoint, testConfig);\n const results: ApiTestResult[] = [];\n\n for (let index = 0; index < cases.length; index++) {\n const testCase = cases[index];\n const caseName = testCase.name ?? `case-${index + 1}`;\n\n if (testCase.skip) {\n results.push({\n ...baseMeta,\n caseName,\n phase: this.options.mode,\n status: \"skipped\",\n durationMs: 0,\n skipReason: typeof testCase.skip === \"string\" ? testCase.skip : \"Case skipped\",\n });\n continue;\n }\n\n const phases = this.getPhases(endpoint);\n for (const phase of phases) {\n const result = await this.runCasePhase(item, testCase, caseName, phase);\n results.push(result);\n\n if (this.options.stopOnFail && result.status === \"failed\") break;\n }\n }\n\n try {\n await testConfig?.teardown?.(this.ctx);\n } catch (error) {\n results.push({\n ...baseMeta,\n caseName: \"teardown\",\n phase: this.options.mode,\n status: \"failed\",\n durationMs: 0,\n error: normalizeError(error),\n });\n }\n\n return results;\n }\n\n private getEndpointSkipReason(testConfig?: EndpointTestConfig<any, any>): string | undefined {\n if (testConfig?.enabled === false) return \"Endpoint tests disabled\";\n if (testConfig?.destructive && !this.options.includeDestructive) return \"Destructive endpoint skipped\";\n\n const tags = testConfig?.tags ?? [];\n if (this.options.includeTags?.length && !tags.some((tag) => this.options.includeTags!.includes(tag))) {\n return \"Endpoint does not match includeTags\";\n }\n\n if (this.options.excludeTags?.length && tags.some((tag) => this.options.excludeTags!.includes(tag))) {\n return \"Endpoint matches excludeTags\";\n }\n\n return undefined;\n }\n\n private getCases(\n endpoint: EndpointDefZ,\n testConfig?: EndpointTestConfig<any, any>,\n ): Array<EndpointTestCase<any, any>> {\n if (testConfig?.cases?.length) return testConfig.cases;\n if (testConfig?.input) return [{ name: \"default\", input: testConfig.input }];\n\n return [\n {\n name: \"auto-generated\",\n input: generateInput(endpoint.request, this.options.autoInput),\n },\n ];\n }\n\n private getPhases(endpoint: EndpointDefZ): Array<\"schema\" | \"mock\" | \"live\"> {\n switch (this.options.mode as ApiTestMode) {\n case \"schema\":\n return [\"schema\"];\n case \"mock\":\n return [\"mock\"];\n case \"full\":\n return endpoint.mockData ? [\"schema\", \"mock\", \"live\"] : [\"schema\", \"live\"];\n case \"live\":\n default:\n return [\"live\"];\n }\n }\n\n private async runCasePhase(\n item: DiscoveredEndpoint,\n testCase: EndpointTestCase<any, any>,\n caseName: string,\n phase: \"schema\" | \"mock\" | \"live\",\n ): Promise<ApiTestResult> {\n const { endpoint, moduleName, endpointName } = item;\n const startedAt = Date.now();\n let input: unknown;\n\n const meta = {\n module: moduleName,\n endpoint: endpointName,\n caseName,\n phase,\n method: endpoint.method,\n path: endpoint.path,\n tags: endpoint.test?.tags ?? [],\n destructive: Boolean(endpoint.test?.destructive),\n };\n\n try {\n input = await resolveInput(endpoint, testCase, this.ctx, this.options.autoInput);\n const parsedInput = endpoint.request.parse(input);\n\n if (phase === \"schema\") {\n return {\n ...meta,\n status: \"passed\",\n durationMs: Date.now() - startedAt,\n input: parsedInput,\n };\n }\n\n if (phase === \"mock\") {\n if (!endpoint.mockData) {\n return {\n ...meta,\n status: \"skipped\",\n durationMs: Date.now() - startedAt,\n input: parsedInput,\n skipReason: \"No mockData configured for endpoint\",\n };\n }\n\n const mockResponse = typeof endpoint.mockData === \"function\" ? endpoint.mockData() : endpoint.mockData;\n const parsedResponse = endpoint.response.parse(mockResponse);\n await testCase.expect?.({ input: parsedInput, response: parsedResponse, ctx: this.ctx });\n\n return {\n ...meta,\n status: \"passed\",\n durationMs: Date.now() - startedAt,\n input: parsedInput,\n response: parsedResponse,\n };\n }\n\n const response = await this.callClient(moduleName, endpointName, parsedInput, testCase);\n await testCase.expect?.({ input: parsedInput, response, ctx: this.ctx });\n\n return {\n ...meta,\n status: \"passed\",\n durationMs: Date.now() - startedAt,\n input: parsedInput,\n response,\n };\n } catch (error) {\n const normalized = normalizeError(error);\n const expectedStatuses = toStatusList(testCase.expectStatus);\n const expectedErrorStatus = normalized.status && expectedStatuses.includes(normalized.status);\n\n if (expectedErrorStatus) {\n return {\n ...meta,\n status: \"passed\",\n durationMs: Date.now() - startedAt,\n input,\n error: normalized,\n };\n }\n\n return {\n ...meta,\n status: \"failed\",\n durationMs: Date.now() - startedAt,\n input,\n error: normalized,\n };\n }\n }\n\n private async callClient(\n moduleName: string,\n endpointName: string,\n input: unknown,\n testCase: EndpointTestCase<any, any>,\n ): Promise<unknown> {\n const fn = this.config.client.modules[moduleName]?.[endpointName];\n if (!fn) throw new Error(`Client method not found: ${moduleName}.${endpointName}`);\n\n const requestOptions: RequestOptions = {\n ...(this.options.requestOptions ?? {}),\n timeout: testCase.timeout ?? this.options.timeout,\n };\n\n return fn(input, requestOptions);\n }\n}\n\nasync function resolveInput(\n endpoint: EndpointDefZ,\n testCase: EndpointTestCase<any, any>,\n ctx: TypeFetchTestContext,\n autoInputOptions: ApiTestRunnerOptions[\"autoInput\"],\n): Promise<unknown> {\n if (typeof testCase.input === \"function\") return testCase.input(ctx);\n if (testCase.input !== undefined) return testCase.input;\n return generateInput(endpoint.request, autoInputOptions);\n}\n\nfunction normalizeError(error: unknown) {\n if (error instanceof z.ZodError) {\n const zodError = error as z.ZodError;\n return {\n name: zodError.name,\n message: `Validation error: ${zodError.issues.map((issue) => issue.message).join(\", \")}`,\n code: \"VALIDATION_ERROR\",\n issues: zodError.issues,\n stack: zodError.stack,\n };\n }\n\n if (error instanceof Error) {\n const anyError = error as any;\n return {\n name: error.name,\n message: error.message,\n status: anyError.status,\n code: anyError.code,\n issues: anyError.issues ?? anyError.errors,\n stack: error.stack,\n };\n }\n\n return { message: String(error) };\n}\n\nfunction toStatusList(status?: number | number[]): number[] {\n if (status === undefined) return [];\n return Array.isArray(status) ? status : [status];\n}\n","import type { Contracts } from \"../types\";\nimport type { TypeFetchCliTestConfig } from \"./types\";\n\nexport function defineTypeFetchTestConfig<C extends Contracts>(\n config: TypeFetchCliTestConfig<C>,\n): TypeFetchCliTestConfig<C> {\n return config;\n}\n"],"mappings":"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","names":["z","z","z"]}
package/package.json CHANGED
@@ -1,10 +1,13 @@
1
1
  {
2
2
  "name": "@tahanabavi/typefetch",
3
- "version": "1.5.7",
3
+ "version": "1.6.0",
4
4
  "description": "A strongly typed TypeScript HTTP client powered by Zod contracts, middleware, retries, auth, mock data, response wrappers, and validation.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
7
7
  "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "typefetch": "./dist/cli/index.js"
10
+ },
8
11
  "exports": {
9
12
  ".": {
10
13
  "types": "./dist/index.d.ts",
@@ -59,6 +62,7 @@
59
62
  "@types/node-forge": "^1.3.14",
60
63
  "jest": "^30.1.3",
61
64
  "jest-fetch-mock": "^3.0.3",
65
+ "jiti": "^2.7.0",
62
66
  "rimraf": "^6.0.1",
63
67
  "ts-jest": "^29.4.1",
64
68
  "ts-node": "^10.9.2",