Skip to content

Commit

Permalink
refactor: remove lodash dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
oscar-guerin committed Jul 9, 2024
1 parent 122d422 commit 36b6c75
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 54 deletions.
3 changes: 0 additions & 3 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,4 @@ module.exports = {
preset: 'ts-jest',
testRegex: '(/__tests__/.*|(\\.|/)(test|spec|spec-e2e))\\.ts?$',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
'^lodash-es/(.*)$': '<rootDir>/node_modules/lodash/$1',
}
};
33 changes: 6 additions & 27 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 5 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"description": "Typescript serializer library",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"engines": {
"node": ">=18.16.1"
},
"files": [
"/dist"
],
Expand All @@ -18,16 +21,12 @@
"test": "jest --coverage",
"publish:lib": "npm run build && npm publish --access=public"
},
"author": "Thomas Nisole",
"author": "Thomas Nisole, Oscar Guérin",
"license": "MIT",
"peerDependencies": {
"typescript": ">=3.4.3"
"typescript": ">=5.4.5"
},
"dependencies": {
"lodash.clonedeep": "^4.5.0",
"lodash.get": "^4.4.2",
"lodash.intersection": "^4.4.0",
"lodash.set": "^4.3.2",
"reflect-metadata": "^0.2.2"
},
"devDependencies": {
Expand Down
3 changes: 1 addition & 2 deletions src/e2e/serializer.spec-e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {Driver} from './driver.model';
import {Address} from './address.model';
import {Car} from './car.model';
import {Truck} from './truck.model';
import cloneDeep from 'lodash.clonedeep';

describe('Serializer E2E', () => {
let vehicleData: any;
Expand Down Expand Up @@ -145,7 +144,7 @@ describe('Serializer E2E', () => {
let expectedResults: any;

function cleanExpectedResults(): void {
expectedResults = cloneDeep(driversData);
expectedResults = structuredClone(driversData);
delete expectedResults[0].type;
delete expectedResults[1].type;

Expand Down
34 changes: 34 additions & 0 deletions src/functions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export const get: (obj: unknown, path: (string | string[]), defValue?: unknown) => unknown = (obj: unknown, path: string | string[], defValue: unknown) => {
// If path is not defined or it has false value
if (!path) {
return undefined;
}
// Check if path is string or array. Regex : ensure that we do not have '.' and brackets.
// Regex explained: https://regexr.com/58j0k
const pathArray: string[] = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);
// Find value
const result: unknown = pathArray.reduce(
(prevObj: unknown, key: string) => prevObj && prevObj[key],
obj
);
// If found value is undefined return default value; otherwise return the value
return result === undefined ? defValue : result;
};

export const set: (obj: unknown, path: (string | string[]), value: unknown) => void = (obj: unknown, path: string | string[], value: unknown) => {
// Regex explained: https://regexr.com/58j0k
const pathArray: (string | string[]) | RegExpMatchArray = Array.isArray(path) ? path : path.match(/([^[.\]])+/g);

pathArray.reduce((acc: unknown, key: string, i: number) => {
if (acc[key] === undefined) {
acc[key] = {};
}
if (i === pathArray.length - 1) {
acc[key] = value;
}
return acc[key];
}, obj);
};

export const intersection: (arr: unknown[], ...args: unknown[][]) => unknown[] = (arr: unknown[], ...args: unknown[][]) =>
arr.filter((item: unknown) => args.every((arr: unknown[]) => arr.includes(item)));
3 changes: 1 addition & 2 deletions src/normalizer/denormalizer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@ import {JsonProperty} from '../decorator/json-property.decorator';
import {DateConverter} from '../converter/date.converter';
import {JsonTypeSupports} from '../decorator/json-type-supports.decorator';
import {SerializerOptions} from '../serializer-options';
import cloneDeep from 'lodash.clonedeep';

class EmptyJsonProperty {
public name: string = 'myEmptyJsonPropertyObject';
}

describe('Denormalizer', () => {
const configuration: NormalizerConfiguration = cloneDeep(DEFAULT_NORMALIZER_CONFIGURATION);
const configuration: NormalizerConfiguration = structuredClone(DEFAULT_NORMALIZER_CONFIGURATION);
const defaultOptions: SerializerOptions = {};

let denormalizerEmptyJsonProperty: Denormalizer;
Expand Down
7 changes: 4 additions & 3 deletions src/normalizer/denormalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ import {SerializeType} from '../common';
import {IDeserializer} from '../ideserializer';
import {JSON_TYPE_SUPPORTS_METADATA_KEY} from '../decorator/json-type-supports.decorator';
import {normalizeSerializerOptions, SerializerOptions} from '../serializer-options';
import get from 'lodash.get';
import intersection from 'lodash.intersection';
import {get, intersection} from '../functions';

export class Denormalizer implements IDeserializer {

Expand Down Expand Up @@ -76,7 +75,9 @@ export class Denormalizer implements IDeserializer {

jsonProperties
.filter((cc: JsonPropertyContextConfiguration<T, any>) => !cc.writeOnly)
.filter((cc: JsonPropertyContextConfiguration<T, any>) => !options?.groups || intersection(cc.groups, options.groups).length > 0)
.filter((cc: JsonPropertyContextConfiguration<T, any>) =>
!options?.groups || intersection(Array.isArray(cc.groups) ? cc.groups : [cc.groups], Array.isArray(options.groups) ? options.groups : [options.groups]).length > 0
)
.filter((cc: JsonPropertyContextConfiguration<T, any>) => get(data, cc.field) !== undefined || !!Denormalizer.haveToDenormalize(this.configuration.denormalizeUndefined, cc.denormalizeUndefined))
.filter((cc: JsonPropertyContextConfiguration<T, any>) => get(data, cc.field) !== null || !!Denormalizer.haveToDenormalize(this.configuration.denormalizeNull, cc.denormalizeNull))
.forEach((cc: JsonPropertyContextConfiguration<T, any>) => {
Expand Down
3 changes: 1 addition & 2 deletions src/normalizer/normalizer.configuration.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import {DEFAULT_NORMALIZER_CONFIGURATION, NormalizerConfiguration} from './normalizer.configuration';
import cloneDeep from 'lodash.clonedeep';

describe('NormalizerConfiguration', () => {

it('should has default values', () => {
const configuration: NormalizerConfiguration = cloneDeep(DEFAULT_NORMALIZER_CONFIGURATION);
const configuration: NormalizerConfiguration = structuredClone(DEFAULT_NORMALIZER_CONFIGURATION);

expect(configuration.denormalizeNull).toBeFalsy();
expect(configuration.denormalizeUndefined).toBeFalsy();
Expand Down
3 changes: 1 addition & 2 deletions src/normalizer/normalizer.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import {DEFAULT_NORMALIZER_CONFIGURATION, NormalizerConfiguration} from './norma
import {JsonProperty} from '../decorator/json-property.decorator';
import {DateConverter} from '../converter/date.converter';
import {SerializerOptions} from '../serializer-options';
import cloneDeep from 'lodash.clonedeep';

class EmptyJsonProperty {
public name: string = 'myEmptyJsonPropertyObject';
Expand All @@ -19,7 +18,7 @@ describe('Normalizer', () => {
let normalizer: Normalizer;

beforeEach(() => {
configuration = cloneDeep(DEFAULT_NORMALIZER_CONFIGURATION);
configuration = structuredClone(DEFAULT_NORMALIZER_CONFIGURATION);
normalizerEmptyJsonProperty = new Normalizer(configuration);
normalizer = new Normalizer(configuration);
});
Expand Down
7 changes: 4 additions & 3 deletions src/normalizer/normalizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ import {JSON_PROPERTY_METADATA_KEY, JsonPropertyContextConfiguration} from '../d
import {DEFAULT_NORMALIZER_CONFIGURATION, NormalizerConfiguration} from './normalizer.configuration';
import {ISerializer} from '../iserializer';
import {normalizeSerializerOptions, SerializerOptions} from '../serializer-options';
import set from 'lodash.set';
import intersection from 'lodash.intersection';
import {intersection, set} from '../functions';

export class Normalizer implements ISerializer {

Expand Down Expand Up @@ -40,7 +39,9 @@ export class Normalizer implements ISerializer {

jsonProperties
.filter((jsonProperty: JsonPropertyContextConfiguration<T, any>) => !jsonProperty.readOnly)
.filter((jsonProperty: JsonPropertyContextConfiguration<T, any>) => !options?.groups || intersection(jsonProperty.groups, options.groups).length > 0)
.filter((jsonProperty: JsonPropertyContextConfiguration<T, any>) =>
!options?.groups || intersection(Array.isArray(jsonProperty.groups) ? jsonProperty.groups : [jsonProperty.groups], Array.isArray(options.groups) ? options.groups : [options.groups]).length > 0
)
.filter((jsonProperty: JsonPropertyContextConfiguration<T, any>) => object[jsonProperty.propertyKey] !== undefined || !!Normalizer.haveToNormalize(this.configuration.normalizeUndefined, jsonProperty.normalizeUndefined))
.filter((jsonProperty: JsonPropertyContextConfiguration<T, any>) => object[jsonProperty.propertyKey] !== null || !!Normalizer.haveToNormalize(this.configuration.normalizeNull, jsonProperty.normalizeNull))
.forEach((jsonProperty: JsonPropertyContextConfiguration<T, any>) => {
Expand Down
6 changes: 2 additions & 4 deletions src/serializer-options.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import cloneDeep from 'lodash.clonedeep';

export interface SerializerOptions {

groups?: string|string[];
groups?: string | string[];
}

export function normalizeSerializerOptions(options: SerializerOptions): SerializerOptions {
const normalizedOptions: SerializerOptions = cloneDeep(options);
const normalizedOptions: SerializerOptions = structuredClone(options);

if (normalizedOptions.groups && !Array.isArray(normalizedOptions.groups)) {
normalizedOptions.groups = [normalizedOptions.groups];
Expand Down

0 comments on commit 36b6c75

Please sign in to comment.