@rabstack/rab-react-sdk
Advanced tools
| function C(...t) { | ||
| if (t.length === 0) return ""; | ||
| let r = [...t].filter(Boolean); | ||
| const o = r[r.length - 1]; | ||
| if (typeof o == "object" && o !== null) { | ||
| const s = o; | ||
| r = r.slice(0, -1).map((e) => { | ||
| if (typeof e == "string") { | ||
| let a = e; | ||
| for (const n in s) | ||
| a = a.replace(`:${n}`, String(s[n])); | ||
| return a; | ||
| } | ||
| return e; | ||
| }); | ||
| } | ||
| return r.filter( | ||
| (s) => typeof s == "string" && s.trim() !== "" | ||
| ).map( | ||
| (s, e) => s.startsWith("/") || e === 0 ? s : "/" + s | ||
| ).join(""); | ||
| } | ||
| function $(t) { | ||
| const { endpointUrl: r, baseUrl: o, params: s, appendTrailingSlash: e, method: a } = t, n = C(r, s), c = o.replace(/\/$/, ""); | ||
| let i = n.startsWith("/") ? n : "/" + n; | ||
| return e && a && ["POST", "PUT", "PATCH"].includes(a) && !i.endsWith("/") && (i = i + "/"), new URL(c + i); | ||
| } | ||
| function k(t, r, o, s) { | ||
| if (o && s !== !1) { | ||
| const e = o(r); | ||
| if (e) { | ||
| const a = e.split("&"); | ||
| for (const n of a) { | ||
| const [c, i] = n.split("="); | ||
| c && i !== void 0 && t.searchParams.append(decodeURIComponent(c), decodeURIComponent(i)); | ||
| } | ||
| } | ||
| } else | ||
| Object.entries(r).forEach(([e, a]) => { | ||
| a != null && t.searchParams.append(e, String(a)); | ||
| }); | ||
| } | ||
| function x(t, r, o) { | ||
| if (!!(r && t)) { | ||
| if (t instanceof FormData) | ||
| return { processedBody: t, isFormDataRequest: !0 }; | ||
| if (o) | ||
| return { processedBody: o(t), isFormDataRequest: !0 }; | ||
| throw new Error("useFormData requires formDataParser in config or body to be FormData instance"); | ||
| } | ||
| return { | ||
| processedBody: t ? JSON.stringify(t) : void 0, | ||
| isFormDataRequest: !1 | ||
| }; | ||
| } | ||
| class d extends Error { | ||
| constructor(r) { | ||
| console.error(`API Error ${r.status}: ${r.message} [${r.method} ${r.url}]`), super(r.message), this.name = "ApiDomainError", this.status = r.status, this.url = r.url, this.method = r.method, this.errorCode = r.errorCode, this.errors = r.errors, this.data = r.data, Error.captureStackTrace && Error.captureStackTrace(this, d); | ||
| } | ||
| isNetworkError() { | ||
| return this.status === 0; | ||
| } | ||
| isClientError() { | ||
| return this.status >= 400 && this.status < 500; | ||
| } | ||
| isServerError() { | ||
| return this.status >= 500; | ||
| } | ||
| isUnauthorized() { | ||
| return this.status === 401; | ||
| } | ||
| isForbidden() { | ||
| return this.status === 403; | ||
| } | ||
| isNotFound() { | ||
| return this.status === 404; | ||
| } | ||
| isValidationError() { | ||
| return this.status === 422 || this.status === 400; | ||
| } | ||
| isConflict() { | ||
| return this.status === 409; | ||
| } | ||
| getAllMessages() { | ||
| const r = [this.message]; | ||
| return this.errors && this.errors.length > 0 && r.push(...this.errors), r; | ||
| } | ||
| getDisplayMessage() { | ||
| return this.errors && this.errors.length > 0 ? `${this.message}: ${this.errors.join(", ")}` : this.message; | ||
| } | ||
| } | ||
| function B(t, r, o, s, e) { | ||
| return { | ||
| status: t, | ||
| url: o, | ||
| method: s, | ||
| message: e?.message || r, | ||
| errorCode: e?.errorCode, | ||
| errors: e?.errors, | ||
| data: e | ||
| }; | ||
| } | ||
| function z(t) { | ||
| return typeof t == "object" && t !== null && "data" in t ? t.data : t; | ||
| } | ||
| function O(t) { | ||
| const { | ||
| baseUrl: r, | ||
| getAuthorization: o, | ||
| extractApiError: s = B, | ||
| parseQuery: e, | ||
| transformResponse: a = z, | ||
| onError: n, | ||
| appendTrailingSlash: c, | ||
| formDataParser: i, | ||
| customFetch: g | ||
| } = t; | ||
| return async (h, y) => { | ||
| try { | ||
| const { body: u, query: f, params: m, encodeQuery: E, headers: P, useFormData: b, ...q } = y ?? {}, D = $({ | ||
| endpointUrl: h.url, | ||
| baseUrl: r, | ||
| params: m ?? {}, | ||
| appendTrailingSlash: c, | ||
| method: h.method | ||
| }); | ||
| f && k(D, f, e, E); | ||
| const { processedBody: j, isFormDataRequest: T } = x(u, b, i), F = { | ||
| "Content-Type": T ? "multipart/form-data" : "application/json", | ||
| ...P | ||
| }, R = o?.(); | ||
| R && Object.assign(F, R); | ||
| const p = { | ||
| url: D.toString(), | ||
| method: h.method, | ||
| headers: F, | ||
| body: j, | ||
| ...q | ||
| }, l = g ? await g(p) : await fetch(p.url, { | ||
| method: p.method, | ||
| headers: p.headers, | ||
| body: p.body | ||
| }); | ||
| if (!l.ok) { | ||
| let w; | ||
| try { | ||
| w = await l.clone().json(); | ||
| } catch { | ||
| w = await l.text(); | ||
| } | ||
| const A = s(l.status, l.statusText, D.toString(), h.method, w), S = new d(A); | ||
| throw n?.(S), S; | ||
| } | ||
| const U = await l.json(); | ||
| return a(U, l); | ||
| } catch (u) { | ||
| if (u instanceof d) | ||
| throw u; | ||
| const f = { | ||
| status: 0, | ||
| url: `${r}${h.url}`, | ||
| method: h.method, | ||
| message: u instanceof Error ? u.message : "Network request failed", | ||
| data: u | ||
| }, m = new d(f); | ||
| throw n?.(m), m; | ||
| } | ||
| }; | ||
| } | ||
| function I(t) { | ||
| const { apiSpecs: r, baseUrl: o, getAuthorization: s, extractApiError: e, parseQuery: a, transformResponse: n, onError: c, appendTrailingSlash: i, formDataParser: g, customFetch: h } = t, y = O({ | ||
| baseUrl: o, | ||
| getAuthorization: s, | ||
| extractApiError: e, | ||
| parseQuery: a, | ||
| transformResponse: n, | ||
| onError: c, | ||
| appendTrailingSlash: i, | ||
| formDataParser: g, | ||
| customFetch: h | ||
| }), u = {}; | ||
| for (const [f, m] of Object.entries(r)) | ||
| u[f] = ((E) => y(m, E)); | ||
| return u; | ||
| } | ||
| export { | ||
| d as A, | ||
| O as a, | ||
| B as b, | ||
| I as c, | ||
| z as d, | ||
| C as e | ||
| }; |
| "use strict";function P(...t){if(t.length===0)return"";let r=[...t].filter(Boolean);const o=r[r.length-1];if(typeof o=="object"&&o!==null){const s=o;r=r.slice(0,-1).map(e=>{if(typeof e=="string"){let a=e;for(const n in s)a=a.replace(`:${n}`,String(s[n]));return a}return e})}return r.filter(s=>typeof s=="string"&&s.trim()!=="").map((s,e)=>s.startsWith("/")||e===0?s:"/"+s).join("")}function B(t){const{endpointUrl:r,baseUrl:o,params:s,appendTrailingSlash:e,method:a}=t,n=P(r,s),c=o.replace(/\/$/,"");let i=n.startsWith("/")?n:"/"+n;return e&&a&&["POST","PUT","PATCH"].includes(a)&&!i.endsWith("/")&&(i=i+"/"),new URL(c+i)}function z(t,r,o,s){if(o&&s!==!1){const e=o(r);if(e){const a=e.split("&");for(const n of a){const[c,i]=n.split("=");c&&i!==void 0&&t.searchParams.append(decodeURIComponent(c),decodeURIComponent(i))}}}else Object.entries(r).forEach(([e,a])=>{a!=null&&t.searchParams.append(e,String(a))})}function O(t,r,o){if(!!(r&&t)){if(t instanceof FormData)return{processedBody:t,isFormDataRequest:!0};if(o)return{processedBody:o(t),isFormDataRequest:!0};throw new Error("useFormData requires formDataParser in config or body to be FormData instance")}return{processedBody:t?JSON.stringify(t):void 0,isFormDataRequest:!1}}class p extends Error{constructor(r){console.error(`API Error ${r.status}: ${r.message} [${r.method} ${r.url}]`),super(r.message),this.name="ApiDomainError",this.status=r.status,this.url=r.url,this.method=r.method,this.errorCode=r.errorCode,this.errors=r.errors,this.data=r.data,Error.captureStackTrace&&Error.captureStackTrace(this,p)}isNetworkError(){return this.status===0}isClientError(){return this.status>=400&&this.status<500}isServerError(){return this.status>=500}isUnauthorized(){return this.status===401}isForbidden(){return this.status===403}isNotFound(){return this.status===404}isValidationError(){return this.status===422||this.status===400}isConflict(){return this.status===409}getAllMessages(){const r=[this.message];return this.errors&&this.errors.length>0&&r.push(...this.errors),r}getDisplayMessage(){return this.errors&&this.errors.length>0?`${this.message}: ${this.errors.join(", ")}`:this.message}}function q(t,r,o,s,e){return{status:t,url:o,method:s,message:e?.message||r,errorCode:e?.errorCode,errors:e?.errors,data:e}}function b(t){return typeof t=="object"&&t!==null&&"data"in t?t.data:t}function T(t){const{baseUrl:r,getAuthorization:o,extractApiError:s=q,parseQuery:e,transformResponse:a=b,onError:n,appendTrailingSlash:c,formDataParser:i,customFetch:g}=t;return async(h,y)=>{try{const{body:u,query:f,params:m,encodeQuery:E,headers:U,useFormData:j,...A}=y??{},D=B({endpointUrl:h.url,baseUrl:r,params:m??{},appendTrailingSlash:c,method:h.method});f&&z(D,f,e,E);const{processedBody:C,isFormDataRequest:$}=O(u,j,i),F={"Content-Type":$?"multipart/form-data":"application/json",...U},S=o?.();S&&Object.assign(F,S);const d={url:D.toString(),method:h.method,headers:F,body:C,...A},l=g?await g(d):await fetch(d.url,{method:d.method,headers:d.headers,body:d.body});if(!l.ok){let R;try{R=await l.clone().json()}catch{R=await l.text()}const x=s(l.status,l.statusText,D.toString(),h.method,R),w=new p(x);throw n?.(w),w}const k=await l.json();return a(k,l)}catch(u){if(u instanceof p)throw u;const f={status:0,url:`${r}${h.url}`,method:h.method,message:u instanceof Error?u.message:"Network request failed",data:u},m=new p(f);throw n?.(m),m}}}function I(t){const{apiSpecs:r,baseUrl:o,getAuthorization:s,extractApiError:e,parseQuery:a,transformResponse:n,onError:c,appendTrailingSlash:i,formDataParser:g,customFetch:h}=t,y=T({baseUrl:o,getAuthorization:s,extractApiError:e,parseQuery:a,transformResponse:n,onError:c,appendTrailingSlash:i,formDataParser:g,customFetch:h}),u={};for(const[f,m]of Object.entries(r))u[f]=(E=>y(m,E));return u}exports.ApiDomainError=p;exports.buildUrlPath=P;exports.createRequestFunction=T;exports.createSDK=I;exports.defaultExtractApiError=q;exports.defaultTransformResponse=b; |
+1
-1
@@ -1,1 +0,1 @@ | ||
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("react/jsx-runtime"),S=require("react"),D=require("@tanstack/react-query"),c=require("./createSDK-DmyWwBIp.cjs"),y=require("@rabstack/rab-api-spec");function f(){const t=S.createContext(null);function d({children:e,sdk:s,baseUrl:a}){return P.jsx(t.Provider,{value:{sdk:s,baseUrl:a},children:e})}function n(){const e=S.useContext(t);if(!e)throw new Error("useSDK must be used within SDKProvider");return e.sdk}return{SDKContext:t,SDKProvider:d,useSDK:n}}function m(t){return function(n,...e){const s=t(),a=e[0],{query:u,queryKey:o,params:r,headers:i,encodeQuery:l,...p}=a||{},K=[n,u,r];return D.useQuery({queryKey:o?[...K,...o]:K,queryFn:async()=>{const b=s[n];return b({query:u,params:r,headers:i,encodeQuery:l})},...p})}}function A(t){return function(n,e){const s=t(),a=D.useQueryClient(),{invalidateQueries:u,...o}=e||{};return D.useMutation({mutationFn:async r=>{const i=s[n];return i(r)},onSettled:async(...r)=>{o.onSettled&&await o.onSettled(...r),u&&u.length>0&&await Promise.all(u.map(i=>a.invalidateQueries({queryKey:[i]})))},...o})}}function q(t){const{SDKContext:d,SDKProvider:n,useSDK:e}=f();function s({children:o,baseUrl:r,getAuthorization:i,onError:l}){const p=S.useMemo(()=>c.createSDK({...t,baseUrl:r,getAuthorization:i||t.getAuthorization,onError:l||t.onError}),[r,i,l]);return P.jsx(n,{sdk:p,baseUrl:r,children:o})}const a=m(e),u=A(e);return{SDKContext:d,SDKProvider:s,useSDK:e,useQuery:a,useMutation:u}}exports.ApiDomainError=c.ApiDomainError;exports.buildUrlPath=c.buildUrlPath;exports.createRequestFunction=c.createRequestFunction;exports.createSDK=c.createSDK;exports.defaultExtractApiError=c.defaultExtractApiError;exports.defaultTransformResponse=c.defaultTransformResponse;Object.defineProperty(exports,"DeleteApi",{enumerable:!0,get:()=>y.DeleteApi});Object.defineProperty(exports,"GetApi",{enumerable:!0,get:()=>y.GetApi});Object.defineProperty(exports,"PatchApi",{enumerable:!0,get:()=>y.PatchApi});Object.defineProperty(exports,"PostApi",{enumerable:!0,get:()=>y.PostApi});Object.defineProperty(exports,"PutApi",{enumerable:!0,get:()=>y.PutApi});exports.createSDKContext=f;exports.createSDKProvider=q;exports.createUseMutation=A;exports.createUseQuery=m; | ||
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("react/jsx-runtime"),S=require("react"),D=require("@tanstack/react-query"),c=require("./createSDK-DH-GKtYY.cjs"),y=require("@rabstack/rab-api-spec");function f(){const t=S.createContext(null);function d({children:e,sdk:s,baseUrl:a}){return P.jsx(t.Provider,{value:{sdk:s,baseUrl:a},children:e})}function n(){const e=S.useContext(t);if(!e)throw new Error("useSDK must be used within SDKProvider");return e.sdk}return{SDKContext:t,SDKProvider:d,useSDK:n}}function m(t){return function(n,...e){const s=t(),a=e[0],{query:u,queryKey:o,params:r,headers:i,encodeQuery:l,...p}=a||{},K=[n,u,r];return D.useQuery({queryKey:o?[...K,...o]:K,queryFn:async()=>{const b=s[n];return b({query:u,params:r,headers:i,encodeQuery:l})},...p})}}function A(t){return function(n,e){const s=t(),a=D.useQueryClient(),{invalidateQueries:u,...o}=e||{};return D.useMutation({mutationFn:async r=>{const i=s[n];return i(r)},onSettled:async(...r)=>{o.onSettled&&await o.onSettled(...r),u&&u.length>0&&await Promise.all(u.map(i=>a.invalidateQueries({queryKey:[i]})))},...o})}}function q(t){const{SDKContext:d,SDKProvider:n,useSDK:e}=f();function s({children:o,baseUrl:r,getAuthorization:i,onError:l}){const p=S.useMemo(()=>c.createSDK({...t,baseUrl:r,getAuthorization:i||t.getAuthorization,onError:l||t.onError}),[r,i,l]);return P.jsx(n,{sdk:p,baseUrl:r,children:o})}const a=m(e),u=A(e);return{SDKContext:d,SDKProvider:s,useSDK:e,useQuery:a,useMutation:u}}exports.ApiDomainError=c.ApiDomainError;exports.buildUrlPath=c.buildUrlPath;exports.createRequestFunction=c.createRequestFunction;exports.createSDK=c.createSDK;exports.defaultExtractApiError=c.defaultExtractApiError;exports.defaultTransformResponse=c.defaultTransformResponse;Object.defineProperty(exports,"DeleteApi",{enumerable:!0,get:()=>y.DeleteApi});Object.defineProperty(exports,"GetApi",{enumerable:!0,get:()=>y.GetApi});Object.defineProperty(exports,"PatchApi",{enumerable:!0,get:()=>y.PatchApi});Object.defineProperty(exports,"PostApi",{enumerable:!0,get:()=>y.PostApi});Object.defineProperty(exports,"PutApi",{enumerable:!0,get:()=>y.PutApi});exports.createSDKContext=f;exports.createSDKProvider=q;exports.createUseMutation=A;exports.createUseQuery=m; |
+52
-11
@@ -53,4 +53,5 @@ import { default as default_2 } from 'react'; | ||
| * Base config shared between request function and SDK provider | ||
| * @template TRequestOptions - Extended request options type passed to customFetch | ||
| */ | ||
| declare interface BaseRequestConfig { | ||
| declare interface BaseRequestConfig<TRequestOptions = EmptyRequestOptions> { | ||
| getAuthorization?: () => Record<string, string> | undefined; | ||
@@ -70,2 +71,15 @@ extractApiError?: (status: number, statusText: string, url: string, method: string, data?: any) => ApiErrorDetails; | ||
| formDataParser?: <T>(body: T) => FormData; | ||
| /** | ||
| * Custom fetch function to replace the default fetch | ||
| * Receives request info merged with extended options from SDK method calls | ||
| * @example | ||
| * customFetch: async (request) => { | ||
| * return fetch(request.url, { | ||
| * method: request.method, | ||
| * headers: request.headers, | ||
| * body: request.body, | ||
| * }); | ||
| * } | ||
| */ | ||
| customFetch?: (request: CustomFetchRequest<TRequestOptions>) => Promise<Response>; | ||
| } | ||
@@ -91,8 +105,9 @@ | ||
| export declare function createRequestFunction(config: CreateRequestFunctionConfig): <RESPONSE, BODY = unknown, QUERY = unknown, PARAMS = unknown>(endpoint: EndpointSpec<RESPONSE, BODY, QUERY, PARAMS>, options?: BaseSdkRequestOptions<BODY, QUERY, PARAMS>) => Promise<RESPONSE>; | ||
| export declare function createRequestFunction<TRequestOptions = EmptyRequestOptions>(config: CreateRequestFunctionConfig<TRequestOptions>): <RESPONSE, BODY = unknown, QUERY = unknown, PARAMS = unknown>(endpoint: EndpointSpec<RESPONSE, BODY, QUERY, PARAMS>, options?: BaseSdkRequestOptions<BODY, QUERY, PARAMS> & TRequestOptions) => Promise<RESPONSE>; | ||
| /** | ||
| * Config for creating request function | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare interface CreateRequestFunctionConfig extends BaseRequestConfig { | ||
| export declare interface CreateRequestFunctionConfig<TRequestOptions = EmptyRequestOptions> extends BaseRequestConfig<TRequestOptions> { | ||
| baseUrl: string; | ||
@@ -103,6 +118,8 @@ } | ||
| * Create SDK instance from API specs | ||
| * @template TApiSpecs - API specs record | ||
| * @template TRequestOptions - Extended request options type for customFetch | ||
| */ | ||
| export declare function createSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>>(config: CreateSDKProviderConfig<TApiSpecs> & { | ||
| export declare function createSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>, TRequestOptions = EmptyRequestOptions>(config: CreateSDKProviderConfig<TApiSpecs, TRequestOptions> & { | ||
| baseUrl: string; | ||
| }): GeneratedSDK<TApiSpecs>; | ||
| }): GeneratedSDK<TApiSpecs, TRequestOptions>; | ||
@@ -119,3 +136,3 @@ /** | ||
| }) => JSX_2.Element; | ||
| useSDK: () => GeneratedSDK<TApiSpecs>; | ||
| useSDK: () => GeneratedSDK<TApiSpecs, EmptyRequestOptions>; | ||
| }; | ||
@@ -135,3 +152,3 @@ | ||
| }) => JSX_2.Element; | ||
| useSDK: () => GeneratedSDK<TApiSpecs>; | ||
| useSDK: () => GeneratedSDK<TApiSpecs, EmptyRequestOptions>; | ||
| useQuery: TypedUseQuery<TApiSpecs>; | ||
@@ -143,4 +160,6 @@ useMutation: TypedUseMutation<TApiSpecs>; | ||
| * Config for createSDKProvider | ||
| * @template TApiSpecs - API specs record | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare interface CreateSDKProviderConfig<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>> extends BaseRequestConfig { | ||
| export declare interface CreateSDKProviderConfig<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>, TRequestOptions = EmptyRequestOptions> extends BaseRequestConfig<TRequestOptions> { | ||
| apiSpecs: TApiSpecs; | ||
@@ -162,2 +181,13 @@ } | ||
| /** | ||
| * Request info passed to customFetch function | ||
| * @template TRequestOptions - Extended request options from SDK method calls | ||
| */ | ||
| export declare type CustomFetchRequest<TRequestOptions = EmptyRequestOptions> = { | ||
| url: string; | ||
| method: string; | ||
| headers: Record<string, string>; | ||
| body?: BodyInit; | ||
| } & TRequestOptions; | ||
| /** | ||
| * Default error extractor - extracts basic error details | ||
@@ -177,2 +207,9 @@ */ | ||
| /** | ||
| * Empty object type for default TRequestOptions | ||
| * Using interface instead of Record<string, never> because it works correctly with intersections | ||
| */ | ||
| export declare interface EmptyRequestOptions { | ||
| } | ||
| export { EndpointSpec } | ||
@@ -202,5 +239,7 @@ | ||
| * Generate SDK type from API specs | ||
| * @template TApiSpecs - API specs record | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare type GeneratedSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>> = { | ||
| [K in keyof TApiSpecs]: SDKMethod<TApiSpecs[K]>; | ||
| export declare type GeneratedSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>, TRequestOptions = EmptyRequestOptions> = { | ||
| [K in keyof TApiSpecs]: SDKMethod<TApiSpecs[K], TRequestOptions>; | ||
| }; | ||
@@ -226,4 +265,6 @@ | ||
| * SDK method signature from endpoint spec | ||
| * @template T - Endpoint spec type | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare type SDKMethod<T> = T extends EndpointSpec<infer R, infer B, infer Q, infer P> ? (options?: SdkRequestOptions<B, Q, P>) => Promise<R> : never; | ||
| export declare type SDKMethod<T, TRequestOptions = EmptyRequestOptions> = T extends EndpointSpec<infer R, infer B, infer Q, infer P> ? (options?: SdkRequestOptions<B, Q, P> & TRequestOptions) => Promise<R> : never; | ||
@@ -230,0 +271,0 @@ /** |
+2
-2
| import { jsx as f } from "react/jsx-runtime"; | ||
| import { createContext as K, useContext as S, useMemo as D } from "react"; | ||
| import { useQuery as l, useQueryClient as P, useMutation as x } from "@tanstack/react-query"; | ||
| import { c as Q } from "./createSDK-B_c0ZLmm.js"; | ||
| import { A as b, e as O, a as R, b as j, d as z } from "./createSDK-B_c0ZLmm.js"; | ||
| import { c as Q } from "./createSDK-BykB15KZ.js"; | ||
| import { A as b, e as O, a as R, b as j, d as z } from "./createSDK-BykB15KZ.js"; | ||
| import { DeleteApi as G, GetApi as T, PatchApi as U, PostApi as g, PutApi as H } from "@rabstack/rab-api-spec"; | ||
@@ -7,0 +7,0 @@ function v() { |
+1
-1
| { | ||
| "name": "@rabstack/rab-react-sdk", | ||
| "version": "0.7.0", | ||
| "version": "0.8.0", | ||
| "description": "React SDK for building applications with React Query and other utilities", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
+183
-0
@@ -924,2 +924,185 @@ # @rabstack/rab-react-sdk | ||
| ### Server-Side SDK with Next.js | ||
| The SDK provides a server-compatible entry point for use in Next.js Server Components, API routes, and other server-side contexts. It supports custom fetch functions and extended request options for features like Next.js revalidation. | ||
| #### Basic Server-Side Usage | ||
| ```typescript | ||
| // lib/server-sdk.ts | ||
| import { createSDK } from '@rabstack/rab-react-sdk/server'; | ||
| import { apiSpecs } from './api-specs'; | ||
| export const serverSdk = createSDK({ | ||
| apiSpecs, | ||
| baseUrl: process.env.API_URL!, | ||
| getAuthorization: () => ({ | ||
| Authorization: `Bearer ${process.env.API_SECRET}`, | ||
| }), | ||
| }); | ||
| // app/products/page.tsx (Server Component) | ||
| import { serverSdk } from '@/lib/server-sdk'; | ||
| export default async function ProductsPage() { | ||
| const products = await serverSdk.listProducts(); | ||
| return ( | ||
| <ul> | ||
| {products.map((product) => ( | ||
| <li key={product.id}>{product.name}</li> | ||
| ))} | ||
| </ul> | ||
| ); | ||
| } | ||
| ``` | ||
| #### Custom Fetch with Next.js Revalidation | ||
| For Next.js Server Components, you can pass a custom fetch function with extended options like `next.revalidate` for ISR (Incremental Static Regeneration) and `next.tags` for on-demand revalidation. | ||
| **Step 1: Define Extended Request Options** | ||
| ```typescript | ||
| // lib/next-sdk.ts | ||
| import { createSDK, CustomFetchRequest } from '@rabstack/rab-react-sdk/server'; | ||
| import { apiSpecs } from './api-specs'; | ||
| // Define Next.js-specific request options | ||
| interface NextRequestOptions { | ||
| next?: { | ||
| revalidate?: number | false; | ||
| tags?: string[]; | ||
| }; | ||
| cache?: RequestCache; | ||
| } | ||
| // Create SDK with extended options | ||
| export const serverSdk = createSDK<typeof apiSpecs, NextRequestOptions>({ | ||
| apiSpecs, | ||
| baseUrl: process.env.API_URL!, | ||
| getAuthorization: () => ({ | ||
| Authorization: `Bearer ${process.env.API_SECRET}`, | ||
| }), | ||
| // Custom fetch that passes Next.js options | ||
| customFetch: async (request: CustomFetchRequest<NextRequestOptions>) => { | ||
| return fetch(request.url, { | ||
| method: request.method, | ||
| headers: request.headers, | ||
| body: request.body, | ||
| next: request.next, | ||
| cache: request.cache, | ||
| }); | ||
| }, | ||
| }); | ||
| ``` | ||
| **Step 2: Use in Server Components with Revalidation** | ||
| ```typescript | ||
| // app/products/page.tsx | ||
| import { serverSdk } from '@/lib/next-sdk'; | ||
| export default async function ProductsPage() { | ||
| // Revalidate every 60 seconds (ISR) | ||
| const products = await serverSdk.listProducts({ | ||
| next: { revalidate: 60 }, | ||
| }); | ||
| return ( | ||
| <ul> | ||
| {products.map((product) => ( | ||
| <li key={product.id}>{product.name}</li> | ||
| ))} | ||
| </ul> | ||
| ); | ||
| } | ||
| // app/products/[id]/page.tsx | ||
| import { serverSdk } from '@/lib/next-sdk'; | ||
| export default async function ProductPage({ params }: { params: { id: string } }) { | ||
| // Use tags for on-demand revalidation | ||
| const product = await serverSdk.getProduct({ | ||
| params: { productId: params.id }, | ||
| next: { | ||
| revalidate: 3600, // 1 hour | ||
| tags: [`product-${params.id}`], | ||
| }, | ||
| }); | ||
| return <div>{product.name}</div>; | ||
| } | ||
| ``` | ||
| **Step 3: On-Demand Revalidation (API Route)** | ||
| ```typescript | ||
| // app/api/revalidate/route.ts | ||
| import { revalidateTag } from 'next/cache'; | ||
| import { NextRequest, NextResponse } from 'next/server'; | ||
| export async function POST(request: NextRequest) { | ||
| const { productId } = await request.json(); | ||
| // Revalidate the specific product | ||
| revalidateTag(`product-${productId}`); | ||
| return NextResponse.json({ revalidated: true }); | ||
| } | ||
| ``` | ||
| #### Common Patterns | ||
| **No Cache (Always Fresh)** | ||
| ```typescript | ||
| const data = await serverSdk.getProfile({ | ||
| cache: 'no-store', | ||
| }); | ||
| ``` | ||
| **Static with Revalidation** | ||
| ```typescript | ||
| const data = await serverSdk.listProducts({ | ||
| next: { revalidate: 300 }, // 5 minutes | ||
| }); | ||
| ``` | ||
| **Force Cache (Static)** | ||
| ```typescript | ||
| const data = await serverSdk.getSettings({ | ||
| cache: 'force-cache', | ||
| }); | ||
| ``` | ||
| **Tagged for On-Demand Revalidation** | ||
| ```typescript | ||
| const data = await serverSdk.getUser({ | ||
| params: { userId }, | ||
| next: { | ||
| revalidate: false, // Never auto-revalidate | ||
| tags: ['users', `user-${userId}`], | ||
| }, | ||
| }); | ||
| ``` | ||
| #### Type Safety | ||
| The extended options are fully type-safe. TypeScript will autocomplete and validate the options: | ||
| ```typescript | ||
| // ✅ Valid - all options are typed | ||
| serverSdk.getProduct({ | ||
| params: { productId: '123' }, | ||
| next: { revalidate: 60, tags: ['products'] }, | ||
| cache: 'force-cache', | ||
| }); | ||
| // ❌ TypeScript error - invalid cache value | ||
| serverSdk.getProduct({ | ||
| params: { productId: '123' }, | ||
| cache: 'invalid-value', // Error! | ||
| }); | ||
| ``` | ||
| ## What's New in v0.0.1 | ||
@@ -926,0 +1109,0 @@ |
+1
-1
@@ -1,1 +0,1 @@ | ||
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./createSDK-DmyWwBIp.cjs"),t=require("@rabstack/rab-api-spec");exports.ApiDomainError=e.ApiDomainError;exports.buildUrlPath=e.buildUrlPath;exports.createRequestFunction=e.createRequestFunction;exports.createSDK=e.createSDK;exports.defaultExtractApiError=e.defaultExtractApiError;exports.defaultTransformResponse=e.defaultTransformResponse;Object.defineProperty(exports,"DeleteApi",{enumerable:!0,get:()=>t.DeleteApi});Object.defineProperty(exports,"GetApi",{enumerable:!0,get:()=>t.GetApi});Object.defineProperty(exports,"PatchApi",{enumerable:!0,get:()=>t.PatchApi});Object.defineProperty(exports,"PostApi",{enumerable:!0,get:()=>t.PostApi});Object.defineProperty(exports,"PutApi",{enumerable:!0,get:()=>t.PutApi}); | ||
| "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./createSDK-DH-GKtYY.cjs"),t=require("@rabstack/rab-api-spec");exports.ApiDomainError=e.ApiDomainError;exports.buildUrlPath=e.buildUrlPath;exports.createRequestFunction=e.createRequestFunction;exports.createSDK=e.createSDK;exports.defaultExtractApiError=e.defaultExtractApiError;exports.defaultTransformResponse=e.defaultTransformResponse;Object.defineProperty(exports,"DeleteApi",{enumerable:!0,get:()=>t.DeleteApi});Object.defineProperty(exports,"GetApi",{enumerable:!0,get:()=>t.GetApi});Object.defineProperty(exports,"PatchApi",{enumerable:!0,get:()=>t.PatchApi});Object.defineProperty(exports,"PostApi",{enumerable:!0,get:()=>t.PostApi});Object.defineProperty(exports,"PutApi",{enumerable:!0,get:()=>t.PutApi}); |
+50
-9
@@ -46,4 +46,5 @@ import { DeleteApi } from '@rabstack/rab-api-spec'; | ||
| * Base config shared between request function and SDK provider | ||
| * @template TRequestOptions - Extended request options type passed to customFetch | ||
| */ | ||
| declare interface BaseRequestConfig { | ||
| declare interface BaseRequestConfig<TRequestOptions = EmptyRequestOptions> { | ||
| getAuthorization?: () => Record<string, string> | undefined; | ||
@@ -63,2 +64,15 @@ extractApiError?: (status: number, statusText: string, url: string, method: string, data?: any) => ApiErrorDetails; | ||
| formDataParser?: <T>(body: T) => FormData; | ||
| /** | ||
| * Custom fetch function to replace the default fetch | ||
| * Receives request info merged with extended options from SDK method calls | ||
| * @example | ||
| * customFetch: async (request) => { | ||
| * return fetch(request.url, { | ||
| * method: request.method, | ||
| * headers: request.headers, | ||
| * body: request.body, | ||
| * }); | ||
| * } | ||
| */ | ||
| customFetch?: (request: CustomFetchRequest<TRequestOptions>) => Promise<Response>; | ||
| } | ||
@@ -84,8 +98,9 @@ | ||
| export declare function createRequestFunction(config: CreateRequestFunctionConfig): <RESPONSE, BODY = unknown, QUERY = unknown, PARAMS = unknown>(endpoint: EndpointSpec<RESPONSE, BODY, QUERY, PARAMS>, options?: BaseSdkRequestOptions<BODY, QUERY, PARAMS>) => Promise<RESPONSE>; | ||
| export declare function createRequestFunction<TRequestOptions = EmptyRequestOptions>(config: CreateRequestFunctionConfig<TRequestOptions>): <RESPONSE, BODY = unknown, QUERY = unknown, PARAMS = unknown>(endpoint: EndpointSpec<RESPONSE, BODY, QUERY, PARAMS>, options?: BaseSdkRequestOptions<BODY, QUERY, PARAMS> & TRequestOptions) => Promise<RESPONSE>; | ||
| /** | ||
| * Config for creating request function | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare interface CreateRequestFunctionConfig extends BaseRequestConfig { | ||
| export declare interface CreateRequestFunctionConfig<TRequestOptions = EmptyRequestOptions> extends BaseRequestConfig<TRequestOptions> { | ||
| baseUrl: string; | ||
@@ -96,11 +111,15 @@ } | ||
| * Create SDK instance from API specs | ||
| * @template TApiSpecs - API specs record | ||
| * @template TRequestOptions - Extended request options type for customFetch | ||
| */ | ||
| export declare function createSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>>(config: CreateSDKProviderConfig<TApiSpecs> & { | ||
| export declare function createSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>, TRequestOptions = EmptyRequestOptions>(config: CreateSDKProviderConfig<TApiSpecs, TRequestOptions> & { | ||
| baseUrl: string; | ||
| }): GeneratedSDK<TApiSpecs>; | ||
| }): GeneratedSDK<TApiSpecs, TRequestOptions>; | ||
| /** | ||
| * Config for createSDKProvider | ||
| * @template TApiSpecs - API specs record | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare interface CreateSDKProviderConfig<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>> extends BaseRequestConfig { | ||
| export declare interface CreateSDKProviderConfig<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>, TRequestOptions = EmptyRequestOptions> extends BaseRequestConfig<TRequestOptions> { | ||
| apiSpecs: TApiSpecs; | ||
@@ -110,2 +129,13 @@ } | ||
| /** | ||
| * Request info passed to customFetch function | ||
| * @template TRequestOptions - Extended request options from SDK method calls | ||
| */ | ||
| export declare type CustomFetchRequest<TRequestOptions = EmptyRequestOptions> = { | ||
| url: string; | ||
| method: string; | ||
| headers: Record<string, string>; | ||
| body?: BodyInit; | ||
| } & TRequestOptions; | ||
| /** | ||
| * Default error extractor - extracts basic error details | ||
@@ -125,2 +155,9 @@ */ | ||
| /** | ||
| * Empty object type for default TRequestOptions | ||
| * Using interface instead of Record<string, never> because it works correctly with intersections | ||
| */ | ||
| export declare interface EmptyRequestOptions { | ||
| } | ||
| export { EndpointSpec } | ||
@@ -150,5 +187,7 @@ | ||
| * Generate SDK type from API specs | ||
| * @template TApiSpecs - API specs record | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare type GeneratedSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>> = { | ||
| [K in keyof TApiSpecs]: SDKMethod<TApiSpecs[K]>; | ||
| export declare type GeneratedSDK<TApiSpecs extends Record<string, EndpointSpec<any, any, any, any>>, TRequestOptions = EmptyRequestOptions> = { | ||
| [K in keyof TApiSpecs]: SDKMethod<TApiSpecs[K], TRequestOptions>; | ||
| }; | ||
@@ -166,4 +205,6 @@ | ||
| * SDK method signature from endpoint spec | ||
| * @template T - Endpoint spec type | ||
| * @template TRequestOptions - Extended request options type | ||
| */ | ||
| export declare type SDKMethod<T> = T extends EndpointSpec<infer R, infer B, infer Q, infer P> ? (options?: SdkRequestOptions<B, Q, P>) => Promise<R> : never; | ||
| export declare type SDKMethod<T, TRequestOptions = EmptyRequestOptions> = T extends EndpointSpec<infer R, infer B, infer Q, infer P> ? (options?: SdkRequestOptions<B, Q, P> & TRequestOptions) => Promise<R> : never; | ||
@@ -170,0 +211,0 @@ /** |
+1
-1
@@ -1,2 +0,2 @@ | ||
| import { A as r, e as t, a as o, c as s, b as i, d as p } from "./createSDK-B_c0ZLmm.js"; | ||
| import { A as r, e as t, a as o, c as s, b as i, d as p } from "./createSDK-BykB15KZ.js"; | ||
| import { DeleteApi as c, GetApi as u, PatchApi as f, PostApi as l, PutApi as n } from "@rabstack/rab-api-spec"; | ||
@@ -3,0 +3,0 @@ export { |
| function x(...o) { | ||
| if (o.length === 0) return ""; | ||
| let r = [...o].filter(Boolean); | ||
| const a = r[r.length - 1]; | ||
| if (typeof a == "object" && a !== null) { | ||
| const t = a; | ||
| r = r.slice(0, -1).map((e) => { | ||
| if (typeof e == "string") { | ||
| let c = e; | ||
| for (const u in t) | ||
| c = c.replace(`:${u}`, String(t[u])); | ||
| return c; | ||
| } | ||
| return e; | ||
| }); | ||
| } | ||
| return r.filter( | ||
| (t) => typeof t == "string" && t.trim() !== "" | ||
| ).map( | ||
| (t, e) => t.startsWith("/") || e === 0 ? t : "/" + t | ||
| ).join(""); | ||
| } | ||
| class m extends Error { | ||
| constructor(r) { | ||
| console.error(`API Error ${r.status}: ${r.message} [${r.method} ${r.url}]`), super(r.message), this.name = "ApiDomainError", this.status = r.status, this.url = r.url, this.method = r.method, this.errorCode = r.errorCode, this.errors = r.errors, this.data = r.data, Error.captureStackTrace && Error.captureStackTrace(this, m); | ||
| } | ||
| isNetworkError() { | ||
| return this.status === 0; | ||
| } | ||
| isClientError() { | ||
| return this.status >= 400 && this.status < 500; | ||
| } | ||
| isServerError() { | ||
| return this.status >= 500; | ||
| } | ||
| isUnauthorized() { | ||
| return this.status === 401; | ||
| } | ||
| isForbidden() { | ||
| return this.status === 403; | ||
| } | ||
| isNotFound() { | ||
| return this.status === 404; | ||
| } | ||
| isValidationError() { | ||
| return this.status === 422 || this.status === 400; | ||
| } | ||
| isConflict() { | ||
| return this.status === 409; | ||
| } | ||
| getAllMessages() { | ||
| const r = [this.message]; | ||
| return this.errors && this.errors.length > 0 && r.push(...this.errors), r; | ||
| } | ||
| getDisplayMessage() { | ||
| return this.errors && this.errors.length > 0 ? `${this.message}: ${this.errors.join(", ")}` : this.message; | ||
| } | ||
| } | ||
| function q(o, r, a, t, e) { | ||
| return { | ||
| status: o, | ||
| url: a, | ||
| method: t, | ||
| message: e?.message || r, | ||
| errorCode: e?.errorCode, | ||
| errors: e?.errors, | ||
| data: e | ||
| }; | ||
| } | ||
| function z(o) { | ||
| return typeof o == "object" && o !== null && "data" in o ? o.data : o; | ||
| } | ||
| function O(o) { | ||
| const { | ||
| baseUrl: r, | ||
| getAuthorization: a, | ||
| extractApiError: t = q, | ||
| parseQuery: e, | ||
| transformResponse: c = z, | ||
| onError: u, | ||
| appendTrailingSlash: w, | ||
| formDataParser: d | ||
| } = o; | ||
| return async (n, S = {}) => { | ||
| try { | ||
| const { body: s, query: h, params: p, encodeQuery: D, headers: k, useFormData: R } = S, P = x(n.url, p ?? {}), F = r.replace(/\/$/, ""); | ||
| let g = P.startsWith("/") ? P : "/" + P; | ||
| w && ["POST", "PUT", "PATCH"].includes(n.method) && !g.endsWith("/") && (g = g + "/"); | ||
| const y = new URL(F + g); | ||
| if (h) | ||
| if (e && D !== !1) { | ||
| const i = e(h); | ||
| if (i) { | ||
| const l = i.split("&"); | ||
| for (const b of l) { | ||
| const [T, $] = b.split("="); | ||
| T && $ !== void 0 && y.searchParams.append(decodeURIComponent(T), decodeURIComponent($)); | ||
| } | ||
| } | ||
| } else | ||
| Object.entries(h).forEach(([i, l]) => { | ||
| l != null && y.searchParams.append(i, String(l)); | ||
| }); | ||
| const j = R && s; | ||
| let E; | ||
| if (j) | ||
| if (s instanceof FormData) | ||
| E = s; | ||
| else if (d) | ||
| E = d(s); | ||
| else | ||
| throw new Error("useFormData requires formDataParser in config or body to be FormData instance"); | ||
| else | ||
| E = s ? JSON.stringify(s) : void 0; | ||
| const A = { | ||
| "Content-Type": j ? "multipart/form-data" : "application/json", | ||
| ...k | ||
| }, C = a?.(); | ||
| C && Object.assign(A, C); | ||
| const f = await fetch(y.toString(), { | ||
| method: n.method, | ||
| headers: A, | ||
| body: E | ||
| }); | ||
| if (!f.ok) { | ||
| let i; | ||
| try { | ||
| i = await f.clone().json(); | ||
| } catch { | ||
| i = await f.text(); | ||
| } | ||
| const l = t(f.status, f.statusText, y.toString(), n.method, i), b = new m(l); | ||
| throw u?.(b), b; | ||
| } | ||
| const U = await f.json(); | ||
| return c(U, f); | ||
| } catch (s) { | ||
| if (s instanceof m) | ||
| throw s; | ||
| const h = { | ||
| status: 0, | ||
| url: `${r}${n.url}`, | ||
| method: n.method, | ||
| message: s instanceof Error ? s.message : "Network request failed", | ||
| data: s | ||
| }, p = new m(h); | ||
| throw u?.(p), p; | ||
| } | ||
| }; | ||
| } | ||
| function N(o) { | ||
| const { apiSpecs: r, baseUrl: a, getAuthorization: t, extractApiError: e, parseQuery: c, transformResponse: u, onError: w, appendTrailingSlash: d, formDataParser: n } = o, S = O({ | ||
| baseUrl: a, | ||
| getAuthorization: t, | ||
| extractApiError: e, | ||
| parseQuery: c, | ||
| transformResponse: u, | ||
| onError: w, | ||
| appendTrailingSlash: d, | ||
| formDataParser: n | ||
| }), s = {}; | ||
| for (const [h, p] of Object.entries(r)) | ||
| s[h] = ((D) => S(p, D)); | ||
| return s; | ||
| } | ||
| export { | ||
| m as A, | ||
| O as a, | ||
| q as b, | ||
| N as c, | ||
| z as d, | ||
| x as e | ||
| }; |
| "use strict";function $(...o){if(o.length===0)return"";let r=[...o].filter(Boolean);const a=r[r.length-1];if(typeof a=="object"&&a!==null){const t=a;r=r.slice(0,-1).map(e=>{if(typeof e=="string"){let u=e;for(const c in t)u=u.replace(`:${c}`,String(t[c]));return u}return e})}return r.filter(t=>typeof t=="string"&&t.trim()!=="").map((t,e)=>t.startsWith("/")||e===0?t:"/"+t).join("")}class m extends Error{constructor(r){console.error(`API Error ${r.status}: ${r.message} [${r.method} ${r.url}]`),super(r.message),this.name="ApiDomainError",this.status=r.status,this.url=r.url,this.method=r.method,this.errorCode=r.errorCode,this.errors=r.errors,this.data=r.data,Error.captureStackTrace&&Error.captureStackTrace(this,m)}isNetworkError(){return this.status===0}isClientError(){return this.status>=400&&this.status<500}isServerError(){return this.status>=500}isUnauthorized(){return this.status===401}isForbidden(){return this.status===403}isNotFound(){return this.status===404}isValidationError(){return this.status===422||this.status===400}isConflict(){return this.status===409}getAllMessages(){const r=[this.message];return this.errors&&this.errors.length>0&&r.push(...this.errors),r}getDisplayMessage(){return this.errors&&this.errors.length>0?`${this.message}: ${this.errors.join(", ")}`:this.message}}function k(o,r,a,t,e){return{status:o,url:a,method:t,message:e?.message||r,errorCode:e?.errorCode,errors:e?.errors,data:e}}function F(o){return typeof o=="object"&&o!==null&&"data"in o?o.data:o}function U(o){const{baseUrl:r,getAuthorization:a,extractApiError:t=k,parseQuery:e,transformResponse:u=F,onError:c,appendTrailingSlash:S,formDataParser:d}=o;return async(n,b={})=>{try{const{body:s,query:h,params:p,encodeQuery:w,headers:q,useFormData:x}=b,P=$(n.url,p??{}),z=r.replace(/\/$/,"");let g=P.startsWith("/")?P:"/"+P;S&&["POST","PUT","PATCH"].includes(n.method)&&!g.endsWith("/")&&(g=g+"/");const y=new URL(z+g);if(h)if(e&&w!==!1){const i=e(h);if(i){const f=i.split("&");for(const D of f){const[T,C]=D.split("=");T&&C!==void 0&&y.searchParams.append(decodeURIComponent(T),decodeURIComponent(C))}}}else Object.entries(h).forEach(([i,f])=>{f!=null&&y.searchParams.append(i,String(f))});const j=x&&s;let E;if(j)if(s instanceof FormData)E=s;else if(d)E=d(s);else throw new Error("useFormData requires formDataParser in config or body to be FormData instance");else E=s?JSON.stringify(s):void 0;const A={"Content-Type":j?"multipart/form-data":"application/json",...q},R=a?.();R&&Object.assign(A,R);const l=await fetch(y.toString(),{method:n.method,headers:A,body:E});if(!l.ok){let i;try{i=await l.clone().json()}catch{i=await l.text()}const f=t(l.status,l.statusText,y.toString(),n.method,i),D=new m(f);throw c?.(D),D}const O=await l.json();return u(O,l)}catch(s){if(s instanceof m)throw s;const h={status:0,url:`${r}${n.url}`,method:n.method,message:s instanceof Error?s.message:"Network request failed",data:s},p=new m(h);throw c?.(p),p}}}function N(o){const{apiSpecs:r,baseUrl:a,getAuthorization:t,extractApiError:e,parseQuery:u,transformResponse:c,onError:S,appendTrailingSlash:d,formDataParser:n}=o,b=U({baseUrl:a,getAuthorization:t,extractApiError:e,parseQuery:u,transformResponse:c,onError:S,appendTrailingSlash:d,formDataParser:n}),s={};for(const[h,p]of Object.entries(r))s[h]=(w=>b(p,w));return s}exports.ApiDomainError=m;exports.buildUrlPath=$;exports.createRequestFunction=U;exports.createSDK=N;exports.defaultExtractApiError=k;exports.defaultTransformResponse=F; |
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 1 instance in 1 package
71566
15.42%801
14.59%1175
18.45%8
300%