Created
August 22, 2024 10:14
-
-
Save stevensacks/43ff750e8aa55ef81fb7bd0602884a52 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { describe, expect, test } from 'vitest'; | |
import { tryCatch } from '../functions'; | |
describe('functions', () => { | |
test('tryCatch success', async () => { | |
expect(await tryCatch((value: number) => 10 / value, 5)).toEqual({ | |
result: 2, | |
}); | |
}); | |
test('tryCatch error', async () => { | |
expect( | |
await tryCatch(() => { | |
throw new Error('failed'); | |
}) | |
).toEqual({ | |
error: new Error('failed'), | |
}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { | |
convertCase, | |
every, | |
isNil, | |
mapKeys, | |
mapValues, | |
md5, | |
some, | |
toCamelCase, | |
toKebabCase, | |
withValues, | |
} from '../object'; | |
describe('object', () => { | |
test('every', () => { | |
const predicate = (value: any) => !!value; | |
expect(every({}, predicate)).toBe(true); | |
expect(every({hello: 'world'}, predicate)).toBe(true); | |
expect(every({foo: 0, hello: 'world'}, predicate)).toBe(false); | |
}); | |
test('some', () => { | |
const predicate = (value: any) => !!value; | |
expect(some({}, predicate)).toBe(false); | |
expect(some({foo: 0, hello: 'world'}, predicate)).toBe(true); | |
expect(some({hello: 0}, predicate)).toBe(false); | |
}); | |
test('md5', () => { | |
expect(md5({a: 'b'})).toBe('92eff9dda44cb8003ee13990782580ff'); | |
}); | |
test('isNil', () => { | |
expect(isNil(undefined)).toBe(true); | |
expect(isNil(null)).toBe(true); | |
expect(isNil(1)).toBe(false); | |
expect(isNil('foo')).toBe(false); | |
expect(isNil({})).toBe(false); | |
}); | |
test('mapKeys', () => { | |
expect(mapKeys({bar: 'baz', foo: 'bar'}, (key) => `${key}1`)).toEqual({ | |
bar1: 'baz', | |
foo1: 'bar', | |
}); | |
}); | |
test('mapValues', () => { | |
expect( | |
mapValues({bar: 'baz', foo: 'bar'}, (value) => `${value}1`) | |
).toEqual({ | |
bar: 'baz1', | |
foo: 'bar1', | |
}); | |
}); | |
test('convertCase', () => { | |
expect(convertCase((f) => f)).toEqual({}); | |
const obj = {a: [{b: 'c'}], d: {e: true}}; | |
expect(convertCase((f) => `${f}${f}`, obj)).toEqual({ | |
aa: [{bb: 'c'}], | |
dd: {ee: true}, | |
}); | |
}); | |
test('toKebabCase', () => { | |
expect( | |
toKebabCase({ | |
nestedObject: { | |
biz: 'baz', | |
fizzBuzz: 5, | |
}, | |
someValue: 'foo', | |
}) | |
).toEqual({ | |
'nested-object': { | |
biz: 'baz', | |
'fizz-buzz': 5, | |
}, | |
'some-value': 'foo', | |
}); | |
}); | |
test('toCamelCase', () => { | |
expect( | |
toCamelCase({ | |
'nested-object': { | |
biz: 'baz', | |
'fizz-buzz': 5, | |
}, | |
'some-value': 'foo', | |
}) | |
).toEqual({ | |
nestedObject: { | |
biz: 'baz', | |
fizzBuzz: 5, | |
}, | |
someValue: 'foo', | |
}); | |
}); | |
test('withValues', () => { | |
const obj = {a: 'b', c: '', d: false, e: null}; | |
expect(withValues(obj)).toEqual({a: 'b'}); | |
expect(withValues(obj, true)).toEqual({a: 'b', c: '', d: false}); | |
}); | |
}); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {camelCase, isObject, snakeCase} from 'lodash'; | |
import SparkMD5 from 'spark-md5'; | |
export const every = ( | |
obj: Record<string, unknown>, | |
predicate: (value: unknown) => boolean | |
): boolean => Object.values(obj).every(predicate); | |
export const some = ( | |
obj: Record<string, unknown>, | |
predicate: (value: unknown) => boolean | |
): boolean => Object.values(obj).some(predicate); | |
export const md5 = (obj: Record<string, unknown>): string => | |
SparkMD5.hash(JSON.stringify(obj)); | |
export const isNil = (value: unknown): boolean => | |
value === null || value === undefined; | |
export const deepRemoveNil = (input: unknown): unknown => { | |
if (isNil(input)) { | |
return; | |
} | |
if (Array.isArray(input)) { | |
return input | |
.filter((value) => !isNil(value)) | |
.map((value) => deepRemoveNil(value)); | |
} | |
if (isObject(input)) { | |
const keys = Object.keys(input); | |
return Object.fromEntries( | |
keys | |
.filter((key) => !isNil((input as Record<string, unknown>)[key])) | |
.map((key) => [ | |
key, | |
deepRemoveNil((input as Record<string, unknown>)[key]), | |
]) | |
); | |
} | |
return input; | |
}; | |
export const mapKeys = ( | |
obj: Record<string, unknown>, | |
fn: (key: string) => string | |
): Record<string, unknown> => | |
Object.entries(obj).reduce((acc: Record<string, unknown>, [key, value]) => { | |
acc[fn(key)] = value; | |
return acc; | |
}, {}); | |
export const mapValues = ( | |
obj: Record<string, unknown>, | |
fn: (p: unknown) => unknown | |
): Record<string, unknown> => | |
Object.entries(obj).reduce((acc: Record<string, unknown>, [key, value]) => { | |
acc[key] = fn(value); | |
return acc; | |
}, {}); | |
export const convertCase = ( | |
fn: (s: string) => string, | |
obj: unknown | |
): unknown => { | |
if (obj === undefined) { | |
return; | |
} | |
if (Array.isArray(obj)) { | |
return obj.map((value: unknown) => convertCase(fn, value)); | |
} | |
if (isObject(obj)) { | |
return Object.entries(obj).reduce( | |
(acc: Record<string, unknown>, [key, value]) => { | |
if (Array.isArray(value)) { | |
acc[fn(key)] = value.map((item) => | |
isObject(item) ? convertCase(fn, item) : item | |
); | |
} else if (isObject(value)) { | |
acc[fn(key)] = convertCase(fn, value); | |
} else { | |
acc[fn(key)] = value; | |
} | |
return acc; | |
}, | |
{} | |
); | |
} | |
return obj; | |
}; | |
export const toSnakeCase = <T = unknown>(obj: unknown) => | |
obj ? (convertCase(snakeCase, obj) as T) : undefined; | |
export const toCamelCase = <T = unknown>(obj: unknown) => | |
obj ? (convertCase(camelCase, obj) as T) : undefined; | |
export const withValues = ( | |
obj: Record<string, unknown>, | |
keepFalsy?: boolean, | |
keepEmptyArray?: boolean | |
): Record<string, unknown> => | |
Object.entries(obj).reduce((acc: Record<string, unknown>, [key, value]) => { | |
if ( | |
((keepFalsy && !isNil(value)) || value) && | |
(!Array.isArray(value) || keepEmptyArray || value.length > 0) | |
) { | |
acc[key] = value; | |
} | |
return acc; | |
}, {}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment