Skip to content

Instantly share code, notes, and snippets.

@stevensacks
Created August 22, 2024 10:14
Show Gist options
  • Save stevensacks/43ff750e8aa55ef81fb7bd0602884a52 to your computer and use it in GitHub Desktop.
Save stevensacks/43ff750e8aa55ef81fb7bd0602884a52 to your computer and use it in GitHub Desktop.
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'),
});
});
});
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});
});
});
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