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.19.5 to 3.20.0

138

index.js

@@ -0,8 +1,86 @@

const isZodType = (obj) => {
return typeof (obj === null || obj === void 0 ? void 0 : obj.safeParse) === 'function';
};
const isZodObject = (obj) => {
const isZodEffects = typeof (obj === null || obj === void 0 ? void 0 : obj.innerType) === 'function';
const maybeZodObject = isZodEffects
? obj === null || obj === void 0 ? void 0 : obj.innerType()
: obj;
return typeof (maybeZodObject === null || maybeZodObject === void 0 ? void 0 : maybeZodObject.passthrough) === 'function';
};
const isZodObjectStrict = (obj) => {
return typeof (obj === null || obj === void 0 ? void 0 : obj.passthrough) === 'function';
};
const extractZodObjectShape = (obj) => {
if (!isZodObject(obj)) {
throw new Error('Unknown zod object type');
}
if ('innerType' in obj) {
return obj.innerType().shape;
}
return obj.shape;
};
const zodMerge = (objectA, objectB) => {
if (isZodObjectStrict(objectA)) {
if (isZodObjectStrict(objectB)) {
return objectA.merge(objectB);
}
return objectA;
}
if (isZodObjectStrict(objectB)) {
return objectB;
}
return Object.assign({}, objectA, objectB);
};
const checkZodSchema = (data, schema, { passThroughExtraKeys = false } = {}) => {
if (isZodObject(schema)) {
const result = schema.safeParse(data);
if (result.success) {
return {
success: true,
data: passThroughExtraKeys && typeof data === 'object'
? { ...data, ...result.data }
: result.data,
};
}
return {
success: false,
error: result.error,
};
}
return {
success: true,
data: data,
};
};
const zodErrorResponse = (error) => {
return {
name: error.name,
issues: error.issues,
};
};
const isAppRoute = (obj) => {
return (obj === null || obj === void 0 ? void 0 : obj.method) !== undefined;
return 'method' in obj && 'path' in obj;
};
const initTsRest = () => initContract();
const recursivelyApplyOptions = (router, options) => {
return Object.fromEntries(Object.entries(router).map(([key, value]) => {
if (isAppRoute(value)) {
return [
key,
{
...value,
headers: zodMerge(options === null || options === void 0 ? void 0 : options.baseHeaders, value.headers),
},
];
}
else {
return [key, recursivelyApplyOptions(value, options)];
}
}));
};
const initContract = () => {
return {
router: (args) => args,
router: (endpoints, options) => recursivelyApplyOptions(endpoints, options),
query: (args) => args,

@@ -171,3 +249,3 @@ mutation: (args) => args,

return async (inputArgs) => {
const { query, params, body, headers, ...extraInputArgs } = inputArgs || {};
const { query, params, body, headers, extraHeaders, ...extraInputArgs } = inputArgs || {};
const completeUrl = getCompleteUrl(query, clientArgs.baseUrl, params, route, !!clientArgs.jsonQuery);

@@ -180,3 +258,6 @@ return await fetchApi({

extraInputArgs,
headers: headers || {},
headers: {
...extraHeaders,
...headers,
},
});

@@ -196,49 +277,2 @@ };

const isZodType = (obj) => {
return typeof (obj === null || obj === void 0 ? void 0 : obj.safeParse) === 'function';
};
const isZodObject = (obj) => {
const isZodEffects = typeof (obj === null || obj === void 0 ? void 0 : obj.innerType) === 'function';
const maybeZodObject = isZodEffects
? obj === null || obj === void 0 ? void 0 : obj.innerType()
: obj;
return typeof (maybeZodObject === null || maybeZodObject === void 0 ? void 0 : maybeZodObject.passthrough) === 'function';
};
const extractZodObjectShape = (obj) => {
if (!isZodObject(obj)) {
throw new Error('Unknown zod object type');
}
if ('innerType' in obj) {
return obj.innerType().shape;
}
return obj.shape;
};
const checkZodSchema = (data, schema, { passThroughExtraKeys = false } = {}) => {
if (isZodObject(schema)) {
const result = schema.safeParse(data);
if (result.success) {
return {
success: true,
data: passThroughExtraKeys && typeof data === 'object'
? { ...data, ...result.data }
: result.data,
};
}
return {
success: false,
error: result.error,
};
}
return {
success: true,
data: data,
};
};
const zodErrorResponse = (error) => {
return {
name: error.name,
issues: error.issues,
};
};
class ResponseValidationError extends Error {

@@ -273,2 +307,2 @@ constructor(cause) {

export { ResponseValidationError, checkZodSchema, convertQueryParamsToUrlString, encodeQueryParams, encodeQueryParamsJson, extractZodObjectShape, fetchApi, getCompleteUrl, getRouteQuery, getRouteResponses, initClient, initContract, initTsRest, insertParamsIntoPath, isAppRoute, isAppRouteResponse, isZodObject, isZodType, parseJsonQueryObject, tsRestFetchApi, validateResponse, zodErrorResponse };
export { ResponseValidationError, checkZodSchema, convertQueryParamsToUrlString, encodeQueryParams, encodeQueryParamsJson, extractZodObjectShape, fetchApi, getCompleteUrl, getRouteQuery, getRouteResponses, initClient, initContract, initTsRest, insertParamsIntoPath, isAppRoute, isAppRouteResponse, isZodObject, isZodObjectStrict, isZodType, parseJsonQueryObject, tsRestFetchApi, validateResponse, zodErrorResponse, zodMerge };
{
"name": "@ts-rest/core",
"version": "3.19.5",
"version": "3.20.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 { ParamsFromUrl } from './paths';
import { HTTPStatusCode } from './status-codes';
import { AreAllPropertiesOptional, Merge, OptionalIfAllOptional, Prettify, Without, ZodInferOrType, ZodInputOrType } from './type-utils';
import { AreAllPropertiesOptional, LowercaseKeys, Merge, OptionalIfAllOptional, PartialByLooseKeys, Prettify, Without, ZodInferOrType, ZodInputOrType } from './type-utils';
type RecursiveProxyObj<T extends AppRouter, TClientArgs extends ClientArgs> = {

@@ -22,14 +22,12 @@ [TKey in keyof T]: T[TKey] extends AppRoute ? AppRouteFunction<T[TKey], TClientArgs> : T[TKey] extends AppRouter ? RecursiveProxyObj<T[TKey], TClientArgs> : never;

export type ExtractExtraParametersFromClientArgs<TClientArgs extends ClientArgs> = TClientArgs['api'] extends ApiFetcher ? Omit<Parameters<TClientArgs['api']>[0], keyof Parameters<ApiFetcher>[0]> : {};
type DataReturnArgsBase<TRoute extends AppRoute, TClientArgs extends ClientArgs> = {
type DataReturnArgsBase<TRoute extends AppRoute, TClientArgs extends ClientArgs, THeaders = Prettify<'headers' extends keyof TRoute ? PartialByLooseKeys<LowercaseKeys<ZodInputOrType<TRoute['headers']>>, keyof LowercaseKeys<TClientArgs['baseHeaders']>> : never>> = {
body: TRoute extends AppRouteMutation ? AppRouteBodyOrFormData<TRoute> : never;
params: PathParamsFromUrl<TRoute>;
query: 'query' extends keyof TRoute ? AppRouteMutationType<TRoute['query']> : never;
/**
* Additional headers to send with the request, merged over baseHeaders,
*
* Unset a header by setting it to undefined
*/
headers?: Record<string, string>;
headers: THeaders;
extraHeaders?: {
[K in NonNullable<keyof THeaders>]: never;
} & Record<string, string | undefined>;
} & ExtractExtraParametersFromClientArgs<TClientArgs>;
type DataReturnArgs<TRoute extends AppRoute, TClientArgs extends ClientArgs> = OptionalIfAllOptional<DataReturnArgsBase<TRoute, TClientArgs>>;
type DataReturnArgs<TRoute extends AppRoute, TClientArgs extends ClientArgs> = OptionalIfAllOptional<Without<DataReturnArgsBase<TRoute, TClientArgs>, never>>;
export type ApiRouteResponse<T> = {

@@ -55,3 +53,3 @@ [K in keyof T]: {

*/
export type AppRouteFunction<TRoute extends AppRoute, TClientArgs extends ClientArgs> = AreAllPropertiesOptional<Without<DataReturnArgs<TRoute, TClientArgs>, never>> extends true ? (args?: Prettify<Without<DataReturnArgs<TRoute, TClientArgs>, never>>) => Promise<Prettify<ApiRouteResponse<TRoute['responses']>>> : (args: Prettify<Without<DataReturnArgs<TRoute, TClientArgs>, never>>) => Promise<Prettify<ApiRouteResponse<TRoute['responses']>>>;
export type AppRouteFunction<TRoute extends AppRoute, TClientArgs extends ClientArgs> = AreAllPropertiesOptional<DataReturnArgs<TRoute, TClientArgs>> extends true ? (args?: Prettify<DataReturnArgs<TRoute, TClientArgs>>) => Promise<Prettify<ApiRouteResponse<TRoute['responses']>>> : (args: Prettify<DataReturnArgs<TRoute, TClientArgs>>) => Promise<Prettify<ApiRouteResponse<TRoute['responses']>>>;
export interface ClientArgs {

@@ -100,3 +98,3 @@ baseUrl: string;

export declare const getCompleteUrl: (query: unknown, baseUrl: string, params: unknown, route: AppRoute, jsonQuery: boolean) => string;
export declare const getRouteQuery: <TAppRoute extends AppRoute>(route: TAppRoute, clientArgs: ClientArgs) => (inputArgs?: DataReturnArgs<any, ClientArgs>) => Promise<{
export declare const getRouteQuery: <TAppRoute extends AppRoute>(route: TAppRoute, clientArgs: ClientArgs) => (inputArgs?: DataReturnArgsBase<any, ClientArgs>) => Promise<{
status: number;

@@ -103,0 +101,0 @@ body: unknown;

@@ -0,1 +1,7 @@

import { Merge, Opaque, Prettify, WithoutUnknown } from './type-utils';
import { z } from 'zod';
type MixedZodError<A, B> = Opaque<{
a: A;
b: B;
}, 'MixedZodError'>;
/**

@@ -14,2 +20,3 @@ * The path with colon-prefixed parameters

query?: unknown;
headers?: unknown;
summary?: string;

@@ -31,2 +38,3 @@ description?: string;

query?: unknown;
headers?: unknown;
summary?: string;

@@ -37,2 +45,7 @@ description?: string;

};
type ValidatedHeaders<T extends AppRoute, TOptions extends RouterOptions, TOptionsApplied = ApplyOptions<T, TOptions>> = 'headers' extends keyof TOptionsApplied ? TOptionsApplied['headers'] extends MixedZodError<infer A, infer B> ? {
_error: 'Cannot mix plain object types with Zod objects for headers';
a: A;
b: B;
} : T : T;
/**

@@ -43,5 +56,12 @@ * Recursively process a router, allowing for you to define nested routers.

*/
type RecursivelyProcessAppRouter<T extends AppRouter> = {
[K in keyof T]: T[K] extends AppRoute ? T[K] : T[K] extends AppRouter ? RecursivelyProcessAppRouter<T[K]> : T[K];
type RecursivelyProcessAppRouter<T extends AppRouter, TOptions extends RouterOptions> = {
[K in keyof T]: T[K] extends AppRoute ? ValidatedHeaders<T[K], TOptions> : T[K] extends AppRouter ? RecursivelyProcessAppRouter<T[K], TOptions> : T[K];
};
type RecursivelyApplyOptions<TRouter extends AppRouter, TOptions extends RouterOptions> = {
[TRouterKey in keyof TRouter]: TRouter[TRouterKey] extends AppRoute ? Prettify<ApplyOptions<TRouter[TRouterKey], TOptions>> : TRouter[TRouterKey] extends AppRouter ? RecursivelyApplyOptions<TRouter[TRouterKey], TOptions> : TRouter[TRouterKey];
};
type UniversalMerge<A, B> = A extends z.AnyZodObject ? B extends z.AnyZodObject ? z.ZodObject<z.objectUtil.MergeShapes<A['shape'], B['shape']>, B['_def']['unknownKeys'], B['_def']['catchall']> : unknown extends B ? A : MixedZodError<A, B> : unknown extends A ? B : B extends z.AnyZodObject ? MixedZodError<A, B> : unknown extends B ? A : Prettify<Merge<A, B>>;
type ApplyOptions<TRoute extends AppRoute, TOptions extends RouterOptions> = Omit<TRoute, 'headers'> & WithoutUnknown<{
headers: UniversalMerge<TOptions['baseHeaders'], TRoute['headers']>;
}>;
/**

@@ -58,2 +78,5 @@ * A union of all possible endpoint types.

};
export type RouterOptions = {
baseHeaders?: unknown;
};
/**

@@ -73,3 +96,3 @@ * Differentiate between a route and a router

*/
router: <T extends AppRouter>(endpoints: RecursivelyProcessAppRouter<T>) => T;
router: <TRouter extends AppRouter, TOptions extends RouterOptions>(endpoints: RecursivelyProcessAppRouter<TRouter, TOptions>, options?: TOptions) => RecursivelyApplyOptions<TRouter, TOptions>;
/**

@@ -76,0 +99,0 @@ * A single query route, should exist within

import { AppRoute, AppRouteMutation, AppRouter } from './dsl';
import { HTTPStatusCode } from './status-codes';
import { Prettify, Without, ZodInferOrType, ZodInputOrType } from './type-utils';
import { LowercaseKeys, Prettify, Without, ZodInferOrType, ZodInputOrType } from './type-utils';
import { PathParamsWithCustomValidators } from './client';

@@ -27,2 +27,3 @@ type AppRouteResponses<T extends AppRoute, TStatus extends HTTPStatusCode, TClientOrServer extends 'client' | 'server'> = {

query: 'query' extends keyof T ? ZodInferOrType<T['query']> : never;
headers: 'headers' extends keyof T ? Prettify<LowercaseKeys<ZodInferOrType<T['headers']>>> : never;
}, never>> : T extends AppRouter ? {

@@ -35,2 +36,3 @@ [TKey in keyof T]: ServerInferRequest<T[TKey]>;

query: 'query' extends keyof T ? ZodInputOrType<T['query']> : never;
headers: 'headers' extends keyof T ? Prettify<LowercaseKeys<ZodInputOrType<T['headers']>>> : never;
}, never>> : T extends AppRouter ? {

@@ -37,0 +39,0 @@ [TKey in keyof T]: ClientInferRequest<T[TKey]>;

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

export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
export type PartialByLooseKeys<T, K> = Omit<T, K extends keyof T ? K : never> & Partial<Pick<T, K extends keyof T ? K : never>>;
type OptionalKeys<T> = T extends unknown ? {

@@ -37,2 +38,14 @@ [K in keyof T]-?: undefined extends {

} & {};
export type DefinedOrEmpty<T, K extends keyof NonNullable<T>> = undefined extends T ? {} : NonNullable<T>[K];
declare const tag: unique symbol;
declare type Tagged<Token> = {
readonly [tag]: Token;
};
export type Opaque<Type, Token = unknown> = Type & Tagged<Token>;
export type WithoutUnknown<T> = Pick<T, {
[K in keyof T]: unknown extends Exclude<T[K], undefined> ? never : K;
}[keyof T]>;
export type LowercaseKeys<T> = Prettify<{
[K in keyof T as K extends string ? Lowercase<K> : K]: T[K];
}>;
export {};

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

}>;
export declare const isZodObjectStrict: (obj: unknown) => obj is z.AnyZodObject;
export declare const extractZodObjectShape: <T extends z.AnyZodObject | z.ZodEffects<z.AnyZodObject, {

@@ -14,2 +15,3 @@ [x: string]: any;

}>>(obj: T) => any;
export declare const zodMerge: (objectA: unknown, objectB: unknown) => {};
export declare const checkZodSchema: (data: unknown, schema: unknown, { passThroughExtraKeys }?: {

@@ -16,0 +18,0 @@ passThroughExtraKeys?: boolean | undefined;

Sorry, the diff of this file is not supported yet

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