From e552f6b86a320a1ff7f3d02c75a3593d4de4cec8 Mon Sep 17 00:00:00 2001 From: M-ZubairAhmed Date: Tue, 24 Oct 2023 14:41:29 +0530 Subject: [PATCH] [MM-54848] Remove deprecated LocalizedInput component (#25052) --- webapp/channels/package.json | 2 +- .../searchable_channel_list.test.tsx.snap | 12 ---- .../browse_channels.test.tsx.snap | 2 +- .../claim/components/email_to_ldap.tsx | 15 ++--- .../claim/components/email_to_oauth.tsx | 11 +--- .../claim/components/ldap_to_email.tsx | 30 ++++------ .../content_layouts/column.tsx | 6 +- .../localized_input.test.tsx.snap | 22 -------- .../localized_input/localized_input.test.tsx | 55 ------------------- .../localized_input/localized_input.tsx | 38 ------------- .../src/components/login/login_mfa.tsx | 11 ++-- .../searchable_channel_list.test.tsx | 7 ++- .../components/searchable_channel_list.tsx | 15 ++--- .../searchable_user_list.tsx | 14 ++--- .../team_general_tab.test.tsx | 6 +- webapp/channels/src/i18n/en.json | 4 +- webapp/package-lock.json | 14 ++--- 17 files changed, 60 insertions(+), 204 deletions(-) delete mode 100644 webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap delete mode 100644 webapp/channels/src/components/localized_input/localized_input.test.tsx delete mode 100644 webapp/channels/src/components/localized_input/localized_input.tsx diff --git a/webapp/channels/package.json b/webapp/channels/package.json index b15fb121f1..fc0a7ddef2 100644 --- a/webapp/channels/package.json +++ b/webapp/channels/package.json @@ -163,7 +163,7 @@ "jest-junit": "12.2.0", "jest-styled-components": "7.1.1", "jest-watch-typeahead": "0.6.4", - "mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10", + "mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44", "nock": "13.2.8", "prettier": "2.3.2", "react-router-enzyme-context": "1.2.0", diff --git a/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap b/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap index bc93201554..ac38d23951 100644 --- a/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap +++ b/webapp/channels/src/components/__snapshots__/searchable_channel_list.test.tsx.snap @@ -20,20 +20,8 @@ exports[`components/SearchableChannelList should match init snapshot 1`] = ` className="form-control filter-textbox" clearable={true} id="searchChannelsTextbox" - inputComponent={ - Object { - "$$typeof": Symbol(react.forward_ref), - "render": [Function], - } - } onClear={[Function]} onInput={[Function]} - placeholder={ - Object { - "defaultMessage": "Search channels", - "id": "filtered_channels_list.search", - } - } value="" /> diff --git a/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap b/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap index d19cca0fca..5c64f04fe7 100644 --- a/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap +++ b/webapp/channels/src/components/browse_channels/__snapshots__/browse_channels.test.tsx.snap @@ -43,7 +43,7 @@ exports[`components/BrowseChannels should match snapshot and state 1`] = ` onExited={[Function]} show={true} > - { const password = emailPasswordInput.current?.value; if (!password) { - setPasswordError(localizeMessage('claim.email_to_ldap.pwdError', 'Please enter your password.')); + setPasswordError(formatMessage({id: 'claim.email_to_ldap.pwdError', defaultMessage: 'Please enter your password.'})); setLdapError(''); setLdapPasswordError(''); setServerError(''); @@ -61,7 +59,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => { const ldapId = ldapIdInput.current?.value.trim(); if (!ldapId) { - setLdapError(localizeMessage('claim.email_to_ldap.ldapIdError', 'Please enter your AD/LDAP ID.')); + setLdapError(formatMessage({id: 'claim.email_to_ldap.ldapIdError', defaultMessage: 'Please enter your AD/LDAP ID.'})); setPasswordError(''); setLdapPasswordError(''); setServerError(''); @@ -70,7 +68,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => { const ldapPassword = ldapPasswordInput.current?.value; if (!ldapPassword) { - setLdapPasswordError(localizeMessage('claim.email_to_ldap.ldapPasswordError', 'Please enter your AD/LDAP password.')); + setLdapPasswordError(formatMessage({id: 'claim.email_to_ldap.ldapPasswordError', defaultMessage: 'Please enter your AD/LDAP password.'})); setLdapError(''); setPasswordError(''); setServerError(''); @@ -126,15 +124,14 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => { ); }; - const loginPlaceholder = ldapLoginFieldName || localizeMessage('claim.email_to_ldap.ldapId', 'AD/LDAP ID'); - const titleMessage = {id: t('claim.email_to_ldap.title'), defaultMessage: 'Switch Email/Password Account to AD/LDAP'}; + const loginPlaceholder = ldapLoginFieldName || formatMessage({id: 'claim.email_to_ldap.ldapId', defaultMessage: 'AD/LDAP ID'}); if (showMfa) { return ( ); @@ -212,7 +209,7 @@ const EmailToLDAP = ({email, siteName, ldapLoginFieldName}: Props) => { name='ldapPassword' ref={ldapPasswordInput} autoComplete='off' - placeholder={formatMessage({id: t('claim.email_to_ldap.ldapPwd'), defaultMessage: 'AD/LDAP Password'})} + placeholder={formatMessage({id: 'claim.email_to_ldap.ldapPwd', defaultMessage: 'AD/LDAP Password'})} spellCheck='false' /> diff --git a/webapp/channels/src/components/claim/components/email_to_oauth.tsx b/webapp/channels/src/components/claim/components/email_to_oauth.tsx index 95c99e1731..0bcc38f110 100644 --- a/webapp/channels/src/components/claim/components/email_to_oauth.tsx +++ b/webapp/channels/src/components/claim/components/email_to_oauth.tsx @@ -12,8 +12,7 @@ import {emailToOAuth} from 'actions/admin_actions.jsx'; import LoginMfa from 'components/login/login_mfa'; import Constants, {ClaimErrors} from 'utils/constants'; -import {t} from 'utils/i18n'; -import {localizeMessage, toTitleCase} from 'utils/utils'; +import {toTitleCase} from 'utils/utils'; import type {SubmitOptions} from './email_to_ldap'; import ErrorLabel from './error_label'; @@ -37,7 +36,7 @@ const EmailToOAuth = (props: Props) => { const password = passwordInput.current?.value; if (!password) { - setServerError(localizeMessage('claim.email_to_oauth.pwdError', 'Please enter your password.')); + setServerError(formatMessage({id: 'claim.email_to_oauth.pwdError', defaultMessage: 'Please enter your password.'})); return; } @@ -72,17 +71,13 @@ const EmailToOAuth = (props: Props) => { const type = (props.newType === Constants.SAML_SERVICE ? Constants.SAML_SERVICE.toUpperCase() : toTitleCase(props.newType || '')); const uiType = `${type} SSO`; - const titleMessage = { - id: t('claim.email_to_oauth.title'), - defaultMessage: 'Switch Email/Password Account to {uiType}', - }; if (showMfa) { return ( ); diff --git a/webapp/channels/src/components/claim/components/ldap_to_email.tsx b/webapp/channels/src/components/claim/components/ldap_to_email.tsx index f82e31eccb..7f4e46f5ad 100644 --- a/webapp/channels/src/components/claim/components/ldap_to_email.tsx +++ b/webapp/channels/src/components/claim/components/ldap_to_email.tsx @@ -3,15 +3,13 @@ import classNames from 'classnames'; import React, {useRef, useState} from 'react'; -import {FormattedMessage} from 'react-intl'; +import {FormattedMessage, useIntl} from 'react-intl'; import type {AuthChangeResponse} from '@mattermost/types/users'; -import LocalizedInput from 'components/localized_input/localized_input'; import LoginMfa from 'components/login/login_mfa'; import {ClaimErrors} from 'utils/constants'; -import {t} from 'utils/i18n'; import {isValidPassword, localizeMessage} from 'utils/utils'; import type {SubmitOptions} from './email_to_ldap'; @@ -38,6 +36,8 @@ const LDAPToEmail = (props: Props) => { const passwordInput = useRef(null); const passwordConfirmInput = useRef(null); + const {formatMessage} = useIntl(); + const preSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -108,17 +108,12 @@ const LDAPToEmail = (props: Props) => { }); }; - const passwordPlaceholder = localizeMessage('claim.ldap_to_email.ldapPwd', 'AD/LDAP Password'); - const titleMessage = {id: t('claim.ldap_to_email.title'), defaultMessage: 'Switch AD/LDAP Account to Email/Password'}; - const placeholderPasswordMessage = {id: t('claim.ldap_to_email.pwd'), defaultMessage: 'Password'}; - const placeholderConfirmMessage = {id: t('claim.ldap_to_email.confirm'), defaultMessage: 'Confirm Password'}; - if (showMfa) { return ( ); @@ -145,8 +140,7 @@ const LDAPToEmail = (props: Props) => {

@@ -155,7 +149,7 @@ const LDAPToEmail = (props: Props) => { className='form-control' name='ldapPassword' ref={ldapPasswordInput} - placeholder={passwordPlaceholder} + placeholder={formatMessage({id: 'claim.ldap_to_email.ldapPwd', defaultMessage: 'AD/LDAP Password'})} spellCheck='false' />
@@ -167,23 +161,23 @@ const LDAPToEmail = (props: Props) => { />

-
-
diff --git a/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx b/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx index c529e41ddc..2136c66150 100644 --- a/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx +++ b/webapp/channels/src/components/header_footer_route/content_layouts/column.tsx @@ -1,15 +1,15 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React from 'react'; +import React, {type ReactNode} from 'react'; import Constants from 'utils/constants'; import './column.scss'; type ColumnProps = { - title: string; - message: string; + title: ReactNode; + message: ReactNode; SVGElement?: React.ReactNode; extraContent?: React.ReactNode; onEnterKeyDown?: (e: React.KeyboardEvent) => void; diff --git a/webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap b/webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap deleted file mode 100644 index 935af0b0c4..0000000000 --- a/webapp/channels/src/components/localized_input/__snapshots__/localized_input.test.tsx.snap +++ /dev/null @@ -1,22 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`components/localized_input/localized_input should match snapshot 1`] = ` - - - -`; diff --git a/webapp/channels/src/components/localized_input/localized_input.test.tsx b/webapp/channels/src/components/localized_input/localized_input.test.tsx deleted file mode 100644 index aed53290b6..0000000000 --- a/webapp/channels/src/components/localized_input/localized_input.test.tsx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import {mount} from 'enzyme'; -import React from 'react'; -import {IntlProvider} from 'react-intl'; - -import {mountWithIntl} from 'tests/helpers/intl-test-helper'; - -import LocalizedInput from './localized_input'; - -describe('components/localized_input/localized_input', () => { - const baseProps = { - className: 'test-class', - onChange: jest.fn(), - placeholder: {id: 'test.placeholder', defaultMessage: 'placeholder to test'}, - value: 'test value', - }; - - test('should match snapshot', () => { - const wrapper = mount( - - - , - ).childAt(0); - - expect(wrapper).toMatchSnapshot(); - expect(wrapper.find('input').length).toBe(1); - expect(wrapper.find('input').get(0).props.value).toBe('test value'); - expect(wrapper.find('input').get(0).props.className).toBe('test-class'); - expect(wrapper.find('input').get(0).props.placeholder).toBe('placeholder to test'); - }); - - it('ref should properly be forwarded', () => { - const ref = React.createRef(); - const props = { - ...baseProps, - ref, - }; - - const wrapper = mountWithIntl( - - - , - ); - - expect(ref.current).toBe(wrapper.find('input').instance()); - }); -}); diff --git a/webapp/channels/src/components/localized_input/localized_input.tsx b/webapp/channels/src/components/localized_input/localized_input.tsx deleted file mode 100644 index ba439dc38e..0000000000 --- a/webapp/channels/src/components/localized_input/localized_input.tsx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. -// See LICENSE.txt for license information. - -import type {PrimitiveType, FormatXMLElementFn} from 'intl-messageformat'; -import React from 'react'; -import type {InputHTMLAttributes} from 'react'; -import {useIntl} from 'react-intl'; -import type {MessageDescriptor} from 'react-intl'; - -export type Props = Omit, 'placeholder'> & { - placeholder: MessageDescriptor & { - values?: Record>; - }; -}; - -const LocalizedInput = React.forwardRef((props: Props, ref?: React.Ref) => { - const { - placeholder: { - id, - defaultMessage, - values, - }, - ...otherProps - } = props; - - const {formatMessage} = useIntl(); - - return ( - - ); -}); -LocalizedInput.displayName = 'LocalizedInput'; - -export default LocalizedInput; diff --git a/webapp/channels/src/components/login/login_mfa.tsx b/webapp/channels/src/components/login/login_mfa.tsx index 6d5ad14e21..bd2a4906ea 100644 --- a/webapp/channels/src/components/login/login_mfa.tsx +++ b/webapp/channels/src/components/login/login_mfa.tsx @@ -1,9 +1,8 @@ // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. // See LICENSE.txt for license information. -import React, {useState} from 'react'; +import React, {type ReactNode, useState} from 'react'; import {useIntl} from 'react-intl'; -import type {MessageDescriptor} from 'react-intl'; import type {SubmitOptions} from 'components/claim/components/email_to_ldap'; import ShieldWithCheckmarkSVG from 'components/common/svg_images_components/shield_with_checkmark'; @@ -16,8 +15,8 @@ import './login_mfa.scss'; type LoginMfaProps = { loginId: string | null; password: string; - title?: MessageDescriptor; - subtitle?: MessageDescriptor; + title?: ReactNode; + subtitle?: ReactNode; onSubmit: ({loginId, password, token}: SubmitOptions) => void; } @@ -49,8 +48,8 @@ const LoginMfa = ({loginId, password, title, subtitle, onSubmit}: LoginMfaProps) return ( } extraContent={(
diff --git a/webapp/channels/src/components/searchable_channel_list.test.tsx b/webapp/channels/src/components/searchable_channel_list.test.tsx index 9c5589563d..ec3ea1c79e 100644 --- a/webapp/channels/src/components/searchable_channel_list.test.tsx +++ b/webapp/channels/src/components/searchable_channel_list.test.tsx @@ -4,7 +4,9 @@ import {shallow} from 'enzyme'; import React from 'react'; -import SearchableChannelList from 'components/searchable_channel_list'; +import {SearchableChannelList} from 'components/searchable_channel_list'; + +import {type MockIntl} from 'tests/helpers/intl-test-helper'; import {Filter} from './browse_channels/browse_channels'; @@ -26,6 +28,9 @@ describe('components/SearchableChannelList', () => { rememberHideJoinedChannelsChecked: false, noResultsText: <>{'no channel found'}, filter: Filter.All, + intl: { + formatMessage: jest.fn(), + } as MockIntl, }; test('should match init snapshot', () => { diff --git a/webapp/channels/src/components/searchable_channel_list.tsx b/webapp/channels/src/components/searchable_channel_list.tsx index 3f1e02094d..b6b8e913bb 100644 --- a/webapp/channels/src/components/searchable_channel_list.tsx +++ b/webapp/channels/src/components/searchable_channel_list.tsx @@ -3,7 +3,7 @@ import classNames from 'classnames'; import React from 'react'; -import {FormattedMessage} from 'react-intl'; +import {FormattedMessage, injectIntl, type WrappedComponentProps} from 'react-intl'; import {ArchiveOutlineIcon, CheckIcon, ChevronDownIcon, GlobeIcon, LockOutlineIcon, MagnifyIcon, AccountOutlineIcon, GlobeCheckedIcon} from '@mattermost/compass-icons/components'; import type {Channel, ChannelMembership} from '@mattermost/types/channels'; @@ -13,7 +13,6 @@ import {isPrivateChannel} from 'mattermost-redux/utils/channel_utils'; import MagnifyingGlassSVG from 'components/common/svg_images_components/magnifying_glass_svg'; import LoadingScreen from 'components/loading_screen'; -import LocalizedInput from 'components/localized_input/localized_input'; import * as Menu from 'components/menu'; import QuickInput from 'components/quick_input'; import CheckboxCheckedIcon from 'components/widgets/icons/checkbox_checked_icon'; @@ -31,7 +30,7 @@ import {Filter} from './browse_channels/browse_channels'; const NEXT_BUTTON_TIMEOUT_MILLISECONDS = 500; -type Props = { +interface Props extends WrappedComponentProps { channels: Channel[]; channelsPerPage: number; nextPage: (page: number) => void; @@ -58,7 +57,7 @@ type State = { isSearch?: boolean; } -export default class SearchableChannelList extends React.PureComponent { +export class SearchableChannelList extends React.PureComponent { private nextTimeoutId: number | NodeJS.Timeout; private filter: React.RefObject; private channelListScroll: React.RefObject; @@ -410,8 +409,7 @@ export default class SearchableChannelList extends React.PureComponent, + , this.props.changeFilter(Filter.Archived)} leadingElement={} @@ -579,3 +578,5 @@ export default class SearchableChannelList extends React.PureComponent { let nextButton; let previousButton; let usersToDisplay; - const {formatMessage} = this.props.intl; if (this.props.term || !this.props.users) { usersToDisplay = this.props.users; @@ -281,7 +277,6 @@ class SearchableUserList extends React.PureComponent { if (this.props.renderFilterRow) { filterRow = this.props.renderFilterRow(this.handleInput); } else { - const searchUsersPlaceholder = {id: t('filtered_user_list.search'), defaultMessage: 'Search users'}; filterRow = (
); diff --git a/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx b/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx index 82f3c156c3..aed275791a 100644 --- a/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx +++ b/webapp/channels/src/components/team_general_tab/team_general_tab.test.tsx @@ -4,16 +4,12 @@ import {shallow} from 'enzyme'; import React from 'react'; import type {ChangeEvent, ComponentProps} from 'react'; -import {type IntlShape} from 'react-intl'; import {GeneralTab} from 'components/team_general_tab/team_general_tab'; +import {type MockIntl} from 'tests/helpers/intl-test-helper'; import {TestHelper} from 'utils/test_helper'; -interface MockIntl extends IntlShape { - formatMessage: jest.Mock; -} - describe('components/TeamSettings', () => { const getTeam = jest.fn().mockResolvedValue({data: true}); const patchTeam = jest.fn().mockReturnValue({data: true}); diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index bdaf318aac..a72819bd65 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -3061,7 +3061,7 @@ "claim.email_to_oauth.title": "Switch Email/Password Account to {uiType}", "claim.ldap_to_email.confirm": "Confirm Password", "claim.ldap_to_email.email": "After switching your authentication method, you will use {email} to login. Your AD/LDAP credentials will no longer allow access to Mattermost.", - "claim.ldap_to_email.enterLdapPwd": "{ldapPassword}:", + "claim.ldap_to_email.enterLdapPwd": "AD/LDAP Password:", "claim.ldap_to_email.enterPwd": "New email login password:", "claim.ldap_to_email.ldapPasswordError": "Please enter your AD/LDAP password.", "claim.ldap_to_email.ldapPwd": "AD/LDAP Password", @@ -3899,6 +3899,8 @@ "local": "local", "login_mfa.saving": "Logging in…", "login_mfa.submit": "Submit", + "login_mfa.subtitle": "To complete the sign in process, please enter a token from your smartphone's authenticator", + "login_mfa.title": "Enter MFA Token", "login_mfa.token": "MFA Token", "login.cardtitle": "Log in", "login.cardtitle.external": "Log in with one of the following:", diff --git a/webapp/package-lock.json b/webapp/package-lock.json index b21ac7fe98..b306616dc3 100644 --- a/webapp/package-lock.json +++ b/webapp/package-lock.json @@ -210,7 +210,7 @@ "jest-junit": "12.2.0", "jest-styled-components": "7.1.1", "jest-watch-typeahead": "0.6.4", - "mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10", + "mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44", "nock": "13.2.8", "prettier": "2.3.2", "react-router-enzyme-context": "1.2.0", @@ -16248,8 +16248,8 @@ }, "node_modules/mmjstool": { "version": "1.0.0", - "resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#d88289ce1d30da1936d9a17e9bed0cdb52de0a10", - "integrity": "sha512-Fia3OL1qvMCBy8B9GpZVyqcMz/7NvQfxVJ6KWxegqQt0rSIkqI0f7UveAWGCxD6XoPHPcCCtdvuklBWjBxzgIQ==", + "resolved": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44", + "integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==", "dev": true, "dependencies": { "estree-walk": "^2.2.0", @@ -35701,7 +35701,7 @@ "mark.js": "8.11.1", "marked": "github:mattermost/marked#2ef7f28cc7718e3f551c4ce9ea75fdd7580c2008", "memoize-one": "6.0.0", - "mmjstool": "github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10", + "mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44", "moment-timezone": "0.5.38", "nock": "13.2.8", "p-queue": "7.3.0", @@ -36349,10 +36349,10 @@ "dev": true }, "mmjstool": { - "version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#d88289ce1d30da1936d9a17e9bed0cdb52de0a10", - "integrity": "sha512-Fia3OL1qvMCBy8B9GpZVyqcMz/7NvQfxVJ6KWxegqQt0rSIkqI0f7UveAWGCxD6XoPHPcCCtdvuklBWjBxzgIQ==", + "version": "git+ssh://git@github.com/mattermost/mattermost-utilities.git#83b1b311972b8f5e750aae4019457a40abb5aa44", + "integrity": "sha512-SFAbT+eN1mvgSfRTe8k6IMKVWbhGItTJtxZ+Pt0mX+fe8pakB3MkIkWzHBHVnEDI9Ek9kmQFGF1aZwzKFHXyYQ==", "dev": true, - "from": "mmjstool@github:mattermost/mattermost-utilities#d88289ce1d30da1936d9a17e9bed0cdb52de0a10", + "from": "mmjstool@github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44", "requires": { "estree-walk": "^2.2.0", "filehound": "^1.17.5",