From c440414917300dbe507af34385347fe186e71523 Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Thu, 30 Oct 2025 13:29:13 +0700 Subject: [PATCH 1/9] fix linter errors --- .../reviewerChecklist/reviewerChecklist.ts | 2 +- .github/libs/GithubUtils.ts | 2 +- .github/libs/sanitizeJSONStringValues.ts | 2 +- .github/libs/sanitizeStringForJSONParse.ts | 2 +- scripts/generateTranslations.ts | 4 +-- src/CONST/index.ts | 2 +- .../AddPaymentCard/PaymentCardForm.tsx | 12 +++---- .../BaseAnchorForCommentsOnly.tsx | 2 +- .../CalendarPicker/YearPickerModal.tsx | 2 +- src/components/EnvironmentContext.tsx | 2 +- .../HTMLRenderers/ImageRenderer.tsx | 2 +- src/components/Icon/BankIconsUtils.ts | 2 +- src/components/ImportSpreadsheet.tsx | 2 +- src/components/MoneyRequestHeader.tsx | 2 +- src/components/RenderHTML.tsx | 8 ++--- .../useReportActionAvatars.ts | 4 +-- .../implementation/index.native.tsx | 2 +- src/components/TimePicker/TimePicker.tsx | 10 +++--- .../DataCells/MerchantCell.tsx | 2 +- src/libs/CardUtils.ts | 12 +++---- src/libs/Clipboard/index.ts | 4 +-- src/libs/Console/index.ts | 2 +- src/libs/EmailUtils.ts | 2 +- src/libs/EmojiUtils.tsx | 6 ++-- src/libs/FormulaDatetime.ts | 6 ++-- src/libs/LocalePhoneNumber.ts | 4 +-- src/libs/LoginUtils.ts | 2 +- src/libs/MarkdownLinkHelpers.ts | 10 +++--- src/libs/MoneyRequestUtils.ts | 8 ++--- src/libs/Navigation/Navigation.ts | 4 +-- src/libs/Navigation/helpers/linkTo/index.ts | 4 +-- .../helpers/replaceCompanyCardsRoute.ts | 2 +- src/libs/NextStepUtils.ts | 6 ++-- src/libs/OptionsListUtils/index.ts | 6 ++-- src/libs/ParsingUtils.ts | 2 +- src/libs/Performance.tsx | 2 +- src/libs/PersonalDetailsUtils.ts | 4 +-- src/libs/PhoneNumber.ts | 2 +- src/libs/PolicyUtils.ts | 2 +- src/libs/ReportActionsUtils.ts | 6 ++-- src/libs/ReportUtils.ts | 12 +++---- src/libs/RoomNameInputUtils.ts | 4 +-- src/libs/SearchQueryUtils.ts | 2 +- src/libs/SelectionScraper/index.ts | 2 +- src/libs/SidebarUtils.ts | 2 +- src/libs/StringUtils/decodeUnicode.ts | 2 +- src/libs/StringUtils/dedent.ts | 4 +-- src/libs/StringUtils/index.ts | 32 +++++++++---------- src/libs/TransactionUtils/index.ts | 8 ++--- src/libs/Url.ts | 2 +- src/libs/WorkspaceReportFieldUtils.ts | 2 +- src/libs/actions/StatsCounter.ts | 2 +- src/libs/fileDownload/FileUtils.ts | 8 ++--- src/libs/fileDownload/heicConverter/index.ts | 2 +- src/libs/getFirstAlphaNumericCharacter.ts | 2 +- src/libs/isPublicScreenRoute.ts | 2 +- src/pages/Debug/Report/DebugReportActions.tsx | 2 +- .../BaseOnboardingPersonalDetails.tsx | 2 +- .../USD/BusinessInfo/BusinessInfo.tsx | 2 +- .../report/ContextMenu/ContextMenuActions.tsx | 2 +- .../ReportActionCompose.tsx | 2 +- src/pages/home/report/ReportFooter.tsx | 2 +- .../report/comment/TextCommentFragment.tsx | 2 +- .../request/step/IOURequestStepSubrate.tsx | 2 +- src/pages/settings/Profile/Contacts/utils.ts | 4 +-- .../settings/Profile/TimezoneSelectPage.tsx | 2 +- .../settings/Security/CloseAccountPage.tsx | 2 +- .../WorkspaceDuplicateSelectFeaturesForm.tsx | 2 +- .../rules/RulesMaxExpenseAgePage.tsx | 2 +- tests/e2e/compare/output/markdownTable.ts | 2 +- tests/e2e/utils/logger.ts | 2 +- tests/ui/WorkspaceUpgradeTest.tsx | 2 +- tests/unit/CloseAccountPageTest.ts | 2 +- tests/unit/FileUtilsTest.ts | 4 +-- tests/unit/GithubUtilsTest.ts | 2 +- tests/unit/ReceiptAlternativeMethodsTest.tsx | 2 +- tests/unit/ReportUtilsTest.ts | 4 +-- 77 files changed, 149 insertions(+), 149 deletions(-) diff --git a/.github/actions/javascript/reviewerChecklist/reviewerChecklist.ts b/.github/actions/javascript/reviewerChecklist/reviewerChecklist.ts index 2d2f3978fa1d..cd470a59c51a 100644 --- a/.github/actions/javascript/reviewerChecklist/reviewerChecklist.ts +++ b/.github/actions/javascript/reviewerChecklist/reviewerChecklist.ts @@ -55,7 +55,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems: number) { } const whitespace = /([\n\r])/gm; - const comment = combinedComments.at(i)?.replace(whitespace, ''); + const comment = combinedComments.at(i)?.replaceAll(whitespace, ''); console.log(`Comment ${i} starts with: ${comment?.slice(0, 20)}...`); diff --git a/.github/libs/GithubUtils.ts b/.github/libs/GithubUtils.ts index a9983db69dc7..c0f44df1827d 100644 --- a/.github/libs/GithubUtils.ts +++ b/.github/libs/GithubUtils.ts @@ -201,7 +201,7 @@ class GithubUtils { static getStagingDeployCashData(issue: OctokitIssueItem): StagingDeployCashData { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, diff --git a/.github/libs/sanitizeJSONStringValues.ts b/.github/libs/sanitizeJSONStringValues.ts index 7ef427688ccd..3329ae63067f 100644 --- a/.github/libs/sanitizeJSONStringValues.ts +++ b/.github/libs/sanitizeJSONStringValues.ts @@ -24,7 +24,7 @@ export default function sanitizeJSONStringValues(inputString: string): string { // Function to recursively sanitize string values in an object const sanitizeValues = (obj: unknown): unknown => { if (typeof obj === 'string') { - return obj.replace(/\\|\t|\n|\r|\f|"/g, replacer); + return obj.replaceAll(/\\|\t|\n|\r|\f|"/g, replacer); } if (Array.isArray(obj)) { return obj.map((item) => sanitizeValues(item)); diff --git a/.github/libs/sanitizeStringForJSONParse.ts b/.github/libs/sanitizeStringForJSONParse.ts index d646a566c517..de12208e2d15 100644 --- a/.github/libs/sanitizeStringForJSONParse.ts +++ b/.github/libs/sanitizeStringForJSONParse.ts @@ -22,7 +22,7 @@ const sanitizeStringForJSONParse = (inputString: string | number | boolean | nul } // Replace any newlines and escape backslashes - return inputString.replace(/\\|\t|\n|\r|\f|"/g, replacer); + return inputString.replaceAll(/\\|\t|\n|\r|\f|"/g, replacer); }; export default sanitizeStringForJSONParse; diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index e6969c9942d3..3dac7105aabc 100755 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -466,8 +466,8 @@ class TranslationGenerator { let keyBase = node .getText() .trim() - .replace(/^['"`]/, '') - .replace(/['"`]$/, ''); + .replaceAll(/^['"`]/g, '') + .replaceAll(/['"`]$/g, ''); const context = this.getContextForNode(node); if (context) { diff --git a/src/CONST/index.ts b/src/CONST/index.ts index cf0c6368090a..6157a5020d7c 100755 --- a/src/CONST/index.ts +++ b/src/CONST/index.ts @@ -3662,7 +3662,7 @@ const CONST = { return new RegExp(this.EMOJIS, this.EMOJIS.flags.concat('g')); }, - MERGED_ACCOUNT_PREFIX: /^(MERGED_\d+@)/, + MERGED_ACCOUNT_PREFIX: /^(MERGED_\d+@)/g, ROUTES: { VALIDATE_LOGIN: /\/v($|(\/\/*))/, UNLINK_LOGIN: /\/u($|(\/\/*))/, diff --git a/src/components/AddPaymentCard/PaymentCardForm.tsx b/src/components/AddPaymentCard/PaymentCardForm.tsx index fddbcd2f0838..00b27ec40409 100644 --- a/src/components/AddPaymentCard/PaymentCardForm.tsx +++ b/src/components/AddPaymentCard/PaymentCardForm.tsx @@ -151,7 +151,7 @@ function PaymentCardForm({ return; } - let value = newValue.replace(CONST.REGEX.NON_NUMERIC, ''); + let value = newValue.replaceAll(CONST.REGEX.NON_NUMERIC, ''); if (value.length === 1) { const firstDigit = value.charAt(0); @@ -170,7 +170,7 @@ function PaymentCardForm({ } } - const prevValue = previousValueRef.current?.replace(CONST.REGEX.NON_NUMERIC, '') ?? ''; + const prevValue = previousValueRef.current?.replaceAll(CONST.REGEX.NON_NUMERIC, '') ?? ''; let formattedValue = value; if (value.length === 2 && prevValue.length < 2) { @@ -192,7 +192,7 @@ function PaymentCardForm({ errors.nameOnCard = translate(label.error.nameOnCard); } - if (values.cardNumber && !isValidDebitCard(values.cardNumber.replace(/ /g, ''))) { + if (values.cardNumber && !isValidDebitCard(values.cardNumber.replaceAll(' ', ''))) { errors.cardNumber = translate(label.error.cardNumber); } @@ -232,13 +232,13 @@ function PaymentCardForm({ const onChangeCardNumber = useCallback((newValue: string) => { // Replace all characters that are not spaces or digits - let validCardNumber = newValue.replace(/[^\d ]/g, ''); + let validCardNumber = newValue.replaceAll(/[^\d ]/g, ''); // Gets only the first 16 digits if the inputted number have more digits than that validCardNumber = validCardNumber.match(/(?:\d *){1,16}/)?.[0] ?? ''; // Remove all spaces to simplify formatting - const cleanedNumber = validCardNumber.replace(/ /g, ''); + const cleanedNumber = validCardNumber.replaceAll(' ', ''); // Check if the number is a potential Amex card (starts with 34 or 37 and has up to 15 digits) const isAmex = /^3[47]\d{0,13}$/.test(cleanedNumber); @@ -246,7 +246,7 @@ function PaymentCardForm({ // Format based on Amex or standard 4-4-4-4 pattern if (isAmex) { // Format as 4-6-5 for Amex - validCardNumber = cleanedNumber.replace(/(\d{1,4})(\d{1,6})?(\d{1,5})?/, (match, p1, p2, p3) => [p1, p2, p3].filter(Boolean).join(' ')); + validCardNumber = cleanedNumber.replaceAll(/(\d{1,4})(\d{1,6})?(\d{1,5})?/g, (match, p1, p2, p3) => [p1, p2, p3].filter(Boolean).join(' ')); } else { // Format as 4-4-4-4 for non-Amex validCardNumber = cleanedNumber.match(/.{1,4}/g)?.join(' ') ?? ''; diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx index 7a0516994b4e..1f936e3702e0 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.tsx @@ -52,7 +52,7 @@ function BaseAnchorForCommentsOnly({ linkProps.href = href; } const defaultTextStyle = canUseTouchScreen() || shouldUseNarrowLayout ? {} : {...styles.userSelectText, ...styles.cursorPointer}; - const isEmail = Str.isValidEmail(href.replace(/mailto:/i, '')); + const isEmail = Str.isValidEmail(href.replaceAll(/mailto:/gi, '')); const linkHref = !linkHasImage ? href : undefined; const isFocused = useIsFocused(); diff --git a/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx b/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx index 7ab4634fc9b5..f46a4e971d2d 100644 --- a/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx +++ b/src/components/DatePicker/CalendarPicker/YearPickerModal.tsx @@ -71,7 +71,7 @@ function YearPickerModal({isVisible, years, currentYear = new Date().getFullYear textInputLabel={translate('yearPickerPage.selectYear')} textInputValue={searchText} textInputMaxLength={4} - onChangeText={(text) => setSearchText(text.replace(CONST.REGEX.NON_NUMERIC, '').trim())} + onChangeText={(text) => setSearchText(text.replaceAll(CONST.REGEX.NON_NUMERIC, '').trim())} inputMode={CONST.INPUT_MODE.NUMERIC} headerMessage={headerMessage} sections={sections} diff --git a/src/components/EnvironmentContext.tsx b/src/components/EnvironmentContext.tsx index 4c807e99e53f..933507c5db77 100644 --- a/src/components/EnvironmentContext.tsx +++ b/src/components/EnvironmentContext.tsx @@ -33,7 +33,7 @@ const EnvironmentContext = createContext({ function EnvironmentProvider({children}: EnvironmentProviderProps): ReactElement { const [environment, setEnvironment] = useState(CONST.ENVIRONMENT.PRODUCTION); const [environmentURL, setEnvironmentURL] = useState(CONST.NEW_EXPENSIFY_URL); - const [environmentURLWithoutTrailingSlash] = useMemo(() => [environmentURL.replace(/\/+$/, '')], [environmentURL]); + const [environmentURLWithoutTrailingSlash] = useMemo(() => [environmentURL.replaceAll(/\/+$/g, '')], [environmentURL]); useEffect(() => { getEnvironment().then(setEnvironment); diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx index 45f9ed3dac3d..7d1635ef68aa 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/ImageRenderer.tsx @@ -56,7 +56,7 @@ function ImageRenderer({tnode}: CustomRendererProps) { // The backend always returns these thumbnails with a .jpg extension, even for .png images. // As a workaround, we remove the .1024.jpg or .320.jpg suffix only for .png images, // For other image formats, we retain the thumbnail as is to avoid unnecessary modifications. - const processedPreviewSource = typeof previewSource === 'string' ? previewSource.replace(/\.png\.(1024|320)\.jpg$/, '.png') : previewSource; + const processedPreviewSource = typeof previewSource === 'string' ? previewSource.replaceAll(/\.png\.(1024|320)\.jpg$/g, '.png') : previewSource; const source = tryResolveUrlFromApiRoot(isAttachmentOrReceipt ? attachmentSourceAttribute : htmlAttribs.src); const alt = htmlAttribs.alt; diff --git a/src/components/Icon/BankIconsUtils.ts b/src/components/Icon/BankIconsUtils.ts index 120165c8694a..c12397080a48 100644 --- a/src/components/Icon/BankIconsUtils.ts +++ b/src/components/Icon/BankIconsUtils.ts @@ -65,7 +65,7 @@ function getBankIconAsset(bankNameKey: BankNameKey, isCard: boolean): IconAsset function getBankNameKey(bankName: string): BankNameKey { const bank = Object.entries(CONST.BANK_NAMES).find(([, value]) => { - const condensedValue = value.replace(/\s/g, ''); + const condensedValue = value.replaceAll(/\s/g, ''); return ( bankName === value || bankName.includes(value) || diff --git a/src/components/ImportSpreadsheet.tsx b/src/components/ImportSpreadsheet.tsx index 08c2243397a6..3e9e77000761 100644 --- a/src/components/ImportSpreadsheet.tsx +++ b/src/components/ImportSpreadsheet.tsx @@ -86,7 +86,7 @@ function ImportSpreadsheet({backTo, goTo, isImportingMultiLevelTags}: ImportSpre return; } if (Platform.OS === 'ios') { - fileURI = fileURI.replace(/^.*\/Documents\//, `${RNFetchBlob.fs.dirs.DocumentDir}/`); + fileURI = fileURI.replaceAll(/^.*\/Documents\//g, `${RNFetchBlob.fs.dirs.DocumentDir}/`); } const {fileExtension} = splitExtensionFromFileName(file?.name ?? ''); const shouldReadAsText = CONST.TEXT_SPREADSHEET_EXTENSIONS.includes(fileExtension as TupleToUnion); diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index 5f62518741ee..90e1cf87934f 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -120,7 +120,7 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre const {isDelegateAccessRestricted, showDelegateNoAccessModal} = useContext(DelegateNoAccessContext); const isReportInRHP = route.name === SCREENS.SEARCH.REPORT_RHP; - const isFromReviewDuplicates = !!route.params.backTo?.replace(/\?.*/g, '').endsWith('/duplicates/review'); + const isFromReviewDuplicates = !!route.params.backTo?.replaceAll(/\?.*/g, '').endsWith('/duplicates/review'); const shouldDisplayTransactionNavigation = !!(reportID && isReportInRHP); const isParentReportArchived = useReportIsArchived(report?.parentReportID); const {iouReport, chatReport: chatIOUReport, isChatIOUReportArchived} = useGetIOUReportFromReportAction(parentReportAction); diff --git a/src/components/RenderHTML.tsx b/src/components/RenderHTML.tsx index 870e81cbb230..812207a00bea 100644 --- a/src/components/RenderHTML.tsx +++ b/src/components/RenderHTML.tsx @@ -18,11 +18,11 @@ function RenderHTML({html: htmlParam}: RenderHTMLProps) { return ( Parser.replace(htmlParam, {shouldEscapeText: false, filterRules: ['emoji']}) // Escape brackets when pasting a link, since unescaped [] can break Markdown link syntax - .replace(/&#91;/g, '[') - .replace(/&#93;/g, ']') + .replaceAll('&#91;', '[') + .replaceAll('&#93;', ']') // Remove double tag if exists and keep the outermost tag (always the original tag). - .replace(/(]*>)(?:]*>)+/g, '$1') - .replace(/(<\/emoji[^>]*>)(?:<\/emoji[^>]*>)+/g, '$1') + .replaceAll(/(]*>)(?:]*>)+/g, '$1') + .replaceAll(/(<\/emoji[^>]*>)(?:<\/emoji[^>]*>)+/g, '$1') ); }, [htmlParam]); return ( diff --git a/src/components/ReportActionAvatars/useReportActionAvatars.ts b/src/components/ReportActionAvatars/useReportActionAvatars.ts index b41359724f76..e61be5626c4c 100644 --- a/src/components/ReportActionAvatars/useReportActionAvatars.ts +++ b/src/components/ReportActionAvatars/useReportActionAvatars.ts @@ -143,7 +143,7 @@ function useReportActionAvatars({ shouldDisplayAllActors: false, isWorkspaceActor: false, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - actorHint: String(policyID).replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''), + actorHint: String(policyID).replaceAll(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''), accountID: workspaceAccountID, delegateAccountID: undefined, }, @@ -331,7 +331,7 @@ function useReportActionAvatars({ shouldDisplayAllActors: displayAllActors, isWorkspaceActor, // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - actorHint: String(shouldUsePrimaryAvatarID ? primaryAvatar.id : login || defaultDisplayName || fallbackDisplayName).replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''), + actorHint: String(shouldUsePrimaryAvatarID ? primaryAvatar.id : login || defaultDisplayName || fallbackDisplayName).replaceAll(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''), accountID, delegateAccountID: !isWorkspaceActor && !!delegateAccountID ? actorAccountID : undefined, }, diff --git a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx index 51ffd2fded98..8f04ccd74da4 100644 --- a/src/components/TextInput/BaseTextInput/implementation/index.native.tsx +++ b/src/components/TextInput/BaseTextInput/implementation/index.native.tsx @@ -230,7 +230,7 @@ function BaseTextInput({ * Set Value & activateLabel */ const setValue = (newValue: string) => { - const formattedValue = isMultiline ? newValue : newValue.replace(/\n/g, ' '); + const formattedValue = isMultiline ? newValue : newValue.replaceAll('\n', ' '); onInputChange?.(formattedValue); diff --git a/src/components/TimePicker/TimePicker.tsx b/src/components/TimePicker/TimePicker.tsx index 5e0e1e245677..f13dfe3f6f3c 100644 --- a/src/components/TimePicker/TimePicker.tsx +++ b/src/components/TimePicker/TimePicker.tsx @@ -208,7 +208,7 @@ function TimePicker( // The valid format is HH(from 00 to 12). If the user input 9, it will be 09. If user try to change 09 to 19 it would skip the first character const handleHourChange = (text: string) => { // Replace spaces with 0 to implement the following digit removal by pressing space - const trimmedText = text.replace(/ /g, '0'); + const trimmedText = text.replaceAll(' ', '0'); if (!trimmedText) { resetHours(); return; @@ -324,7 +324,7 @@ function TimePicker( */ const handleMinutesChange = (text: string) => { // Replace spaces with 0 to implement the following digit removal by pressing space - const trimmedText = text.replace(/ /g, '0'); + const trimmedText = text.replaceAll(' ', '0'); if (!trimmedText) { resetMinutes(); return; @@ -403,7 +403,7 @@ function TimePicker( */ const handleSecondsChange = (text: string) => { // Replace spaces with 0 to implement the following digit removal by pressing space - const trimmedText = text.replace(/ /g, '0'); + const trimmedText = text.replaceAll(' ', '0'); if (!trimmedText) { resetSeconds(); return; @@ -482,7 +482,7 @@ function TimePicker( */ const handleMillisecondsChange = (text: string) => { // Replace spaces with 0 to implement the following digit removal by pressing space - const trimmedText = text.replace(/ /g, '0'); + const trimmedText = text.replaceAll(' ', '0'); if (!trimmedText) { resetMilliseconds(); return; @@ -604,7 +604,7 @@ function TimePicker( } return; } - const trimmedKey = key.replace(/[^0-9]/g, ''); + const trimmedKey = key.replaceAll(/[^0-9]/g, ''); if (isHourFocused) { handleHourChange(insertAtPosition(hours, trimmedKey, selectionHour.start, selectionHour.end)); diff --git a/src/components/TransactionItemRow/DataCells/MerchantCell.tsx b/src/components/TransactionItemRow/DataCells/MerchantCell.tsx index 4206159b6910..efb8b7d35f53 100644 --- a/src/components/TransactionItemRow/DataCells/MerchantCell.tsx +++ b/src/components/TransactionItemRow/DataCells/MerchantCell.tsx @@ -20,7 +20,7 @@ function MerchantOrDescriptionCell({ if (!isDescription) { return merchantOrDescription; } - return Parser.htmlToText(merchantOrDescription).replace(/\n/g, ' '); + return Parser.htmlToText(merchantOrDescription).replaceAll('\n', ' '); }, [merchantOrDescription, isDescription]); return ( diff --git a/src/libs/CardUtils.ts b/src/libs/CardUtils.ts index 5abc29ee9a54..4a111e4f1603 100644 --- a/src/libs/CardUtils.ts +++ b/src/libs/CardUtils.ts @@ -172,7 +172,7 @@ function maskCard(lastFour = ''): string { const maskedString = '•'.repeat(maskedLength) + lastFour; // Insert space for every four symbols - return maskedString.replace(/(.{4})/g, '$1 ').trim(); + return maskedString.replaceAll(/(.{4})/g, '$1 ').trim(); } /** @@ -189,21 +189,21 @@ function maskCardNumber(cardName?: string, feed?: string, showOriginalName?: boo return ''; } const hasSpace = /\s/.test(cardName); - const maskedString = cardName.replace(/X/g, '•'); + const maskedString = cardName.replaceAll('X', '•'); const isAmexBank = [CONST.COMPANY_CARD.FEED_BANK_NAME.AMEX, CONST.COMPANY_CARD.FEED_BANK_NAME.AMEX_DIRECT].some((value) => value === feed); if (hasSpace) { if (showOriginalName) { return cardName; } - return cardName.replace(/ - \d{4}$/, ''); + return cardName.replaceAll(/ - \d{4}$/g, ''); } if (isAmexBank && maskedString.length === 15) { - return maskedString.replace(/(.{4})(.{6})(.{5})/, '$1 $2 $3'); + return maskedString.replaceAll(/(.{4})(.{6})(.{5})/g, '$1 $2 $3'); } - return maskedString.replace(/(.{4})/g, '$1 ').trim(); + return maskedString.replaceAll(/(.{4})/g, '$1 ').trim(); } /** @@ -223,7 +223,7 @@ function lastFourNumbersFromCardName(cardName: string | undefined): string { } function getMCardNumberString(cardNumber: string): string { - return cardNumber.replace(/\s/g, ''); + return cardNumber.replaceAll(/\s/g, ''); } function getTranslationKeyForLimitType(limitType: ValueOf | undefined): TranslationPaths | '' { diff --git a/src/libs/Clipboard/index.ts b/src/libs/Clipboard/index.ts index 130aad270b92..ff8b66cca66e 100644 --- a/src/libs/Clipboard/index.ts +++ b/src/libs/Clipboard/index.ts @@ -116,8 +116,8 @@ const setHtml: SetHtml = (html: string, text: string) => { setHTMLSync(html, text); } else { const htmlNonClosingTags = html - .replace(//gi, '') - .replace(//gi, ''); + .replaceAll(//gi, '') + .replaceAll(//gi, ''); navigator.clipboard.write([ new ClipboardItem({ diff --git a/src/libs/Console/index.ts b/src/libs/Console/index.ts index 672683ebb889..93fdf7192565 100644 --- a/src/libs/Console/index.ts +++ b/src/libs/Console/index.ts @@ -90,7 +90,7 @@ const charMap: Record = { * @returns the sanitized text */ function sanitizeConsoleInput(text: string): string { - return text.replace(charsToSanitize, (match) => charMap[match]); + return text.replaceAll(charsToSanitize, (match) => charMap[match]); } /** diff --git a/src/libs/EmailUtils.ts b/src/libs/EmailUtils.ts index 886823faae87..8eecb8988f51 100644 --- a/src/libs/EmailUtils.ts +++ b/src/libs/EmailUtils.ts @@ -20,7 +20,7 @@ function trimMailTo(mailLink: string) { * @returns The email with inserted line break opportunities */ function prefixMailSeparatorsWithBreakOpportunities(email: string) { - return email.replace( + return email.replaceAll( /([.@])/g, // below: zero-width space (U+200B) character '​$1', diff --git a/src/libs/EmojiUtils.tsx b/src/libs/EmojiUtils.tsx index 7658da6c6a44..52d0bf435d0d 100644 --- a/src/libs/EmojiUtils.tsx +++ b/src/libs/EmojiUtils.tsx @@ -135,7 +135,7 @@ const getEmojiUnicode = memoize( * Validates first character is emoji in text string */ function isFirstLetterEmoji(message: string): boolean { - const trimmedMessage = Str.replaceAll(message.replace(/ /g, ''), '\n', ''); + const trimmedMessage = Str.replaceAll(message.replaceAll(' ', ''), '\n', ''); const match = trimmedMessage.match(CONST.REGEX.ALL_EMOJIS); if (!match) { @@ -149,7 +149,7 @@ function isFirstLetterEmoji(message: string): boolean { * Validates that this message contains only emojis */ function containsOnlyEmojis(message: string): boolean { - const trimmedMessage = Str.replaceAll(message.replace(/ /g, ''), '\n', ''); + const trimmedMessage = Str.replaceAll(message.replaceAll(' ', ''), '\n', ''); const match = trimmedMessage.match(CONST.REGEX.ALL_EMOJIS); if (!match) { @@ -572,7 +572,7 @@ const getEmojiReactionDetails = (emojiName: string, reaction: ReportActionReacti /** * Given an emoji code, returns an base emoji code without skin tone */ -const getRemovedSkinToneEmoji = (emoji?: string) => emoji?.replace(CONST.REGEX.EMOJI_SKIN_TONES, ''); +const getRemovedSkinToneEmoji = (emoji?: string) => emoji?.replaceAll(CONST.REGEX.EMOJI_SKIN_TONES, ''); function getSpacersIndexes(allEmojis: EmojiPickerList): number[] { const spacersIndexes: number[] = []; diff --git a/src/libs/FormulaDatetime.ts b/src/libs/FormulaDatetime.ts index 2c2de2256f8f..df73775db288 100644 --- a/src/libs/FormulaDatetime.ts +++ b/src/libs/FormulaDatetime.ts @@ -208,17 +208,17 @@ function applyTokenReplacement(format: string, tokens: Array<{token: string; val const {token, value} = tokenData; const placeholder = `###${i.toString().padStart(3, '0')}###`; - const regex = new RegExp(token.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'); + const regex = new RegExp(token.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'); if (result.includes(token)) { - result = result.replace(regex, placeholder); + result = result.replaceAll(regex, placeholder); placeholderMap[placeholder] = value; } } // Phase 2: Replace placeholders with actual values for (const [placeholder, value] of Object.entries(placeholderMap)) { - result = result.replace(new RegExp(placeholder.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), value); + result = result.replaceAll(new RegExp(placeholder.replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), value); } return result; diff --git a/src/libs/LocalePhoneNumber.ts b/src/libs/LocalePhoneNumber.ts index c7750e031f48..dcef75752bc5 100644 --- a/src/libs/LocalePhoneNumber.ts +++ b/src/libs/LocalePhoneNumber.ts @@ -20,7 +20,7 @@ function formatPhoneNumber(number: string): string { } // eslint-disable-next-line no-param-reassign - number = number.replace(/ /g, '\u00A0'); + number = number.replaceAll(' ', '\u00A0'); // do not parse the string, if it doesn't contain the SMS domain and it's not a phone number if (number.indexOf(CONST.SMS.DOMAIN) === -1 && !CONST.REGEX.DIGITS_AND_PLUS.test(number)) { @@ -57,7 +57,7 @@ function formatPhoneNumberWithCountryCode(number: string, countryCodeByIP: numbe } // eslint-disable-next-line no-param-reassign - number = number.replace(/ /g, '\u00A0'); + number = number.replaceAll(' ', '\u00A0'); // do not parse the string, if it doesn't contain the SMS domain and it's not a phone number if (number.indexOf(CONST.SMS.DOMAIN) === -1 && !CONST.REGEX.DIGITS_AND_PLUS.test(number)) { diff --git a/src/libs/LoginUtils.ts b/src/libs/LoginUtils.ts index b07d9ccdcc62..72f69fce4b5d 100644 --- a/src/libs/LoginUtils.ts +++ b/src/libs/LoginUtils.ts @@ -10,7 +10,7 @@ import {parsePhoneNumber} from './PhoneNumber'; * Remove the special chars from the phone number */ function getPhoneNumberWithoutSpecialChars(phone: string): string { - return phone.replace(CONST.REGEX.SPECIAL_CHARS_WITHOUT_NEWLINE, ''); + return phone.replaceAll(CONST.REGEX.SPECIAL_CHARS_WITHOUT_NEWLINE, ''); } /** diff --git a/src/libs/MarkdownLinkHelpers.ts b/src/libs/MarkdownLinkHelpers.ts index 20e20f1c27ce..2fe184fb341f 100644 --- a/src/libs/MarkdownLinkHelpers.ts +++ b/src/libs/MarkdownLinkHelpers.ts @@ -11,7 +11,7 @@ const isStandaloneURL = (text: string): boolean => { if (/\s/.test(trimmed)) { return false; } - const unwrapped = trimmed.replace(/^<|>$/g, ''); + const unwrapped = trimmed.replaceAll(/^<|>$/g, ''); // Reject if contains emoji or any non-ASCII characters // (valid URLs per RFC 3986 should be ASCII-only) @@ -32,10 +32,10 @@ const escapeLinkText = (text: string): string => { return ''; } const collapsed = text - .replace(/\r?\n+/g, ' ') - .replace(/\s+/g, ' ') + .replaceAll(/\r?\n+/g, ' ') + .replaceAll(/\s+/g, ' ') .trim(); - return collapsed.replace(/\[/g, '[').replace(/\]/g, ']'); + return collapsed.replaceAll('[', '[').replaceAll(']', ']'); }; /** @@ -49,7 +49,7 @@ const sanitizeUrlForMarkdown = (url: string): string => { } const trimmed = (url || '').trim(); - const unwrapped = trimmed.replace(/^<|>$/g, ''); + const unwrapped = trimmed.replaceAll(/^<|>$/g, ''); try { return encodeURI(unwrapped); diff --git a/src/libs/MoneyRequestUtils.ts b/src/libs/MoneyRequestUtils.ts index 16e04fd3d71e..ade3c386078d 100644 --- a/src/libs/MoneyRequestUtils.ts +++ b/src/libs/MoneyRequestUtils.ts @@ -4,25 +4,25 @@ import CONST from '@src/CONST'; * Strip comma from the amount */ function stripCommaFromAmount(amount: string): string { - return amount.replace(/,/g, ''); + return amount.replaceAll(',', ''); } /** * Strip spaces from the amount */ function stripSpacesFromAmount(amount: string): string { - return amount.replace(/\s+/g, ''); + return amount.replaceAll(/\s+/g, ''); } function replaceCommasWithPeriod(amount: string): string { - return amount.replace(/,+/g, '.'); + return amount.replaceAll(/,+/g, '.'); } /** * Strip decimals from the amount */ function stripDecimalsFromAmount(amount: string): string { - return amount.replace(/\.\d*$/, ''); + return amount.replaceAll(/\.\d*$/g, ''); } /** diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 1549486c1849..cb82ceea3da4 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -154,7 +154,7 @@ function getReportRHPActiveRoute(): string { * @returns The cleaned route path. */ function cleanRoutePath(routePath: string): string { - return routePath.replace(CONST.REGEX.ROUTES.REDUNDANT_SLASHES, (match, p1) => (p1 ? '/' : '')).replace(/\?.*/, ''); + return routePath.replaceAll(CONST.REGEX.ROUTES.REDUNDANT_SLASHES, (match, p1) => (p1 ? '/' : '')).replaceAll(/\?.*/g, ''); } /** @@ -436,7 +436,7 @@ function setParams(params: Record, routeKey = '') { * Returns the current active route without the URL params. */ function getActiveRouteWithoutParams(): string { - return getActiveRoute().replace(/\?.*/, ''); + return getActiveRoute().replaceAll(/\?.*/g, ''); } /** diff --git a/src/libs/Navigation/helpers/linkTo/index.ts b/src/libs/Navigation/helpers/linkTo/index.ts index 1649e9c7ab29..6f3142148ea7 100644 --- a/src/libs/Navigation/helpers/linkTo/index.ts +++ b/src/libs/Navigation/helpers/linkTo/index.ts @@ -37,8 +37,8 @@ function arePathAndBackToEqual(stateFromPath: PartialState { - return route?.replace(/\/edit\/export$/, '') as Routes; + return route?.replaceAll(/\/edit\/export$/g, '') as Routes; }; export default replaceCompanyCardsRoute; diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index 5fb699c463eb..f8bc458d0fb7 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -96,9 +96,9 @@ function parseMessage(messages: Message[] | undefined) { }); const formattedHtml = nextStepHTML - .replace(/%expenses/g, 'expenses') - .replace(/%Expenses/g, 'Expenses') - .replace(/%tobe/g, 'are'); + .replaceAll('%expenses', 'expenses') + .replaceAll('%Expenses', 'Expenses') + .replaceAll('%tobe', 'are'); return `${formattedHtml}`; } diff --git a/src/libs/OptionsListUtils/index.ts b/src/libs/OptionsListUtils/index.ts index c22c12fa3ffb..29fc1f6fd1c4 100644 --- a/src/libs/OptionsListUtils/index.ts +++ b/src/libs/OptionsListUtils/index.ts @@ -514,8 +514,8 @@ function getAlternateText( * Searches for a match when provided with a value */ function isSearchStringMatch(searchValue: string, searchText?: string | null, participantNames = new Set(), isReportChatRoom = false): boolean { - const searchWords = new Set(searchValue.replace(/,/g, ' ').split(/\s+/)); - const valueToSearch = searchText?.replace(new RegExp(/ /g), ''); + const searchWords = new Set(searchValue.replaceAll(',', ' ').split(/\s+/)); + const valueToSearch = searchText?.replaceAll(new RegExp(/ /g), ''); let matching = true; searchWords.forEach((word) => { // if one of the word is not matching, we don't need to check further @@ -2406,7 +2406,7 @@ function filterReports(reports: SearchOptionData[], searchTerms: string[]): Sear const values: string[] = []; if (item.text) { values.push(StringUtils.normalizeAccents(item.text)); - values.push(StringUtils.normalizeAccents(item.text).replace(/['-]/g, '')); + values.push(StringUtils.normalizeAccents(item.text).replaceAll(/['-]/g, '')); } if (item.login) { diff --git a/src/libs/ParsingUtils.ts b/src/libs/ParsingUtils.ts index 43644a75c05e..3591a74e8622 100644 --- a/src/libs/ParsingUtils.ts +++ b/src/libs/ParsingUtils.ts @@ -110,7 +110,7 @@ function getParsedMessageWithShortMentions({text, availableMentionLogins, userEm extras: parserOptions.extras, }); - const textWithHandledMentions = parsedText.replace(CONST.REGEX.SHORT_MENTION_HTML, (fullMatch, group1) => { + const textWithHandledMentions = parsedText.replaceAll(CONST.REGEX.SHORT_MENTION_HTML, (fullMatch, group1) => { // Casting here is safe since our logic guarantees that if regex matches we will get group1 as non-empty string const shortMention = group1 as string; if (!Str.isValidMention(shortMention)) { diff --git a/src/libs/Performance.tsx b/src/libs/Performance.tsx index 3e502006defe..8956e792bc60 100644 --- a/src/libs/Performance.tsx +++ b/src/libs/Performance.tsx @@ -109,7 +109,7 @@ const customMarksObserver = new PerformanceObserver((list) => { list.getEntriesByType('mark').forEach((mark) => { if (mark.name.endsWith('_end')) { const end = mark.name; - const name = end.replace(/_end$/, ''); + const name = end.replaceAll(/_end$/g, ''); const start = `${name}_start`; measureFailSafe(name, start, end); } diff --git a/src/libs/PersonalDetailsUtils.ts b/src/libs/PersonalDetailsUtils.ts index a74597f286fb..eee8c01b7efc 100644 --- a/src/libs/PersonalDetailsUtils.ts +++ b/src/libs/PersonalDetailsUtils.ts @@ -53,7 +53,7 @@ function getDisplayNameOrDefault( // If the displayName starts with the merged account prefix, remove it. if (regexMergedAccount.test(displayName)) { // Remove the merged account prefix from the displayName. - displayName = displayName.replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); + displayName = displayName.replaceAll(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); } // If the displayName is not set by the user, the backend sets the displayName same as the login so @@ -296,7 +296,7 @@ function getFormattedAddress(privatePersonalDetails: OnyxEntry m.concat(`${CONST.ATTACHMENT_ID_ATTRIBUTE}="${reportActionID}_${++attachmentID}" `)); + return html.replaceAll(/ m.concat(`${CONST.ATTACHMENT_ID_ATTRIBUTE}="${reportActionID}_${++attachmentID}" `)); } function getReportActionMessage(reportAction: PartialReportAction) { @@ -1982,7 +1982,7 @@ function getActionableMentionWhisperMessage(reportAction: OnyxEntry@${handleText}`; }); const preMentionsText = 'Heads up, '; - const mentions = mentionElements.join(', ').replace(/, ([^,]*)$/, ' and $1'); + const mentions = mentionElements.join(', ').replaceAll(/, ([^,]*)$/g, ' and $1'); const postMentionsText = ` ${mentionElements.length > 1 ? "aren't members" : "isn't a member"} of this room.`; return `${preMentionsText}${mentions}${postMentionsText}`; @@ -3013,7 +3013,7 @@ function getActionableCardFraudAlertMessage( const merchant = fraudMessage?.triggerMerchant ?? ''; const formattedAmount = convertToDisplayString(fraudMessage?.triggerAmount ?? 0, fraudMessage?.currency ?? CONST.CURRENCY.USD); const resolution = fraudMessage?.resolution; - const formattedDate = reportAction?.created ? format(getLocalDateFromDatetime(reportAction?.created), 'MMM. d - h:mma').replace(/am|pm/i, (match) => match.toUpperCase()) : ''; + const formattedDate = reportAction?.created ? format(getLocalDateFromDatetime(reportAction?.created), 'MMM. d - h:mma').replaceAll(/am|pm/gi, (match) => match.toUpperCase()) : ''; if (resolution === CONST.CARD_FRAUD_ALERT_RESOLUTION.RECOGNIZED) { // eslint-disable-next-line @typescript-eslint/no-deprecated diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index a6c1449c6b73..28ce889549bc 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -2900,7 +2900,7 @@ function canShowReportRecipientLocalTime(personalDetails: OnyxEntry { // Remove all chars not A-Z or 0-9 including underscore const alphaNumeric = workspaceName .normalize('NFD') - .replace(/[^0-9a-z]/gi, '') + .replaceAll(/[^0-9a-z]/gi, '') .toUpperCase(); const workspace = `Workspace${alphaNumeric[0]}` as keyof typeof defaultWorkspaceAvatars; @@ -2937,7 +2937,7 @@ function getDefaultWorkspaceAvatarTestID(workspaceName: string): string { // Remove all chars not A-Z or 0-9 including underscore const alphaNumeric = workspaceName .normalize('NFD') - .replace(/[^0-9a-z]/gi, '') + .replaceAll(/[^0-9a-z]/gi, '') .toLowerCase(); return !alphaNumeric ? defaultAvatarBuildingIconTestID : `SvgDefaultAvatar_${alphaNumeric[0]} Icon`; @@ -5692,7 +5692,7 @@ function getReportName( childReportID: report?.reportID, reports, personalDetails, - }).replace(/(\n+|\r\n|\n|\r)/gm, ' '); + }).replaceAll(/(\n+|\r\n|\n|\r)/gm, ' '); if (isAttachment && reportActionMessage) { // eslint-disable-next-line @typescript-eslint/no-deprecated return `[${translateLocal('common.attachment')}]`; @@ -9119,7 +9119,7 @@ function shouldShowFlagComment(reportAction: OnyxInputOrEntry, rep */ function getCommentLength(textComment: string, parsingDetails?: ParsingDetails): number { return getParsedComment(textComment, parsingDetails) - .replace(/[^ -~]/g, '\\u????') + .replaceAll(/[^ -~]/g, '\\u????') .trim().length; } @@ -9142,7 +9142,7 @@ function getRouteFromLink(url: string | null): string { // Remove the port if it's a localhost URL if (/^:\d+/.test(route)) { - route = route.replace(/:\d+/, ''); + route = route.replaceAll(/:\d+/g, ''); } // Remove the leading slash if exists diff --git a/src/libs/RoomNameInputUtils.ts b/src/libs/RoomNameInputUtils.ts index cff0bbc30274..c7d05a283f9b 100644 --- a/src/libs/RoomNameInputUtils.ts +++ b/src/libs/RoomNameInputUtils.ts @@ -5,10 +5,10 @@ import CONST from '@src/CONST'; */ function modifyRoomName(roomName: string): string { const modifiedRoomNameWithoutHash = roomName - .replace(/ /g, '-') + .replaceAll(' ', '-') // Replaces the smart dash on iOS devices with two hyphens - .replace(/—/g, '--'); + .replaceAll('—', '--'); return `${CONST.POLICY.ROOM_PREFIX}${modifiedRoomNameWithoutHash}`; } diff --git a/src/libs/SearchQueryUtils.ts b/src/libs/SearchQueryUtils.ts index 58f9f58ff516..ca14cf9cf829 100644 --- a/src/libs/SearchQueryUtils.ts +++ b/src/libs/SearchQueryUtils.ts @@ -1206,7 +1206,7 @@ function shouldHighlight(referenceText: string, searchText: string) { const escapedText = searchText .toLowerCase() .trim() - .replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); + .replaceAll(/[.*+?^${}()|[\]\\]/g, '\\$&'); const pattern = new RegExp(`(^|\\s)${escapedText}(?=\\s|$)`, 'i'); return pattern.test(referenceText.toLowerCase()); diff --git a/src/libs/SelectionScraper/index.ts b/src/libs/SelectionScraper/index.ts index a4954d6525ca..bdd754466b2e 100644 --- a/src/libs/SelectionScraper/index.ts +++ b/src/libs/SelectionScraper/index.ts @@ -160,7 +160,7 @@ const getCurrentSelection: GetCurrentSelection = () => { // Newline characters need to be removed here because the HTML could contain both newlines and
tags, and when //
tags are converted later to markdown, it creates duplicate newline characters. This means that when the content // is pasted, there are extra newlines in the content that we want to avoid. - const newHtml = render(domRepresentation).replace(/
\n/g, '
'); + const newHtml = render(domRepresentation).replaceAll('
\n', '
'); return newHtml || ''; }; diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 2ffe5bf060cd..b85eb9ccaa73 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -159,7 +159,7 @@ type MiniReport = { }; function ensureSingleSpacing(text: string) { - return text.replace(CONST.REGEX.WHITESPACE, ' ').trim(); + return text.replaceAll(CONST.REGEX.WHITESPACE, ' ').trim(); } function shouldDisplayReportInLHN( diff --git a/src/libs/StringUtils/decodeUnicode.ts b/src/libs/StringUtils/decodeUnicode.ts index 016f886afc58..fee1e7f08513 100644 --- a/src/libs/StringUtils/decodeUnicode.ts +++ b/src/libs/StringUtils/decodeUnicode.ts @@ -1,3 +1,3 @@ export default function decodeUnicode(str: string): string { - return str.replace(/\\u[\dA-Fa-f]{4}/g, (match) => String.fromCharCode(parseInt(match.slice(2), 16))); + return str.replaceAll(/\\u[\dA-Fa-f]{4}/g, (match) => String.fromCharCode(parseInt(match.slice(2), 16))); } diff --git a/src/libs/StringUtils/dedent.ts b/src/libs/StringUtils/dedent.ts index 11f793b8ee9b..515eddd23bce 100644 --- a/src/libs/StringUtils/dedent.ts +++ b/src/libs/StringUtils/dedent.ts @@ -36,10 +36,10 @@ */ export default function dedent(str: string): string { // Remove at most one leading newline - const stringWithoutLeadingNewlines = str.replace(/^\r?\n/, ''); + const stringWithoutLeadingNewlines = str.replaceAll(/^\r?\n/g, ''); // Split string by remaining newlines - const lines = stringWithoutLeadingNewlines.replace(/\r\n/g, '\n').split('\n'); + const lines = stringWithoutLeadingNewlines.replaceAll('\r\n', '\n').split('\n'); // Find the minimum indentation of non-empty lines let minIndent = Number.MAX_SAFE_INTEGER; diff --git a/src/libs/StringUtils/index.ts b/src/libs/StringUtils/index.ts index 85cf14f313a7..c79a8b765f1e 100644 --- a/src/libs/StringUtils/index.ts +++ b/src/libs/StringUtils/index.ts @@ -22,17 +22,17 @@ function isEmptyString(value: string): boolean { // so we should not remove it. // Temporarily replace \uE100 with a placeholder const PLACEHOLDER = '<>'; - let transformed = value.replace(/\uE100/g, PLACEHOLDER); + let transformed = value.replaceAll('\uE100', PLACEHOLDER); // \p{C} matches all 'Other' characters // \p{Z} matches all separators (spaces etc.) // Source: http://www.unicode.org/reports/tr18/#General_Category_Property - transformed = transformed.replace(CONST.REGEX.INVISIBLE_CHARACTERS_GROUPS, ''); + transformed = transformed.replaceAll(CONST.REGEX.INVISIBLE_CHARACTERS_GROUPS, ''); // Remove other invisible characters that are not in the above unicode categories - transformed = transformed.replace(CONST.REGEX.OTHER_INVISIBLE_CHARACTERS, ''); + transformed = transformed.replaceAll(CONST.REGEX.OTHER_INVISIBLE_CHARACTERS, ''); - transformed = transformed.replace(new RegExp(PLACEHOLDER, 'g'), '\uE100'); + transformed = transformed.replaceAll(new RegExp(PLACEHOLDER, 'g'), '\uE100'); // Check if after removing invisible characters the string is empty return transformed === ''; @@ -48,12 +48,12 @@ function removeInvisibleCharacters(value: string): string { // so we should not remove it. // Temporarily replace \uE100 with a placeholder const PLACEHOLDER = '<>'; - result = result.replace(/\uE100/g, PLACEHOLDER); + result = result.replaceAll('\uE100', PLACEHOLDER); // Remove spaces: // - \u200B: zero-width space // - \u2060: word joiner - result = result.replace(/[\u200B\u2060]/g, ''); + result = result.replaceAll(/[\u200B\u2060]/g, ''); const invisibleCharacterRegex = isSafari() ? /([\uD800-\uDBFF][\uDC00-\uDFFF])|[\p{Cc}\p{Co}\p{Cn}]/gu : /[\p{Cc}\p{Cs}\p{Co}\p{Cn}]/gu; @@ -69,13 +69,13 @@ function removeInvisibleCharacters(value: string): string { .join('\n'); // Remove characters from the (Cf) category that are not used for emojis - result = result.replace(/[\u200E-\u200F]/g, ''); + result = result.replaceAll(/[\u200E-\u200F]/g, ''); // Remove all characters from the 'Separator' (Z) category except for Space Separator (Zs) - result = result.replace(/[\p{Zl}\p{Zp}]/gu, ''); + result = result.replaceAll(/[\p{Zl}\p{Zp}]/gu, ''); // Restore \uE100 from placeholder - result = result.replace(new RegExp(PLACEHOLDER, 'g'), '\uE100'); + result = result.replaceAll(new RegExp(PLACEHOLDER, 'g'), '\uE100'); // If the result consist of only invisible characters, return an empty string if (isEmptyString(result)) { @@ -91,7 +91,7 @@ function removeInvisibleCharacters(value: string): string { * @returns The string with all accents/diacritics removed */ function normalizeAccents(text: string) { - return text.normalize('NFD').replace(/[\u0300-\u036f]/g, ''); + return text.normalize('NFD').replaceAll(/[\u0300-\u036f]/g, ''); } /** @@ -105,8 +105,8 @@ function normalizeAccents(text: string) { */ function normalize(text: string): string { return removeInvisibleCharacters(text) - .replace(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, ' ') // space-like -> ' ' - .replace(/\s+/g, ' ') // collapse spaces + .replaceAll(/[\u00A0\u1680\u2000-\u200A\u202F\u205F\u3000]/g, ' ') // space-like -> ' ' + .replaceAll(/\s+/g, ' ') // collapse spaces .trim(); } @@ -116,14 +116,14 @@ function normalize(text: string): string { * @returns The string with all CRLF replaced with LF */ function normalizeCRLF(value?: string): string | undefined { - return value?.replace(/\r\n/g, '\n'); + return value?.replaceAll('\r\n', '\n'); } /** * Replace all line breaks with white spaces */ function lineBreaksToSpaces(text = '', useNonBreakingSpace = false) { - return text.replace(CONST.REGEX.LINE_BREAK, useNonBreakingSpace ? '\u00A0' : ' '); + return text.replaceAll(CONST.REGEX.LINE_BREAK, useNonBreakingSpace ? '\u00A0' : ' '); } /** @@ -139,7 +139,7 @@ function getFirstLine(text = '') { * Remove double quotes from the string */ function removeDoubleQuotes(text = '') { - return text.replace(/"/g, ''); + return text.replaceAll('"', ''); } /** @@ -154,7 +154,7 @@ function sortStringArrayByLength(arr: string[]): string[] { * Remove pre tag from the html */ function removePreCodeBlock(text = '') { - return text.replace(/]*>|<\/pre>/g, ''); + return text.replaceAll(/]*>|<\/pre>/g, ''); } /** diff --git a/src/libs/TransactionUtils/index.ts b/src/libs/TransactionUtils/index.ts index 051d8ad68830..07c82ce1b392 100644 --- a/src/libs/TransactionUtils/index.ts +++ b/src/libs/TransactionUtils/index.ts @@ -962,16 +962,16 @@ function getTagArrayFromName(tagName: string): string[] { // and not have it interfere with splitting on a colon (:). // So, let's replace it with something absurd to begin with, do our split, and // then replace the double backslashes in the end. - const tagWithoutDoubleSlashes = tagName.replace(/\\\\/g, '☠'); - const tagWithoutEscapedColons = tagWithoutDoubleSlashes.replace(/\\:/g, '☢'); + const tagWithoutDoubleSlashes = tagName.replaceAll('\\\\', '☠'); + const tagWithoutEscapedColons = tagWithoutDoubleSlashes.replaceAll('\\:', '☢'); // Do our split const matches = tagWithoutEscapedColons.split(':'); const newMatches: string[] = []; for (const item of matches) { - const tagWithEscapedColons = item.replace(/☢/g, '\\:'); - const tagWithDoubleSlashes = tagWithEscapedColons.replace(/☠/g, '\\\\'); + const tagWithEscapedColons = item.replaceAll('☢', '\\:'); + const tagWithDoubleSlashes = tagWithEscapedColons.replaceAll('☠', '\\\\'); newMatches.push(tagWithDoubleSlashes); } diff --git a/src/libs/Url.ts b/src/libs/Url.ts index 9a416ff35c78..1750eabaa998 100644 --- a/src/libs/Url.ts +++ b/src/libs/Url.ts @@ -27,7 +27,7 @@ function getPathFromURL(url: string): string { * Determine if two urls have the same origin */ function hasSameExpensifyOrigin(url1: string, url2: string): boolean { - const removeW3 = (host: string) => host.replace(/^www\./i, ''); + const removeW3 = (host: string) => host.replaceAll(/^www\./gi, ''); try { const parsedUrl1 = new URL(url1); const parsedUrl2 = new URL(url2); diff --git a/src/libs/WorkspaceReportFieldUtils.ts b/src/libs/WorkspaceReportFieldUtils.ts index f0e262758acb..866260877bdd 100644 --- a/src/libs/WorkspaceReportFieldUtils.ts +++ b/src/libs/WorkspaceReportFieldUtils.ts @@ -66,7 +66,7 @@ function validateReportFieldListValueName( * Generates a field ID based on the field name. */ function generateFieldID(name: string) { - return `field_id_${name.replace(CONST.REGEX.ANY_SPACE, '_').toUpperCase()}`; + return `field_id_${name.replaceAll(CONST.REGEX.ANY_SPACE, '_').toUpperCase()}`; } /** diff --git a/src/libs/actions/StatsCounter.ts b/src/libs/actions/StatsCounter.ts index 351582068e46..8cc50b4219e9 100644 --- a/src/libs/actions/StatsCounter.ts +++ b/src/libs/actions/StatsCounter.ts @@ -9,7 +9,7 @@ import pkg from '../../../package.json'; const StatsCounter = (eventName: string, value = 1) => { getEnvironment().then((envName) => { const platform = getPlatform(); - const version = pkg.version.replace(/\./g, '-'); + const version = pkg.version.replaceAll('.', '-'); // This normalizes the name of the web platform so it will be more consistent in Grafana const grafanaEventName = `${platform === 'web' ? 'webApp' : platform}.${envName}.new.expensify.${eventName}.${version}`; diff --git a/src/libs/fileDownload/FileUtils.ts b/src/libs/fileDownload/FileUtils.ts index 49fa01c7b4ad..da6fe4a378c2 100644 --- a/src/libs/fileDownload/FileUtils.ts +++ b/src/libs/fileDownload/FileUtils.ts @@ -109,7 +109,7 @@ function getFileName(url: string): string { Log.warn('[FileUtils] Could not get attachment name', {url}); } - return decodeURIComponent(fileName).replace(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_'); + return decodeURIComponent(fileName).replaceAll(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_'); } function isImage(fileName: string): boolean { @@ -157,14 +157,14 @@ const splitExtensionFromFileName: SplitExtensionFromFileName = (fullFileName) => * Returns the filename replacing special characters with underscore */ function cleanFileName(fileName: string): string { - return fileName.replace(/[^a-zA-Z0-9\-._]/g, '_'); + return fileName.replaceAll(/[^a-zA-Z0-9\-._]/g, '_'); } function appendTimeToFileName(fileName: string): string { const file = splitExtensionFromFileName(fileName); let newFileName = `${file.fileName}-${DateUtils.getDBTime()}`; // Replace illegal characters before trying to download the attachment. - newFileName = newFileName.replace(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_'); + newFileName = newFileName.replaceAll(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_'); if (file.fileExtension) { newFileName += `.${file.fileExtension}`; } @@ -698,7 +698,7 @@ const canvasFallback = (blob: Blob, fileName: string): Promise => { return; } - const jpegFileName = fileName.replace(/\.(heic|heif)$/i, '.jpg'); + const jpegFileName = fileName.replaceAll(/\.(heic|heif)$/gi, '.jpg'); const jpegFile = Object.assign(new File([convertedBlob], jpegFileName, {type: CONST.IMAGE_FILE_FORMAT.JPEG}), {uri: URL.createObjectURL(convertedBlob)}); resolve(jpegFile); }, diff --git a/src/libs/fileDownload/heicConverter/index.ts b/src/libs/fileDownload/heicConverter/index.ts index 9e388cec89da..174e260b4183 100644 --- a/src/libs/fileDownload/heicConverter/index.ts +++ b/src/libs/fileDownload/heicConverter/index.ts @@ -54,7 +54,7 @@ const convertHeicImage: HeicConverterFunction = (file, {onSuccess = () => {}, on return heicConverter .heicTo({blob, type: CONST.IMAGE_FILE_FORMAT.JPEG}) .then((convertedBlob) => { - const jpegFile = Object.assign(new File([convertedBlob], fileName.replace(/\.(heic|heif)$/i, '.jpg'), {type: CONST.IMAGE_FILE_FORMAT.JPEG}), { + const jpegFile = Object.assign(new File([convertedBlob], fileName.replaceAll(/\.(heic|heif)$/gi, '.jpg'), {type: CONST.IMAGE_FILE_FORMAT.JPEG}), { uri: URL.createObjectURL(convertedBlob), }); onSuccess(jpegFile as FileObject); diff --git a/src/libs/getFirstAlphaNumericCharacter.ts b/src/libs/getFirstAlphaNumericCharacter.ts index d2db2706d946..734ab1129a8d 100644 --- a/src/libs/getFirstAlphaNumericCharacter.ts +++ b/src/libs/getFirstAlphaNumericCharacter.ts @@ -2,7 +2,7 @@ function getFirstAlphaNumericCharacter(str = '') { return ( str .normalize('NFD') - .replace(/[^0-9a-z]/gi, '') + .replaceAll(/[^0-9a-z]/gi, '') .toUpperCase()[0] ?? '' ); } diff --git a/src/libs/isPublicScreenRoute.ts b/src/libs/isPublicScreenRoute.ts index e2c5ca5944eb..b55009232ef6 100644 --- a/src/libs/isPublicScreenRoute.ts +++ b/src/libs/isPublicScreenRoute.ts @@ -2,7 +2,7 @@ import {PUBLIC_SCREENS_ROUTES} from '@src/ROUTES'; export default function isPublicScreenRoute(route: string) { return Object.values(PUBLIC_SCREENS_ROUTES).some((screenRoute) => { - const routeRegex = new RegExp(`^${screenRoute.replace(/:\w+/g, '\\w+')}$`); + const routeRegex = new RegExp(`^${screenRoute.replaceAll(/:\w+/g, '\\w+')}$`); return routeRegex.test(route); }); } diff --git a/src/pages/Debug/Report/DebugReportActions.tsx b/src/pages/Debug/Report/DebugReportActions.tsx index c548842227a4..18704507df60 100644 --- a/src/pages/Debug/Report/DebugReportActions.tsx +++ b/src/pages/Debug/Report/DebugReportActions.tsx @@ -82,7 +82,7 @@ function DebugReportActions({reportID}: DebugReportActionsProps) { } if (reportActionMessage.html) { - return Parser.htmlToText(reportActionMessage.html.replace(/\s*<\/mention-user>/gi, '')); + return Parser.htmlToText(reportActionMessage.html.replaceAll(/\s*<\/mention-user>/gi, '')); } return getReportActionMessageText(reportAction); diff --git a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx index 37fa88397e05..beef1117cb7d 100644 --- a/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx +++ b/src/pages/OnboardingPersonalDetails/BaseOnboardingPersonalDetails.tsx @@ -131,7 +131,7 @@ function BaseOnboardingPersonalDetails({currentUserPersonalDetails, shouldUseNat const errors = {}; // First we validate the first name field - if (values.firstName.replace(CONST.REGEX.ANY_SPACE, '').length === 0) { + if (values.firstName.replaceAll(CONST.REGEX.ANY_SPACE, '').length === 0) { addErrorMessage(errors, 'firstName', translate('onboarding.error.requiredFirstName')); } if (!isValidDisplayName(values.firstName)) { diff --git a/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx b/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx index c5a9730e14d2..d875cc51539d 100644 --- a/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx +++ b/src/pages/ReimbursementAccount/USD/BusinessInfo/BusinessInfo.tsx @@ -69,7 +69,7 @@ function BusinessInfo({onBackButtonPress}: BusinessInfoProps) { { ...values, ...getBankAccountFields(['routingNumber', 'accountNumber', 'bankName', 'plaidAccountID', 'plaidAccessToken', 'isSavings']), - companyTaxID: values.companyTaxID?.replace(CONST.REGEX.NON_NUMERIC, ''), + companyTaxID: values.companyTaxID?.replaceAll(CONST.REGEX.NON_NUMERIC, ''), companyPhone: parsePhoneNumber(values.companyPhone ?? '', {regionCode: CONST.COUNTRY.US}).number?.significant, website: isValidWebsite(companyWebsite) ? companyWebsite : undefined, }, diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 9c82262e6aba..2d12dad87e04 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -727,7 +727,7 @@ const ContextMenuActions: ContextMenuAction[] = [ Clipboard.setString(displayMessage); } else if (content) { setClipboardMessage( - content.replace(/()(.*?)(<\/mention-user>)/gi, (match, openTag: string, innerContent: string, closeTag: string): string => { + content.replaceAll(/()(.*?)(<\/mention-user>)/gi, (match, openTag: string, innerContent: string, closeTag: string): string => { const modifiedContent = Str.removeSMSDomain(innerContent) || ''; return openTag + modifiedContent + closeTag || ''; }), diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index aaaf759eaf50..7bee17fcee3f 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -430,7 +430,7 @@ function ReportActionCompose({ (value: string) => { const taskCommentMatch = value?.match(CONST.REGEX.TASK_TITLE_WITH_OPTIONAL_SHORT_MENTION); if (taskCommentMatch) { - const title = taskCommentMatch?.[3] ? taskCommentMatch[3].trim().replace(/\n/g, ' ') : ''; + const title = taskCommentMatch?.[3] ? taskCommentMatch[3].trim().replaceAll('\n', ' ') : ''; setHasExceededMaxCommentLength(false); validateTaskTitleMaxLength(title); } else { diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 6ffe045a57ca..51778e15f71d 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -128,7 +128,7 @@ function ReportFooter({ if (!match) { return false; } - let title = match[3] ? match[3].trim().replace(/\n/g, ' ') : undefined; + let title = match[3] ? match[3].trim().replaceAll('\n', ' ') : undefined; if (!title) { return false; } diff --git a/src/pages/home/report/comment/TextCommentFragment.tsx b/src/pages/home/report/comment/TextCommentFragment.tsx index c27ac40c1260..6408f0f4443d 100644 --- a/src/pages/home/report/comment/TextCommentFragment.tsx +++ b/src/pages/home/report/comment/TextCommentFragment.tsx @@ -77,7 +77,7 @@ function TextCommentFragment({fragment, styleAsDeleted, reportActionID, styleAsM if (!shouldRenderAsText(html, text ?? '') && !(containsOnlyEmojis && styleAsDeleted) && (containsOnlyEmojis || !containsCustomEmoji(text))) { const editedTag = fragment?.isEdited ? `` : ''; // We need to replace the space at the beginning of each line with   - const escapedHtml = html.replace(/(^|
)[ ]+/gm, (match: string, p1: string) => p1 + ' '.repeat(match.length - p1.length)); + const escapedHtml = html.replaceAll(/(^|
)[ ]+/gm, (match: string, p1: string) => p1 + ' '.repeat(match.length - p1.length)); const htmlWithDeletedTag = styleAsDeleted ? `${escapedHtml}` : escapedHtml; let htmlContent = htmlWithDeletedTag; diff --git a/src/pages/iou/request/step/IOURequestStepSubrate.tsx b/src/pages/iou/request/step/IOURequestStepSubrate.tsx index dbddcb36cc43..9aa1da1dc9f7 100644 --- a/src/pages/iou/request/step/IOURequestStepSubrate.tsx +++ b/src/pages/iou/request/step/IOURequestStepSubrate.tsx @@ -88,7 +88,7 @@ function IOURequestStepSubrate({ const onChangeQuantity = useCallback((newValue: string) => { // replace all characters that are not spaces or digits - let validQuantity = newValue.replace(/[^0-9]/g, ''); + let validQuantity = newValue.replaceAll(/[^0-9]/g, ''); validQuantity = validQuantity.match(/(?:\d *){1,12}/)?.[0] ?? ''; setQuantityValue(validQuantity); }, []); diff --git a/src/pages/settings/Profile/Contacts/utils.ts b/src/pages/settings/Profile/Contacts/utils.ts index 978ff888e1c0..ee53e1a337f3 100644 --- a/src/pages/settings/Profile/Contacts/utils.ts +++ b/src/pages/settings/Profile/Contacts/utils.ts @@ -9,14 +9,14 @@ function getDecodedContactMethodFromUriParam(contactMethodParam: string) { const lastPercentIndex = contactMethodParam.lastIndexOf('%'); const encodePercents = contactMethodParam.substring(lastPercentIndex).match(/25/g); let numberEncodePercents = encodePercents?.length ?? 0; - const beforeAtSign = contactMethodParam.substring(0, lastPercentIndex).replace(CONST.REGEX.ENCODE_PERCENT_CHARACTER, (match) => { + const beforeAtSign = contactMethodParam.substring(0, lastPercentIndex).replaceAll(CONST.REGEX.ENCODE_PERCENT_CHARACTER, (match) => { if (numberEncodePercents > 0) { numberEncodePercents--; return '%'; } return match; }); - const afterAtSign = contactMethodParam.substring(lastPercentIndex).replace(CONST.REGEX.ENCODE_PERCENT_CHARACTER, '%'); + const afterAtSign = contactMethodParam.substring(lastPercentIndex).replaceAll(CONST.REGEX.ENCODE_PERCENT_CHARACTER, '%'); return addSMSDomainIfPhoneNumber(decodeURIComponent(beforeAtSign + afterAtSign)); } diff --git a/src/pages/settings/Profile/TimezoneSelectPage.tsx b/src/pages/settings/Profile/TimezoneSelectPage.tsx index e7e13c7f9a09..e4b3087ffb60 100644 --- a/src/pages/settings/Profile/TimezoneSelectPage.tsx +++ b/src/pages/settings/Profile/TimezoneSelectPage.tsx @@ -50,7 +50,7 @@ function TimezoneSelectPage({currentUserPersonalDetails}: TimezoneSelectPageProp searchWords.every((word) => tz.text .toLowerCase() - .replace(/[^a-z0-9]/g, ' ') + .replaceAll(/[^a-z0-9]/g, ' ') .includes(word), ), ), diff --git a/src/pages/settings/Security/CloseAccountPage.tsx b/src/pages/settings/Security/CloseAccountPage.tsx index cb720c1c65be..00c7abbedd5d 100644 --- a/src/pages/settings/Security/CloseAccountPage.tsx +++ b/src/pages/settings/Security/CloseAccountPage.tsx @@ -62,7 +62,7 @@ function CloseAccountPage() { * @param phoneOrEmail - The input string to be sanitized. * @returns The sanitized string */ - const sanitizePhoneOrEmail = (phoneOrEmail: string): string => phoneOrEmail.replace(/\s+/g, '').toLowerCase(); + const sanitizePhoneOrEmail = (phoneOrEmail: string): string => phoneOrEmail.replaceAll(/\s+/g, '').toLowerCase(); const validate = (values: FormOnyxValues): FormInputErrors => { const errors = getFieldRequiredErrors(values, ['phoneOrEmail']); diff --git a/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx b/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx index 219866a61614..e7bbd960c9de 100644 --- a/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx +++ b/src/pages/workspace/duplicate/WorkspaceDuplicateSelectFeaturesForm.tsx @@ -184,7 +184,7 @@ function WorkspaceDuplicateSelectFeaturesForm({policyID}: WorkspaceDuplicateForm const listData: ListItem[] = useMemo(() => { return items.map((option) => { - const alternateText = option?.alternateText ? option.alternateText.trim().replace(/,$/, '') : undefined; + const alternateText = option?.alternateText ? option.alternateText.trim().replaceAll(/,$/g, '') : undefined; return { text: option.translation, keyForList: option.value, diff --git a/src/pages/workspace/rules/RulesMaxExpenseAgePage.tsx b/src/pages/workspace/rules/RulesMaxExpenseAgePage.tsx index b9645a8f152e..fc5d0402dc0d 100644 --- a/src/pages/workspace/rules/RulesMaxExpenseAgePage.tsx +++ b/src/pages/workspace/rules/RulesMaxExpenseAgePage.tsx @@ -39,7 +39,7 @@ function RulesMaxExpenseAgePage({ const onChangeMaxExpenseAge = useCallback((newValue: string) => { // replace all characters that are not spaces or digits - let validMaxExpenseAge = newValue.replace(/[^0-9]/g, ''); + let validMaxExpenseAge = newValue.replaceAll(/[^0-9]/g, ''); validMaxExpenseAge = validMaxExpenseAge.match(/(?:\d *){1,5}/)?.[0] ?? ''; setMaxExpenseAgeValue(validMaxExpenseAge); }, []); diff --git a/tests/e2e/compare/output/markdownTable.ts b/tests/e2e/compare/output/markdownTable.ts index 4daea0bbdd63..5fe976159202 100644 --- a/tests/e2e/compare/output/markdownTable.ts +++ b/tests/e2e/compare/output/markdownTable.ts @@ -347,7 +347,7 @@ function markdownTable(table: Array>, options: } } - lines.push(options.delimiterEnd === false ? line.join('').replace(/ +$/, '') : line.join('')); + lines.push(options.delimiterEnd === false ? line.join('').replaceAll(/ +$/g, '') : line.join('')); } return lines.join('\n'); diff --git a/tests/e2e/utils/logger.ts b/tests/e2e/utils/logger.ts index ebe8fc05e66a..02b91ef33b3f 100644 --- a/tests/e2e/utils/logger.ts +++ b/tests/e2e/utils/logger.ts @@ -28,7 +28,7 @@ const writeToLogFile = (...args: string[]) => { if (typeof arg === 'string') { // Remove color codes from arg, because they are not supported in log files // eslint-disable-next-line no-control-regex - return arg.replace(/\x1b\[\d+m/g, ''); + return arg.replaceAll(/\x1b\[\d+m/g, ''); } return arg; }) diff --git a/tests/ui/WorkspaceUpgradeTest.tsx b/tests/ui/WorkspaceUpgradeTest.tsx index 95df4ae663c2..6dce53e9f63e 100644 --- a/tests/ui/WorkspaceUpgradeTest.tsx +++ b/tests/ui/WorkspaceUpgradeTest.tsx @@ -26,7 +26,7 @@ jest.mock('@components/RenderHTML', () => { const {Text} = require('react-native') as {Text: React.ComponentType<{children?: React.ReactNode}>}; return ({html}: {html: string}) => { - const plainText = html.replace(/<[^>]*>/g, ''); + const plainText = html.replaceAll(/<[^>]*>/g, ''); return ReactMock.createElement(Text, null, plainText); }; }); diff --git a/tests/unit/CloseAccountPageTest.ts b/tests/unit/CloseAccountPageTest.ts index f07260ca4952..025fc73b6ec6 100644 --- a/tests/unit/CloseAccountPageTest.ts +++ b/tests/unit/CloseAccountPageTest.ts @@ -2,7 +2,7 @@ import {Str} from 'expensify-common'; import {formatE164PhoneNumber, getPhoneNumberWithoutSpecialChars} from '@libs/LoginUtils'; import CONST from '@src/CONST'; -const sanitizePhoneOrEmail = (value: string) => value.replace(/\s/g, '').toLowerCase(); +const sanitizePhoneOrEmail = (value: string) => value.replaceAll(/\s/g, '').toLowerCase(); const validatePhoneOrEmail = (inputValue: string, storedValue: string, translate: (key: string) => string, countryCode?: number) => { const errors: {phoneOrEmail?: string} = {}; diff --git a/tests/unit/FileUtilsTest.ts b/tests/unit/FileUtilsTest.ts index 6bd4be939789..8371acdcb32a 100644 --- a/tests/unit/FileUtilsTest.ts +++ b/tests/unit/FileUtilsTest.ts @@ -34,13 +34,13 @@ describe('FileUtils', () => { it('should append current time to the end of the file name', () => { const actualFileName = FileUtils.appendTimeToFileName('image.jpg'); const expectedFileName = `image-${DateUtils.getDBTime()}.jpg`; - expect(actualFileName).toEqual(expectedFileName.replace(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_')); + expect(actualFileName).toEqual(expectedFileName.replaceAll(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_')); }); it('should append current time to the end of the file name without extension', () => { const actualFileName = FileUtils.appendTimeToFileName('image'); const expectedFileName = `image-${DateUtils.getDBTime()}`; - expect(actualFileName).toEqual(expectedFileName.replace(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_')); + expect(actualFileName).toEqual(expectedFileName.replaceAll(CONST.REGEX.ILLEGAL_FILENAME_CHARACTERS, '_')); }); }); diff --git a/tests/unit/GithubUtilsTest.ts b/tests/unit/GithubUtilsTest.ts index c5af6081bf1b..f0f40549484e 100644 --- a/tests/unit/GithubUtilsTest.ts +++ b/tests/unit/GithubUtilsTest.ts @@ -183,7 +183,7 @@ describe('GithubUtils', () => { test('Test finding an open issue successfully and parsing with blockers w/o carriage returns', () => { const modifiedIssueWithDeployBlockers = {...issueWithDeployBlockers}; - modifiedIssueWithDeployBlockers.body = modifiedIssueWithDeployBlockers.body.replace(/\r/g, ''); + modifiedIssueWithDeployBlockers.body = modifiedIssueWithDeployBlockers.body.replaceAll('\r', ''); GithubUtils.octokit.issues.listForRepo = jest.fn().mockResolvedValue({ data: [modifiedIssueWithDeployBlockers], diff --git a/tests/unit/ReceiptAlternativeMethodsTest.tsx b/tests/unit/ReceiptAlternativeMethodsTest.tsx index f6ef26d24876..7972a02b3e4c 100644 --- a/tests/unit/ReceiptAlternativeMethodsTest.tsx +++ b/tests/unit/ReceiptAlternativeMethodsTest.tsx @@ -12,7 +12,7 @@ jest.mock('@components/RenderHTML', () => { const {Text} = require('react-native') as {Text: React.ComponentType<{children?: React.ReactNode}>}; return ({html}: {html: string}) => { - const plainText = html.replace(/<[^>]*>/g, ''); + const plainText = html.replaceAll(/<[^>]*>/g, ''); return ReactMock.createElement(Text, null, plainText); }; }); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 69f6b1916b06..7e48be731c29 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -2026,13 +2026,13 @@ describe('ReportUtils', () => { it('should return the correct parent navigation subtitle for the archived invoice report', () => { const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, true); - const normalizedActual = {...actual, reportName: actual.reportName?.replace(/\u00A0/g, ' ')}; + const normalizedActual = {...actual, reportName: actual.reportName?.replaceAll('\u00A0', ' ')}; expect(normalizedActual).toEqual({reportName: 'A workspace & Ragnar Lothbrok (archived)'}); }); it('should return the correct parent navigation subtitle for the non archived invoice report', () => { const actual = getParentNavigationSubtitle(baseArchivedPolicyExpenseChat, false); - const normalizedActual = {...actual, reportName: actual.reportName?.replace(/\u00A0/g, ' ')}; + const normalizedActual = {...actual, reportName: actual.reportName?.replaceAll('\u00A0', ' ')}; expect(normalizedActual).toEqual({reportName: 'A workspace & Ragnar Lothbrok'}); }); }); From c8b599b3220e4edda1fd991bfda01c725fa1475c Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Thu, 30 Oct 2025 14:18:07 +0700 Subject: [PATCH 2/9] fix: use .replaceAll instead .replace --- .github/actions/javascript/authorChecklist/index.js | 2 +- .github/actions/javascript/awaitStagingDeploys/index.js | 2 +- .github/actions/javascript/checkAndroidStatus/index.js | 2 +- .github/actions/javascript/checkDeployBlockers/index.js | 2 +- .github/actions/javascript/checkSVGCompression/index.js | 2 +- .../actions/javascript/createOrUpdateStagingDeploy/index.js | 2 +- .../generateHelpPreviewComment/generateHelpPreviewComment.ts | 4 ++-- .github/actions/javascript/getArtifactInfo/index.js | 2 +- .github/actions/javascript/getDeployPullRequestList/index.js | 2 +- .github/actions/javascript/getPreviousVersion/index.js | 2 +- .github/actions/javascript/getPullRequestDetails/index.js | 2 +- .../javascript/getPullRequestIncrementalChanges/index.js | 2 +- .github/actions/javascript/isStagingDeployLocked/index.js | 2 +- .../actions/javascript/markPullRequestsAsDeployed/index.js | 2 +- .github/actions/javascript/postTestBuildComment/index.js | 2 +- .github/actions/javascript/proposalPoliceComment/index.js | 4 ++-- .github/actions/javascript/reopenIssueWithComment/index.js | 2 +- .github/actions/javascript/reviewerChecklist/index.js | 4 ++-- .github/actions/javascript/verifySignedCommits/index.js | 2 +- src/libs/SearchParser/searchParser.js | 4 ++-- src/libs/SearchParser/searchParser.peggy | 4 ++-- 21 files changed, 26 insertions(+), 26 deletions(-) diff --git a/.github/actions/javascript/authorChecklist/index.js b/.github/actions/javascript/authorChecklist/index.js index 4dd1a907257d..a3abd790b7c4 100644 --- a/.github/actions/javascript/authorChecklist/index.js +++ b/.github/actions/javascript/authorChecklist/index.js @@ -15766,7 +15766,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/awaitStagingDeploys/index.js b/.github/actions/javascript/awaitStagingDeploys/index.js index 8c07232d29de..b04f350fde15 100644 --- a/.github/actions/javascript/awaitStagingDeploys/index.js +++ b/.github/actions/javascript/awaitStagingDeploys/index.js @@ -12570,7 +12570,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/checkAndroidStatus/index.js b/.github/actions/javascript/checkAndroidStatus/index.js index 2f347064b8bc..6a3857a921bc 100644 --- a/.github/actions/javascript/checkAndroidStatus/index.js +++ b/.github/actions/javascript/checkAndroidStatus/index.js @@ -737313,7 +737313,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/checkDeployBlockers/index.js b/.github/actions/javascript/checkDeployBlockers/index.js index 33e12d3a2bb5..7f42ac04f069 100644 --- a/.github/actions/javascript/checkDeployBlockers/index.js +++ b/.github/actions/javascript/checkDeployBlockers/index.js @@ -11837,7 +11837,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/checkSVGCompression/index.js b/.github/actions/javascript/checkSVGCompression/index.js index 1a8494265e3b..8f5ca274c9bb 100644 --- a/.github/actions/javascript/checkSVGCompression/index.js +++ b/.github/actions/javascript/checkSVGCompression/index.js @@ -20362,7 +20362,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js index 98f1ecea463d..f079ec335eed 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js @@ -12124,7 +12124,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts b/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts index cbb119fa19a4..93691432b03f 100644 --- a/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts +++ b/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts @@ -12,7 +12,7 @@ function normalizeAlias(alias: string): string { } function toRoutePath(filename: string): string { - return filename.slice(DOCS_DIRECTORY_PREFIX.length).replace(/\.md$/, ''); + return filename.slice(DOCS_DIRECTORY_PREFIX.length).replaceAll(/\.md$/, ''); } async function getUpdatedDocRoutes(octokit: OctokitClient, owner: string, repo: string, prNumber: number): Promise { @@ -61,7 +61,7 @@ async function run(): Promise { const routes = await getUpdatedDocRoutes(octokit, owner, repo, prNumber); const normalizedRootURL = normalizeAlias(rootURL); - const displayRootURL = normalizedRootURL.replace(/\/$/, ''); + const displayRootURL = normalizedRootURL.replaceAll(/\/$/, ''); let body = `A preview of your ExpensifyHelp changes have been deployed to ${displayRootURL} ⚡️`; if (routes.length > 0) { diff --git a/.github/actions/javascript/getArtifactInfo/index.js b/.github/actions/javascript/getArtifactInfo/index.js index 9774ff366926..37fc042656db 100644 --- a/.github/actions/javascript/getArtifactInfo/index.js +++ b/.github/actions/javascript/getArtifactInfo/index.js @@ -11798,7 +11798,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/getDeployPullRequestList/index.js b/.github/actions/javascript/getDeployPullRequestList/index.js index ea09737a3963..36955f98039d 100644 --- a/.github/actions/javascript/getDeployPullRequestList/index.js +++ b/.github/actions/javascript/getDeployPullRequestList/index.js @@ -12143,7 +12143,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/getPreviousVersion/index.js b/.github/actions/javascript/getPreviousVersion/index.js index 3d7d341a8ddb..d21c730cae36 100644 --- a/.github/actions/javascript/getPreviousVersion/index.js +++ b/.github/actions/javascript/getPreviousVersion/index.js @@ -11954,7 +11954,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index b495c41be6b9..b3a645abc749 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -11927,7 +11927,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/getPullRequestIncrementalChanges/index.js b/.github/actions/javascript/getPullRequestIncrementalChanges/index.js index 281f9e64a9fe..77a38d3fd899 100644 --- a/.github/actions/javascript/getPullRequestIncrementalChanges/index.js +++ b/.github/actions/javascript/getPullRequestIncrementalChanges/index.js @@ -12029,7 +12029,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/isStagingDeployLocked/index.js b/.github/actions/javascript/isStagingDeployLocked/index.js index c30d651dba42..066b313d8c7e 100644 --- a/.github/actions/javascript/isStagingDeployLocked/index.js +++ b/.github/actions/javascript/isStagingDeployLocked/index.js @@ -11798,7 +11798,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/index.js b/.github/actions/javascript/markPullRequestsAsDeployed/index.js index b019da7e5e79..8ce424d1a3e1 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/index.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/index.js @@ -13251,7 +13251,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/postTestBuildComment/index.js b/.github/actions/javascript/postTestBuildComment/index.js index 75ad6573dd5c..d9ef74a8e7e8 100644 --- a/.github/actions/javascript/postTestBuildComment/index.js +++ b/.github/actions/javascript/postTestBuildComment/index.js @@ -11928,7 +11928,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/proposalPoliceComment/index.js b/.github/actions/javascript/proposalPoliceComment/index.js index 997a7577a873..fd2aa7c5b44d 100644 --- a/.github/actions/javascript/proposalPoliceComment/index.js +++ b/.github/actions/javascript/proposalPoliceComment/index.js @@ -12067,7 +12067,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, @@ -12595,7 +12595,7 @@ function sanitizeJSONStringValues(inputString) { // Function to recursively sanitize string values in an object const sanitizeValues = (obj) => { if (typeof obj === 'string') { - return obj.replace(/\\|\t|\n|\r|\f|"/g, replacer); + return obj.replaceAll(/\\|\t|\n|\r|\f|"/g, replacer); } if (Array.isArray(obj)) { return obj.map((item) => sanitizeValues(item)); diff --git a/.github/actions/javascript/reopenIssueWithComment/index.js b/.github/actions/javascript/reopenIssueWithComment/index.js index 48d990ca57ff..a47b56f3af0f 100644 --- a/.github/actions/javascript/reopenIssueWithComment/index.js +++ b/.github/actions/javascript/reopenIssueWithComment/index.js @@ -11808,7 +11808,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/reviewerChecklist/index.js b/.github/actions/javascript/reviewerChecklist/index.js index 3b8cb4133826..dec014a6605b 100644 --- a/.github/actions/javascript/reviewerChecklist/index.js +++ b/.github/actions/javascript/reviewerChecklist/index.js @@ -11632,7 +11632,7 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems) { break; } const whitespace = /([\n\r])/gm; - const comment = combinedComments.at(i)?.replace(whitespace, ''); + const comment = combinedComments.at(i)?.replaceAll(whitespace, ''); console.log(`Comment ${i} starts with: ${comment?.slice(0, 20)}...`); // Found the reviewer checklist, so count how many completed checklist items there are if (comment?.indexOf(reviewerChecklistContains) !== -1) { @@ -11900,7 +11900,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/.github/actions/javascript/verifySignedCommits/index.js b/.github/actions/javascript/verifySignedCommits/index.js index 1f444b15d7b8..af4bad39a193 100644 --- a/.github/actions/javascript/verifySignedCommits/index.js +++ b/.github/actions/javascript/verifySignedCommits/index.js @@ -11840,7 +11840,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, diff --git a/src/libs/SearchParser/searchParser.js b/src/libs/SearchParser/searchParser.js index c31e456b6aee..7e815816680e 100644 --- a/src/libs/SearchParser/searchParser.js +++ b/src/libs/SearchParser/searchParser.js @@ -392,7 +392,7 @@ function peg$parse(input, options) { "eq", "keyword", keywords - .map((filter) => filter.right.replace(/^(['"])(.*)\1$/, "$2")) + .map((filter) => filter.right.replaceAll(/^(['"])(.*)\1$/g, "$2")) .flat() ); if (keywordFilter.right.length > 0) { @@ -431,7 +431,7 @@ function peg$parse(input, options) { return buildFilter(operator, key, values); }; var peg$f5 = function(rest) { - const suffix = rest.replace(/^-+/, ""); + const suffix = rest.replace(/^-+/g, ""); return "reportField-" + (suffix ? suffix : ""); }; var peg$f6 = function(k) { diff --git a/src/libs/SearchParser/searchParser.peggy b/src/libs/SearchParser/searchParser.peggy index 8cc4241d2ea7..f5d020bb36af 100644 --- a/src/libs/SearchParser/searchParser.peggy +++ b/src/libs/SearchParser/searchParser.peggy @@ -80,7 +80,7 @@ filterList "eq", "keyword", keywords - .map((filter) => filter.right.replace(/^(['"])(.*)\1$/, "$2")) + .map((filter) => filter.right.replaceAll(/^(['"])(.*)\1$/g, "$2")) .flat() ); if (keywordFilter.right.length > 0) { @@ -129,7 +129,7 @@ standardFilter reportFieldDynamic = ("report-field"i / "reportfield"i) "-" rest:$((!([ \t\r\n\xA0,:=<>!]) .)*) { - const suffix = rest.replace(/^-+/, ""); + const suffix = rest.replace(/^-+/g, ""); return "reportField-" + (suffix ? suffix : ""); } From f4959a623f42462de5a13c451f2a1b1d856d677b Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Thu, 30 Oct 2025 14:27:13 +0700 Subject: [PATCH 3/9] fix: eslint & prettier error --- src/libs/NextStepUtils.ts | 5 +---- src/pages/settings/Profile/TimezoneSelectPage.tsx | 4 ++-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index f8bc458d0fb7..c80b935808c9 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -95,10 +95,7 @@ function parseMessage(messages: Message[] | undefined) { nextStepHTML += `<${tagType}>${content}`; }); - const formattedHtml = nextStepHTML - .replaceAll('%expenses', 'expenses') - .replaceAll('%Expenses', 'Expenses') - .replaceAll('%tobe', 'are'); + const formattedHtml = nextStepHTML.replaceAll('%expenses', 'expenses').replaceAll('%Expenses', 'Expenses').replaceAll('%tobe', 'are'); return `${formattedHtml}`; } diff --git a/src/pages/settings/Profile/TimezoneSelectPage.tsx b/src/pages/settings/Profile/TimezoneSelectPage.tsx index e4b3087ffb60..39414b8264ca 100644 --- a/src/pages/settings/Profile/TimezoneSelectPage.tsx +++ b/src/pages/settings/Profile/TimezoneSelectPage.tsx @@ -9,7 +9,7 @@ import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalD import useInitialValue from '@hooks/useInitialValue'; import useLocalize from '@hooks/useLocalize'; import Navigation from '@libs/Navigation/Navigation'; -import * as PersonalDetails from '@userActions/PersonalDetails'; +import {updateSelectedTimezone} from '@userActions/PersonalDetails'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import TIMEZONES from '@src/TIMEZONES'; @@ -39,7 +39,7 @@ function TimezoneSelectPage({currentUserPersonalDetails}: TimezoneSelectPageProp const [timezoneOptions, setTimezoneOptions] = useState(allTimezones); const saveSelectedTimezone = ({text}: {text: string}) => { - PersonalDetails.updateSelectedTimezone(text as SelectedTimezone, currentUserPersonalDetails.accountID); + updateSelectedTimezone(text as SelectedTimezone, currentUserPersonalDetails.accountID); }; const filterShownTimezones = (searchText: string) => { From 9ddfe3711296554d772e3dbf572ae7262c327b2d Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Wed, 12 Nov 2025 09:18:12 +0700 Subject: [PATCH 4/9] chore: bump eslint-config-expensify --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9bf1036a0c4c..afeb5a5e15b5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -244,7 +244,7 @@ "electron-builder": "26.0.19", "eslint": "^9.36.0", "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-config-expensify": "2.0.95", + "eslint-config-expensify": "2.0.98", "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^29.0.1", "eslint-plugin-jsdoc": "^60.7.0", @@ -21608,9 +21608,9 @@ } }, "node_modules/eslint-config-expensify": { - "version": "2.0.95", - "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.95.tgz", - "integrity": "sha512-yKoIlNAMHkUx82TJOby6MV14L+1q91Grp/ypRupyivaJ7yLUIoczTrsh4nmcLp5IUkf6QpbES4TxGAIkpFkhuQ==", + "version": "2.0.98", + "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.98.tgz", + "integrity": "sha512-jsfS0d34IldVgoEj28pLGVqLNppyoO8UAB8jCe9ZOwv5XwOhsc61KnP5mQ78KixxpHcYQ7ju9B3OiZlZ623D7Q==", "dev": true, "license": "ISC", "dependencies": { diff --git a/package.json b/package.json index 30e7342b4608..79673125df67 100644 --- a/package.json +++ b/package.json @@ -314,7 +314,7 @@ "electron-builder": "26.0.19", "eslint": "^9.36.0", "eslint-config-airbnb-typescript": "^18.0.0", - "eslint-config-expensify": "2.0.95", + "eslint-config-expensify": "2.0.98", "eslint-config-prettier": "^9.1.0", "eslint-plugin-jest": "^29.0.1", "eslint-plugin-jsdoc": "^60.7.0", From 2eac30e80652a466af192e82f23bc9d0b3beda57 Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Thu, 13 Nov 2025 17:04:39 +0700 Subject: [PATCH 5/9] fix: build gh actions --- .github/actions/javascript/formatCodeCovComment/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/javascript/formatCodeCovComment/index.js b/.github/actions/javascript/formatCodeCovComment/index.js index 3341eb6f5d88..cd388170e8f1 100644 --- a/.github/actions/javascript/formatCodeCovComment/index.js +++ b/.github/actions/javascript/formatCodeCovComment/index.js @@ -12024,7 +12024,7 @@ class GithubUtils { static getStagingDeployCashData(issue) { try { const versionRegex = new RegExp('([0-9]+)\\.([0-9]+)\\.([0-9]+)(?:-([0-9]+))?', 'g'); - const version = (issue.body?.match(versionRegex)?.[0] ?? '').replace(/`/g, ''); + const version = (issue.body?.match(versionRegex)?.[0] ?? '').replaceAll('`', ''); return { title: issue.title, url: issue.url, From 37395a3d4731c140ce676d388866552b9a21dccb Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Fri, 14 Nov 2025 16:01:42 +0700 Subject: [PATCH 6/9] fix: eslint errors --- src/libs/Clipboard/index.ts | 1 + .../home/report/ReportActionCompose/ReportActionCompose.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/Clipboard/index.ts b/src/libs/Clipboard/index.ts index ff8b66cca66e..6713d3eb82f3 100644 --- a/src/libs/Clipboard/index.ts +++ b/src/libs/Clipboard/index.ts @@ -75,6 +75,7 @@ function setHTMLSync(html: string, text: string) { selection.addRange(range); try { + // eslint-disable-next-line @typescript-eslint/no-deprecated document.execCommand('copy'); } catch (e) { // The 'copy' command can throw a SecurityError exception, we ignore this exception on purpose. diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index 6e397e1c314e..a31f3e160f34 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -381,7 +381,7 @@ function ReportActionCompose({ (value: string) => { const taskCommentMatch = value?.match(CONST.REGEX.TASK_TITLE_WITH_OPTIONAL_SHORT_MENTION); if (taskCommentMatch) { - const title = taskCommentMatch?.[3] ? taskCommentMatch[3].trim().replaceAll(/\n/g, ' ') : ''; + const title = taskCommentMatch?.[3] ? taskCommentMatch[3].trim().replaceAll('\n', ' ') : ''; setHasExceededMaxCommentLength(false); return validateTaskTitleMaxLength(title); } From 4dbeae7024c843c06181bf49af4c6bba2bf6894c Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Fri, 14 Nov 2025 17:19:31 +0700 Subject: [PATCH 7/9] fix eslint errors --- tests/ui/ContactMethodsPageTest.tsx | 2 +- tests/unit/PaymentCardFormTest.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ui/ContactMethodsPageTest.tsx b/tests/ui/ContactMethodsPageTest.tsx index d0f7b96d1363..3d4a887e6a68 100644 --- a/tests/ui/ContactMethodsPageTest.tsx +++ b/tests/ui/ContactMethodsPageTest.tsx @@ -23,7 +23,7 @@ jest.mock('@components/RenderHTML', () => { const {Text} = require('react-native') as {Text: React.ComponentType<{children?: React.ReactNode}>}; return ({html}: {html: string}) => { - const plainText = html.replace(/<[^>]*>/g, ''); + const plainText = html.replaceAll(/<[^>]*>/g, ''); return ReactMock.createElement(Text, null, plainText); }; }); diff --git a/tests/unit/PaymentCardFormTest.tsx b/tests/unit/PaymentCardFormTest.tsx index bbd4755b4de0..dd5a040f8b81 100644 --- a/tests/unit/PaymentCardFormTest.tsx +++ b/tests/unit/PaymentCardFormTest.tsx @@ -18,7 +18,7 @@ jest.mock('@components/RenderHTML', () => { const {Text} = require('react-native') as {Text: React.ComponentType<{children?: React.ReactNode}>}; return ({html}: {html: string}) => { - const plainText = html.replace(/<[^>]*>/g, ''); + const plainText = html.replaceAll(/<[^>]*>/g, ''); return ReactMock.createElement(Text, null, plainText); }; }); From a14ea71e1c1a76d42fe0fc8844454622ecbf1c1c Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Sat, 15 Nov 2025 09:48:49 +0700 Subject: [PATCH 8/9] fix search parser: prefer .replaceAll instead of .replace --- src/libs/SearchParser/autocompleteParser.js | 2 +- src/libs/SearchParser/autocompleteParser.peggy | 2 +- src/libs/SearchParser/searchParser.js | 2 +- src/libs/SearchParser/searchParser.peggy | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/SearchParser/autocompleteParser.js b/src/libs/SearchParser/autocompleteParser.js index ed0ff795d2b7..a404845a0a66 100644 --- a/src/libs/SearchParser/autocompleteParser.js +++ b/src/libs/SearchParser/autocompleteParser.js @@ -398,7 +398,7 @@ function peg$parse(input, options) { })); }; var peg$f3 = function(rest) { - const suffix = rest.replace(/^-+/, ""); + const suffix = rest.replaceAll(/^-+/g, ""); return "reportField-" + (suffix ? suffix : ""); }; var peg$f4 = function() { autocomplete = null; }; diff --git a/src/libs/SearchParser/autocompleteParser.peggy b/src/libs/SearchParser/autocompleteParser.peggy index c9842ec19ade..a07cb01c80fc 100644 --- a/src/libs/SearchParser/autocompleteParser.peggy +++ b/src/libs/SearchParser/autocompleteParser.peggy @@ -67,7 +67,7 @@ defaultFilter reportFieldDynamic = ("report-field"i / "reportfield"i) "-" rest:$((!([ \t\r\n\xA0,:=<>!]) .)*) { - const suffix = rest.replace(/^-+/, ""); + const suffix = rest.replaceAll(/^-+/g, ""); return "reportField-" + (suffix ? suffix : ""); } diff --git a/src/libs/SearchParser/searchParser.js b/src/libs/SearchParser/searchParser.js index 7e815816680e..2f8a0a112ff0 100644 --- a/src/libs/SearchParser/searchParser.js +++ b/src/libs/SearchParser/searchParser.js @@ -431,7 +431,7 @@ function peg$parse(input, options) { return buildFilter(operator, key, values); }; var peg$f5 = function(rest) { - const suffix = rest.replace(/^-+/g, ""); + const suffix = rest.replaceAll(/^-+/g, ""); return "reportField-" + (suffix ? suffix : ""); }; var peg$f6 = function(k) { diff --git a/src/libs/SearchParser/searchParser.peggy b/src/libs/SearchParser/searchParser.peggy index f5d020bb36af..3487e13e0d7f 100644 --- a/src/libs/SearchParser/searchParser.peggy +++ b/src/libs/SearchParser/searchParser.peggy @@ -129,7 +129,7 @@ standardFilter reportFieldDynamic = ("report-field"i / "reportfield"i) "-" rest:$((!([ \t\r\n\xA0,:=<>!]) .)*) { - const suffix = rest.replace(/^-+/g, ""); + const suffix = rest.replaceAll(/^-+/g, ""); return "reportField-" + (suffix ? suffix : ""); } From 752d790622f9ecdc2978444f44c22ae5902603ba Mon Sep 17 00:00:00 2001 From: NJ-2020 Date: Sat, 15 Nov 2025 09:57:38 +0700 Subject: [PATCH 9/9] fix: missing global flag --- .../generateHelpPreviewComment/generateHelpPreviewComment.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts b/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts index 93691432b03f..a1800f5f3306 100644 --- a/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts +++ b/.github/actions/javascript/generateHelpPreviewComment/generateHelpPreviewComment.ts @@ -12,7 +12,7 @@ function normalizeAlias(alias: string): string { } function toRoutePath(filename: string): string { - return filename.slice(DOCS_DIRECTORY_PREFIX.length).replaceAll(/\.md$/, ''); + return filename.slice(DOCS_DIRECTORY_PREFIX.length).replaceAll(/\.md$/g, ''); } async function getUpdatedDocRoutes(octokit: OctokitClient, owner: string, repo: string, prNumber: number): Promise { @@ -61,7 +61,7 @@ async function run(): Promise { const routes = await getUpdatedDocRoutes(octokit, owner, repo, prNumber); const normalizedRootURL = normalizeAlias(rootURL); - const displayRootURL = normalizedRootURL.replaceAll(/\/$/, ''); + const displayRootURL = normalizedRootURL.replaceAll(/\/$/g, ''); let body = `A preview of your ExpensifyHelp changes have been deployed to ${displayRootURL} ⚡️`; if (routes.length > 0) {