@amaster.ai/http-client 1.1.0-beta.31 → 1.1.0-beta.32

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.
package/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';function q(e){if(!e)return "Request failed";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;return t.message||t.error||t.msg||t.detail||"Request failed"}return "Request failed"}function k(e){if(!e||typeof e!="object"||!("data"in e))return false;if("status"in e){let t=e.status;return t===0||t===1||t==="0"||t==="1"}return false}function E(e){return k(e)?e.data:e}var x=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;function P(e){return x.test(e)}function S(e){return `${e.replace(" ","T")}.000Z`}function m(e){if(e==null)return e;if(Array.isArray(e))return e.map(t=>m(t));if(typeof e=="object"){let t={};for(let[n,o]of Object.entries(e))t[n]=m(o);return t}return typeof e=="string"&&P(e)?S(e):e}function U(e){return /^https?:\/\//i.test(e)}function _(e,t){let n=e.replace(/\/+$/,""),o=t.startsWith("/")?t:`/${t}`;return `${n}${o}`}function H(e){if(!e||typeof e!="object")return "";let t=Object.entries(e).filter(([,r])=>r!=null);if(t.length===0)return "";let n=globalThis?.URLSearchParams,o="";if(n){let r=new n;for(let[a,s]of t)if(Array.isArray(s))for(let i of s)r.append(a,String(i));else r.append(a,String(s));o=r.toString();}else o=t.flatMap(([r,a])=>Array.isArray(a)?a.map(s=>[r,s]):[[r,a]]).map(([r,a])=>`${encodeURIComponent(r)}=${encodeURIComponent(String(a))}`).join("&");return o?`?${o}`:""}function w(e,t){let n=H(t);return n?e.includes("?")?`${e}&${n.slice(1)}`:`${e}${n}`:e}function $(){let e="";try{let t=globalThis.import?.meta?.env;t&&(e=t.TARO_APP_API_BASE_URL||t.VITE_API_BASE_URL||"");}catch{}return !e&&typeof process<"u"&&process?.env&&(e=process.env.TARO_APP_API_BASE_URL||process.env.VITE_API_BASE_URL||""),String(e||"").trim()}function B(e,t){let n=String(e.url||"");if(U(n))return w(n,e.params);let o=String(e.baseURL||t?.baseURL||$()||"").trim(),r=o?_(o,n):n;return w(r,e.params)}function C(){let e=globalThis;return typeof e?.Taro?.request=="function"?e.Taro.request.bind(e.Taro):typeof e?.wx?.request=="function"?e.wx.request.bind(e.wx):typeof e?.tt?.request=="function"?e.tt.request.bind(e.tt):typeof e?.my?.request=="function"?e.my.request.bind(e.my):typeof e?.swan?.request=="function"?e.swan.request.bind(e.swan):typeof e?.qq?.request=="function"?e.qq.request.bind(e.qq):typeof e?.jd?.request=="function"?e.jd.request.bind(e.jd):null}async function I(e,t){try{let n=e(t);if(n&&typeof n.then=="function")return await n}catch{}return await new Promise((n,o)=>{e({...t,success:r=>n(r),fail:r=>o(r)});})}function b(e,t){let n={...e||{}};if(!t)return n;if(typeof t=="object")for(let[o,r]of Object.entries(t))r!=null&&(n[o]=String(r));return n}async function j(e,t){let n=C();if(!n)throw new Error("Mini-program request API not found (wx/tt/my/... or global Taro.request).");let o=B(e,t),r=String(e.method||"GET").toUpperCase(),a=b(t?.headers,e.headers),s=await I(n,{url:o,method:r,header:a,data:e.data});return {status:s?.statusCode??s?.status??0,data:s?.data,headers:s?.header}}function h(e){let t=e;return typeof t=="function"&&!!t?.defaults&&!!t?.interceptors}function A(e,t,n,o,r=true){if(!r)return;let a=String(e.method||"GET").toUpperCase(),s=e.url;console.error(`[HTTP Error] ${a} ${s} - ${t} ${n}`,`
1
+ 'use strict';function q(e){if(!e)return "Request failed";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;return t.message||t.error||t.msg||t.detail||"Request failed"}return "Request failed"}function k(e){if(!e||typeof e!="object"||!("data"in e))return false;if("status"in e){let t=e.status;return t===0||t===1||t==="0"||t==="1"}return false}function E(e){return k(e)?e.data:e}var x=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;function P(e){return x.test(e)}function S(e){return `${e.replace(" ","T")}.000Z`}function m(e){if(e==null)return e;if(Array.isArray(e))return e.map(t=>m(t));if(typeof e=="object"){let t={};for(let[n,o]of Object.entries(e))t[n]=m(o);return t}return typeof e=="string"&&P(e)?S(e):e}function U(e){return /^https?:\/\//i.test(e)}function _(e,t){let n=e.replace(/\/+$/,""),o=t.startsWith("/")?t:`/${t}`;return `${n}${o}`}function H(e){if(!e||typeof e!="object")return "";let t=Object.entries(e).filter(([,r])=>r!=null);if(t.length===0)return "";let n=globalThis?.URLSearchParams,o="";if(n){let r=new n;for(let[a,s]of t)if(Array.isArray(s))for(let i of s)r.append(a,String(i));else r.append(a,String(s));o=r.toString();}else o=t.flatMap(([r,a])=>Array.isArray(a)?a.map(s=>[r,s]):[[r,a]]).map(([r,a])=>`${encodeURIComponent(r)}=${encodeURIComponent(String(a))}`).join("&");return o?`?${o}`:""}function w(e,t){let n=H(t);return n?e.includes("?")?`${e}&${n.slice(1)}`:`${e}${n}`:e}function $(){let e="";try{let t=globalThis.import?.meta?.env;t&&(e=t.TARO_APP_API_BASE_URL||t.VITE_API_BASE_URL||"");}catch{}return e||(e=process.env.TARO_APP_API_BASE_URL||process.env.VITE_API_BASE_URL||""),String(e||"").trim()}function B(e,t){let n=String(e.url||"");if(U(n))return w(n,e.params);let o=String(e.baseURL||t?.baseURL||$()||"").trim(),r=o?_(o,n):n;return w(r,e.params)}function C(){let e=globalThis;return typeof e?.Taro?.request=="function"?e.Taro.request.bind(e.Taro):typeof e?.wx?.request=="function"?e.wx.request.bind(e.wx):typeof e?.tt?.request=="function"?e.tt.request.bind(e.tt):typeof e?.my?.request=="function"?e.my.request.bind(e.my):typeof e?.swan?.request=="function"?e.swan.request.bind(e.swan):typeof e?.qq?.request=="function"?e.qq.request.bind(e.qq):typeof e?.jd?.request=="function"?e.jd.request.bind(e.jd):null}async function I(e,t){try{let n=e(t);if(n&&typeof n.then=="function")return await n}catch{}return await new Promise((n,o)=>{e({...t,success:r=>n(r),fail:r=>o(r)});})}function b(e,t){let n={...e||{}};if(!t)return n;if(typeof t=="object")for(let[o,r]of Object.entries(t))r!=null&&(n[o]=String(r));return n}async function j(e,t){let n=C();if(!n)throw new Error("Mini-program request API not found (wx/tt/my/... or global Taro.request).");let o=B(e,t),r=String(e.method||"GET").toUpperCase(),a=b(t?.headers,e.headers),s=await I(n,{url:o,method:r,header:a,data:e.data});return {status:s?.statusCode??s?.status??0,data:s?.data,headers:s?.header}}function h(e){let t=e;return typeof t=="function"&&!!t?.defaults&&!!t?.interceptors}function A(e,t,n,o,r=true){if(!r)return;let a=String(e.method||"GET").toUpperCase(),s=e.url;console.error(`[HTTP Error] ${a} ${s} - ${t} ${n}`,`
2
2
  \u2192 Details:`,o);}function v(e){let t,n,o=false;h(e)?(t=e,o=true):(n=e,n?.adapter&&h(n.adapter)&&(t=n.adapter,o=true,n={...n,adapter:void 0}));let r=n?.adapter??(C()?"taro":"axios");return {async request(a){try{let s=0,i=null,d=typeof r=="function"?r:r==="taro"?"taro":"axios";if(typeof d=="function"){let u=await d(a);s=u.status??0,i=u.data??null;}else if(d==="taro"){let u=await j(a,n);s=u.status??0,i=u.data??null;}else {t||(t=(await import('axios')).default.create());let u=a;if(o){let g=t.defaults.headers||{},T=a.headers||{},R={};for(let[c,y]of Object.entries(g))c==="common"||c==="get"||c==="post"||c==="put"||c==="patch"||c==="delete"||c==="head"||c==="options"||y!=null&&(R[c]=String(y));u={...a,headers:{...R,...T}};}else n?.headers&&(u={...a,headers:b(n.headers,a.headers)});let p=await t(u);s=p?.status??0,i=p?.data;}if(s>=200&&s<300){let p=(n?.transformResponse??E)(i);return {data:m(p)??null,error:null,status:s}}let f=q(i)||`HTTP ${s}`,l=n?.logErrors!==!1;return A(a,s,f,i,l),{data:null,error:{status:s,message:f,details:i},status:s}}catch(s){let i=s,d=i?.response?.status||i?.statusCode||0,f=i?.response?.data??i?.data,l=q(f)||i?.message||"Network error",u=n?.logErrors!==false;return A(a,d,l,f||i,u),{data:null,error:{status:d,message:l,details:f},status:d}}}}}exports.createHttpClient=v;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http.ts"],"names":["normalizeErrorMessage","payload","errorPayload","isBackendStandardFormat","data","status","defaultUnwrapBackendResponse","responseData","BACKEND_DATETIME_REGEX","isBackendDatetime","value","parseBackendDatetime","processResponseDates","item","processed","key","isAbsoluteUrl","url","joinBaseUrl","baseURL","b","u","encodeQuery","params","entries","v","URLSearchParamsCtor","q","sp","k","appendParamsToUrl","readEnvBaseUrl","meta","resolveUrl","config","options","raw","withBase","getMiniProgramRequest","g","callMaybePromiseRequest","fn","ret","resolve","reject","res","err","mergeHeaders","base","extra","out","taroLikeAdapter","req","method","header","isAxiosInstance","logErrorToConsole","message","details","shouldLog","createHttpClient","axiosInstanceOrOptions","instance","isUserProvidedInstance","adapterChoice","adapter","r","finalConfig","defaultHeaders","configHeaders","flattenedDefaults","resp","transformedData","errorMessage","error_","error"],"mappings":"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","file":"index.cjs","sourcesContent":["/* eslint-disable no-unused-vars */\nimport type { AxiosInstance, AxiosRequestConfig } from \"axios\";\n\nexport type ClientError = {\n message: string;\n status?: number;\n code?: string;\n details?: unknown;\n};\n\nexport type ClientResult<T> = {\n data: T | null;\n error: ClientError | null;\n status: number;\n};\n\nexport type RequestConfig = AxiosRequestConfig & {\n url: string;\n method: NonNullable<AxiosRequestConfig[\"method\"]> | string;\n};\n\nexport type AdapterResponse = {\n status: number;\n data: unknown;\n headers?: unknown;\n};\n\nexport type HttpAdapter = (_config: RequestConfig) => Promise<AdapterResponse>;\n\nexport type HttpClientOptions = {\n /**\n * HTTP adapter to use:\n * - undefined: auto-detect (taro if mini-program APIs exist, otherwise axios)\n * - \"taro\": force mini-program request (wx/tt/my/...) or global Taro.request\n * - \"axios\": force axios\n * - AxiosInstance: use provided axios instance\n * - function: custom adapter\n */\n adapter?: \"taro\" | \"axios\" | AxiosInstance | HttpAdapter;\n /**\n * Base URL to prefix when `config.url` is relative (e.g. \"/api/...\").\n * \n * If not provided:\n * - Taro/mini-program: auto-reads from process.env.TARO_APP_API_BASE_URL or process.env.VITE_API_BASE_URL\n * - H5/Browser: no baseURL (expects dev proxy or absolute URLs)\n */\n baseURL?: string;\n /** Default headers merged into each request */\n headers?: Record<string, string>;\n /**\n * Custom response transform function to extract/modify data from backend response\n * If not provided, uses default transform logic for { status: 0/1, data: {...} }\n * \n * Similar to axios's transformResponse option\n * \n * @example\n * ```typescript\n * // For backend that returns: { statusCode: 200, data: {...} }\n * const client = createHttpClient({\n * transformResponse: (response) => {\n * if (response && typeof response === 'object' && 'data' in response) {\n * return response.data;\n * }\n * return response;\n * }\n * });\n * ```\n */\n transformResponse?: <T>(responseData: unknown) => T;\n /**\n * Whether to log errors to console (default: true)\n * Set to false to disable automatic error logging\n */\n logErrors?: boolean;\n};\n\nexport type HttpClient = {\n request<T>(\n _config: RequestConfig\n ): Promise<ClientResult<T>>;\n};\n\ninterface ErrorPayload {\n message?: string;\n error?: string;\n msg?: string;\n detail?: string;\n}\n\nfunction normalizeErrorMessage(payload: unknown): string {\n if (!payload) {\n return \"Request failed\";\n }\n if (typeof payload === \"string\") {\n return payload;\n }\n if (typeof payload === \"object\") {\n const errorPayload = payload as ErrorPayload;\n return (\n errorPayload.message ||\n errorPayload.error ||\n errorPayload.msg ||\n errorPayload.detail ||\n \"Request failed\"\n );\n }\n return \"Request failed\";\n}\n\ninterface BackendStandardResponse {\n status: number | string;\n data: unknown;\n}\n\n/**\n * Check if response data matches backend standard format: { status: 0/1, data: {...} }\n * Handles both number and string status values\n */\nfunction isBackendStandardFormat(data: unknown): data is BackendStandardResponse {\n if (!data || typeof data !== \"object\" || !(\"data\" in data)) {\n return false;\n }\n\n // Check status field - handle both number and string values\n if (\"status\" in data) {\n const status = (data as BackendStandardResponse).status;\n // Accept 0, 1, \"0\", \"1\" as valid status values\n return status === 0 || status === 1 || status === \"0\" || status === \"1\";\n }\n\n return false;\n}\n\n/**\n * Default unwrap logic for backend standard format response\n * Backend returns: { status: 0, data: {...} }\n * We extract the inner 'data' field for cleaner client usage\n */\nfunction defaultUnwrapBackendResponse<T>(responseData: unknown): T {\n if (isBackendStandardFormat(responseData)) {\n // Extract inner data field\n return responseData.data as T;\n }\n // Return as-is if not standard format (e.g., BPM/Workflow APIs)\n return responseData as T;\n}\n\n/**\n * Backend datetime format regex: \"YYYY-MM-DD HH:MM:SS\"\n */\nconst BACKEND_DATETIME_REGEX = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/;\n\n/**\n * Check if a string matches backend datetime format\n */\nfunction isBackendDatetime(value: string): boolean {\n return BACKEND_DATETIME_REGEX.test(value);\n}\n\n/**\n * Convert backend datetime string to ISO 8601 format\n * \"2026-01-05 10:30:45\" → \"2026-01-05T10:30:45.000Z\"\n */\nfunction parseBackendDatetime(value: string): string {\n // Replace space with T and append Z for UTC\n return `${value.replace(\" \", \"T\")}.000Z`;\n}\n\n/**\n * Recursively process response data to convert backend datetime strings to ISO format\n * Handles nested objects and arrays\n */\nfunction processResponseDates(data: unknown): unknown {\n if (data === null || data === undefined) {\n return data;\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map((item) => processResponseDates(item));\n }\n\n // Handle objects\n if (typeof data === \"object\") {\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n processed[key] = processResponseDates(value);\n }\n return processed;\n }\n\n // Handle backend datetime strings\n if (typeof data === \"string\" && isBackendDatetime(data)) {\n return parseBackendDatetime(data);\n }\n\n return data;\n}\n\nfunction isAbsoluteUrl(url: string): boolean {\n return /^https?:\\/\\//i.test(url);\n}\n\nfunction joinBaseUrl(baseURL: string, url: string): string {\n const b = baseURL.replace(/\\/+$/, \"\");\n const u = url.startsWith(\"/\") ? url : `/${url}`;\n return `${b}${u}`;\n}\n\nfunction encodeQuery(params: unknown): string {\n if (!params || typeof params !== \"object\") return \"\";\n const entries = Object.entries(params as Record<string, unknown>).filter(\n ([, v]) => v !== undefined && v !== null\n );\n if (entries.length === 0) return \"\";\n const URLSearchParamsCtor = (globalThis as any)?.URLSearchParams as\n | (new () => { append: (k: string, v: string) => void; toString: () => string })\n | undefined;\n\n let q = \"\";\n if (URLSearchParamsCtor) {\n const sp = new URLSearchParamsCtor();\n for (const [k, v] of entries) {\n if (Array.isArray(v)) {\n for (const item of v) sp.append(k, String(item));\n } else {\n sp.append(k, String(v));\n }\n }\n q = sp.toString();\n } else {\n // Minimal fallback (older runtimes): k=v&k=v...\n q = entries\n .flatMap(([k, v]) =>\n Array.isArray(v) ? v.map((item) => [k, item] as const) : ([[k, v]] as const)\n )\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join(\"&\");\n }\n return q ? `?${q}` : \"\";\n}\n\nfunction appendParamsToUrl(url: string, params: unknown): string {\n const q = encodeQuery(params);\n if (!q) return url;\n if (url.includes(\"?\")) return `${url}&${q.slice(1)}`;\n return `${url}${q}`;\n}\n\nfunction readEnvBaseUrl(): string {\n // Safely access environment variables across different environments\n // - Browser with Vite: import.meta.env.VITE_*\n // - Node.js: process.env.*\n // - Taro/Mini-program: process.env.TARO_APP_* (replaced at build time)\n let value = \"\";\n \n // Try import.meta.env first (Vite browser environment)\n try {\n const meta = (globalThis as any).import?.meta?.env;\n if (meta) {\n value = meta.TARO_APP_API_BASE_URL || meta.VITE_API_BASE_URL || \"\";\n }\n } catch {\n // import.meta may not be available\n }\n \n // Fallback to process.env (Node.js / build-time replacement)\n if (!value && typeof process !== \"undefined\" && process?.env) {\n value =\n process.env.TARO_APP_API_BASE_URL ||\n process.env.VITE_API_BASE_URL ||\n \"\";\n }\n \n return String(value || \"\").trim();\n}\n\nfunction resolveUrl(config: RequestConfig, options?: HttpClientOptions): string {\n const raw = String(config.url || \"\");\n if (isAbsoluteUrl(raw)) return appendParamsToUrl(raw, (config as any).params);\n\n const baseURL =\n String((config as any).baseURL || options?.baseURL || readEnvBaseUrl() || \"\").trim();\n const withBase = baseURL ? joinBaseUrl(baseURL, raw) : raw;\n return appendParamsToUrl(withBase, (config as any).params);\n}\n\nfunction getMiniProgramRequest():\n | ((_options: any) => any)\n | null {\n const g: any = globalThis as any;\n if (typeof g?.Taro?.request === \"function\") return g.Taro.request.bind(g.Taro);\n if (typeof g?.wx?.request === \"function\") return g.wx.request.bind(g.wx);\n if (typeof g?.tt?.request === \"function\") return g.tt.request.bind(g.tt);\n if (typeof g?.my?.request === \"function\") return g.my.request.bind(g.my);\n if (typeof g?.swan?.request === \"function\") return g.swan.request.bind(g.swan);\n if (typeof g?.qq?.request === \"function\") return g.qq.request.bind(g.qq);\n if (typeof g?.jd?.request === \"function\") return g.jd.request.bind(g.jd);\n return null;\n}\n\nasync function callMaybePromiseRequest(fn: (options: any) => any, options: any): Promise<any> {\n try {\n const ret = fn(options);\n if (ret && typeof ret.then === \"function\") {\n return await ret;\n }\n } catch {\n // fall through to callback-style below\n }\n\n return await new Promise((resolve, reject) => {\n fn({\n ...options,\n success: (res: any) => resolve(res),\n fail: (err: any) => reject(err),\n });\n });\n}\n\nfunction mergeHeaders(\n base: Record<string, string> | undefined,\n extra: unknown\n): Record<string, string> {\n const out: Record<string, string> = { ...(base || {}) };\n if (!extra) return out;\n if (typeof extra === \"object\") {\n for (const [k, v] of Object.entries(extra as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n out[k] = String(v);\n }\n }\n return out;\n}\n\nasync function taroLikeAdapter(config: RequestConfig, options?: HttpClientOptions): Promise<AdapterResponse> {\n const req = getMiniProgramRequest();\n if (!req) {\n throw new Error(\"Mini-program request API not found (wx/tt/my/... or global Taro.request).\");\n }\n const url = resolveUrl(config, options);\n const method = String(config.method || \"GET\").toUpperCase();\n const header = mergeHeaders(options?.headers, (config as any).headers);\n\n const res = await callMaybePromiseRequest(req, {\n url,\n method,\n header,\n data: (config as any).data,\n });\n\n const status = (res?.statusCode ?? res?.status ?? 0) as number;\n return { status, data: res?.data, headers: res?.header };\n}\n\nfunction isAxiosInstance(value: unknown): value is AxiosInstance {\n const v: any = value as any;\n // axios instance is callable and has defaults + interceptors\n return typeof v === \"function\" && !!v?.defaults && !!v?.interceptors;\n}\n\n/**\n * Log error to console with detailed information\n * Only logs if logErrors option is not explicitly set to false\n */\nfunction logErrorToConsole(\n config: RequestConfig,\n status: number,\n message: string,\n details: unknown,\n shouldLog: boolean = true\n): void {\n if (!shouldLog) return;\n\n const method = String(config.method || \"GET\").toUpperCase();\n const url = config.url;\n\n // Format error message with request context\n console.error(\n `[HTTP Error] ${method} ${url} - ${status} ${message}`,\n \"\\n→ Details:\",\n details\n );\n}\n\n/**\n * Create an HTTP client instance\n * \n * @param axiosInstance - Optional axios instance to use (defaults to a basic axios instance)\n * @returns HttpClient with request method\n * \n * @example\n * ```typescript\n * import axios from \"axios\";\n * import { createHttpClient } from \"@amaster.ai/http-client\";\n * \n * const instance = axios.create({ baseURL: \"https://api.example.com\" });\n * const client = createHttpClient(instance);\n * \n * const result = await client.request({\n * url: \"/users\",\n * method: \"get\",\n * });\n * ```\n */\nexport function createHttpClient(axiosInstanceOrOptions?: AxiosInstance | HttpClientOptions): HttpClient {\n // Import axios dynamically to avoid bundling it\n let instance: AxiosInstance | undefined;\n let options: HttpClientOptions | undefined;\n let isUserProvidedInstance = false;\n\n if (isAxiosInstance(axiosInstanceOrOptions)) {\n instance = axiosInstanceOrOptions;\n isUserProvidedInstance = true;\n } else {\n options = axiosInstanceOrOptions;\n // Check if adapter is an axios instance\n if (options?.adapter && isAxiosInstance(options.adapter)) {\n instance = options.adapter;\n isUserProvidedInstance = true;\n // Remove adapter from options to avoid confusion\n options = { ...options, adapter: undefined };\n }\n }\n\n // Smart default: auto-detect environment\n // - If mini-program APIs exist (wx/tt/my/Taro.request) → use taro adapter\n // - Otherwise → use axios (for H5/browser)\n // User can still explicitly override via { adapter: \"axios\" } or { adapter: \"taro\" }\n const adapterChoice = options?.adapter ?? (getMiniProgramRequest() ? \"taro\" : \"axios\");\n \n return {\n async request<T>(\n config: RequestConfig\n ) {\n try {\n let status = 0;\n let responseData: unknown = null;\n\n const adapter =\n typeof adapterChoice === \"function\" ? adapterChoice :\n adapterChoice === \"taro\" ? \"taro\" :\n \"axios\";\n\n if (typeof adapter === \"function\") {\n const r = await adapter(config);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else if (adapter === \"taro\") {\n const r = await taroLikeAdapter(config, options);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else {\n // axios path\n if (!instance) {\n const axios = await import(\"axios\");\n instance = axios.default.create();\n }\n \n // Axios behavior: if config.headers is set, it REPLACES defaults.headers\n // We need to manually merge instance defaults with request headers\n let finalConfig: any = config;\n \n if (isUserProvidedInstance) {\n // For user-provided instances, merge defaults.headers with config.headers\n const defaultHeaders = instance.defaults.headers || {};\n const configHeaders = (config as any).headers || {};\n \n // Flatten axios headers structure (common, get, post, etc. + top-level)\n const flattenedDefaults: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaultHeaders)) {\n if (key === 'common' || key === 'get' || key === 'post' || key === 'put' || \n key === 'patch' || key === 'delete' || key === 'head' || key === 'options') {\n // These are method-specific headers, skip for now\n continue;\n }\n if (value !== undefined && value !== null) {\n flattenedDefaults[key] = String(value);\n }\n }\n \n // Merge: defaults < config headers\n finalConfig = {\n ...config,\n headers: { ...flattenedDefaults, ...configHeaders },\n };\n } else if (options?.headers) {\n // For auto-created instances, merge options.headers\n finalConfig = {\n ...config,\n headers: mergeHeaders(options.headers, (config as any).headers),\n };\n }\n \n const resp = await instance(finalConfig);\n status = resp?.status ?? 0;\n responseData = resp?.data;\n }\n\n if (status >= 200 && status < 300) {\n // Transform backend response using custom or default logic\n const transformFn = options?.transformResponse ?? defaultUnwrapBackendResponse;\n const transformedData = transformFn<T>(responseData);\n // Convert backend datetime strings to ISO format\n const processedData = processResponseDates(transformedData);\n return { data: (processedData ?? null) as T | null, error: null, status };\n }\n\n // Non-2xx status code - log error before returning\n const errorMessage = normalizeErrorMessage(responseData) || `HTTP ${status}`;\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, responseData, shouldLog);\n\n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details: responseData,\n },\n status,\n };\n } catch (error_: unknown) {\n // Catch network errors, timeouts, and other exceptions\n const error = error_ as any;\n const status = error?.response?.status || error?.statusCode || 0;\n const details = error?.response?.data ?? error?.data;\n const errorMessage = normalizeErrorMessage(details) || error?.message || \"Network error\";\n \n // Log error to console\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, details || error, shouldLog);\n \n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details,\n },\n status,\n };\n }\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/http.ts"],"names":["normalizeErrorMessage","payload","errorPayload","isBackendStandardFormat","data","status","defaultUnwrapBackendResponse","responseData","BACKEND_DATETIME_REGEX","isBackendDatetime","value","parseBackendDatetime","processResponseDates","item","processed","key","isAbsoluteUrl","url","joinBaseUrl","baseURL","b","u","encodeQuery","params","entries","v","URLSearchParamsCtor","q","sp","k","appendParamsToUrl","readEnvBaseUrl","meta","resolveUrl","config","options","raw","withBase","getMiniProgramRequest","g","callMaybePromiseRequest","fn","ret","resolve","reject","res","err","mergeHeaders","base","extra","out","taroLikeAdapter","req","method","header","isAxiosInstance","logErrorToConsole","message","details","shouldLog","createHttpClient","axiosInstanceOrOptions","instance","isUserProvidedInstance","adapterChoice","adapter","r","finalConfig","defaultHeaders","configHeaders","flattenedDefaults","resp","transformedData","errorMessage","error_","error"],"mappings":"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","file":"index.cjs","sourcesContent":["/* eslint-disable no-unused-vars */\nimport type { AxiosInstance, AxiosRequestConfig } from \"axios\";\n\nexport type ClientError = {\n message: string;\n status?: number;\n code?: string;\n details?: unknown;\n};\n\nexport type ClientResult<T> = {\n data: T | null;\n error: ClientError | null;\n status: number;\n};\n\nexport type RequestConfig = AxiosRequestConfig & {\n url: string;\n method: NonNullable<AxiosRequestConfig[\"method\"]> | string;\n};\n\nexport type AdapterResponse = {\n status: number;\n data: unknown;\n headers?: unknown;\n};\n\nexport type HttpAdapter = (_config: RequestConfig) => Promise<AdapterResponse>;\n\nexport type HttpClientOptions = {\n /**\n * HTTP adapter to use:\n * - undefined: auto-detect (taro if mini-program APIs exist, otherwise axios)\n * - \"taro\": force mini-program request (wx/tt/my/...) or global Taro.request\n * - \"axios\": force axios\n * - AxiosInstance: use provided axios instance\n * - function: custom adapter\n */\n adapter?: \"taro\" | \"axios\" | AxiosInstance | HttpAdapter;\n /**\n * Base URL to prefix when `config.url` is relative (e.g. \"/api/...\").\n * \n * If not provided:\n * - Taro/mini-program: auto-reads from process.env.TARO_APP_API_BASE_URL or process.env.VITE_API_BASE_URL\n * - H5/Browser: no baseURL (expects dev proxy or absolute URLs)\n */\n baseURL?: string;\n /** Default headers merged into each request */\n headers?: Record<string, string>;\n /**\n * Custom response transform function to extract/modify data from backend response\n * If not provided, uses default transform logic for { status: 0/1, data: {...} }\n * \n * Similar to axios's transformResponse option\n * \n * @example\n * ```typescript\n * // For backend that returns: { statusCode: 200, data: {...} }\n * const client = createHttpClient({\n * transformResponse: (response) => {\n * if (response && typeof response === 'object' && 'data' in response) {\n * return response.data;\n * }\n * return response;\n * }\n * });\n * ```\n */\n transformResponse?: <T>(responseData: unknown) => T;\n /**\n * Whether to log errors to console (default: true)\n * Set to false to disable automatic error logging\n */\n logErrors?: boolean;\n};\n\nexport type HttpClient = {\n request<T>(\n _config: RequestConfig\n ): Promise<ClientResult<T>>;\n};\n\ninterface ErrorPayload {\n message?: string;\n error?: string;\n msg?: string;\n detail?: string;\n}\n\nfunction normalizeErrorMessage(payload: unknown): string {\n if (!payload) {\n return \"Request failed\";\n }\n if (typeof payload === \"string\") {\n return payload;\n }\n if (typeof payload === \"object\") {\n const errorPayload = payload as ErrorPayload;\n return (\n errorPayload.message ||\n errorPayload.error ||\n errorPayload.msg ||\n errorPayload.detail ||\n \"Request failed\"\n );\n }\n return \"Request failed\";\n}\n\ninterface BackendStandardResponse {\n status: number | string;\n data: unknown;\n}\n\n/**\n * Check if response data matches backend standard format: { status: 0/1, data: {...} }\n * Handles both number and string status values\n */\nfunction isBackendStandardFormat(data: unknown): data is BackendStandardResponse {\n if (!data || typeof data !== \"object\" || !(\"data\" in data)) {\n return false;\n }\n\n // Check status field - handle both number and string values\n if (\"status\" in data) {\n const status = (data as BackendStandardResponse).status;\n // Accept 0, 1, \"0\", \"1\" as valid status values\n return status === 0 || status === 1 || status === \"0\" || status === \"1\";\n }\n\n return false;\n}\n\n/**\n * Default unwrap logic for backend standard format response\n * Backend returns: { status: 0, data: {...} }\n * We extract the inner 'data' field for cleaner client usage\n */\nfunction defaultUnwrapBackendResponse<T>(responseData: unknown): T {\n if (isBackendStandardFormat(responseData)) {\n // Extract inner data field\n return responseData.data as T;\n }\n // Return as-is if not standard format (e.g., BPM/Workflow APIs)\n return responseData as T;\n}\n\n/**\n * Backend datetime format regex: \"YYYY-MM-DD HH:MM:SS\"\n */\nconst BACKEND_DATETIME_REGEX = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/;\n\n/**\n * Check if a string matches backend datetime format\n */\nfunction isBackendDatetime(value: string): boolean {\n return BACKEND_DATETIME_REGEX.test(value);\n}\n\n/**\n * Convert backend datetime string to ISO 8601 format\n * \"2026-01-05 10:30:45\" → \"2026-01-05T10:30:45.000Z\"\n */\nfunction parseBackendDatetime(value: string): string {\n // Replace space with T and append Z for UTC\n return `${value.replace(\" \", \"T\")}.000Z`;\n}\n\n/**\n * Recursively process response data to convert backend datetime strings to ISO format\n * Handles nested objects and arrays\n */\nfunction processResponseDates(data: unknown): unknown {\n if (data === null || data === undefined) {\n return data;\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map((item) => processResponseDates(item));\n }\n\n // Handle objects\n if (typeof data === \"object\") {\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n processed[key] = processResponseDates(value);\n }\n return processed;\n }\n\n // Handle backend datetime strings\n if (typeof data === \"string\" && isBackendDatetime(data)) {\n return parseBackendDatetime(data);\n }\n\n return data;\n}\n\nfunction isAbsoluteUrl(url: string): boolean {\n return /^https?:\\/\\//i.test(url);\n}\n\nfunction joinBaseUrl(baseURL: string, url: string): string {\n const b = baseURL.replace(/\\/+$/, \"\");\n const u = url.startsWith(\"/\") ? url : `/${url}`;\n return `${b}${u}`;\n}\n\nfunction encodeQuery(params: unknown): string {\n if (!params || typeof params !== \"object\") return \"\";\n const entries = Object.entries(params as Record<string, unknown>).filter(\n ([, v]) => v !== undefined && v !== null\n );\n if (entries.length === 0) return \"\";\n const URLSearchParamsCtor = (globalThis as any)?.URLSearchParams as\n | (new () => { append: (k: string, v: string) => void; toString: () => string })\n | undefined;\n\n let q = \"\";\n if (URLSearchParamsCtor) {\n const sp = new URLSearchParamsCtor();\n for (const [k, v] of entries) {\n if (Array.isArray(v)) {\n for (const item of v) sp.append(k, String(item));\n } else {\n sp.append(k, String(v));\n }\n }\n q = sp.toString();\n } else {\n // Minimal fallback (older runtimes): k=v&k=v...\n q = entries\n .flatMap(([k, v]) =>\n Array.isArray(v) ? v.map((item) => [k, item] as const) : ([[k, v]] as const)\n )\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join(\"&\");\n }\n return q ? `?${q}` : \"\";\n}\n\nfunction appendParamsToUrl(url: string, params: unknown): string {\n const q = encodeQuery(params);\n if (!q) return url;\n if (url.includes(\"?\")) return `${url}&${q.slice(1)}`;\n return `${url}${q}`;\n}\n\nfunction readEnvBaseUrl(): string {\n // Safely access environment variables across different environments\n // - Browser with Vite: import.meta.env.VITE_*\n // - Node.js: process.env.*\n // - Taro/Mini-program: process.env.TARO_APP_* (replaced at build time)\n let value = \"\";\n \n // Try import.meta.env first (Vite browser environment)\n try {\n const meta = (globalThis as any).import?.meta?.env;\n if (meta) {\n value = meta.TARO_APP_API_BASE_URL || meta.VITE_API_BASE_URL || \"\";\n }\n } catch {\n // import.meta may not be available\n }\n \n // Fallback to process.env (Node.js / build-time replacement)\n if (!value) {\n value =\n process.env.TARO_APP_API_BASE_URL ||\n process.env.VITE_API_BASE_URL ||\n \"\";\n }\n \n return String(value || \"\").trim();\n}\n\nfunction resolveUrl(config: RequestConfig, options?: HttpClientOptions): string {\n const raw = String(config.url || \"\");\n if (isAbsoluteUrl(raw)) return appendParamsToUrl(raw, (config as any).params);\n\n const baseURL =\n String((config as any).baseURL || options?.baseURL || readEnvBaseUrl() || \"\").trim();\n const withBase = baseURL ? joinBaseUrl(baseURL, raw) : raw;\n return appendParamsToUrl(withBase, (config as any).params);\n}\n\nfunction getMiniProgramRequest():\n | ((_options: any) => any)\n | null {\n const g: any = globalThis as any;\n if (typeof g?.Taro?.request === \"function\") return g.Taro.request.bind(g.Taro);\n if (typeof g?.wx?.request === \"function\") return g.wx.request.bind(g.wx);\n if (typeof g?.tt?.request === \"function\") return g.tt.request.bind(g.tt);\n if (typeof g?.my?.request === \"function\") return g.my.request.bind(g.my);\n if (typeof g?.swan?.request === \"function\") return g.swan.request.bind(g.swan);\n if (typeof g?.qq?.request === \"function\") return g.qq.request.bind(g.qq);\n if (typeof g?.jd?.request === \"function\") return g.jd.request.bind(g.jd);\n return null;\n}\n\nasync function callMaybePromiseRequest(fn: (options: any) => any, options: any): Promise<any> {\n try {\n const ret = fn(options);\n if (ret && typeof ret.then === \"function\") {\n return await ret;\n }\n } catch {\n // fall through to callback-style below\n }\n\n return await new Promise((resolve, reject) => {\n fn({\n ...options,\n success: (res: any) => resolve(res),\n fail: (err: any) => reject(err),\n });\n });\n}\n\nfunction mergeHeaders(\n base: Record<string, string> | undefined,\n extra: unknown\n): Record<string, string> {\n const out: Record<string, string> = { ...(base || {}) };\n if (!extra) return out;\n if (typeof extra === \"object\") {\n for (const [k, v] of Object.entries(extra as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n out[k] = String(v);\n }\n }\n return out;\n}\n\nasync function taroLikeAdapter(config: RequestConfig, options?: HttpClientOptions): Promise<AdapterResponse> {\n const req = getMiniProgramRequest();\n if (!req) {\n throw new Error(\"Mini-program request API not found (wx/tt/my/... or global Taro.request).\");\n }\n const url = resolveUrl(config, options);\n const method = String(config.method || \"GET\").toUpperCase();\n const header = mergeHeaders(options?.headers, (config as any).headers);\n\n const res = await callMaybePromiseRequest(req, {\n url,\n method,\n header,\n data: (config as any).data,\n });\n\n const status = (res?.statusCode ?? res?.status ?? 0) as number;\n return { status, data: res?.data, headers: res?.header };\n}\n\nfunction isAxiosInstance(value: unknown): value is AxiosInstance {\n const v: any = value as any;\n // axios instance is callable and has defaults + interceptors\n return typeof v === \"function\" && !!v?.defaults && !!v?.interceptors;\n}\n\n/**\n * Log error to console with detailed information\n * Only logs if logErrors option is not explicitly set to false\n */\nfunction logErrorToConsole(\n config: RequestConfig,\n status: number,\n message: string,\n details: unknown,\n shouldLog: boolean = true\n): void {\n if (!shouldLog) return;\n\n const method = String(config.method || \"GET\").toUpperCase();\n const url = config.url;\n\n // Format error message with request context\n console.error(\n `[HTTP Error] ${method} ${url} - ${status} ${message}`,\n \"\\n→ Details:\",\n details\n );\n}\n\n/**\n * Create an HTTP client instance\n * \n * @param axiosInstance - Optional axios instance to use (defaults to a basic axios instance)\n * @returns HttpClient with request method\n * \n * @example\n * ```typescript\n * import axios from \"axios\";\n * import { createHttpClient } from \"@amaster.ai/http-client\";\n * \n * const instance = axios.create({ baseURL: \"https://api.example.com\" });\n * const client = createHttpClient(instance);\n * \n * const result = await client.request({\n * url: \"/users\",\n * method: \"get\",\n * });\n * ```\n */\nexport function createHttpClient(axiosInstanceOrOptions?: AxiosInstance | HttpClientOptions): HttpClient {\n // Import axios dynamically to avoid bundling it\n let instance: AxiosInstance | undefined;\n let options: HttpClientOptions | undefined;\n let isUserProvidedInstance = false;\n\n if (isAxiosInstance(axiosInstanceOrOptions)) {\n instance = axiosInstanceOrOptions;\n isUserProvidedInstance = true;\n } else {\n options = axiosInstanceOrOptions;\n // Check if adapter is an axios instance\n if (options?.adapter && isAxiosInstance(options.adapter)) {\n instance = options.adapter;\n isUserProvidedInstance = true;\n // Remove adapter from options to avoid confusion\n options = { ...options, adapter: undefined };\n }\n }\n\n // Smart default: auto-detect environment\n // - If mini-program APIs exist (wx/tt/my/Taro.request) → use taro adapter\n // - Otherwise → use axios (for H5/browser)\n // User can still explicitly override via { adapter: \"axios\" } or { adapter: \"taro\" }\n const adapterChoice = options?.adapter ?? (getMiniProgramRequest() ? \"taro\" : \"axios\");\n \n return {\n async request<T>(\n config: RequestConfig\n ) {\n try {\n let status = 0;\n let responseData: unknown = null;\n\n const adapter =\n typeof adapterChoice === \"function\" ? adapterChoice :\n adapterChoice === \"taro\" ? \"taro\" :\n \"axios\";\n\n if (typeof adapter === \"function\") {\n const r = await adapter(config);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else if (adapter === \"taro\") {\n const r = await taroLikeAdapter(config, options);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else {\n // axios path\n if (!instance) {\n const axios = await import(\"axios\");\n instance = axios.default.create();\n }\n \n // Axios behavior: if config.headers is set, it REPLACES defaults.headers\n // We need to manually merge instance defaults with request headers\n let finalConfig: any = config;\n \n if (isUserProvidedInstance) {\n // For user-provided instances, merge defaults.headers with config.headers\n const defaultHeaders = instance.defaults.headers || {};\n const configHeaders = (config as any).headers || {};\n \n // Flatten axios headers structure (common, get, post, etc. + top-level)\n const flattenedDefaults: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaultHeaders)) {\n if (key === 'common' || key === 'get' || key === 'post' || key === 'put' || \n key === 'patch' || key === 'delete' || key === 'head' || key === 'options') {\n // These are method-specific headers, skip for now\n continue;\n }\n if (value !== undefined && value !== null) {\n flattenedDefaults[key] = String(value);\n }\n }\n \n // Merge: defaults < config headers\n finalConfig = {\n ...config,\n headers: { ...flattenedDefaults, ...configHeaders },\n };\n } else if (options?.headers) {\n // For auto-created instances, merge options.headers\n finalConfig = {\n ...config,\n headers: mergeHeaders(options.headers, (config as any).headers),\n };\n }\n \n const resp = await instance(finalConfig);\n status = resp?.status ?? 0;\n responseData = resp?.data;\n }\n\n if (status >= 200 && status < 300) {\n // Transform backend response using custom or default logic\n const transformFn = options?.transformResponse ?? defaultUnwrapBackendResponse;\n const transformedData = transformFn<T>(responseData);\n // Convert backend datetime strings to ISO format\n const processedData = processResponseDates(transformedData);\n return { data: (processedData ?? null) as T | null, error: null, status };\n }\n\n // Non-2xx status code - log error before returning\n const errorMessage = normalizeErrorMessage(responseData) || `HTTP ${status}`;\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, responseData, shouldLog);\n\n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details: responseData,\n },\n status,\n };\n } catch (error_: unknown) {\n // Catch network errors, timeouts, and other exceptions\n const error = error_ as any;\n const status = error?.response?.status || error?.statusCode || 0;\n const details = error?.response?.data ?? error?.data;\n const errorMessage = normalizeErrorMessage(details) || error?.message || \"Network error\";\n \n // Log error to console\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, details || error, shouldLog);\n \n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details,\n },\n status,\n };\n }\n },\n };\n}\n"]}
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- function q(e){if(!e)return "Request failed";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;return t.message||t.error||t.msg||t.detail||"Request failed"}return "Request failed"}function k(e){if(!e||typeof e!="object"||!("data"in e))return false;if("status"in e){let t=e.status;return t===0||t===1||t==="0"||t==="1"}return false}function E(e){return k(e)?e.data:e}var x=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;function P(e){return x.test(e)}function S(e){return `${e.replace(" ","T")}.000Z`}function m(e){if(e==null)return e;if(Array.isArray(e))return e.map(t=>m(t));if(typeof e=="object"){let t={};for(let[n,o]of Object.entries(e))t[n]=m(o);return t}return typeof e=="string"&&P(e)?S(e):e}function U(e){return /^https?:\/\//i.test(e)}function _(e,t){let n=e.replace(/\/+$/,""),o=t.startsWith("/")?t:`/${t}`;return `${n}${o}`}function H(e){if(!e||typeof e!="object")return "";let t=Object.entries(e).filter(([,r])=>r!=null);if(t.length===0)return "";let n=globalThis?.URLSearchParams,o="";if(n){let r=new n;for(let[a,s]of t)if(Array.isArray(s))for(let i of s)r.append(a,String(i));else r.append(a,String(s));o=r.toString();}else o=t.flatMap(([r,a])=>Array.isArray(a)?a.map(s=>[r,s]):[[r,a]]).map(([r,a])=>`${encodeURIComponent(r)}=${encodeURIComponent(String(a))}`).join("&");return o?`?${o}`:""}function w(e,t){let n=H(t);return n?e.includes("?")?`${e}&${n.slice(1)}`:`${e}${n}`:e}function $(){let e="";try{let t=globalThis.import?.meta?.env;t&&(e=t.TARO_APP_API_BASE_URL||t.VITE_API_BASE_URL||"");}catch{}return !e&&typeof process<"u"&&process?.env&&(e=process.env.TARO_APP_API_BASE_URL||process.env.VITE_API_BASE_URL||""),String(e||"").trim()}function B(e,t){let n=String(e.url||"");if(U(n))return w(n,e.params);let o=String(e.baseURL||t?.baseURL||$()||"").trim(),r=o?_(o,n):n;return w(r,e.params)}function C(){let e=globalThis;return typeof e?.Taro?.request=="function"?e.Taro.request.bind(e.Taro):typeof e?.wx?.request=="function"?e.wx.request.bind(e.wx):typeof e?.tt?.request=="function"?e.tt.request.bind(e.tt):typeof e?.my?.request=="function"?e.my.request.bind(e.my):typeof e?.swan?.request=="function"?e.swan.request.bind(e.swan):typeof e?.qq?.request=="function"?e.qq.request.bind(e.qq):typeof e?.jd?.request=="function"?e.jd.request.bind(e.jd):null}async function I(e,t){try{let n=e(t);if(n&&typeof n.then=="function")return await n}catch{}return await new Promise((n,o)=>{e({...t,success:r=>n(r),fail:r=>o(r)});})}function b(e,t){let n={...e||{}};if(!t)return n;if(typeof t=="object")for(let[o,r]of Object.entries(t))r!=null&&(n[o]=String(r));return n}async function j(e,t){let n=C();if(!n)throw new Error("Mini-program request API not found (wx/tt/my/... or global Taro.request).");let o=B(e,t),r=String(e.method||"GET").toUpperCase(),a=b(t?.headers,e.headers),s=await I(n,{url:o,method:r,header:a,data:e.data});return {status:s?.statusCode??s?.status??0,data:s?.data,headers:s?.header}}function h(e){let t=e;return typeof t=="function"&&!!t?.defaults&&!!t?.interceptors}function A(e,t,n,o,r=true){if(!r)return;let a=String(e.method||"GET").toUpperCase(),s=e.url;console.error(`[HTTP Error] ${a} ${s} - ${t} ${n}`,`
1
+ function q(e){if(!e)return "Request failed";if(typeof e=="string")return e;if(typeof e=="object"){let t=e;return t.message||t.error||t.msg||t.detail||"Request failed"}return "Request failed"}function k(e){if(!e||typeof e!="object"||!("data"in e))return false;if("status"in e){let t=e.status;return t===0||t===1||t==="0"||t==="1"}return false}function E(e){return k(e)?e.data:e}var x=/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/;function P(e){return x.test(e)}function S(e){return `${e.replace(" ","T")}.000Z`}function m(e){if(e==null)return e;if(Array.isArray(e))return e.map(t=>m(t));if(typeof e=="object"){let t={};for(let[n,o]of Object.entries(e))t[n]=m(o);return t}return typeof e=="string"&&P(e)?S(e):e}function U(e){return /^https?:\/\//i.test(e)}function _(e,t){let n=e.replace(/\/+$/,""),o=t.startsWith("/")?t:`/${t}`;return `${n}${o}`}function H(e){if(!e||typeof e!="object")return "";let t=Object.entries(e).filter(([,r])=>r!=null);if(t.length===0)return "";let n=globalThis?.URLSearchParams,o="";if(n){let r=new n;for(let[a,s]of t)if(Array.isArray(s))for(let i of s)r.append(a,String(i));else r.append(a,String(s));o=r.toString();}else o=t.flatMap(([r,a])=>Array.isArray(a)?a.map(s=>[r,s]):[[r,a]]).map(([r,a])=>`${encodeURIComponent(r)}=${encodeURIComponent(String(a))}`).join("&");return o?`?${o}`:""}function w(e,t){let n=H(t);return n?e.includes("?")?`${e}&${n.slice(1)}`:`${e}${n}`:e}function $(){let e="";try{let t=globalThis.import?.meta?.env;t&&(e=t.TARO_APP_API_BASE_URL||t.VITE_API_BASE_URL||"");}catch{}return e||(e=process.env.TARO_APP_API_BASE_URL||process.env.VITE_API_BASE_URL||""),String(e||"").trim()}function B(e,t){let n=String(e.url||"");if(U(n))return w(n,e.params);let o=String(e.baseURL||t?.baseURL||$()||"").trim(),r=o?_(o,n):n;return w(r,e.params)}function C(){let e=globalThis;return typeof e?.Taro?.request=="function"?e.Taro.request.bind(e.Taro):typeof e?.wx?.request=="function"?e.wx.request.bind(e.wx):typeof e?.tt?.request=="function"?e.tt.request.bind(e.tt):typeof e?.my?.request=="function"?e.my.request.bind(e.my):typeof e?.swan?.request=="function"?e.swan.request.bind(e.swan):typeof e?.qq?.request=="function"?e.qq.request.bind(e.qq):typeof e?.jd?.request=="function"?e.jd.request.bind(e.jd):null}async function I(e,t){try{let n=e(t);if(n&&typeof n.then=="function")return await n}catch{}return await new Promise((n,o)=>{e({...t,success:r=>n(r),fail:r=>o(r)});})}function b(e,t){let n={...e||{}};if(!t)return n;if(typeof t=="object")for(let[o,r]of Object.entries(t))r!=null&&(n[o]=String(r));return n}async function j(e,t){let n=C();if(!n)throw new Error("Mini-program request API not found (wx/tt/my/... or global Taro.request).");let o=B(e,t),r=String(e.method||"GET").toUpperCase(),a=b(t?.headers,e.headers),s=await I(n,{url:o,method:r,header:a,data:e.data});return {status:s?.statusCode??s?.status??0,data:s?.data,headers:s?.header}}function h(e){let t=e;return typeof t=="function"&&!!t?.defaults&&!!t?.interceptors}function A(e,t,n,o,r=true){if(!r)return;let a=String(e.method||"GET").toUpperCase(),s=e.url;console.error(`[HTTP Error] ${a} ${s} - ${t} ${n}`,`
2
2
  \u2192 Details:`,o);}function v(e){let t,n,o=false;h(e)?(t=e,o=true):(n=e,n?.adapter&&h(n.adapter)&&(t=n.adapter,o=true,n={...n,adapter:void 0}));let r=n?.adapter??(C()?"taro":"axios");return {async request(a){try{let s=0,i=null,d=typeof r=="function"?r:r==="taro"?"taro":"axios";if(typeof d=="function"){let u=await d(a);s=u.status??0,i=u.data??null;}else if(d==="taro"){let u=await j(a,n);s=u.status??0,i=u.data??null;}else {t||(t=(await import('axios')).default.create());let u=a;if(o){let g=t.defaults.headers||{},T=a.headers||{},R={};for(let[c,y]of Object.entries(g))c==="common"||c==="get"||c==="post"||c==="put"||c==="patch"||c==="delete"||c==="head"||c==="options"||y!=null&&(R[c]=String(y));u={...a,headers:{...R,...T}};}else n?.headers&&(u={...a,headers:b(n.headers,a.headers)});let p=await t(u);s=p?.status??0,i=p?.data;}if(s>=200&&s<300){let p=(n?.transformResponse??E)(i);return {data:m(p)??null,error:null,status:s}}let f=q(i)||`HTTP ${s}`,l=n?.logErrors!==!1;return A(a,s,f,i,l),{data:null,error:{status:s,message:f,details:i},status:s}}catch(s){let i=s,d=i?.response?.status||i?.statusCode||0,f=i?.response?.data??i?.data,l=q(f)||i?.message||"Network error",u=n?.logErrors!==false;return A(a,d,l,f||i,u),{data:null,error:{status:d,message:l,details:f},status:d}}}}}export{v as createHttpClient};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/http.ts"],"names":["normalizeErrorMessage","payload","errorPayload","isBackendStandardFormat","data","status","defaultUnwrapBackendResponse","responseData","BACKEND_DATETIME_REGEX","isBackendDatetime","value","parseBackendDatetime","processResponseDates","item","processed","key","isAbsoluteUrl","url","joinBaseUrl","baseURL","b","u","encodeQuery","params","entries","v","URLSearchParamsCtor","q","sp","k","appendParamsToUrl","readEnvBaseUrl","meta","resolveUrl","config","options","raw","withBase","getMiniProgramRequest","g","callMaybePromiseRequest","fn","ret","resolve","reject","res","err","mergeHeaders","base","extra","out","taroLikeAdapter","req","method","header","isAxiosInstance","logErrorToConsole","message","details","shouldLog","createHttpClient","axiosInstanceOrOptions","instance","isUserProvidedInstance","adapterChoice","adapter","r","finalConfig","defaultHeaders","configHeaders","flattenedDefaults","resp","transformedData","errorMessage","error_","error"],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable no-unused-vars */\nimport type { AxiosInstance, AxiosRequestConfig } from \"axios\";\n\nexport type ClientError = {\n message: string;\n status?: number;\n code?: string;\n details?: unknown;\n};\n\nexport type ClientResult<T> = {\n data: T | null;\n error: ClientError | null;\n status: number;\n};\n\nexport type RequestConfig = AxiosRequestConfig & {\n url: string;\n method: NonNullable<AxiosRequestConfig[\"method\"]> | string;\n};\n\nexport type AdapterResponse = {\n status: number;\n data: unknown;\n headers?: unknown;\n};\n\nexport type HttpAdapter = (_config: RequestConfig) => Promise<AdapterResponse>;\n\nexport type HttpClientOptions = {\n /**\n * HTTP adapter to use:\n * - undefined: auto-detect (taro if mini-program APIs exist, otherwise axios)\n * - \"taro\": force mini-program request (wx/tt/my/...) or global Taro.request\n * - \"axios\": force axios\n * - AxiosInstance: use provided axios instance\n * - function: custom adapter\n */\n adapter?: \"taro\" | \"axios\" | AxiosInstance | HttpAdapter;\n /**\n * Base URL to prefix when `config.url` is relative (e.g. \"/api/...\").\n * \n * If not provided:\n * - Taro/mini-program: auto-reads from process.env.TARO_APP_API_BASE_URL or process.env.VITE_API_BASE_URL\n * - H5/Browser: no baseURL (expects dev proxy or absolute URLs)\n */\n baseURL?: string;\n /** Default headers merged into each request */\n headers?: Record<string, string>;\n /**\n * Custom response transform function to extract/modify data from backend response\n * If not provided, uses default transform logic for { status: 0/1, data: {...} }\n * \n * Similar to axios's transformResponse option\n * \n * @example\n * ```typescript\n * // For backend that returns: { statusCode: 200, data: {...} }\n * const client = createHttpClient({\n * transformResponse: (response) => {\n * if (response && typeof response === 'object' && 'data' in response) {\n * return response.data;\n * }\n * return response;\n * }\n * });\n * ```\n */\n transformResponse?: <T>(responseData: unknown) => T;\n /**\n * Whether to log errors to console (default: true)\n * Set to false to disable automatic error logging\n */\n logErrors?: boolean;\n};\n\nexport type HttpClient = {\n request<T>(\n _config: RequestConfig\n ): Promise<ClientResult<T>>;\n};\n\ninterface ErrorPayload {\n message?: string;\n error?: string;\n msg?: string;\n detail?: string;\n}\n\nfunction normalizeErrorMessage(payload: unknown): string {\n if (!payload) {\n return \"Request failed\";\n }\n if (typeof payload === \"string\") {\n return payload;\n }\n if (typeof payload === \"object\") {\n const errorPayload = payload as ErrorPayload;\n return (\n errorPayload.message ||\n errorPayload.error ||\n errorPayload.msg ||\n errorPayload.detail ||\n \"Request failed\"\n );\n }\n return \"Request failed\";\n}\n\ninterface BackendStandardResponse {\n status: number | string;\n data: unknown;\n}\n\n/**\n * Check if response data matches backend standard format: { status: 0/1, data: {...} }\n * Handles both number and string status values\n */\nfunction isBackendStandardFormat(data: unknown): data is BackendStandardResponse {\n if (!data || typeof data !== \"object\" || !(\"data\" in data)) {\n return false;\n }\n\n // Check status field - handle both number and string values\n if (\"status\" in data) {\n const status = (data as BackendStandardResponse).status;\n // Accept 0, 1, \"0\", \"1\" as valid status values\n return status === 0 || status === 1 || status === \"0\" || status === \"1\";\n }\n\n return false;\n}\n\n/**\n * Default unwrap logic for backend standard format response\n * Backend returns: { status: 0, data: {...} }\n * We extract the inner 'data' field for cleaner client usage\n */\nfunction defaultUnwrapBackendResponse<T>(responseData: unknown): T {\n if (isBackendStandardFormat(responseData)) {\n // Extract inner data field\n return responseData.data as T;\n }\n // Return as-is if not standard format (e.g., BPM/Workflow APIs)\n return responseData as T;\n}\n\n/**\n * Backend datetime format regex: \"YYYY-MM-DD HH:MM:SS\"\n */\nconst BACKEND_DATETIME_REGEX = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/;\n\n/**\n * Check if a string matches backend datetime format\n */\nfunction isBackendDatetime(value: string): boolean {\n return BACKEND_DATETIME_REGEX.test(value);\n}\n\n/**\n * Convert backend datetime string to ISO 8601 format\n * \"2026-01-05 10:30:45\" → \"2026-01-05T10:30:45.000Z\"\n */\nfunction parseBackendDatetime(value: string): string {\n // Replace space with T and append Z for UTC\n return `${value.replace(\" \", \"T\")}.000Z`;\n}\n\n/**\n * Recursively process response data to convert backend datetime strings to ISO format\n * Handles nested objects and arrays\n */\nfunction processResponseDates(data: unknown): unknown {\n if (data === null || data === undefined) {\n return data;\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map((item) => processResponseDates(item));\n }\n\n // Handle objects\n if (typeof data === \"object\") {\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n processed[key] = processResponseDates(value);\n }\n return processed;\n }\n\n // Handle backend datetime strings\n if (typeof data === \"string\" && isBackendDatetime(data)) {\n return parseBackendDatetime(data);\n }\n\n return data;\n}\n\nfunction isAbsoluteUrl(url: string): boolean {\n return /^https?:\\/\\//i.test(url);\n}\n\nfunction joinBaseUrl(baseURL: string, url: string): string {\n const b = baseURL.replace(/\\/+$/, \"\");\n const u = url.startsWith(\"/\") ? url : `/${url}`;\n return `${b}${u}`;\n}\n\nfunction encodeQuery(params: unknown): string {\n if (!params || typeof params !== \"object\") return \"\";\n const entries = Object.entries(params as Record<string, unknown>).filter(\n ([, v]) => v !== undefined && v !== null\n );\n if (entries.length === 0) return \"\";\n const URLSearchParamsCtor = (globalThis as any)?.URLSearchParams as\n | (new () => { append: (k: string, v: string) => void; toString: () => string })\n | undefined;\n\n let q = \"\";\n if (URLSearchParamsCtor) {\n const sp = new URLSearchParamsCtor();\n for (const [k, v] of entries) {\n if (Array.isArray(v)) {\n for (const item of v) sp.append(k, String(item));\n } else {\n sp.append(k, String(v));\n }\n }\n q = sp.toString();\n } else {\n // Minimal fallback (older runtimes): k=v&k=v...\n q = entries\n .flatMap(([k, v]) =>\n Array.isArray(v) ? v.map((item) => [k, item] as const) : ([[k, v]] as const)\n )\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join(\"&\");\n }\n return q ? `?${q}` : \"\";\n}\n\nfunction appendParamsToUrl(url: string, params: unknown): string {\n const q = encodeQuery(params);\n if (!q) return url;\n if (url.includes(\"?\")) return `${url}&${q.slice(1)}`;\n return `${url}${q}`;\n}\n\nfunction readEnvBaseUrl(): string {\n // Safely access environment variables across different environments\n // - Browser with Vite: import.meta.env.VITE_*\n // - Node.js: process.env.*\n // - Taro/Mini-program: process.env.TARO_APP_* (replaced at build time)\n let value = \"\";\n \n // Try import.meta.env first (Vite browser environment)\n try {\n const meta = (globalThis as any).import?.meta?.env;\n if (meta) {\n value = meta.TARO_APP_API_BASE_URL || meta.VITE_API_BASE_URL || \"\";\n }\n } catch {\n // import.meta may not be available\n }\n \n // Fallback to process.env (Node.js / build-time replacement)\n if (!value && typeof process !== \"undefined\" && process?.env) {\n value =\n process.env.TARO_APP_API_BASE_URL ||\n process.env.VITE_API_BASE_URL ||\n \"\";\n }\n \n return String(value || \"\").trim();\n}\n\nfunction resolveUrl(config: RequestConfig, options?: HttpClientOptions): string {\n const raw = String(config.url || \"\");\n if (isAbsoluteUrl(raw)) return appendParamsToUrl(raw, (config as any).params);\n\n const baseURL =\n String((config as any).baseURL || options?.baseURL || readEnvBaseUrl() || \"\").trim();\n const withBase = baseURL ? joinBaseUrl(baseURL, raw) : raw;\n return appendParamsToUrl(withBase, (config as any).params);\n}\n\nfunction getMiniProgramRequest():\n | ((_options: any) => any)\n | null {\n const g: any = globalThis as any;\n if (typeof g?.Taro?.request === \"function\") return g.Taro.request.bind(g.Taro);\n if (typeof g?.wx?.request === \"function\") return g.wx.request.bind(g.wx);\n if (typeof g?.tt?.request === \"function\") return g.tt.request.bind(g.tt);\n if (typeof g?.my?.request === \"function\") return g.my.request.bind(g.my);\n if (typeof g?.swan?.request === \"function\") return g.swan.request.bind(g.swan);\n if (typeof g?.qq?.request === \"function\") return g.qq.request.bind(g.qq);\n if (typeof g?.jd?.request === \"function\") return g.jd.request.bind(g.jd);\n return null;\n}\n\nasync function callMaybePromiseRequest(fn: (options: any) => any, options: any): Promise<any> {\n try {\n const ret = fn(options);\n if (ret && typeof ret.then === \"function\") {\n return await ret;\n }\n } catch {\n // fall through to callback-style below\n }\n\n return await new Promise((resolve, reject) => {\n fn({\n ...options,\n success: (res: any) => resolve(res),\n fail: (err: any) => reject(err),\n });\n });\n}\n\nfunction mergeHeaders(\n base: Record<string, string> | undefined,\n extra: unknown\n): Record<string, string> {\n const out: Record<string, string> = { ...(base || {}) };\n if (!extra) return out;\n if (typeof extra === \"object\") {\n for (const [k, v] of Object.entries(extra as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n out[k] = String(v);\n }\n }\n return out;\n}\n\nasync function taroLikeAdapter(config: RequestConfig, options?: HttpClientOptions): Promise<AdapterResponse> {\n const req = getMiniProgramRequest();\n if (!req) {\n throw new Error(\"Mini-program request API not found (wx/tt/my/... or global Taro.request).\");\n }\n const url = resolveUrl(config, options);\n const method = String(config.method || \"GET\").toUpperCase();\n const header = mergeHeaders(options?.headers, (config as any).headers);\n\n const res = await callMaybePromiseRequest(req, {\n url,\n method,\n header,\n data: (config as any).data,\n });\n\n const status = (res?.statusCode ?? res?.status ?? 0) as number;\n return { status, data: res?.data, headers: res?.header };\n}\n\nfunction isAxiosInstance(value: unknown): value is AxiosInstance {\n const v: any = value as any;\n // axios instance is callable and has defaults + interceptors\n return typeof v === \"function\" && !!v?.defaults && !!v?.interceptors;\n}\n\n/**\n * Log error to console with detailed information\n * Only logs if logErrors option is not explicitly set to false\n */\nfunction logErrorToConsole(\n config: RequestConfig,\n status: number,\n message: string,\n details: unknown,\n shouldLog: boolean = true\n): void {\n if (!shouldLog) return;\n\n const method = String(config.method || \"GET\").toUpperCase();\n const url = config.url;\n\n // Format error message with request context\n console.error(\n `[HTTP Error] ${method} ${url} - ${status} ${message}`,\n \"\\n→ Details:\",\n details\n );\n}\n\n/**\n * Create an HTTP client instance\n * \n * @param axiosInstance - Optional axios instance to use (defaults to a basic axios instance)\n * @returns HttpClient with request method\n * \n * @example\n * ```typescript\n * import axios from \"axios\";\n * import { createHttpClient } from \"@amaster.ai/http-client\";\n * \n * const instance = axios.create({ baseURL: \"https://api.example.com\" });\n * const client = createHttpClient(instance);\n * \n * const result = await client.request({\n * url: \"/users\",\n * method: \"get\",\n * });\n * ```\n */\nexport function createHttpClient(axiosInstanceOrOptions?: AxiosInstance | HttpClientOptions): HttpClient {\n // Import axios dynamically to avoid bundling it\n let instance: AxiosInstance | undefined;\n let options: HttpClientOptions | undefined;\n let isUserProvidedInstance = false;\n\n if (isAxiosInstance(axiosInstanceOrOptions)) {\n instance = axiosInstanceOrOptions;\n isUserProvidedInstance = true;\n } else {\n options = axiosInstanceOrOptions;\n // Check if adapter is an axios instance\n if (options?.adapter && isAxiosInstance(options.adapter)) {\n instance = options.adapter;\n isUserProvidedInstance = true;\n // Remove adapter from options to avoid confusion\n options = { ...options, adapter: undefined };\n }\n }\n\n // Smart default: auto-detect environment\n // - If mini-program APIs exist (wx/tt/my/Taro.request) → use taro adapter\n // - Otherwise → use axios (for H5/browser)\n // User can still explicitly override via { adapter: \"axios\" } or { adapter: \"taro\" }\n const adapterChoice = options?.adapter ?? (getMiniProgramRequest() ? \"taro\" : \"axios\");\n \n return {\n async request<T>(\n config: RequestConfig\n ) {\n try {\n let status = 0;\n let responseData: unknown = null;\n\n const adapter =\n typeof adapterChoice === \"function\" ? adapterChoice :\n adapterChoice === \"taro\" ? \"taro\" :\n \"axios\";\n\n if (typeof adapter === \"function\") {\n const r = await adapter(config);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else if (adapter === \"taro\") {\n const r = await taroLikeAdapter(config, options);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else {\n // axios path\n if (!instance) {\n const axios = await import(\"axios\");\n instance = axios.default.create();\n }\n \n // Axios behavior: if config.headers is set, it REPLACES defaults.headers\n // We need to manually merge instance defaults with request headers\n let finalConfig: any = config;\n \n if (isUserProvidedInstance) {\n // For user-provided instances, merge defaults.headers with config.headers\n const defaultHeaders = instance.defaults.headers || {};\n const configHeaders = (config as any).headers || {};\n \n // Flatten axios headers structure (common, get, post, etc. + top-level)\n const flattenedDefaults: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaultHeaders)) {\n if (key === 'common' || key === 'get' || key === 'post' || key === 'put' || \n key === 'patch' || key === 'delete' || key === 'head' || key === 'options') {\n // These are method-specific headers, skip for now\n continue;\n }\n if (value !== undefined && value !== null) {\n flattenedDefaults[key] = String(value);\n }\n }\n \n // Merge: defaults < config headers\n finalConfig = {\n ...config,\n headers: { ...flattenedDefaults, ...configHeaders },\n };\n } else if (options?.headers) {\n // For auto-created instances, merge options.headers\n finalConfig = {\n ...config,\n headers: mergeHeaders(options.headers, (config as any).headers),\n };\n }\n \n const resp = await instance(finalConfig);\n status = resp?.status ?? 0;\n responseData = resp?.data;\n }\n\n if (status >= 200 && status < 300) {\n // Transform backend response using custom or default logic\n const transformFn = options?.transformResponse ?? defaultUnwrapBackendResponse;\n const transformedData = transformFn<T>(responseData);\n // Convert backend datetime strings to ISO format\n const processedData = processResponseDates(transformedData);\n return { data: (processedData ?? null) as T | null, error: null, status };\n }\n\n // Non-2xx status code - log error before returning\n const errorMessage = normalizeErrorMessage(responseData) || `HTTP ${status}`;\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, responseData, shouldLog);\n\n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details: responseData,\n },\n status,\n };\n } catch (error_: unknown) {\n // Catch network errors, timeouts, and other exceptions\n const error = error_ as any;\n const status = error?.response?.status || error?.statusCode || 0;\n const details = error?.response?.data ?? error?.data;\n const errorMessage = normalizeErrorMessage(details) || error?.message || \"Network error\";\n \n // Log error to console\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, details || error, shouldLog);\n \n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details,\n },\n status,\n };\n }\n },\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/http.ts"],"names":["normalizeErrorMessage","payload","errorPayload","isBackendStandardFormat","data","status","defaultUnwrapBackendResponse","responseData","BACKEND_DATETIME_REGEX","isBackendDatetime","value","parseBackendDatetime","processResponseDates","item","processed","key","isAbsoluteUrl","url","joinBaseUrl","baseURL","b","u","encodeQuery","params","entries","v","URLSearchParamsCtor","q","sp","k","appendParamsToUrl","readEnvBaseUrl","meta","resolveUrl","config","options","raw","withBase","getMiniProgramRequest","g","callMaybePromiseRequest","fn","ret","resolve","reject","res","err","mergeHeaders","base","extra","out","taroLikeAdapter","req","method","header","isAxiosInstance","logErrorToConsole","message","details","shouldLog","createHttpClient","axiosInstanceOrOptions","instance","isUserProvidedInstance","adapterChoice","adapter","r","finalConfig","defaultHeaders","configHeaders","flattenedDefaults","resp","transformedData","errorMessage","error_","error"],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable no-unused-vars */\nimport type { AxiosInstance, AxiosRequestConfig } from \"axios\";\n\nexport type ClientError = {\n message: string;\n status?: number;\n code?: string;\n details?: unknown;\n};\n\nexport type ClientResult<T> = {\n data: T | null;\n error: ClientError | null;\n status: number;\n};\n\nexport type RequestConfig = AxiosRequestConfig & {\n url: string;\n method: NonNullable<AxiosRequestConfig[\"method\"]> | string;\n};\n\nexport type AdapterResponse = {\n status: number;\n data: unknown;\n headers?: unknown;\n};\n\nexport type HttpAdapter = (_config: RequestConfig) => Promise<AdapterResponse>;\n\nexport type HttpClientOptions = {\n /**\n * HTTP adapter to use:\n * - undefined: auto-detect (taro if mini-program APIs exist, otherwise axios)\n * - \"taro\": force mini-program request (wx/tt/my/...) or global Taro.request\n * - \"axios\": force axios\n * - AxiosInstance: use provided axios instance\n * - function: custom adapter\n */\n adapter?: \"taro\" | \"axios\" | AxiosInstance | HttpAdapter;\n /**\n * Base URL to prefix when `config.url` is relative (e.g. \"/api/...\").\n * \n * If not provided:\n * - Taro/mini-program: auto-reads from process.env.TARO_APP_API_BASE_URL or process.env.VITE_API_BASE_URL\n * - H5/Browser: no baseURL (expects dev proxy or absolute URLs)\n */\n baseURL?: string;\n /** Default headers merged into each request */\n headers?: Record<string, string>;\n /**\n * Custom response transform function to extract/modify data from backend response\n * If not provided, uses default transform logic for { status: 0/1, data: {...} }\n * \n * Similar to axios's transformResponse option\n * \n * @example\n * ```typescript\n * // For backend that returns: { statusCode: 200, data: {...} }\n * const client = createHttpClient({\n * transformResponse: (response) => {\n * if (response && typeof response === 'object' && 'data' in response) {\n * return response.data;\n * }\n * return response;\n * }\n * });\n * ```\n */\n transformResponse?: <T>(responseData: unknown) => T;\n /**\n * Whether to log errors to console (default: true)\n * Set to false to disable automatic error logging\n */\n logErrors?: boolean;\n};\n\nexport type HttpClient = {\n request<T>(\n _config: RequestConfig\n ): Promise<ClientResult<T>>;\n};\n\ninterface ErrorPayload {\n message?: string;\n error?: string;\n msg?: string;\n detail?: string;\n}\n\nfunction normalizeErrorMessage(payload: unknown): string {\n if (!payload) {\n return \"Request failed\";\n }\n if (typeof payload === \"string\") {\n return payload;\n }\n if (typeof payload === \"object\") {\n const errorPayload = payload as ErrorPayload;\n return (\n errorPayload.message ||\n errorPayload.error ||\n errorPayload.msg ||\n errorPayload.detail ||\n \"Request failed\"\n );\n }\n return \"Request failed\";\n}\n\ninterface BackendStandardResponse {\n status: number | string;\n data: unknown;\n}\n\n/**\n * Check if response data matches backend standard format: { status: 0/1, data: {...} }\n * Handles both number and string status values\n */\nfunction isBackendStandardFormat(data: unknown): data is BackendStandardResponse {\n if (!data || typeof data !== \"object\" || !(\"data\" in data)) {\n return false;\n }\n\n // Check status field - handle both number and string values\n if (\"status\" in data) {\n const status = (data as BackendStandardResponse).status;\n // Accept 0, 1, \"0\", \"1\" as valid status values\n return status === 0 || status === 1 || status === \"0\" || status === \"1\";\n }\n\n return false;\n}\n\n/**\n * Default unwrap logic for backend standard format response\n * Backend returns: { status: 0, data: {...} }\n * We extract the inner 'data' field for cleaner client usage\n */\nfunction defaultUnwrapBackendResponse<T>(responseData: unknown): T {\n if (isBackendStandardFormat(responseData)) {\n // Extract inner data field\n return responseData.data as T;\n }\n // Return as-is if not standard format (e.g., BPM/Workflow APIs)\n return responseData as T;\n}\n\n/**\n * Backend datetime format regex: \"YYYY-MM-DD HH:MM:SS\"\n */\nconst BACKEND_DATETIME_REGEX = /^\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}$/;\n\n/**\n * Check if a string matches backend datetime format\n */\nfunction isBackendDatetime(value: string): boolean {\n return BACKEND_DATETIME_REGEX.test(value);\n}\n\n/**\n * Convert backend datetime string to ISO 8601 format\n * \"2026-01-05 10:30:45\" → \"2026-01-05T10:30:45.000Z\"\n */\nfunction parseBackendDatetime(value: string): string {\n // Replace space with T and append Z for UTC\n return `${value.replace(\" \", \"T\")}.000Z`;\n}\n\n/**\n * Recursively process response data to convert backend datetime strings to ISO format\n * Handles nested objects and arrays\n */\nfunction processResponseDates(data: unknown): unknown {\n if (data === null || data === undefined) {\n return data;\n }\n\n // Handle arrays\n if (Array.isArray(data)) {\n return data.map((item) => processResponseDates(item));\n }\n\n // Handle objects\n if (typeof data === \"object\") {\n const processed: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n processed[key] = processResponseDates(value);\n }\n return processed;\n }\n\n // Handle backend datetime strings\n if (typeof data === \"string\" && isBackendDatetime(data)) {\n return parseBackendDatetime(data);\n }\n\n return data;\n}\n\nfunction isAbsoluteUrl(url: string): boolean {\n return /^https?:\\/\\//i.test(url);\n}\n\nfunction joinBaseUrl(baseURL: string, url: string): string {\n const b = baseURL.replace(/\\/+$/, \"\");\n const u = url.startsWith(\"/\") ? url : `/${url}`;\n return `${b}${u}`;\n}\n\nfunction encodeQuery(params: unknown): string {\n if (!params || typeof params !== \"object\") return \"\";\n const entries = Object.entries(params as Record<string, unknown>).filter(\n ([, v]) => v !== undefined && v !== null\n );\n if (entries.length === 0) return \"\";\n const URLSearchParamsCtor = (globalThis as any)?.URLSearchParams as\n | (new () => { append: (k: string, v: string) => void; toString: () => string })\n | undefined;\n\n let q = \"\";\n if (URLSearchParamsCtor) {\n const sp = new URLSearchParamsCtor();\n for (const [k, v] of entries) {\n if (Array.isArray(v)) {\n for (const item of v) sp.append(k, String(item));\n } else {\n sp.append(k, String(v));\n }\n }\n q = sp.toString();\n } else {\n // Minimal fallback (older runtimes): k=v&k=v...\n q = entries\n .flatMap(([k, v]) =>\n Array.isArray(v) ? v.map((item) => [k, item] as const) : ([[k, v]] as const)\n )\n .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`)\n .join(\"&\");\n }\n return q ? `?${q}` : \"\";\n}\n\nfunction appendParamsToUrl(url: string, params: unknown): string {\n const q = encodeQuery(params);\n if (!q) return url;\n if (url.includes(\"?\")) return `${url}&${q.slice(1)}`;\n return `${url}${q}`;\n}\n\nfunction readEnvBaseUrl(): string {\n // Safely access environment variables across different environments\n // - Browser with Vite: import.meta.env.VITE_*\n // - Node.js: process.env.*\n // - Taro/Mini-program: process.env.TARO_APP_* (replaced at build time)\n let value = \"\";\n \n // Try import.meta.env first (Vite browser environment)\n try {\n const meta = (globalThis as any).import?.meta?.env;\n if (meta) {\n value = meta.TARO_APP_API_BASE_URL || meta.VITE_API_BASE_URL || \"\";\n }\n } catch {\n // import.meta may not be available\n }\n \n // Fallback to process.env (Node.js / build-time replacement)\n if (!value) {\n value =\n process.env.TARO_APP_API_BASE_URL ||\n process.env.VITE_API_BASE_URL ||\n \"\";\n }\n \n return String(value || \"\").trim();\n}\n\nfunction resolveUrl(config: RequestConfig, options?: HttpClientOptions): string {\n const raw = String(config.url || \"\");\n if (isAbsoluteUrl(raw)) return appendParamsToUrl(raw, (config as any).params);\n\n const baseURL =\n String((config as any).baseURL || options?.baseURL || readEnvBaseUrl() || \"\").trim();\n const withBase = baseURL ? joinBaseUrl(baseURL, raw) : raw;\n return appendParamsToUrl(withBase, (config as any).params);\n}\n\nfunction getMiniProgramRequest():\n | ((_options: any) => any)\n | null {\n const g: any = globalThis as any;\n if (typeof g?.Taro?.request === \"function\") return g.Taro.request.bind(g.Taro);\n if (typeof g?.wx?.request === \"function\") return g.wx.request.bind(g.wx);\n if (typeof g?.tt?.request === \"function\") return g.tt.request.bind(g.tt);\n if (typeof g?.my?.request === \"function\") return g.my.request.bind(g.my);\n if (typeof g?.swan?.request === \"function\") return g.swan.request.bind(g.swan);\n if (typeof g?.qq?.request === \"function\") return g.qq.request.bind(g.qq);\n if (typeof g?.jd?.request === \"function\") return g.jd.request.bind(g.jd);\n return null;\n}\n\nasync function callMaybePromiseRequest(fn: (options: any) => any, options: any): Promise<any> {\n try {\n const ret = fn(options);\n if (ret && typeof ret.then === \"function\") {\n return await ret;\n }\n } catch {\n // fall through to callback-style below\n }\n\n return await new Promise((resolve, reject) => {\n fn({\n ...options,\n success: (res: any) => resolve(res),\n fail: (err: any) => reject(err),\n });\n });\n}\n\nfunction mergeHeaders(\n base: Record<string, string> | undefined,\n extra: unknown\n): Record<string, string> {\n const out: Record<string, string> = { ...(base || {}) };\n if (!extra) return out;\n if (typeof extra === \"object\") {\n for (const [k, v] of Object.entries(extra as Record<string, unknown>)) {\n if (v === undefined || v === null) continue;\n out[k] = String(v);\n }\n }\n return out;\n}\n\nasync function taroLikeAdapter(config: RequestConfig, options?: HttpClientOptions): Promise<AdapterResponse> {\n const req = getMiniProgramRequest();\n if (!req) {\n throw new Error(\"Mini-program request API not found (wx/tt/my/... or global Taro.request).\");\n }\n const url = resolveUrl(config, options);\n const method = String(config.method || \"GET\").toUpperCase();\n const header = mergeHeaders(options?.headers, (config as any).headers);\n\n const res = await callMaybePromiseRequest(req, {\n url,\n method,\n header,\n data: (config as any).data,\n });\n\n const status = (res?.statusCode ?? res?.status ?? 0) as number;\n return { status, data: res?.data, headers: res?.header };\n}\n\nfunction isAxiosInstance(value: unknown): value is AxiosInstance {\n const v: any = value as any;\n // axios instance is callable and has defaults + interceptors\n return typeof v === \"function\" && !!v?.defaults && !!v?.interceptors;\n}\n\n/**\n * Log error to console with detailed information\n * Only logs if logErrors option is not explicitly set to false\n */\nfunction logErrorToConsole(\n config: RequestConfig,\n status: number,\n message: string,\n details: unknown,\n shouldLog: boolean = true\n): void {\n if (!shouldLog) return;\n\n const method = String(config.method || \"GET\").toUpperCase();\n const url = config.url;\n\n // Format error message with request context\n console.error(\n `[HTTP Error] ${method} ${url} - ${status} ${message}`,\n \"\\n→ Details:\",\n details\n );\n}\n\n/**\n * Create an HTTP client instance\n * \n * @param axiosInstance - Optional axios instance to use (defaults to a basic axios instance)\n * @returns HttpClient with request method\n * \n * @example\n * ```typescript\n * import axios from \"axios\";\n * import { createHttpClient } from \"@amaster.ai/http-client\";\n * \n * const instance = axios.create({ baseURL: \"https://api.example.com\" });\n * const client = createHttpClient(instance);\n * \n * const result = await client.request({\n * url: \"/users\",\n * method: \"get\",\n * });\n * ```\n */\nexport function createHttpClient(axiosInstanceOrOptions?: AxiosInstance | HttpClientOptions): HttpClient {\n // Import axios dynamically to avoid bundling it\n let instance: AxiosInstance | undefined;\n let options: HttpClientOptions | undefined;\n let isUserProvidedInstance = false;\n\n if (isAxiosInstance(axiosInstanceOrOptions)) {\n instance = axiosInstanceOrOptions;\n isUserProvidedInstance = true;\n } else {\n options = axiosInstanceOrOptions;\n // Check if adapter is an axios instance\n if (options?.adapter && isAxiosInstance(options.adapter)) {\n instance = options.adapter;\n isUserProvidedInstance = true;\n // Remove adapter from options to avoid confusion\n options = { ...options, adapter: undefined };\n }\n }\n\n // Smart default: auto-detect environment\n // - If mini-program APIs exist (wx/tt/my/Taro.request) → use taro adapter\n // - Otherwise → use axios (for H5/browser)\n // User can still explicitly override via { adapter: \"axios\" } or { adapter: \"taro\" }\n const adapterChoice = options?.adapter ?? (getMiniProgramRequest() ? \"taro\" : \"axios\");\n \n return {\n async request<T>(\n config: RequestConfig\n ) {\n try {\n let status = 0;\n let responseData: unknown = null;\n\n const adapter =\n typeof adapterChoice === \"function\" ? adapterChoice :\n adapterChoice === \"taro\" ? \"taro\" :\n \"axios\";\n\n if (typeof adapter === \"function\") {\n const r = await adapter(config);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else if (adapter === \"taro\") {\n const r = await taroLikeAdapter(config, options);\n status = r.status ?? 0;\n responseData = r.data ?? null;\n } else {\n // axios path\n if (!instance) {\n const axios = await import(\"axios\");\n instance = axios.default.create();\n }\n \n // Axios behavior: if config.headers is set, it REPLACES defaults.headers\n // We need to manually merge instance defaults with request headers\n let finalConfig: any = config;\n \n if (isUserProvidedInstance) {\n // For user-provided instances, merge defaults.headers with config.headers\n const defaultHeaders = instance.defaults.headers || {};\n const configHeaders = (config as any).headers || {};\n \n // Flatten axios headers structure (common, get, post, etc. + top-level)\n const flattenedDefaults: Record<string, string> = {};\n for (const [key, value] of Object.entries(defaultHeaders)) {\n if (key === 'common' || key === 'get' || key === 'post' || key === 'put' || \n key === 'patch' || key === 'delete' || key === 'head' || key === 'options') {\n // These are method-specific headers, skip for now\n continue;\n }\n if (value !== undefined && value !== null) {\n flattenedDefaults[key] = String(value);\n }\n }\n \n // Merge: defaults < config headers\n finalConfig = {\n ...config,\n headers: { ...flattenedDefaults, ...configHeaders },\n };\n } else if (options?.headers) {\n // For auto-created instances, merge options.headers\n finalConfig = {\n ...config,\n headers: mergeHeaders(options.headers, (config as any).headers),\n };\n }\n \n const resp = await instance(finalConfig);\n status = resp?.status ?? 0;\n responseData = resp?.data;\n }\n\n if (status >= 200 && status < 300) {\n // Transform backend response using custom or default logic\n const transformFn = options?.transformResponse ?? defaultUnwrapBackendResponse;\n const transformedData = transformFn<T>(responseData);\n // Convert backend datetime strings to ISO format\n const processedData = processResponseDates(transformedData);\n return { data: (processedData ?? null) as T | null, error: null, status };\n }\n\n // Non-2xx status code - log error before returning\n const errorMessage = normalizeErrorMessage(responseData) || `HTTP ${status}`;\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, responseData, shouldLog);\n\n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details: responseData,\n },\n status,\n };\n } catch (error_: unknown) {\n // Catch network errors, timeouts, and other exceptions\n const error = error_ as any;\n const status = error?.response?.status || error?.statusCode || 0;\n const details = error?.response?.data ?? error?.data;\n const errorMessage = normalizeErrorMessage(details) || error?.message || \"Network error\";\n \n // Log error to console\n const shouldLog = options?.logErrors !== false; // Default to true\n logErrorToConsole(config, status, errorMessage, details || error, shouldLog);\n \n return {\n data: null,\n error: {\n status,\n message: errorMessage,\n details,\n },\n status,\n };\n }\n },\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amaster.ai/http-client",
3
- "version": "1.1.0-beta.31",
3
+ "version": "1.1.0-beta.32",
4
4
  "description": "Base HTTP client with error handling and response unwrapping",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",