lil-fp
Advanced tools
Comparing version 1.4.5 to 1.5.0
113
package.json
{ | ||
"name": "lil-fp", | ||
"version": "1.4.5", | ||
"version": "1.5.0", | ||
"description": "Functional programming utilities for TypeScript", | ||
"main": "dist/index.js", | ||
"module": "dist/index.mjs", | ||
"types": "dist/index.d.ts", | ||
"exports": { | ||
".": { | ||
"types": "./dist/index.d.ts", | ||
"import": "./dist/index.mjs", | ||
"require": "./dist/index.js" | ||
}, | ||
"./arr": { | ||
"types": "./dist/arr.d.ts", | ||
"import": "./dist/arr.mjs", | ||
"require": "./dist/arr.js" | ||
}, | ||
"./bool": { | ||
"types": "./dist/bool.d.ts", | ||
"import": "./dist/bool.mjs", | ||
"require": "./dist/bool.js" | ||
}, | ||
"./func": { | ||
"types": "./dist/func.d.ts", | ||
"import": "./dist/func.mjs", | ||
"require": "./dist/func.js" | ||
}, | ||
"./logic": { | ||
"types": "./dist/logic.d.ts", | ||
"import": "./dist/logic.mjs", | ||
"require": "./dist/logic.js" | ||
}, | ||
"./is": { | ||
"types": "./dist/is.d.ts", | ||
"import": "./dist/is.mjs", | ||
"require": "./dist/is.js" | ||
}, | ||
"./obj": { | ||
"types": "./dist/obj.d.ts", | ||
"import": "./dist/obj.mjs", | ||
"require": "./dist/obj.js" | ||
}, | ||
"./option": { | ||
"types": "./dist/option.d.ts", | ||
"import": "./dist/option.mjs", | ||
"require": "./dist/option.js" | ||
}, | ||
"./package.json": "./package.json" | ||
"main": "dist/lil-fp.cjs.js", | ||
"module": "dist/lil-fp.esm.js", | ||
"preconstruct": { | ||
"entrypoints": [ | ||
"index.ts", | ||
"arr.ts", | ||
"bool.ts", | ||
"func.ts", | ||
"logic.ts", | ||
"is.ts", | ||
"obj.ts", | ||
"task.ts", | ||
"str.ts", | ||
"opt.ts" | ||
] | ||
}, | ||
"typesVersions": { | ||
"*": { | ||
".": [ | ||
"dist/index.d.ts" | ||
], | ||
"arr": [ | ||
"dist/arr.d.ts" | ||
], | ||
"bool": [ | ||
"dist/bool.d.ts" | ||
], | ||
"func": [ | ||
"dist/func.d.ts" | ||
], | ||
"logic": [ | ||
"dist/logic.d.ts" | ||
], | ||
"is": [ | ||
"dist/is.d.ts" | ||
], | ||
"obj": [ | ||
"dist/obj.d.ts" | ||
], | ||
"option": [ | ||
"dist/option.d.ts" | ||
] | ||
} | ||
}, | ||
"files": [ | ||
"dist", | ||
"src" | ||
"src", | ||
"arr", | ||
"bool", | ||
"task", | ||
"func", | ||
"logic", | ||
"is", | ||
"str", | ||
"obj", | ||
"opt" | ||
], | ||
@@ -96,14 +48,19 @@ "sideEffects": false, | ||
"devDependencies": { | ||
"@babel/preset-typescript": "^7.21.5", | ||
"@changesets/cli": "^2.26.1", | ||
"@mobily/ts-belt": "^3.13.1", | ||
"@preconstruct/cli": "^2.7.0", | ||
"prettier": "^2.8.7", | ||
"tsup": "^6.7.0", | ||
"typescript": "^5.0.4" | ||
"typescript": "^5.0.4", | ||
"vitest": "0.34.4" | ||
}, | ||
"scripts": { | ||
"build": "tsup", | ||
"postinstall": "preconstruct dev", | ||
"build": "preconstruct build", | ||
"dev": "preconstruct dev", | ||
"clean": "rm -rf dist", | ||
"release": "pnpm changeset version && pnpm publish --no-git-checks", | ||
"prerelease": "pnpm build" | ||
"prerelease": "pnpm build", | ||
"test": "vitest" | ||
} | ||
} |
@@ -12,4 +12,12 @@ /** | ||
<T>(f: (v: T, index: number, array: T[]) => boolean) => | ||
(arr: T[]): T[] => | ||
arr.filter(f) | ||
(arr: T[]): T[] => { | ||
const len = arr.length | ||
const filtered: T[] = [] | ||
for (let i = 0; i < len; i++) { | ||
if (f(arr[i], i, arr)) { | ||
filtered.push(arr[i]) | ||
} | ||
} | ||
return filtered | ||
} | ||
@@ -21,4 +29,10 @@ /** | ||
<T, U>(f: (v: T, index: number, array: T[]) => U) => | ||
(arr: T[]): U[] => | ||
arr.map(f) | ||
(arr: T[]): U[] => { | ||
const len = arr.length | ||
const mapped = new Array<U>(len) | ||
for (let i = 0; i < len; i++) { | ||
mapped[i] = f(arr[i], i, arr) | ||
} | ||
return mapped | ||
} | ||
@@ -33,18 +47,12 @@ /** | ||
<T, U>(f: (acc: U, v: T, index: number, array: T[]) => U, init: U) => | ||
(arr: T[]): U => | ||
arr.reduce(f, init) | ||
(arr: T[]): U => { | ||
const len = arr.length | ||
let acc = init | ||
for (let i = 0; i < len; i++) { | ||
acc = f(acc, arr[i], i, arr) | ||
} | ||
return acc | ||
} | ||
/** | ||
* Calls the specified callback function for all the elements in an array. | ||
* The return value is the non-nullable result of the callback function. | ||
*/ | ||
export const filterMap = | ||
<T, U>(f: (v: T, index: number, array: T[]) => U | undefined | null) => | ||
(arr: T[]): U[] => | ||
arr.reduce((acc, v, index, arr) => { | ||
const x = f(v, index, arr) | ||
return x == null ? acc : [...acc, x] | ||
}, [] as U[]) | ||
/** | ||
* Performs the specified action for each element in an array. | ||
@@ -54,4 +62,8 @@ */ | ||
<T>(f: (v: T, index: number, array: T[]) => void) => | ||
(arr: T[]): void => | ||
arr.forEach(f) | ||
(arr: T[]): void => { | ||
const len = arr.length | ||
for (let i = 0; i < len; i++) { | ||
f(arr[i], i, arr) | ||
} | ||
} | ||
@@ -89,4 +101,6 @@ /** | ||
<T>(i: number) => | ||
(arr: T[]): T | undefined => | ||
arr.at(i) | ||
(arr: T[]): T | undefined => { | ||
const index = i < 0 ? arr.length + i : i | ||
return arr[index] | ||
} | ||
@@ -96,3 +110,3 @@ /** | ||
*/ | ||
export const uniq = <T>(arr: T[]): T[] => [...new Set(arr)] | ||
export const uniq = <T>(arr: T[]): T[] => Array.from(new Set(arr)) | ||
@@ -104,4 +118,11 @@ /** | ||
<T>(f: (v: T, index: number, array: T[]) => boolean) => | ||
(arr: T[]): boolean => | ||
arr.some(f) | ||
(arr: T[]): boolean => { | ||
const len = arr.length | ||
for (let i = 0; i < len; i++) { | ||
if (f(arr[i], i, arr)) { | ||
return true | ||
} | ||
} | ||
return false | ||
} | ||
@@ -113,4 +134,11 @@ /** | ||
<T>(f: (v: T, index: number, array: T[]) => boolean) => | ||
(arr: T[]): boolean => | ||
arr.every(f) | ||
(arr: T[]): boolean => { | ||
const len = arr.length | ||
for (let i = 0; i < len; i++) { | ||
if (!f(arr[i], i, arr)) { | ||
return false | ||
} | ||
} | ||
return true | ||
} | ||
@@ -117,0 +145,0 @@ /** |
@@ -8,1 +8,2 @@ export * as Arr from './arr' | ||
export * as Opt from './opt' | ||
export * as Task from './task' |
@@ -1,35 +0,22 @@ | ||
export const match = <T, R>(...fns: ((v: T) => R)[]) => { | ||
return (v: T) => { | ||
for (const fn of fns) { | ||
const x = fn(v) | ||
if (x != null) return x | ||
export function match<T extends string | number, R>( | ||
lookup: Record<T | '_', R | (() => R)> | ||
) { | ||
return (value: T): R => { | ||
if (value in lookup || '_' in lookup) { | ||
const returnValue = value in lookup ? lookup[value] : lookup['_'] | ||
return typeof returnValue === 'function' ? returnValue() : returnValue | ||
} | ||
} | ||
} | ||
export function when<T, U extends T, R>( | ||
predicate: (v: T) => boolean, | ||
fn: (v: U) => R | ||
): (v: T) => R | undefined | ||
export function when<T, U extends T, R>( | ||
predicate: (v: T) => v is U, | ||
fn: (v: U) => R | ||
): (v: T) => R | undefined | ||
export function when(predicate: (v: any) => boolean, fn: (v: any) => any) { | ||
return (v: any) => { | ||
if (predicate(v)) { | ||
return fn(v) | ||
} | ||
const handlers = Object.keys(lookup) | ||
.map((key) => `"${key}"`) | ||
.join(', ') | ||
const error = new Error( | ||
`Tried to handle "${value}" but there is no handler defined. Only defined handlers are: ${handlers}.` | ||
) | ||
Error.captureStackTrace?.(error, match) | ||
throw error | ||
} | ||
} | ||
export const otherwise = | ||
<T, R>(fn: (v: T) => R) => | ||
(v: T) => | ||
when(() => true, fn)(v) | ||
export const orElse = | ||
<T, U>(u: U | (() => U)) => | ||
(v: T | null | undefined): T | U => | ||
// @ts-ignore | ||
v == null ? (typeof u === 'function' ? u() : u) : v |
import { cast } from './func' | ||
import { isFunc, isObj } from './is' | ||
import { | ||
Assign, | ||
Bind, | ||
@@ -9,3 +8,3 @@ Compact, | ||
Dict, | ||
Path, | ||
DistributiveMerge, | ||
Simplify, | ||
@@ -46,3 +45,3 @@ Split, | ||
v: K | ((obj: T) => K) | ||
): (obj: T) => Assign<[T, K]> | ||
): (obj: T) => DistributiveMerge<T, K> | ||
export function assign(v: any) { | ||
@@ -58,4 +57,4 @@ return (obj: any) => ({ | ||
*/ | ||
export const assignTo = | ||
<K extends string, T extends Dict>(key: K) => | ||
export const bindTo = | ||
<K extends string, T>(key: K) => | ||
(prev: T): Record<K, T> => | ||
@@ -100,3 +99,3 @@ fromEntries([[key, prev]]) | ||
const descriptors = Object.getOwnPropertyDescriptors(obj) | ||
const dKeys = Object.keys(descriptors) | ||
const keys = Object.keys(descriptors) | ||
const split = (k: any[]) => { | ||
@@ -113,4 +112,4 @@ const clone = {} | ||
} | ||
const fn = (key: any) => split(Array.isArray(key) ? key : dKeys.filter(key)) | ||
return keys.map(fn).concat(split(dKeys)) as any | ||
const fn = (key: any) => split(Array.isArray(key) ? key : keys.filter(key)) | ||
return keys.map(fn).concat(split(keys)) as any | ||
} | ||
@@ -121,12 +120,24 @@ | ||
*/ | ||
export function merge<T, U>(source: U): (target: T) => Assign<[T, U]> | ||
export function merge<T, U>(source: U): (target: T) => DistributiveMerge<T, U> | ||
export function merge<T, U, V>( | ||
target: T | ||
): (source: U, source2: V) => Assign<[T, U, V]> | ||
): (source: U, source2: V) => DistributiveMerge<DistributiveMerge<T, U>, V> | ||
export function merge<T, U, V, W>( | ||
target: T | ||
): (source: U, source2: V, source3: W) => Assign<[T, U, V, W]> | ||
): ( | ||
source: U, | ||
source2: V, | ||
source3: W | ||
) => DistributiveMerge<DistributiveMerge<DistributiveMerge<T, U>, V>, W> | ||
export function merge<T, U, V, W, X>( | ||
target: T | ||
): (source: U, source2: V, source3: W, source4: X) => Assign<[T, U, V, W, X]> | ||
): ( | ||
source: U, | ||
source2: V, | ||
source3: W, | ||
source4: X | ||
) => DistributiveMerge< | ||
DistributiveMerge<DistributiveMerge<DistributiveMerge<T, U>, V>, W>, | ||
X | ||
> | ||
export function merge(...args: Dict[]) { | ||
@@ -186,29 +197,10 @@ return (obj: any) => { | ||
...defaults, | ||
...obj, | ||
...compact(obj), | ||
}) | ||
const isSafeKey = (key: any) => | ||
key !== '__proto__' && key !== 'prototype' && key !== 'constructor' | ||
export const isEmpty = (v: Dict) => Object.keys(v).length === 0 | ||
/** | ||
* Get a property from an object by dot notation | ||
*/ | ||
export const get = | ||
<T extends Dict, K extends Path<T>>(path: K, undef?: T[K]) => | ||
(obj: T): T[K] => { | ||
const keys = Array.isArray(path) ? path : path.split('.') | ||
for (let i = 0; i < keys.length; i++) { | ||
const key = keys[i] | ||
if ( | ||
!obj || | ||
!Object.prototype.hasOwnProperty.call(obj, key) || | ||
!isSafeKey(key) | ||
) { | ||
// @ts-ignore | ||
obj = undefined | ||
break | ||
} | ||
obj = obj[key] | ||
} | ||
return cast(obj ?? undef) | ||
} | ||
export const has = | ||
<T extends Dict>(key: keyof T) => | ||
(obj: T): boolean => | ||
Object.prototype.hasOwnProperty.call(obj, key) |
@@ -5,7 +5,12 @@ /** | ||
type Option<T> = None | Some<T> | ||
interface None { | ||
_tag: 'None' | ||
} | ||
type None = { _tag: 'None' } | ||
interface Some<T> { | ||
_tag: 'Some' | ||
value: T | ||
} | ||
type Some<T> = { _tag: 'Some'; value: T } | ||
type Option<T> = None | Some<T> | ||
@@ -12,0 +17,0 @@ /** |
110
src/types.ts
@@ -1,3 +0,13 @@ | ||
export type Dict = Record<string, any> | ||
export interface Dict { | ||
[key: string]: any | ||
} | ||
export type DistributiveOmit<T, K extends keyof any> = T extends any | ||
? Omit<T, K> | ||
: never | ||
export type DistributiveMerge<P1 = {}, P2 = {}> = Simplify< | ||
DistributiveOmit<P1, keyof P2> & P2 | ||
> | ||
export type Compact<T extends Dict> = { | ||
@@ -7,2 +17,4 @@ [K in keyof T]: T[K] extends undefined ? never : T[K] | ||
export type Simplify<T> = T extends any ? { [K in keyof T]: T[K] } : T | ||
export type SplitProp<T> = ReadonlyArray<keyof T> | ||
@@ -16,3 +28,3 @@ | ||
}, | ||
Omit<T, K[number][number]> | ||
DistributiveOmit<T, K[number][number]> | ||
] | ||
@@ -29,3 +41,3 @@ | ||
export type Defaults<T extends Dict, K extends Partial<T>> = Simplify< | ||
Omit<T, keyof K> & Required<K> | ||
DistributiveOmit<T, keyof K> & Required<K> | ||
> | ||
@@ -36,93 +48,3 @@ | ||
obj: T | ||
) => Assign<[T, Record<K, U>]> | ||
) => DistributiveMerge<T, Record<K, U>> | ||
} | ||
export type Simplify<T> = T extends any ? { [K in keyof T]: T[K] } : T | ||
type Merge<P1 = {}, P2 = {}> = Omit<P1, keyof P2> & P2 | ||
export type Assign<T extends unknown[], Target = {}> = T extends [ | ||
infer Next, | ||
...infer Rest | ||
] | ||
? Simplify<Assign<Rest, Merge<Target, Next>>> | ||
: T extends [...infer Rest, infer Next] | ||
? Simplify<Merge<Assign<Rest, Target>, Next>> | ||
: T extends [] | ||
? Simplify<Target> | ||
: T extends (infer I)[] | ||
? Simplify<Merge<Target, I>> | ||
: Simplify<Target> | ||
export type Primitive = | ||
| null | ||
| undefined | ||
| string | ||
| number | ||
| boolean | ||
| symbol | ||
| bigint | ||
type ArrayKey = number | ||
type IsTuple<T extends readonly any[]> = number extends T['length'] | ||
? false | ||
: true | ||
type TupleKeys<T extends readonly any[]> = Exclude<keyof T, keyof any[]> | ||
export type PathConcat< | ||
TKey extends string | number, | ||
TValue | ||
> = TValue extends Primitive ? `${TKey}` : `${TKey}` | `${TKey}.${Path<TValue>}` | ||
export type Path<T> = T extends readonly (infer V)[] | ||
? IsTuple<T> extends true | ||
? { | ||
[K in TupleKeys<T>]-?: PathConcat<K & string, T[K]> | ||
}[TupleKeys<T>] | ||
: PathConcat<ArrayKey, V> | ||
: { | ||
[K in keyof T]-?: PathConcat<K & string, T[K]> | ||
}[keyof T] | ||
type ArrayPathConcat< | ||
TKey extends string | number, | ||
TValue | ||
> = TValue extends Primitive | ||
? never | ||
: TValue extends readonly (infer U)[] | ||
? U extends Primitive | ||
? never | ||
: `${TKey}` | `${TKey}.${ArrayPath<TValue>}` | ||
: `${TKey}.${ArrayPath<TValue>}` | ||
export type ArrayPath<T> = T extends readonly (infer V)[] | ||
? IsTuple<T> extends true | ||
? { | ||
[K in TupleKeys<T>]-?: ArrayPathConcat<K & string, T[K]> | ||
}[TupleKeys<T>] | ||
: ArrayPathConcat<ArrayKey, V> | ||
: { | ||
[K in keyof T]-?: ArrayPathConcat<K & string, T[K]> | ||
}[keyof T] | ||
export type PathValue<T, TPath extends Path<T> | ArrayPath<T>> = T extends any | ||
? TPath extends `${infer K}.${infer R}` | ||
? K extends keyof T | ||
? R extends Path<T[K]> | ||
? PathValue<T[K], R> | ||
: never | ||
: K extends `${ArrayKey}` | ||
? T extends readonly (infer V)[] | ||
? PathValue<V, R & Path<V>> | ||
: never | ||
: never | ||
: TPath extends keyof T | ||
? T[TPath] | ||
: TPath extends `${ArrayKey}` | ||
? T extends readonly (infer V)[] | ||
? V | ||
: never | ||
: never | ||
: never |
Install scripts
Supply chain riskInstall scripts are run when the package is installed. The majority of malware in npm is hidden in install scripts.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
134218
108
4285
7
1
11
1