Created
August 22, 2024 10:14
-
-
Save stevensacks/43ff750e8aa55ef81fb7bd0602884a52 to your computer and use it in GitHub Desktop.
Revisions
-
stevensacks created this gist
Aug 22, 2024 .There are no files selected for viewing
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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,20 @@ 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,108 @@ 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 charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,121 @@ 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; }, {});