{"version":3,"sources":["../../src/errors.ts","../../src/client/fetcher.ts"],"sourcesContent":["export interface WextsErrorOptions {\n    code: string;\n    message: string;\n    cause?: unknown;\n    suggestedFix?: string;\n    docsSlug?: string;\n}\n\nexport class WextsError extends Error {\n    readonly code: string;\n    readonly suggestedFix?: string;\n    readonly docsSlug?: string;\n\n    constructor(options: WextsErrorOptions) {\n        super(options.message, options.cause === undefined ? undefined : { cause: options.cause });\n        this.name = 'WextsError';\n        this.code = options.code;\n        this.suggestedFix = options.suggestedFix;\n        this.docsSlug = options.docsSlug;\n    }\n\n    get docsUrl(): string | undefined {\n        return this.docsSlug ? `https://github.com/ziadmustafa1/wexts/blob/main/docs/${this.docsSlug}.md` : undefined;\n    }\n}\n\nexport class WextsRpcError extends WextsError {\n    constructor(options: Omit<WextsErrorOptions, 'code'> & { code?: string }) {\n        super({ code: options.code ?? 'WEXTS_RPC_ERROR', ...options });\n        this.name = 'WextsRpcError';\n    }\n}\n\nexport class WextsCodegenError extends WextsError {\n    constructor(options: Omit<WextsErrorOptions, 'code'> & { code?: string }) {\n        super({ code: options.code ?? 'WEXTS_CODEGEN_ERROR', ...options });\n        this.name = 'WextsCodegenError';\n    }\n}\n\nexport class WextsRuntimeError extends WextsError {\n    constructor(options: Omit<WextsErrorOptions, 'code'> & { code?: string }) {\n        super({ code: options.code ?? 'WEXTS_RUNTIME_ERROR', ...options });\n        this.name = 'WextsRuntimeError';\n    }\n}\n\nexport class WextsSecurityError extends WextsError {\n    constructor(options: Omit<WextsErrorOptions, 'code'> & { code?: string }) {\n        super({ code: options.code ?? 'WEXTS_SECURITY_ERROR', ...options });\n        this.name = 'WextsSecurityError';\n    }\n}\n\nexport function formatWextsError(error: unknown): string {\n    if (!(error instanceof WextsError)) {\n        return error instanceof Error ? error.message : String(error);\n    }\n\n    const lines = [`${error.code}: ${error.message}`];\n    if (error.suggestedFix) lines.push(`Suggested fix: ${error.suggestedFix}`);\n    if (error.docsUrl) lines.push(`Docs: ${error.docsUrl}`);\n    return lines.join('\\n');\n}\n","import type { RpcManifest, RpcInvocationResponse } from '../rpc/types';\nimport { WextsRpcError } from '../errors';\n\nexport class FusionFetcher {\n    private baseUrl: string;\n\n    constructor(baseUrl: string = '/api') {\n        this.baseUrl = baseUrl;\n    }\n\n    private async request<T>(method: string, path: string, body?: any): Promise<T> {\n        const headers: Record<string, string> = {\n            'Content-Type': 'application/json',\n        };\n\n        // Automatically attach Fusion Token if present\n        if (typeof window !== 'undefined') {\n            const token = localStorage.getItem('fusion_token');\n            if (token) headers['Authorization'] = `Bearer ${token}`;\n        }\n\n        const response = await fetch(`${this.baseUrl}${path}`, {\n            method,\n            headers,\n            body: body ? JSON.stringify(body) : undefined,\n        });\n\n        if (!response.ok) {\n            throw new WextsRpcError({\n                code: 'WEXTS_API_REQUEST_FAILED',\n                message: `Fusion API Error: ${response.status} ${response.statusText}`,\n                suggestedFix: 'Check the API route, server logs, and authentication headers.',\n                docsSlug: 'troubleshooting',\n            });\n        }\n\n        if (response.status === 204) {\n            return undefined as T;\n        }\n\n        return response.json();\n    }\n\n    get<T>(path: string) { return this.request<T>('GET', path); }\n    post<T>(path: string, body: any) { return this.request<T>('POST', path, body); }\n    put<T>(path: string, body: any) { return this.request<T>('PUT', path, body); }\n    delete<T>(path: string) { return this.request<T>('DELETE', path); }\n}\n\nexport const apiFetcher = new FusionFetcher();\n\nexport interface WextsRpcClientOptions {\n    baseUrl?: string;\n    fetch?: typeof fetch;\n    getHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n}\n\nexport type WextsRpcClient = Record<string, Record<string, (...args: unknown[]) => Promise<unknown>>>;\n\nexport function createWextsRpcClient(\n    manifest: Pick<RpcManifest, 'services'> | undefined,\n    options: WextsRpcClientOptions = {}\n): WextsRpcClient {\n    const hasManifest = Boolean(manifest);\n    const services = new Set((manifest?.services ?? []).map((service) => service.name));\n    const methodMap = new Map<string, Set<string>>();\n\n    for (const service of manifest?.services ?? []) {\n        methodMap.set(service.name, new Set(service.methods.map((method) => method.name)));\n    }\n\n    const createServiceProxy = (serviceName: string) => new Proxy({}, {\n        get(_target, methodName) {\n            if (typeof methodName !== 'string') return undefined;\n            if (methodName === 'then') return undefined;\n\n            const knownMethods = methodMap.get(serviceName);\n            if (knownMethods && !knownMethods.has(methodName)) {\n                throw new WextsRpcError({\n                    code: 'WEXTS_RPC_METHOD_NOT_FOUND',\n                    message: `Wexts RPC method not found: ${serviceName}.${methodName}`,\n                    suggestedFix: 'Run `wexts generate` and verify the method is decorated with @RpcMethod().',\n                    docsSlug: 'rpc',\n                });\n            }\n\n            return (...args: unknown[]) => invokeRpc(serviceName, methodName, args, options);\n        },\n    }) as Record<string, (...args: unknown[]) => Promise<unknown>>;\n\n    return new Proxy({}, {\n        get(_target, serviceName) {\n            if (typeof serviceName !== 'string') return undefined;\n            if (serviceName === 'then') return undefined;\n            if (!hasManifest) {\n                throw new WextsRpcError({\n                    code: 'WEXTS_RPC_MANIFEST_MISSING',\n                    message: 'Wexts RPC manifest is missing.',\n                    suggestedFix: 'Run `wexts generate` and import the generated client/provider instead of creating an empty client.',\n                    docsSlug: 'codegen',\n                });\n            }\n            if (!services.has(serviceName)) {\n                throw new WextsRpcError({\n                    code: 'WEXTS_RPC_SERVICE_NOT_FOUND',\n                    message: `Wexts RPC service not found: ${serviceName}`,\n                    suggestedFix: 'Run `wexts generate` and verify the service is decorated with @RpcService().',\n                    docsSlug: 'rpc',\n                });\n            }\n\n            return createServiceProxy(serviceName);\n        },\n    }) as WextsRpcClient;\n}\n\nasync function invokeRpc(\n    serviceName: string,\n    methodName: string,\n    args: unknown[],\n    options: WextsRpcClientOptions\n): Promise<unknown> {\n    const fetchImpl = options.fetch ?? fetch;\n    const baseUrl = options.baseUrl ?? '/rpc';\n    const headers = {\n        'Content-Type': 'application/json',\n        ...(await options.getHeaders?.() ?? {}),\n    };\n    const response = await fetchImpl(`${baseUrl}/${encodeURIComponent(serviceName)}/${encodeURIComponent(methodName)}`, {\n        method: 'POST',\n        headers,\n        body: JSON.stringify({ args }),\n    });\n\n    if (!response.ok) {\n        throw new WextsRpcError({\n            code: 'WEXTS_RPC_REQUEST_FAILED',\n            message: `Wexts RPC Error: ${response.status} ${response.statusText}`,\n            suggestedFix: 'Check the RPC route, service policy, and server logs.',\n            docsSlug: 'troubleshooting',\n        });\n    }\n\n    const payload = await response.json() as RpcInvocationResponse;\n    return payload.data;\n}\n"],"mappings":"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","names":["WextsError","Error","code","suggestedFix","docsSlug","options","message","cause","undefined","name","docsUrl","WextsRpcError","FusionFetcher","baseUrl","request","method","path","body","headers","window","token","localStorage","getItem","response","fetch","JSON","stringify","undefined","ok","WextsRpcError","code","message","status","statusText","suggestedFix","docsSlug","json","get","post","put","delete","apiFetcher","createWextsRpcClient","manifest","options","hasManifest","Boolean","services","Set","map","service","name","methodMap","Map","set","methods","createServiceProxy","serviceName","Proxy","_target","methodName","knownMethods","has","args","invokeRpc","fetchImpl","getHeaders","encodeURIComponent","payload","data"]}