pl-fe: replace UUID package with crypto.randomUUID

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-10-02 17:57:14 +02:00
parent b07205f2e0
commit 97c638b871
11 changed files with 21 additions and 38 deletions

View file

@ -143,7 +143,6 @@
"type-fest": "^4.0.0",
"typescript": "^5.6.2",
"util": "^0.12.5",
"uuid": "^10.0.0",
"vite": "^5.4.8",
"vite-plugin-compile-time": "^0.2.1",
"vite-plugin-html": "^3.2.2",
@ -176,7 +175,6 @@
"@types/react-swipeable-views": "^0.13.5",
"@types/redux-mock-store": "^1.0.6",
"@types/semver": "^7.5.8",
"@types/uuid": "^10.0.0",
"@typescript-eslint/eslint-plugin": "^8.6.0",
"@typescript-eslint/parser": "^8.6.0",
"eslint": "^8.57.1",

View file

@ -1,4 +1,3 @@
import { v4 as uuid } from 'uuid';
import { makeGetAccount } from 'pl-fe/selectors';
import KVStore from 'pl-fe/storage/kv-store';
@ -34,7 +33,7 @@ const saveDraftStatus = (composeId: string) =>
const draft = {
...compose.toJS(),
draft_id: compose.draft_id || uuid(),
draft_id: compose.draft_id || crypto.randomUUID(),
};
dispatch({

View file

@ -1,7 +1,6 @@
import clsx from 'clsx';
import React from 'react';
import { Link } from 'react-router-dom';
import { v4 as uuidv4 } from 'uuid';
import { SelectDropdown } from '../features/forms';
@ -29,7 +28,7 @@ interface IListItem {
}
const ListItem: React.FC<IListItem> = ({ className, label, hint, children, to, href, onClick, onSelect, isSelected, size = 'md' }) => {
const id = uuidv4();
const id = crypto.randomUUID();
const domId = `list-group-${id}`;
const onKeyDown = (e: React.KeyboardEvent) => {

View file

@ -1,5 +1,4 @@
import React, { useMemo } from 'react';
import { v4 as uuidv4 } from 'uuid';
import Checkbox from '../checkbox/checkbox';
import HStack from '../hstack/hstack';
@ -21,7 +20,7 @@ interface IFormGroup {
/** Input container with label. Renders the child. */
const FormGroup: React.FC<IFormGroup> = (props) => {
const { children, errors = [], labelText, labelTitle, hintText } = props;
const formFieldId: string = useMemo(() => `field-${uuidv4()}`, []);
const formFieldId: string = useMemo(() => `field-${crypto.randomUUID()}`, []);
const inputChildren = React.Children.toArray(children);
const hasError = errors?.length > 0;

View file

@ -1,5 +1,4 @@
import React, { useMemo } from 'react';
import { v4 as uuidv4 } from 'uuid';
import HStack from '../hstack/hstack';
@ -15,7 +14,7 @@ interface IRadioButton {
* A group for radio input with label.
*/
const RadioButton: React.FC<IRadioButton> = ({ name, value, checked, onChange, label }) => {
const formFieldId: string = useMemo(() => `radio-${uuidv4()}`, []);
const formFieldId: string = useMemo(() => `radio-${crypto.randomUUID()}`, []);
return (
<HStack alignItems='center' space={3}>

View file

@ -3,7 +3,6 @@ import debounce from 'lodash/debounce';
import React, { useState, useRef, useCallback } from 'react';
import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
import { Link, useHistory } from 'react-router-dom';
import { v4 as uuidv4 } from 'uuid';
import { accountLookup } from 'pl-fe/actions/accounts';
import { register, verifyCredentials } from 'pl-fe/actions/auth';
@ -63,7 +62,7 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
agreement: false,
locale: '',
});
const [captchaIdempotencyKey, setCaptchaIdempotencyKey] = useState(uuidv4());
const [captchaIdempotencyKey, setCaptchaIdempotencyKey] = useState(crypto.randomUUID());
const [usernameUnavailable, setUsernameUnavailable] = useState(false);
const [passwordConfirmation, setPasswordConfirmation] = useState('');
const [passwordMismatch, setPasswordMismatch] = useState(false);
@ -227,7 +226,7 @@ const RegistrationForm: React.FC<IRegistrationForm> = ({ inviteToken }) => {
};
const refreshCaptcha = () => {
setCaptchaIdempotencyKey(uuidv4());
setCaptchaIdempotencyKey(crypto.randomUUID());
setParams(params => ({ ...params, captcha_solution: '' }));
};

View file

@ -2,7 +2,6 @@ import clsx from 'clsx';
import MultiselectReactDropdown from 'multiselect-react-dropdown';
import React, { useMemo, useState } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { v4 as uuidv4 } from 'uuid';
import { Icon, Select } from '../../components/ui';
@ -44,7 +43,7 @@ interface ILabelInputContainer {
}
const LabelInputContainer: React.FC<ILabelInputContainer> = ({ label, hint, children }) => {
const [id] = useState(uuidv4());
const [id] = useState(crypto.randomUUID());
const childrenWithProps = React.Children.map(children, child => (
// @ts-ignore: not sure how to get the right type here
React.cloneElement(child, { id, key: id })

View file

@ -1,6 +1,5 @@
import React, { useRef, useState } from 'react';
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
import { v4 as uuidv4 } from 'uuid';
import { updatePlFeConfig } from 'pl-fe/actions/admin';
import { getHost } from 'pl-fe/actions/instance';
@ -51,7 +50,7 @@ const ThemeEditor: React.FC<IThemeEditor> = () => {
const [colors, setColors] = useState(plFe.colors.toJS() as any);
const [submitting, setSubmitting] = useState(false);
const [resetKey, setResetKey] = useState(uuidv4());
const [resetKey, setResetKey] = useState(crypto.randomUUID());
const fileInput = useRef<HTMLInputElement>(null);
@ -73,7 +72,7 @@ const ThemeEditor: React.FC<IThemeEditor> = () => {
};
const setTheme = (theme: any) => {
setResetKey(uuidv4());
setResetKey(crypto.randomUUID());
setTimeout(() => setColors(theme));
};

View file

@ -17,17 +17,18 @@ import {
type Relationship,
type Status,
} from 'pl-api';
import { v4 as uuidv4 } from 'uuid';
import type { PartialDeep } from 'type-fest';
const uuid = crypto.randomUUID;
// TODO: there's probably a better way to create these factory functions.
// This looks promising but didn't work on my first attempt: https://github.com/anatine/zod-plugins/tree/main/packages/zod-mock
const buildAccount = (props: PartialDeep<Account> = {}): Account =>
accountSchema.parse(Object.assign({
id: uuidv4(),
url: `https://soapbox.test/users/${uuidv4()}`,
id: uuid(),
url: `https://soapbox.test/users/${uuid()}`,
}, props));
const buildCard = (props: PartialDeep<PreviewCard> = {}): PreviewCard =>
@ -37,22 +38,22 @@ const buildCard = (props: PartialDeep<PreviewCard> = {}): PreviewCard =>
const buildGroup = (props: PartialDeep<Group> = {}): Group =>
groupSchema.parse(Object.assign({
id: uuidv4(),
id: uuid(),
owner: {
id: uuidv4(),
id: uuid(),
},
}, props));
const buildGroupRelationship = (props: PartialDeep<GroupRelationship> = {}): GroupRelationship =>
groupRelationshipSchema.parse(Object.assign({
id: uuidv4(),
id: uuid(),
}, props));
const buildGroupMember = (
props: PartialDeep<GroupMember> = {},
accountProps: PartialDeep<Account> = {},
): GroupMember => groupMemberSchema.parse(Object.assign({
id: uuidv4(),
id: uuid(),
account: buildAccount(accountProps),
role: GroupRoles.USER,
}, props));
@ -61,12 +62,12 @@ const buildInstance = (props: PartialDeep<Instance> = {}) => instanceSchema.pars
const buildRelationship = (props: PartialDeep<Relationship> = {}): Relationship =>
relationshipSchema.parse(Object.assign({
id: uuidv4(),
id: uuid(),
}, props));
const buildStatus = (props: PartialDeep<Status> = {}) =>
statusSchema.parse(Object.assign({
id: uuidv4(),
id: uuid(),
account: buildAccount(),
}, props));

View file

@ -1,6 +1,5 @@
import { Map as ImmutableMap, List as ImmutableList, OrderedSet as ImmutableOrderedSet, Record as ImmutableRecord, fromJS } from 'immutable';
import { PLEROMA, type CredentialAccount, type MediaAttachment, type Tag } from 'pl-api';
import { v4 as uuid } from 'uuid';
import { isNativeEmoji } from 'pl-fe/features/emoji';
import { tagHistory } from 'pl-fe/settings';
@ -72,6 +71,8 @@ import type { Language } from 'pl-fe/features/preferences';
import type { Account, Status } from 'pl-fe/normalizers';
import type { APIEntity } from 'pl-fe/types/entities';
const uuid = crypto.randomUUID;
const getResetFileKey = () => Math.floor((Math.random() * 0x10000));
const PollRecord = ImmutableRecord({

View file

@ -2885,11 +2885,6 @@
resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
"@types/uuid@^10.0.0":
version "10.0.0"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-10.0.0.tgz#e9c07fe50da0f53dc24970cca94d619ff03f6f6d"
integrity sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==
"@typescript-eslint/eslint-plugin@^5.59.5":
version "5.62.0"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db"
@ -11434,11 +11429,6 @@ uuid@3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131"
integrity sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==
uuid@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-10.0.0.tgz#5a95aa454e6e002725c79055fd42aaba30ca6294"
integrity sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==
uuidv4@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/uuidv4/-/uuidv4-2.0.0.tgz#3ec764288f9e9c4e40f8027ad309c2c528be2976"