Skip to content

Commit

Permalink
feat: added function builders for object filters
Browse files Browse the repository at this point in the history
- added filterKeyValueTuplesFunction
- added forEachKeyValueOnPOJOTupleFunction
- added functions for all previous POJO object filter functions
  • Loading branch information
dereekb committed Jun 7, 2022
1 parent 96ed5fb commit c01db20
Show file tree
Hide file tree
Showing 9 changed files with 471 additions and 285 deletions.
26 changes: 14 additions & 12 deletions packages/util/src/lib/auth/auth.role.claims.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { AuthRole, AuthRoleSet } from './auth.role';
import { filterFromPOJO, forEachKeyValue, KeyValueTypleValueFilter, objectHasKey } from '../object/object';
import { objectHasKey } from '../object/object';
import { filterFromPOJO, forEachKeyValueOnPOJOFunction } from '../object/object.filter.pojo';
import { forEachKeyValue, KeyValueTypleValueFilter } from '../object/object.filter.tuple';
import { objectToTuples } from '../object/object.map';
import { ArrayOrValue, asArray } from '../array/array';
import { addToSet, setContainsAllValues } from '../set';
Expand Down Expand Up @@ -197,20 +199,20 @@ export function authRoleClaimsService<T extends AuthClaimsObject>(config: AuthRo
return claims;
};

const toRoles: AuthRoleRolesToClaimsFunction<T> = (claims: AuthClaimsUpdate<T>) => {
const roles = new Set<string>();

forEachKeyValue(claims, {
forEach: ([claimsKey, value]) => {
const entry = authRoleMap.get(claimsKey as string);
const forEachKeyValueAddToSet = forEachKeyValueOnPOJOFunction<AuthClaimsUpdate<T>, Set<string>>({
forEach: ([claimsKey, value], i, claims, roles: Set<string>) => {
const entry = authRoleMap.get(claimsKey as string);

if (entry != null) {
const decodedRoles = entry.decodeRolesFromValue(value);
addToSet(roles, decodedRoles);
}
if (entry != null) {
const decodedRoles = entry.decodeRolesFromValue(value);
addToSet(roles, decodedRoles);
}
});
}
});

const toRoles: AuthRoleRolesToClaimsFunction<T> = (claims: AuthClaimsUpdate<T>) => {
const roles = new Set<string>();
forEachKeyValueAddToSet(claims, roles);
return roles;
};

Expand Down
3 changes: 2 additions & 1 deletion packages/util/src/lib/model/model.conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
// any is used with intent here, as there isn't enough typing information available when going from a parent of fields to the types of each child.

import { asGetter, Getter, GetterOrValue } from '../getter/getter';
import { filterKeyValueTuples, findPOJOKeys, KeyValueTypleValueFilter } from '../object/object';
import { findPOJOKeys } from '../object/object.filter.pojo';
import { filterKeyValueTuples, KeyValueTypleValueFilter } from '../object/object.filter.tuple';
import { isMaybeSo, Maybe, MaybeSo } from '../value/maybe';
import { ApplyMapFunctionWithOptions, MapFunction } from '../value/map';
import { MergeReplace, ReplaceType } from '../type';
Expand Down
2 changes: 2 additions & 0 deletions packages/util/src/lib/object/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export * from './object.array';
export * from './object.equal';
export * from './object.map';
export * from './object';
export * from './object.filter.tuple';
export * from './object.filter.pojo';
Original file line number Diff line number Diff line change
@@ -1,4 +1,51 @@
import { allMaybeSoKeys, allKeyValueTuples, allNonUndefinedKeys, filterKeyValueTupleFunction, KeyValueTypleValueFilter, filterFromPOJO, objectHasKey } from './object';
import { filterUndefinedValues } from '@dereekb/util';
import { objectHasKey } from './object';
import { filterFromPOJO, allNonUndefinedKeys, allMaybeSoKeys, countPOJOKeys, findPOJOKeys } from './object.filter.pojo';
import { KeyValueTypleValueFilter } from './object.filter.tuple';

describe('findPOJOKeys()', () => {
describe('with config', () => {
describe('valueFilter = null', () => {
it('should return keys of all non-null/undefined values', () => {
const result = findPOJOKeys({ x: undefined, y: 'test', z: null }, KeyValueTypleValueFilter.NULL);
expect(result.length).toBe(1);
expect(result[0]).toBe('y');
});
});
describe('valueFilter = undefined', () => {
it('should return keys of all non-null/undefined values', () => {
const result = findPOJOKeys({ x: undefined, y: 'test', z: null }, KeyValueTypleValueFilter.UNDEFINED);
expect(result.length).toBe(2);
expect(result[0]).toBe('y');
expect(result[1]).toBe('z');
});
});
});
});

describe('countPOJOKeys()', () => {
it('should count all undefined keys be default.', () => {
const result = countPOJOKeys({ x: undefined, y: 'test', z: null });
expect(result).toBe(2);
});
});

describe('filterUndefinedValues', () => {
it('should return a copy of the input object with all undefined values removed.', () => {
const result = filterUndefinedValues({ x: undefined, y: 'test', z: null });
expect(result).toBeDefined();
expect(objectHasKey(result, 'y'));
expect(objectHasKey(result, 'z'));
});

describe('filterNull=true', () => {
it('should return a copy of the input object with all null and undefined values removed.', () => {
const result = filterUndefinedValues({ x: undefined, y: 'test', z: null }, true);
expect(result).toBeDefined();
expect(objectHasKey(result, 'y'));
});
});
});

describe('filterFromPOJO()', () => {
it('should remove undefined values from the object by default', () => {
Expand Down Expand Up @@ -101,26 +148,3 @@ describe('allMaybeSoKeys()', () => {
expect(result.findIndex((x) => x === 'd')).not.toBe(-1);
});
});

describe('filterKeyValueTuplesFn()', () => {
describe('config', () => {
describe('invertFilter', () => {
it('should not invert the filter if invertFilter is not defined.', () => {
const object = {
a: 0,
b: 1,
c: undefined
};

const tuples = allKeyValueTuples(object);
const filter = filterKeyValueTupleFunction<typeof object>({
valueFilter: KeyValueTypleValueFilter.NONE
});

const result = tuples.filter(filter);

expect(result.length).toBe(3);
});
});
});
});
Loading

0 comments on commit c01db20

Please sign in to comment.