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

composable-functions

Package Overview
Dependencies
Maintainers
2
Versions
24
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

composable-functions - npm Package Compare versions

Comparing version 0.0.0-experimental-20240418-1 to 0.0.0-experimental-20240419-1

11

esm/combinators.js

@@ -34,7 +34,6 @@ import { composable, failure, success } from './constructors.js';

return (async (...args) => {
//@ts-ignore pipe uses exactly he same generic input type as sequence
// I don't understand what is the issue here but ignoring the errors
// is safe and much nicer than a bunch of casts to any
const res = await sequence(...fns)(...args);
return !res.success ? failure(res.errors) : success(res.data.at(-1));
return !res.success
? failure(res.errors)
: success(res.data[res.data.length - 1]);
});

@@ -160,3 +159,3 @@ }

function catchError(fn, catcher) {
return (async (...args) => {
return async (...args) => {
const res = await fn(...args);

@@ -166,3 +165,3 @@ if (res.success)

return composable(catcher)(res.errors, ...args);
});
};
}

@@ -169,0 +168,0 @@ /**

{
"name": "composable-functions",
"version": "0.0.0-experimental-20240418-1",
"version": "0.0.0-experimental-20240419-1",
"description": "Decouple your business logic from your controllers. With first-class type inference from end to end.",

@@ -5,0 +5,0 @@ "author": "Seasoned",

@@ -38,7 +38,6 @@ "use strict";

return (async (...args) => {
//@ts-ignore pipe uses exactly he same generic input type as sequence
// I don't understand what is the issue here but ignoring the errors
// is safe and much nicer than a bunch of casts to any
const res = await sequence(...fns)(...args);
return !res.success ? (0, constructors_js_1.failure)(res.errors) : (0, constructors_js_1.success)(res.data.at(-1));
return !res.success
? (0, constructors_js_1.failure)(res.errors)
: (0, constructors_js_1.success)(res.data[res.data.length - 1]);
});

@@ -171,3 +170,3 @@ }

function catchError(fn, catcher) {
return (async (...args) => {
return async (...args) => {
const res = await fn(...args);

@@ -177,3 +176,3 @@ if (res.success)

return (0, constructors_js_1.composable)(catcher)(res.errors, ...args);
});
};
}

@@ -180,0 +179,0 @@ exports.catchError = catchError;

@@ -1,2 +0,2 @@

import type { AllArguments, CollectArguments, Composable, First, MergeObjs, PipeArguments, PipeReturn, RecordToTuple, Result, UnpackAll, UnpackData } from './types.js';
import type { AllArguments, CollectArguments, Composable, MergeObjs, PipeArguments, PipeReturn, RecordToTuple, Result, UnpackAll, UnpackData } from './types.js';
/**

@@ -29,3 +29,3 @@ * Merges a list of objects into a single object.

*/
declare function pipe<T extends [Composable, ...Composable[]]>(...fns: T & PipeArguments<T>): PipeReturn<T>;
declare function pipe<Fns extends [Composable, ...Composable[]]>(...fns: Fns & PipeArguments<Fns>): PipeReturn<Fns>;
/**

@@ -42,3 +42,3 @@ * Creates a single function out of multiple Composables. It will pass the same input to each provided function. The functions will run in parallel. If all constituent functions are successful, The data field will be a tuple containing each function's output.

*/
declare function all<T extends Composable[]>(...fns: T & AllArguments<T>): Composable<(...args: Parameters<AllArguments<T>[0]>) => { [key in keyof T]: UnpackData<Extract<T[key], Composable>>; }>;
declare function all<Fns extends Composable[]>(...fns: Fns & AllArguments<Fns>): Composable<(...args: Parameters<AllArguments<Fns>[0]>) => { [k in keyof Fns]: UnpackData<Fns[k]>; }>;
/**

@@ -54,3 +54,3 @@ * Receives a Record of Composables, runs them all in parallel and preserves the shape of this record for the data property in successful results.

*/
declare function collect<T extends Record<string, Composable>>(fns: T & CollectArguments<T>): Composable<(...args: Parameters<AllArguments<RecordToTuple<T>>[0]>) => { [key in keyof T]: UnpackData<Extract<T[key], Composable>>; }>;
declare function collect<Fns extends Record<string, Composable>>(fns: Fns & CollectArguments<Fns>): Composable<(...args: Parameters<AllArguments<RecordToTuple<Fns>>[0]>) => { [key in keyof Fns]: UnpackData<Fns[key]>; }>;
/**

@@ -66,3 +66,3 @@ * Works like `pipe` but it will collect the output of every function in a tuple.

*/
declare function sequence<T extends [Composable, ...Composable[]]>(...fns: T & PipeArguments<T>): Composable<(...args: Parameters<Extract<First<T>, Composable>>) => UnpackAll<T>>;
declare function sequence<Fn extends [Composable, ...Composable[]]>(...fns: Fn & PipeArguments<Fn>): Composable<(...args: Parameters<Fn[0]>) => UnpackAll<Fn>>;
/**

@@ -77,3 +77,3 @@ * It takes a Composable and a predicate to apply a transformation over the resulting `data`. It only runs if the function was successfull. When the given function fails, its error is returned wihout changes.

*/
declare function map<T extends Composable, R>(fn: T, mapper: (res: UnpackData<T>) => R): Composable<(...args: Parameters<T>) => R>;
declare function map<Fn extends Composable, O>(fn: Fn, mapper: (res: UnpackData<Fn>) => O): Composable<(...args: Parameters<Fn>) => O>;
/**

@@ -89,4 +89,4 @@ * **NOTE :** Try to use [collect](collect) instead wherever possible since it is much safer. `merge` can create domain functions that will always fail in run-time or even overwrite data from successful constituent functions application. The `collect` function does not have these issues and serves a similar purpose.

*/
declare function merge<T extends Composable[]>(...fns: T & AllArguments<T>): Composable<(...args: Parameters<AllArguments<T>[0]>) => MergeObjs<{
[key in keyof T]: UnpackData<Extract<T[key], Composable>>;
declare function merge<Fn extends Composable[]>(...fns: Fn & AllArguments<Fn>): Composable<(...args: Parameters<AllArguments<Fn>[0]>) => MergeObjs<{
[key in keyof Fn]: UnpackData<Fn[key]>;
}>>;

@@ -103,3 +103,3 @@ /**

*/
declare function first<T extends Composable[]>(...fns: T & AllArguments<T>): Composable<(...args: Parameters<AllArguments<T>[0]>) => UnpackData<Extract<T[number], Composable>>>;
declare function first<Fn extends Composable[]>(...fns: Fn & AllArguments<Fn>): Composable<(...args: Parameters<AllArguments<Fn>[0]>) => UnpackData<Fn[number]>>;
/**

@@ -115,3 +115,3 @@ * Creates a new function that will try to recover from a resulting Failure. When the given function succeeds, its result is returned without changes.

*/
declare function catchError<F extends Composable, C extends (err: Error[], ...originalInput: Parameters<F>) => any>(fn: F, catcher: C): Composable<(...args: Parameters<F>) => Awaited<ReturnType<C>> extends never[] ? UnpackData<F> extends any[] ? UnpackData<F> : Awaited<ReturnType<C>> | UnpackData<F> : Awaited<ReturnType<C>> | UnpackData<F>>;
declare function catchError<Fn extends Composable, C extends (err: Error[], ...originalInput: Parameters<Fn>) => any>(fn: Fn, catcher: C): Composable<(...args: Parameters<Fn>) => Awaited<ReturnType<C>> extends never[] ? UnpackData<Fn> extends any[] ? UnpackData<Fn> : Awaited<ReturnType<C>> | UnpackData<Fn> : Awaited<ReturnType<C>> | UnpackData<Fn>>;
/**

@@ -127,3 +127,3 @@ * Creates a new function that will apply a transformation over a resulting Failure from the given function. When the given function succeeds, its result is returned without changes.

*/
declare function mapError<T extends Composable, R>(fn: T, mapper: (err: Error[]) => Error[] | Promise<Error[]>): T;
declare function mapError<Fn extends Composable>(fn: Fn, mapper: (err: Error[]) => Error[] | Promise<Error[]>): Fn;
/**

@@ -143,3 +143,3 @@ * Whenever you need to intercept inputs and a domain function result without changing them you can use this function.

*/
declare function trace(traceFn: (result: Result<unknown>, ...originalInput: unknown[]) => Promise<void> | void): <C extends Composable>(fn: C) => C;
declare function trace(traceFn: (result: Result<unknown>, ...originalInput: unknown[]) => Promise<void> | void): <Fn extends Composable>(fn: Fn) => Fn;
export { all, catchError, collect, first, map, mapError, merge, mergeObjects, pipe, sequence, trace, };

@@ -1,2 +0,2 @@

import type { Composable, Failure, Fn, ParserSchema, Success } from './types.js';
import type { Composable, Failure, ParserSchema, Success } from './types.js';
import { UnpackData } from './types.js';

@@ -10,3 +10,3 @@ declare function success<const T>(data: T): Success<T>;

*/
declare function composable<T extends Fn>(fn: T): Composable<T>;
declare function composable<T extends (...args: any[]) => any>(fn: T): Composable<T>;
/**

@@ -13,0 +13,0 @@ * It can be used to call a domain function from another domain function. It will return the output of the given domain function if it was successfull, otherwise it will throw a `ErrorList` that will bubble up to the parent function.

import type { Composable, Last, UnpackAll, UnpackData } from '../types.js';
import type { UnpackDFObject } from './types.js';
/**

@@ -28,3 +27,3 @@ * Takes a function with 2 parameters and partially applies the second one.

*/
declare function pipe<T extends Composable[]>(...fns: T): Composable<(input?: unknown, environment?: unknown) => Last<UnpackAll<T>>>;
declare function pipe<Fns extends Composable[]>(...fns: Fns): Composable<(input?: unknown, environment?: unknown) => Last<UnpackAll<Fns>>>;
/**

@@ -43,3 +42,5 @@ * Receives a Record of domain functions, runs them all in sequence like `pipe` but preserves the shape of that record for the data property in successful results.

*/
declare function collectSequence<Fns extends Record<string, Composable>>(fns: Fns): Composable<(input?: unknown, environment?: unknown) => UnpackDFObject<Fns>>;
declare function collectSequence<Fns extends Record<string, Composable>>(fns: Fns): Composable<(input?: unknown, environment?: unknown) => {
[K in keyof Fns]: UnpackData<Fns[K]>;
}>;
/**

@@ -80,3 +81,3 @@ * Works like `pipe` but it will collect the output of every function in a tuple.

*/
declare function branch<T, R extends Composable | null>(dfn: Composable<(input?: unknown, environment?: unknown) => T>, resolver: (o: T) => Promise<R> | R): Composable<(input?: unknown, environment?: unknown) => R extends Composable<(input?: unknown, environment?: unknown) => infer U> ? U : T | UnpackData<NonNullable<R>>>;
declare function branch<O, MaybeFn extends Composable | null>(dfn: Composable<(input?: unknown, environment?: unknown) => O>, resolver: (o: O) => Promise<MaybeFn> | MaybeFn): Composable<(input?: unknown, environment?: unknown) => MaybeFn extends Composable<(input?: unknown, environment?: unknown) => infer BranchOutput> ? BranchOutput : O | UnpackData<NonNullable<MaybeFn>>>;
export { applyEnvironment, branch, collectSequence, pipe, sequence };

@@ -1,2 +0,1 @@

export type { UnpackDFObject } from './types.js';
export { applyEnvironment, branch, collectSequence, pipe, sequence, } from './combinators.js';

@@ -6,4 +6,4 @@ export { applySchema, composable, failure, fromSuccess, success, withSchema, } from './constructors.js';

export { EnvironmentError, ErrorList, InputError } from './errors.js';
export type { Composable, Failure, Last, MergeObjs, Result, SerializableError, SerializedResult, Success, UnpackAll, UnpackData, } from './types.js';
export type { Composable, Failure, MergeObjs, ParserSchema, Result, SerializableError, SerializedResult, Success, UnpackAll, UnpackData, } from './types.js';
export * as environment from './environment/index.js';
export * as compat from './compat/index.js';

@@ -5,2 +5,3 @@ declare namespace Internal {

} & {};
type IsNever<A> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends never ? 1 : 2) ? true : false;
type UnionToTuple<T> = ((T extends any ? (t: T) => T : never) extends infer U ? (U extends any ? (u: U) => any : never) extends (v: infer V) => any ? V : never : never) extends (_: any) => infer W ? [...UnionToTuple<Exclude<T, W>>, W] : [];

@@ -7,0 +8,0 @@ type Keys<R extends Record<string, any>> = UnionToTuple<keyof R>;

@@ -26,14 +26,3 @@ import { Internal } from './internal/types.js';

] ? MergeObjs<rest, Internal.Prettify<Omit<output, keyof first> & first>> : output;
/**
* Returns the last item of a tuple type.
* @example
* type MyTuple = [string, number]
* type Result = Last<MyTuple>
* // ^? number
*/
type Last<T extends readonly unknown[]> = T extends [...infer _I, infer L] ? L : never;
type IsNever<A> = (<T>() => T extends A ? 1 : 2) extends (<T>() => T extends never ? 1 : 2) ? true : false;
type First<T extends readonly any[]> = T extends [infer F, ...infer _I] ? F : never;
type Fn = (...args: any[]) => any;
type Composable<T extends Fn = Fn> = (...args: Parameters<T>) => Promise<Result<Awaited<ReturnType<T>>>>;
type Composable<T extends (...args: any[]) => any = (...args: any[]) => any> = (...args: Parameters<T>) => Promise<Result<Awaited<ReturnType<T>>>>;
type UnpackData<T extends Composable> = Extract<Awaited<ReturnType<T>>, {

@@ -49,6 +38,7 @@ success: true;

...infer rest
] ? IsNever<OA> extends true ? ['Fail to compose, "never" does not fit in', PB] : Awaited<OA> extends PB ? PipeReturn<[Composable<(...args: PA) => OB>, ...rest]> : ['Fail to compose', Awaited<OA>, 'does not fit in', PB] : Fns extends [Composable<(...args: infer P) => infer O>] ? Composable<(...args: P) => O> : never;
] ? Internal.IsNever<OA> extends true ? ['Fail to compose, "never" does not fit in', PB] : Awaited<OA> extends PB ? PipeReturn<[Composable<(...args: PA) => OB>, ...rest]> : ['Fail to compose', Awaited<OA>, 'does not fit in', PB] : Fns extends [Composable<(...args: infer P) => infer O>] ? Composable<(...args: P) => O> : never;
type PipeArguments<Fns extends any[], Arguments extends any[] = []> = Fns extends [Composable<(...a: infer PA) => infer OA>, ...infer restA] ? restA extends [
Composable<(firstParameter: infer FirstBParameter, ...b: infer PB) => any>
] ? IsNever<Awaited<OA>> extends true ? ['Fail to compose, "never" does not fit in', FirstBParameter] : Awaited<OA> extends FirstBParameter ? Internal.EveryElementTakes<PB, undefined> extends true ? PipeArguments<restA, [...Arguments, Composable<(...a: PA) => OA>]> : Internal.EveryElementTakes<PB, undefined> : ['Fail to compose', Awaited<OA>, 'does not fit in', FirstBParameter] : [...Arguments, Composable<(...a: PA) => OA>] : never;
Composable<(firstParameter: infer FirstBParameter, ...b: infer PB) => any>,
...unknown[]
] ? Internal.IsNever<Awaited<OA>> extends true ? ['Fail to compose, "never" does not fit in', FirstBParameter] : Awaited<OA> extends FirstBParameter ? Internal.EveryElementTakes<PB, undefined> extends true ? PipeArguments<restA, [...Arguments, Composable<(...a: PA) => OA>]> : Internal.EveryElementTakes<PB, undefined> : ['Fail to compose', Awaited<OA>, 'does not fit in', FirstBParameter] : [...Arguments, Composable<(...a: PA) => OA>] : never;
type AllArguments<Fns extends any[], Arguments extends any[] = []> = Fns extends [Composable<(...a: infer PA) => infer OA>, ...infer restA] ? restA extends [Composable<(...b: infer PB) => infer OB>, ...infer restB] ? Internal.SubtypesTuple<PA, PB, []> extends [...infer MergedP] ? AllArguments<[

@@ -61,3 +51,3 @@ Composable<(...args: MergedP) => OB>,

]> : ['Fail to compose', PA, 'does not fit in', PB] : [...Arguments, Composable<(...a: PA) => OA>] : never;
type CollectArguments<T extends Record<string, Composable>> = {} extends Internal.Zip<Internal.Keys<T>, AllArguments<Internal.RecordValuesFromKeysTuple<T, Internal.Keys<T>>>> ? never : AllArguments<Internal.RecordValuesFromKeysTuple<T, Internal.Keys<T>>> extends ['Fail to compose', ...any[]] ? AllArguments<Internal.RecordValuesFromKeysTuple<T, Internal.Keys<T>>> : Internal.Zip<Internal.Keys<T>, AllArguments<Internal.RecordValuesFromKeysTuple<T, Internal.Keys<T>>>>;
type CollectArguments<T extends Record<string, Composable>> = AllArguments<Internal.UnionToTuple<T[keyof T]>> extends ['Fail to compose', ...any[]] ? AllArguments<Internal.UnionToTuple<T[keyof T]>> : Internal.Zip<Internal.Keys<T>, AllArguments<Internal.UnionToTuple<T[keyof T]>>>;
type RecordToTuple<T extends Record<string, Composable>> = Internal.RecordValuesFromKeysTuple<T, Internal.Keys<T>>;

@@ -75,30 +65,19 @@ type SerializableError<T extends Error = Error> = {

/**
* A parsing error when validating the input or environment schemas.
* This will be transformed into an `InputError` before being returned from the domain function.
* It is usually not visible to the end user unless one wants to write an adapter for a schema validator.
*/
type ParserIssue = {
path: PropertyKey[];
message: string;
};
/**
* The result of input or environment validation.
* See the type `Result` for the return values of domain functions.
* It is usually not visible to the end user unless one wants to write an adapter for a schema validator.
*/
type ParserResult<T> = {
success: true;
data: T;
} | {
success: false;
error: {
issues: ParserIssue[];
};
};
/**
* The object used to validate either input or environment when creating domain functions.
*/
type ParserSchema<T extends unknown = unknown> = {
safeParseAsync: (a: unknown) => Promise<ParserResult<T>>;
safeParseAsync: (a: unknown) => Promise<{
success: true;
data: T;
} | {
success: false;
error: {
issues: {
path: PropertyKey[];
message: string;
}[];
};
}>;
};
export type { AllArguments, CollectArguments, Composable, Failure, First, Fn, Last, MergeObjs, ParserIssue, ParserResult, ParserSchema, PipeArguments, PipeReturn, RecordToTuple, Result, SerializableError, SerializedResult, Success, UnpackAll, UnpackData, };
type Last<T extends readonly unknown[]> = T extends [...infer _I, infer L] ? L : never;
export type { AllArguments, CollectArguments, Composable, Failure, Last, MergeObjs, ParserSchema, PipeArguments, PipeReturn, RecordToTuple, Result, SerializableError, SerializedResult, Success, UnpackAll, UnpackData, };
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