Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@ts-rest/core

Package Overview
Dependencies
Maintainers
1
Versions
136
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@ts-rest/core - npm Package Compare versions

Comparing version 3.36.0 to 3.37.0

10

CHANGELOG.md
# @ts-rest/core
## 3.37.0
### Minor Changes
- 6a5280c: Allow fetch options to be set and client options to be overridden per request
### Patch Changes
- 77db06b: Fix client not correctly encoding application/x-www-form-urlencoded body
## 3.36.0

@@ -4,0 +14,0 @@

178

index.cjs.js

@@ -199,31 +199,25 @@ 'use strict';

}
const tsRestFetchApi = async ({ path, method, headers, body, credentials, signal, cache, next, route, }) => {
const tsRestFetchApi = async ({ route, path, method, headers, body, validateResponse, fetchOptions, }) => {
const result = await fetch(path, {
...fetchOptions,
method,
headers,
body,
credentials,
signal,
cache,
next,
});
const contentType = result.headers.get('content-type');
if ((contentType === null || contentType === void 0 ? void 0 : contentType.includes('application/')) && (contentType === null || contentType === void 0 ? void 0 : contentType.includes('json'))) {
if (!route.validateResponseOnClient) {
const response = {
status: result.status,
body: await result.json(),
headers: result.headers,
};
const responseSchema = route.responses[response.status];
if ((validateResponse !== null && validateResponse !== void 0 ? validateResponse : route.validateResponseOnClient) &&
isZodType(responseSchema)) {
return {
status: result.status,
body: await result.json(),
headers: result.headers,
...response,
body: responseSchema.parse(response.body),
};
}
const jsonData = await result.json();
const statusCode = result.status;
const response = route.responses[statusCode];
return {
status: statusCode,
body: response && typeof response !== 'symbol' && 'parse' in response
? response === null || response === void 0 ? void 0 : response.parse(jsonData)
: jsonData,
headers: result.headers,
};
return response;
}

@@ -258,3 +252,3 @@ if (contentType === null || contentType === void 0 ? void 0 : contentType.includes('text/')) {

};
const fetchApi = ({ path, clientArgs, route, body, query, extraInputArgs, headers, signal, next, }) => {
const fetchApi = ({ path, clientArgs, route, body, query, extraInputArgs, headers, fetchOptions, }) => {
const apiFetcher = clientArgs.api || tsRestFetchApi;

@@ -270,58 +264,87 @@ const combinedHeaders = {

});
if (route.method !== 'GET' && route.contentType === 'multipart/form-data') {
return apiFetcher({
route,
path,
method: route.method,
credentials: clientArgs.credentials,
headers: combinedHeaders,
body: body instanceof FormData ? body : createFormData(body),
rawBody: body,
rawQuery: query,
contentType: 'multipart/form-data',
signal,
next,
...extraInputArgs,
});
}
if (route.method !== 'GET' &&
route.contentType === 'application/x-www-form-urlencoded') {
const headers = {
...combinedHeaders,
'content-type': 'application/x-www-form-urlencoded',
};
return apiFetcher({
route,
path,
method: route.method,
credentials: clientArgs.credentials,
headers,
body: body instanceof FormData ? body : createFormData(body),
rawBody: body,
rawQuery: query,
contentType: 'application/x-www-form-urlencoded',
signal,
next,
...extraInputArgs,
});
}
const includeContentTypeHeader = route.method !== 'GET' && body !== null && body !== undefined;
return apiFetcher({
let fetcherArgs = {
route,
path,
method: route.method,
credentials: clientArgs.credentials,
headers: {
...(includeContentTypeHeader && { 'content-type': 'application/json' }),
...combinedHeaders,
},
body: body !== null && body !== undefined ? JSON.stringify(body) : undefined,
headers: combinedHeaders,
body: undefined,
rawBody: body,
rawQuery: query,
contentType: includeContentTypeHeader ? 'application/json' : undefined,
signal,
next,
contentType: undefined,
fetchOptions: {
...(clientArgs.credentials && { credentials: clientArgs.credentials }),
...fetchOptions,
},
...((fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.signal) && { signal: fetchOptions.signal }),
...((fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.cache) && { cache: fetchOptions.cache }),
...(fetchOptions &&
'next' in fetchOptions &&
!!(fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.next) && { next: fetchOptions.next }),
};
if (route.method !== 'GET') {
if (route.contentType === 'multipart/form-data') {
fetcherArgs = {
...fetcherArgs,
contentType: 'multipart/form-data',
body: body instanceof FormData ? body : createFormData(body),
};
}
else if (route.contentType === 'application/x-www-form-urlencoded') {
fetcherArgs = {
...fetcherArgs,
contentType: 'application/x-www-form-urlencoded',
headers: {
...fetcherArgs.headers,
'content-type': 'application/x-www-form-urlencoded',
},
body: typeof body === 'string'
? body
: new URLSearchParams(body),
};
}
else if (body !== null && body !== undefined) {
fetcherArgs = {
...fetcherArgs,
contentType: 'application/json',
headers: {
...fetcherArgs.headers,
'content-type': 'application/json',
},
body: JSON.stringify(body),
};
}
}
return apiFetcher({
...fetcherArgs,
...extraInputArgs,
});
};
const evaluateFetchApiArgs = (route, clientArgs, inputArgs) => {
const { query, params, body, headers, extraHeaders, overrideClientOptions, fetchOptions,
cache,
next,
...extraInputArgs } = inputArgs || {};
const overriddenClientArgs = {
...clientArgs,
...overrideClientOptions,
};
const completeUrl = getCompleteUrl(query, overriddenClientArgs.baseUrl, params, route, !!overriddenClientArgs.jsonQuery);
return {
path: completeUrl,
clientArgs: overriddenClientArgs,
route,
body,
query,
extraInputArgs,
fetchOptions: {
...(cache && { cache }),
...(next && { next }),
...fetchOptions,
},
headers: {
...extraHeaders,
...headers,
},
};
};
const getCompleteUrl = (query, baseUrl, params, route, jsonQuery) => {

@@ -338,18 +361,4 @@ const path = insertParamsIntoPath({

return async (inputArgs) => {
const { query, params, body, headers, extraHeaders, next, ...extraInputArgs } =
inputArgs || {};
const completeUrl = getCompleteUrl(query, clientArgs.baseUrl, params, route, !!clientArgs.jsonQuery);
const response = await fetchApi({
path: completeUrl,
clientArgs,
route,
body,
query,
extraInputArgs,
next,
headers: {
...extraHeaders,
...headers,
},
});
const fetchApiArgs = evaluateFetchApiArgs(route, clientArgs, inputArgs);
const response = await fetchApi(fetchApiArgs);
if (!clientArgs.throwOnUnknownStatus) {

@@ -419,2 +428,3 @@ return response;

exports.encodeQueryParamsJson = encodeQueryParamsJson;
exports.evaluateFetchApiArgs = evaluateFetchApiArgs;
exports.extractZodObjectShape = extractZodObjectShape;

@@ -421,0 +431,0 @@ exports.fetchApi = fetchApi;

@@ -195,31 +195,25 @@ const isZodType = (obj) => {

}
const tsRestFetchApi = async ({ path, method, headers, body, credentials, signal, cache, next, route, }) => {
const tsRestFetchApi = async ({ route, path, method, headers, body, validateResponse, fetchOptions, }) => {
const result = await fetch(path, {
...fetchOptions,
method,
headers,
body,
credentials,
signal,
cache,
next,
});
const contentType = result.headers.get('content-type');
if ((contentType === null || contentType === void 0 ? void 0 : contentType.includes('application/')) && (contentType === null || contentType === void 0 ? void 0 : contentType.includes('json'))) {
if (!route.validateResponseOnClient) {
const response = {
status: result.status,
body: await result.json(),
headers: result.headers,
};
const responseSchema = route.responses[response.status];
if ((validateResponse !== null && validateResponse !== void 0 ? validateResponse : route.validateResponseOnClient) &&
isZodType(responseSchema)) {
return {
status: result.status,
body: await result.json(),
headers: result.headers,
...response,
body: responseSchema.parse(response.body),
};
}
const jsonData = await result.json();
const statusCode = result.status;
const response = route.responses[statusCode];
return {
status: statusCode,
body: response && typeof response !== 'symbol' && 'parse' in response
? response === null || response === void 0 ? void 0 : response.parse(jsonData)
: jsonData,
headers: result.headers,
};
return response;
}

@@ -254,3 +248,3 @@ if (contentType === null || contentType === void 0 ? void 0 : contentType.includes('text/')) {

};
const fetchApi = ({ path, clientArgs, route, body, query, extraInputArgs, headers, signal, next, }) => {
const fetchApi = ({ path, clientArgs, route, body, query, extraInputArgs, headers, fetchOptions, }) => {
const apiFetcher = clientArgs.api || tsRestFetchApi;

@@ -266,58 +260,87 @@ const combinedHeaders = {

});
if (route.method !== 'GET' && route.contentType === 'multipart/form-data') {
return apiFetcher({
route,
path,
method: route.method,
credentials: clientArgs.credentials,
headers: combinedHeaders,
body: body instanceof FormData ? body : createFormData(body),
rawBody: body,
rawQuery: query,
contentType: 'multipart/form-data',
signal,
next,
...extraInputArgs,
});
}
if (route.method !== 'GET' &&
route.contentType === 'application/x-www-form-urlencoded') {
const headers = {
...combinedHeaders,
'content-type': 'application/x-www-form-urlencoded',
};
return apiFetcher({
route,
path,
method: route.method,
credentials: clientArgs.credentials,
headers,
body: body instanceof FormData ? body : createFormData(body),
rawBody: body,
rawQuery: query,
contentType: 'application/x-www-form-urlencoded',
signal,
next,
...extraInputArgs,
});
}
const includeContentTypeHeader = route.method !== 'GET' && body !== null && body !== undefined;
return apiFetcher({
let fetcherArgs = {
route,
path,
method: route.method,
credentials: clientArgs.credentials,
headers: {
...(includeContentTypeHeader && { 'content-type': 'application/json' }),
...combinedHeaders,
},
body: body !== null && body !== undefined ? JSON.stringify(body) : undefined,
headers: combinedHeaders,
body: undefined,
rawBody: body,
rawQuery: query,
contentType: includeContentTypeHeader ? 'application/json' : undefined,
signal,
next,
contentType: undefined,
fetchOptions: {
...(clientArgs.credentials && { credentials: clientArgs.credentials }),
...fetchOptions,
},
...((fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.signal) && { signal: fetchOptions.signal }),
...((fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.cache) && { cache: fetchOptions.cache }),
...(fetchOptions &&
'next' in fetchOptions &&
!!(fetchOptions === null || fetchOptions === void 0 ? void 0 : fetchOptions.next) && { next: fetchOptions.next }),
};
if (route.method !== 'GET') {
if (route.contentType === 'multipart/form-data') {
fetcherArgs = {
...fetcherArgs,
contentType: 'multipart/form-data',
body: body instanceof FormData ? body : createFormData(body),
};
}
else if (route.contentType === 'application/x-www-form-urlencoded') {
fetcherArgs = {
...fetcherArgs,
contentType: 'application/x-www-form-urlencoded',
headers: {
...fetcherArgs.headers,
'content-type': 'application/x-www-form-urlencoded',
},
body: typeof body === 'string'
? body
: new URLSearchParams(body),
};
}
else if (body !== null && body !== undefined) {
fetcherArgs = {
...fetcherArgs,
contentType: 'application/json',
headers: {
...fetcherArgs.headers,
'content-type': 'application/json',
},
body: JSON.stringify(body),
};
}
}
return apiFetcher({
...fetcherArgs,
...extraInputArgs,
});
};
const evaluateFetchApiArgs = (route, clientArgs, inputArgs) => {
const { query, params, body, headers, extraHeaders, overrideClientOptions, fetchOptions,
cache,
next,
...extraInputArgs } = inputArgs || {};
const overriddenClientArgs = {
...clientArgs,
...overrideClientOptions,
};
const completeUrl = getCompleteUrl(query, overriddenClientArgs.baseUrl, params, route, !!overriddenClientArgs.jsonQuery);
return {
path: completeUrl,
clientArgs: overriddenClientArgs,
route,
body,
query,
extraInputArgs,
fetchOptions: {
...(cache && { cache }),
...(next && { next }),
...fetchOptions,
},
headers: {
...extraHeaders,
...headers,
},
};
};
const getCompleteUrl = (query, baseUrl, params, route, jsonQuery) => {

@@ -334,18 +357,4 @@ const path = insertParamsIntoPath({

return async (inputArgs) => {
const { query, params, body, headers, extraHeaders, next, ...extraInputArgs } =
inputArgs || {};
const completeUrl = getCompleteUrl(query, clientArgs.baseUrl, params, route, !!clientArgs.jsonQuery);
const response = await fetchApi({
path: completeUrl,
clientArgs,
route,
body,
query,
extraInputArgs,
next,
headers: {
...extraHeaders,
...headers,
},
});
const fetchApiArgs = evaluateFetchApiArgs(route, clientArgs, inputArgs);
const response = await fetchApi(fetchApiArgs);
if (!clientArgs.throwOnUnknownStatus) {

@@ -408,2 +417,2 @@ return response;

export { ContractPlainTypeRuntimeSymbol, ResponseValidationError, UnknownStatusError, checkZodSchema, convertQueryParamsToUrlString, encodeQueryParams, encodeQueryParamsJson, extractZodObjectShape, fetchApi, getCompleteUrl, getRouteQuery, getRouteResponses, initClient, initContract, initTsRest, insertParamsIntoPath, isAppRoute, isAppRouteOtherResponse, isAppRouteResponse, isZodObject, isZodObjectStrict, isZodType, parseJsonQueryObject, tsRestFetchApi, validateResponse, zodErrorResponse, zodMerge };
export { ContractPlainTypeRuntimeSymbol, ResponseValidationError, UnknownStatusError, checkZodSchema, convertQueryParamsToUrlString, encodeQueryParams, encodeQueryParamsJson, evaluateFetchApiArgs, extractZodObjectShape, fetchApi, getCompleteUrl, getRouteQuery, getRouteResponses, initClient, initContract, initTsRest, insertParamsIntoPath, isAppRoute, isAppRouteOtherResponse, isAppRouteResponse, isZodObject, isZodObjectStrict, isZodType, parseJsonQueryObject, tsRestFetchApi, validateResponse, zodErrorResponse, zodMerge };
{
"name": "@ts-rest/core",
"version": "3.36.0",
"version": "3.37.0",
"description": "RPC-like experience over a regular REST API, with type safe server implementations 🪄",

@@ -5,0 +5,0 @@ "license": "MIT",

import { AppRoute, AppRouteMutation, AppRouter } from './dsl';
import { AreAllPropertiesOptional, Prettify } from './type-utils';
import { ClientInferRequest, ClientInferResponses, PartialClientInferRequest, NextClientArgs, Frameworks } from './infer-types';
import { ClientInferRequest, ClientInferResponses, PartialClientInferRequest } from './infer-types';
type RecursiveProxyObj<T extends AppRouter, TClientArgs extends ClientArgs> = {

@@ -19,9 +19,13 @@ [TKey in keyof T]: T[TKey] extends AppRoute ? AppRouteFunction<T[TKey], TClientArgs> : T[TKey] extends AppRouter ? RecursiveProxyObj<T[TKey], TClientArgs> : never;

export type AppRouteFunction<TRoute extends AppRoute, TClientArgs extends ClientArgs, TArgs = PartialClientInferRequest<TRoute, TClientArgs>> = AreAllPropertiesOptional<TArgs> extends true ? (args?: Prettify<TArgs>) => Promise<Prettify<ClientInferResponses<TRoute>>> : (args: Prettify<TArgs>) => Promise<Prettify<ClientInferResponses<TRoute>>>;
export interface ClientArgs {
export type FetchOptions = Omit<RequestInit, 'method' | 'headers' | 'body'>;
export interface OverrideableClientArgs {
baseUrl: string;
baseHeaders: Record<string, string>;
api?: ApiFetcher;
credentials?: RequestCredentials;
jsonQuery?: boolean;
validateResponse?: boolean;
}
export interface ClientArgs extends OverrideableClientArgs {
baseHeaders: Record<string, string>;
api?: ApiFetcher;
}
export type ApiFetcherArgs = {

@@ -32,14 +36,27 @@ route: AppRoute;

headers: Record<string, string>;
body: FormData | string | null | undefined;
body: FormData | URLSearchParams | string | null | undefined;
rawBody: unknown;
rawQuery: unknown;
contentType: AppRouteMutation['contentType'];
fetchOptions?: FetchOptions;
validateResponse?: boolean;
/**
* @deprecated Use `fetchOptions.credentials` instead
*/
credentials?: RequestCredentials;
/**
* @deprecated Use `fetchOptions.signal` instead
*/
signal?: AbortSignal;
/**
* @deprecated Use `fetchOptions.cache` instead
*/
cache?: RequestCache;
/**
* Only to be used by `@ts-rest/next`.
* You can obtain a Nextjs Client by calling `initNextClient`
* @deprecated Use `fetchOptions.next` instead
*/
next?: NextClientArgs['next'] | undefined;
next?: {
revalidate?: number | false;
tags?: string[];
} | undefined;
};

@@ -59,3 +76,3 @@ export type ApiFetcher = (args: ApiFetcherArgs) => Promise<{

export declare const tsRestFetchApi: ApiFetcher;
export declare const fetchApi: ({ path, clientArgs, route, body, query, extraInputArgs, headers, signal, next, }: {
export declare const fetchApi: ({ path, clientArgs, route, body, query, extraInputArgs, headers, fetchOptions, }: {
path: string;

@@ -68,8 +85,3 @@ clientArgs: ClientArgs;

headers: Record<string, string | undefined>;
signal?: AbortSignal | undefined;
/**
* only to be used by @ts-rest/next
* You can obtain a Nextjs Client by calling `initNextClient`
*/
next?: NextClientArgs['next'] | undefined;
fetchOptions?: FetchOptions | undefined;
}) => Promise<{

@@ -80,2 +92,12 @@ status: number;

}>;
export declare const evaluateFetchApiArgs: <TAppRoute extends AppRoute>(route: TAppRoute, clientArgs: InitClientArgs, inputArgs?: ClientInferRequest<AppRouteMutation, ClientArgs>) => {
path: string;
clientArgs: ClientArgs;
route: AppRoute;
query: unknown;
body: unknown;
extraInputArgs: Record<string, unknown>;
headers: Record<string, string | undefined>;
fetchOptions?: FetchOptions | undefined;
};
/**

@@ -85,33 +107,3 @@ * @hidden

export declare const getCompleteUrl: (query: unknown, baseUrl: string, params: unknown, route: AppRoute, jsonQuery: boolean) => string;
export declare const getRouteQuery: <TAppRoute extends AppRoute, Framework extends Frameworks = "none">(route: TAppRoute, clientArgs: InitClientArgs) => (inputArgs?: (Framework extends "nextjs" ? {
headers: {
[x: Lowercase<string>]: any;
};
body: any;
cache?: RequestCache | undefined;
next?: {
revalidate?: number | false | undefined;
tags?: string[] | undefined;
} | undefined;
params: {
[x: string]: any;
};
query: any;
extraHeaders?: ({
[x: Lowercase<string>]: undefined;
} & Record<string, string | undefined>) | undefined;
} : {
headers: {
[x: Lowercase<string>]: any;
};
body: any;
cache?: RequestCache | undefined;
params: {
[x: string]: any;
};
query: any;
extraHeaders?: ({
[x: Lowercase<string>]: undefined;
} & Record<string, string | undefined>) | undefined;
}) | undefined) => Promise<{
export declare const getRouteQuery: <TAppRoute extends AppRoute>(route: TAppRoute, clientArgs: InitClientArgs) => (inputArgs?: ClientInferRequest<AppRouteMutation, ClientArgs>) => Promise<{
status: number;

@@ -118,0 +110,0 @@ body: unknown;

@@ -31,2 +31,5 @@ import { Merge, Opaque, Prettify, WithoutUnknown } from './type-utils';

metadata?: unknown;
/**
* @deprecated Use `validateResponse` on the client options
*/
validateResponseOnClient?: boolean;

@@ -89,2 +92,5 @@ };

pathPrefix?: TPrefix;
/**
* @deprecated Use `validateResponse` on the client options
*/
validateResponseOnClient?: boolean;

@@ -91,0 +97,0 @@ };

import { AppRoute, AppRouteMutation, AppRouter, AppRouteStrictStatusCodes, ContractAnyType, ContractOtherResponse } from './dsl';
import { HTTPStatusCode } from './status-codes';
import { And, Extends, LowercaseKeys, Merge, Not, OptionalIfAllOptional, Or, PartialByLooseKeys, Prettify, Without, ZodInferOrType, ZodInputOrType } from './type-utils';
import { ApiFetcher, ClientArgs } from './client';
import { ApiFetcher, ClientArgs, OverrideableClientArgs, FetchOptions } from './client';
import { ParamsFromUrl } from './paths';
export type Frameworks = 'nextjs' | 'none';
export type NextClientArgs = {
next?: {
revalidate?: number | false;
tags?: string[];
} | undefined;
};
type ExtractExtraParametersFromClientArgs<TClientArgs extends Pick<ClientArgs, 'api'>> = TClientArgs['api'] extends ApiFetcher ? Omit<Parameters<TClientArgs['api']>[0], keyof Parameters<ApiFetcher>[0]> : {};

@@ -53,9 +46,9 @@ /**

} : never;
type ClientInferRequestBase<Framework extends Frameworks, T extends AppRoute, TClientArgs extends Omit<ClientArgs, 'baseUrl'> = {
type ClientInferRequestBase<T extends AppRoute, TClientArgs extends Omit<ClientArgs, 'baseUrl'> = {
baseHeaders: {};
}, THeaders = 'headers' extends keyof T ? Prettify<PartialByLooseKeys<LowercaseKeys<ZodInputOrType<T['headers']>>, keyof LowercaseKeys<TClientArgs['baseHeaders']>>> : never> = Prettify<Without<{
}, THeaders = 'headers' extends keyof T ? Prettify<PartialByLooseKeys<LowercaseKeys<ZodInputOrType<T['headers']>>, keyof LowercaseKeys<TClientArgs['baseHeaders']>>> : never, TFetchOptions extends FetchOptions = FetchOptions> = Prettify<Without<{
params: [keyof PathParamsWithCustomValidators<T, 'client'>] extends [
never
] ? never : Prettify<PathParamsWithCustomValidators<T, 'client'>>;
body: T extends AppRouteMutation ? T['body'] extends null ? never : T['contentType'] extends 'multipart/form-data' ? FormData | ZodInputOrType<T['body']> : ZodInputOrType<T['body']> : never;
body: T extends AppRouteMutation ? T['body'] extends null ? never : T['contentType'] extends 'multipart/form-data' ? FormData | ZodInputOrType<T['body']> : T['contentType'] extends 'application/x-www-form-urlencoded' ? string | ZodInputOrType<T['body']> : ZodInputOrType<T['body']> : never;
query: 'query' extends keyof T ? T['query'] extends null ? never : ZodInputOrType<T['query']> : never;

@@ -66,8 +59,16 @@ headers: THeaders;

} & Record<string, string | undefined>;
fetchOptions?: FetchOptions;
overrideClientOptions?: Partial<OverrideableClientArgs>;
/**
* @deprecated Use `fetchOptions.cache` instead
*/
cache?: RequestCache;
next?: Framework extends 'nextjs' ? NextClientArgs['next'] : never;
/**
* @deprecated Use `fetchOptions.next` instead
*/
next?: 'next' extends keyof TFetchOptions ? TFetchOptions['next'] : never;
} & ExtractExtraParametersFromClientArgs<TClientArgs>, never>>;
export type ClientInferRequest<T extends AppRoute | AppRouter, TClientArgs extends Omit<ClientArgs, 'baseUrl'> = {
baseHeaders: {};
}, Framework extends Frameworks = 'none'> = T extends AppRoute ? ClientInferRequestBase<Framework, T, TClientArgs> : T extends AppRouter ? {
}> = T extends AppRoute ? ClientInferRequestBase<T, TClientArgs> : T extends AppRouter ? {
[TKey in keyof T]: ClientInferRequest<T[TKey]>;

@@ -77,3 +78,3 @@ } : never;

baseHeaders: {};
}, Framework extends Frameworks = 'none'> = OptionalIfAllOptional<ClientInferRequest<TRoute, TClientArgs, Framework>>;
}> = OptionalIfAllOptional<ClientInferRequest<TRoute, TClientArgs>>;
export {};

@@ -76,3 +76,2 @@ import { z } from 'zod';

}[`${B}`];
export type Promisable<T> = Promise<T> | T;
export {};
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc