Skip to content

Commit

Permalink
(release-2.17.1) remove individual lodash deps, add whole lodash, rep…
Browse files Browse the repository at this point in the history
…lace & remove old code
  • Loading branch information
mrTuomoK committed Feb 7, 2024
1 parent 68798c0 commit ecddf6c
Show file tree
Hide file tree
Showing 38 changed files with 756 additions and 277 deletions.
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
# Changelog

All notable changes to this project will be documented in this file.
## [2.17.1] - Feb, 7, 2024

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
### React

#### Fixed

## [Unreleased]
- Removed old & deprecated individual `lodash` dependencies and replaced with the full package and importing the needed functions only.

## [2.17.0] - Aug, 18, 2023

Expand Down
4 changes: 2 additions & 2 deletions packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hds-core",
"version": "2.17.0",
"version": "2.17.1",
"description": "Core styles for the Helsinki Design System",
"homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme",
"license": "MIT",
Expand Down Expand Up @@ -30,7 +30,7 @@
"@storybook/manager-webpack5": "^6.5.16",
"copyfiles": "2.2.0",
"cssnano": "4.1.10",
"hds-design-tokens": "2.17.0",
"hds-design-tokens": "2.17.1",
"normalize.css": "8.0.1",
"postcss": "8.2.15",
"postcss-cli": "8.3.1",
Expand Down
2 changes: 1 addition & 1 deletion packages/design-tokens/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hds-design-tokens",
"version": "2.17.0",
"version": "2.17.1",
"description": "Design tokens for the Helsinki Design System",
"homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme",
"license": "MIT",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 3 additions & 12 deletions packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "hds-react",
"version": "2.17.0",
"version": "2.17.1",
"description": "React components for the Helsinki Design System",
"homepage": "https://github.com/City-of-Helsinki/helsinki-design-system#readme",
"license": "MIT",
Expand Down Expand Up @@ -121,18 +121,9 @@
"crc-32": "1.2.0",
"date-fns": "2.16.1",
"downshift": "6.0.6",
"hds-core": "2.17.0",
"hds-core": "2.17.1",
"kashe": "1.0.4",
"lodash.get": "^4.4.2",
"lodash.isequal": "4.5.0",
"lodash.isfunction": "3.0.9",
"lodash.isobject": "3.0.2",
"lodash.isundefined": "3.0.1",
"lodash.pick": "^4.4.0",
"lodash.pickby": "^4.6.0",
"lodash.throttle": "^4.1.1",
"lodash.uniqueid": "4.0.1",
"lodash.xor": "^4.5.0",
"lodash": "^4.17.21",
"memoize-one": "5.2.1",
"react-hook-form": "^7.43.3",
"react-merge-refs": "1.1.0",
Expand Down
4 changes: 1 addition & 3 deletions packages/react/rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,7 @@ const external = [
'postcss',
'react',
'react-dom',
'lodash.uniqueid',
'lodash.isequal',
'lodash.isfunction',
'lodash',
'react-spring',
'react-use-measure',
'react-merge-refs',
Expand Down
3 changes: 1 addition & 2 deletions packages/react/src/components/accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useEffect, useRef, useState } from 'react';
import uniqueId from 'lodash.uniqueid';
import pickBy from 'lodash.pickby';
import { uniqueId, pickBy } from 'lodash';

// import base styles
import '../../styles/base.css';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _get from 'lodash.get';
import { get } from 'lodash';

import { CookieContentSource, ContentSourceCookieGroup, createContent, setPropsToObject } from './content.builder';
import { CookieContentSource, ContentSourceCookieGroup, createContent } from './content.builder';
import { getCookieContent } from './getContent';
import { CookieData, CookieGroup, Content, Category } from './contexts/ContentContext';

Expand Down Expand Up @@ -155,7 +155,7 @@ describe(`content.builder.ts`, () => {
expect(plainContent.requiredCookies).toBeUndefined();
expect(plainContent.optionalCookies).toBeUndefined();

expect(_get(plainContent, mainTitlePath).indexOf(siteName)).toBe(0);
expect(get(plainContent, mainTitlePath).indexOf(siteName)).toBe(0);
});
});
describe('contentSource.texts', () => {
Expand All @@ -166,14 +166,14 @@ describe(`content.builder.ts`, () => {
...commonContentTestProps,
texts: { sections: { main: { title: newMainTitle } } },
});
expect(_get(contentWithNewMainTitle, mainTitlePath)).toBe(newMainTitle);
expect(_get(contentWithNewMainTitle, mainTextPath)).toBe(_get(defaults, mainTextPath));
expect(get(contentWithNewMainTitle, mainTitlePath)).toBe(newMainTitle);
expect(get(contentWithNewMainTitle, mainTextPath)).toBe(get(defaults, mainTextPath));
const contentWithNewDetailsText = createContent({
...commonContentTestProps,
texts: { sections: { details: { text: newDetailsText } } },
});
expect(_get(contentWithNewDetailsText, detailsTextPath)).toBe(newDetailsText);
expect(_get(contentWithNewDetailsText, detailsTitlePath)).toBe(_get(defaults, detailsTitlePath));
expect(get(contentWithNewDetailsText, detailsTextPath)).toBe(newDetailsText);
expect(get(contentWithNewDetailsText, detailsTitlePath)).toBe(get(defaults, detailsTitlePath));
});
});
describe('contentSource.language', () => {
Expand Down Expand Up @@ -893,89 +893,4 @@ describe(`content.builder.ts`, () => {
);
});
});
describe('setPropsToObject merges given value/object to the target object', () => {
type AnyObject = { [key: string]: unknown };
type TargetObject = { [key: string]: TargetObject | string };
it('Path indicates where to merge. Path is a given as a comma delimetered path.', () => {
const target = setPropsToObject({}, 'a', 'valueOfA');
expect(target).toEqual({ a: 'valueOfA' });

const target2 = setPropsToObject({}, 'a.a', 'valueOfAA');
expect(target2).toEqual({ a: { a: 'valueOfAA' } });

const target3 = setPropsToObject({}, 'a.b.c.d.e.f', 'valueOfABCDEF');
expect(target3).toEqual({
a: {
b: {
c: {
d: {
e: {
f: 'valueOfABCDEF',
},
},
},
},
},
});
});
it('existing props are not overridden or copied', () => {
const target: TargetObject & { obj1: { obj2?: AnyObject; newObj2?: { newObj3?: AnyObject } } } = {
prop1: 'valueOfProp1',
obj1: { obj2: { value: 'valueOfObj2' } },
};

// save refs to objects to check refs do not change
const { obj1: obj1Ref } = target;
const { obj2: obj2Ref } = target.obj1 as TargetObject;

// objects added later
const obj3 = { value: 'valueOfObj3' };
const newObj4 = { newObj5: 'valueOfNewObj5' };

setPropsToObject(target, 'prop2', 'valueOfProp2');
expect(target.prop2).toBe('valueOfProp2');

setPropsToObject(target.obj1.obj2 as AnyObject, 'obj3', obj3);
expect((target.obj1.obj2 as AnyObject).obj3).toBe(obj3);

setPropsToObject(target, 'obj1.newObj2.newObj3', newObj4);
expect((target.obj1.newObj2 as AnyObject).newObj3).toBe(newObj4);

// check initial values/refs have not changed
expect(target.prop1).toBe('valueOfProp1');
expect(target.obj1).toBe(obj1Ref);
expect(target.obj1.obj2).toBe(obj2Ref);
expect((target.obj1.obj2 as AnyObject).value).toBe('valueOfObj2');
});
it('object to merge is not copied, but assigned', () => {
const target: AnyObject = {};
const mergedObject1 = { obj: 'valueOfObj', object2: {} };
const mergedObject2 = { obj2: 'valueOfObj2' };
const finalObject1 = { obj3: 'valueOfObj3' };

setPropsToObject(target, 'object1', mergedObject1);
expect(target.object1).toEqual(mergedObject1);

setPropsToObject(target, 'object1.object2', mergedObject2);
expect((target.object1 as AnyObject).object2).toEqual(mergedObject2);

setPropsToObject(target, 'object1', finalObject1);
expect(target.object1).toEqual(finalObject1);
expect((target.object1 as AnyObject).object2).toBeUndefined();
});
it('merged value can be anything', () => {
const target: AnyObject = {};
const values = [null, undefined, 1, 'abc', () => undefined, new Map(), Object.create({})];
values.forEach((value, index) => {
const key = `value-${index}`;
setPropsToObject(target, key, value);
expect(target[key]).toBe(value);
});
});
it('Using "_" is prohibited to avoid prototype pollution', () => {
const target: AnyObject = {};
expect(() => setPropsToObject(target, '__proto__.toString', () => 'hello')).toThrow();
expect(target.toString()).not.toBe('hello');
});
});
});
35 changes: 5 additions & 30 deletions packages/react/src/components/cookieConsent/content.builder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import _get from 'lodash.get';
import { get, set } from 'lodash';

import type {
CookieData,
Expand Down Expand Up @@ -143,40 +143,15 @@ function getCommonCookie(language: string, id: string): CookieData {
return cookie;
}

// lodash.set has a high vulnerability without a fix
// replaced with this custom merge function
export function setPropsToObject(
targetObject: Record<string, unknown>,
path: string,
value: unknown,
): Record<string, unknown> {
if (path.includes('_')) {
throw new Error('String "_" is not allowed in the path to avoid prototype pollution');
}
const splitPath = path.split('.');
const lastPath = splitPath.pop();
const targetPointInObject = splitPath.reduce((currentObj, currentPath) => {
if (typeof currentObj[currentPath] === 'undefined') {
// eslint-disable-next-line no-param-reassign
currentObj[currentPath] = Object.create(null);
}
return currentObj[currentPath];
}, targetObject);
if (lastPath) {
targetPointInObject[lastPath] = value;
}
return targetObject;
}

function mergeObjects(target: MergableContent, source: MergableContent, paths: string[]) {
paths.forEach((path) => {
const pickedFromSource = _get(source, path);
const pickedFromSource = get(source, path);
if (pickedFromSource) {
const pickedFromTarget = _get(target, path);
const pickedFromTarget = get(target, path);
if (typeof pickedFromSource === 'string') {
setPropsToObject(target, path, pickedFromSource || pickedFromTarget);
set(target, path, pickedFromSource || pickedFromTarget);
} else {
setPropsToObject(target, path, {
set(target, path, {
...pickedFromTarget,
...pickedFromSource,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import _pick from 'lodash.pick';
import _isObject from 'lodash.isobject';
import _isUndefined from 'lodash.isundefined';
import { pick, isObject, isUndefined } from 'lodash';

import { createCookieController } from './cookieController';

Expand Down Expand Up @@ -48,7 +46,7 @@ function mergeConsents(set1: ConsentObject, set2: ConsentObject, set3?: ConsentO
}

function createConsentsString(consents: ConsentObject): string {
if (!_isObject(consents)) {
if (!isObject(consents)) {
return '{}';
}
return JSON.stringify(consents);
Expand Down Expand Up @@ -107,10 +105,10 @@ export function createStorage(
};

const findConsentSource = (consentName: string, targetStorage: ConsentStorage): ConsentObject | undefined => {
if (!_isUndefined(targetStorage.required[consentName])) {
if (!isUndefined(targetStorage.required[consentName])) {
return targetStorage.required;
}
if (!_isUndefined(targetStorage.optional[consentName])) {
if (!isUndefined(targetStorage.optional[consentName])) {
return targetStorage.optional;
}
return undefined;
Expand Down Expand Up @@ -168,17 +166,17 @@ export default function createConsentController(props: ConsentControllerProps):

const required = mergeConsents(
convertStringArrayToKeyConsentObject(requiredConsents),
_pick(currentConsentsInCookie, requiredConsents),
pick(currentConsentsInCookie, requiredConsents),
);

const optional = mergeConsents(
convertStringArrayToKeyConsentObject(optionalConsents),
_pick(currentConsentsInCookie, optionalConsents),
pick(currentConsentsInCookie, optionalConsents),
);

const unknownConsentKeys = Object.keys(currentConsentsInCookie).filter((key) => !allConsents.includes(key));

const unknown = unknownConsentKeys.length ? _pick(currentConsentsInCookie, unknownConsentKeys) : undefined;
const unknown = unknownConsentKeys.length ? pick(currentConsentsInCookie, unknownConsentKeys) : undefined;

const storage = createStorage({ required, optional, unknown });

Expand Down Expand Up @@ -222,7 +220,7 @@ export default function createConsentController(props: ConsentControllerProps):
rejectAll,
getUnhandledConsents: () => {
const storedCookies = parseConsents(cookieController.get());
return allConsents.filter((key) => _isUndefined(storedCookies[key]));
return allConsents.filter((key) => isUndefined(storedCookies[key]));
},
save,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { action } from '@storybook/addon-actions';
import uniqueId from 'lodash.uniqueid';
import { uniqueId } from 'lodash';

import { Button } from '../../button';
import { Combobox } from './Combobox';
Expand Down
3 changes: 1 addition & 2 deletions packages/react/src/components/dropdown/combobox/Combobox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
/* eslint-disable react/destructuring-assignment */
import React, { useRef, useState, KeyboardEvent, FocusEvent, FocusEventHandler, useMemo, useCallback } from 'react';
import { useCombobox, useMultipleSelection } from 'downshift';
import isEqual from 'lodash.isequal';
import uniqueId from 'lodash.uniqueid';
import { uniqueId, isEqual } from 'lodash';
import { useVirtual } from 'react-virtual';

// import base styles
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/dropdown/dropdownUtils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import isEqual from 'lodash.isequal';
import { isEqual } from 'lodash';

export const DROPDOWN_MENU_ITEM_HEIGHT = 52;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { action } from '@storybook/addon-actions';
import uniqueId from 'lodash.uniqueid';
import { uniqueId } from 'lodash';

import { Button } from '../../button';
import { Select } from './Select';
Expand Down
3 changes: 1 addition & 2 deletions packages/react/src/components/dropdown/select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import {
UseMultipleSelectionStateChangeOptions,
UseMultipleSelectionState,
} from 'downshift';
import isEqual from 'lodash.isequal';
import uniqueId from 'lodash.uniqueid';
import { uniqueId, isEqual } from 'lodash';
import { useVirtual } from 'react-virtual';

// import base styles
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/fileInput/FileInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { ChangeEvent, useEffect, useRef, useState } from 'react';
import uniqueId from 'lodash.uniqueid';
import { uniqueId } from 'lodash';

// import base styles
import '../../styles/base.css';
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/koros/Koros.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react';
import uniqueId from 'lodash.uniqueid';
import { uniqueId } from 'lodash';

// import base styles
import '../../styles/base.css';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useEffect, useRef, useState, useCallback } from 'react';
import uniqueId from 'lodash.uniqueid';
import { uniqueId } from 'lodash';

import styles from './LoadingSpinner.module.scss';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { MouseEventHandler, useState } from 'react';
import uniqueId from 'lodash.uniqueid';
import { uniqueId } from 'lodash';

import { MenuButton, MenuButtonProps } from '../../../internal/menuButton/MenuButton';
import { NavigationItem } from '../navigationItem/NavigationItem';
Expand Down
Loading

0 comments on commit ecddf6c

Please sign in to comment.