From d6df0af3760eacbffdf72f6c8df780d2503f8e13 Mon Sep 17 00:00:00 2001 From: ShridharGoel <35566748+ShridharGoel@users.noreply.github.com> Date: Tue, 17 Sep 2024 12:50:53 +0530 Subject: [PATCH] Updates --- .../javascript/authorChecklist/index.js | 16 +- .../javascript/awaitStagingDeploys/index.js | 14 +- .../actions/javascript/bumpVersion/index.js | 2 +- .../javascript/checkDeployBlockers/index.js | 14 +- .../createOrUpdateStagingDeploy.ts | 4 +- .../createOrUpdateStagingDeploy/index.js | 24 +- .../javascript/getArtifactInfo/index.js | 14 +- .../getDeployPullRequestList/index.js | 14 +- .../javascript/getPullRequestDetails/index.js | 14 +- .../javascript/isStagingDeployLocked/index.js | 14 +- .../markPullRequestsAsDeployed/index.js | 16 +- .../markPullRequestsAsDeployed.ts | 5 +- .../javascript/postTestBuildComment/index.js | 2594 ++++++++--------- .../javascript/proposalPoliceComment/index.js | 22 +- .../reopenIssueWithComment/index.js | 14 +- .../javascript/reviewerChecklist/index.js | 24 +- .../validateReassureOutput/index.js | 3 + .../validateReassureOutput.ts | 9 +- .../javascript/verifySignedCommits/index.js | 14 +- .github/scripts/createDocsRoutes.ts | 5 +- src/components/AccountSwitcher.tsx | 2 +- .../AttachmentCarousel/index.native.tsx | 7 +- src/components/AvatarWithDisplayName.tsx | 1 + .../ButtonWithDropdownMenu/index.tsx | 12 +- .../CalendarPicker/generateMonthMatrix.ts | 10 +- .../EmojiPicker/EmojiPickerMenu/index.tsx | 6 +- src/components/FilePicker/index.native.tsx | 2 +- src/components/ImportColumn.tsx | 4 +- src/components/ImportSpreadsheetColumns.tsx | 4 +- .../LHNOptionsList/OptionRowLHN.tsx | 29 +- .../OptionsList/BaseOptionsList.tsx | 6 +- .../MoneyRequestPreviewContent.tsx | 15 +- .../ReportActionItem/MoneyRequestView.tsx | 14 +- src/components/RoomHeaderAvatars.tsx | 12 +- .../WorkspaceMembersSelectionList.tsx | 2 +- src/hooks/useSubStep/index.ts | 5 +- src/languages/en.ts | 4 +- src/languages/es.ts | 4 +- src/libs/ModifiedExpenseMessage.ts | 8 +- .../createCustomStackNavigator/index.tsx | 20 +- .../getMatchingCentralPaneRouteForState.ts | 10 +- src/libs/Network/SequentialQueue.ts | 1 - src/libs/OptionsListUtils.ts | 2 - src/libs/PolicyUtils.ts | 8 +- src/libs/ReportActionsUtils.ts | 12 +- src/libs/ReportUtils.ts | 9 +- src/libs/SearchUtils.ts | 16 +- src/libs/SidebarUtils.ts | 10 - src/libs/actions/IOU.ts | 8 +- src/libs/actions/ImportSpreadsheet.ts | 13 +- src/libs/actions/Policy/Category.ts | 11 +- src/libs/actions/Policy/Tag.ts | 1 - src/libs/actions/Report.ts | 25 +- src/libs/actions/Welcome/OnboardingFlow.ts | 8 +- src/libs/actions/Workflow.ts | 10 - src/libs/memoize/cache/ArrayCache.ts | 4 +- src/pages/Search/SearchTypeMenuNarrow.tsx | 6 +- src/pages/home/ReportScreen.tsx | 13 - src/pages/home/report/ReportActionsList.tsx | 10 - src/pages/home/report/ReportActionsView.tsx | 2 +- .../ValidateCodeForm/BaseValidateCodeForm.tsx | 2 +- .../settings/Wallet/PaymentMethodList.tsx | 11 +- .../qbo/advanced/QuickbooksAdvancedPage.tsx | 14 +- ...ompanyCardExpenseAccountSelectCardPage.tsx | 24 - ...NonReimbursableDefaultVendorSelectPage.tsx | 12 - ...ooksOutOfPocketExpenseEntitySelectPage.tsx | 12 - .../WorkspaceCompanyCardFeedSelectorPage.tsx | 2 +- .../WorkspaceCompanyCardsPage.tsx | 4 +- .../tags/WorkspaceTagsSettingsPage.tsx | 47 - ...orkspaceWorkflowsApprovalsApproverPage.tsx | 50 +- .../WorkspaceWorkflowsApprovalsEditPage.tsx | 13 - ...paceWorkflowsApprovalsExpensesFromPage.tsx | 48 - src/stories/PromotedActionBar.stories.tsx | 14 +- .../perf-test/ReportActionsList.perf-test.tsx | 2 +- tests/unit/SidebarOrderTest.ts | 307 -- tests/unit/WorkflowUtilsTest.ts | 1 + 76 files changed, 1604 insertions(+), 2141 deletions(-) diff --git a/.github/actions/javascript/authorChecklist/index.js b/.github/actions/javascript/authorChecklist/index.js index 612a2457d630..856c1b0582e3 100644 --- a/.github/actions/javascript/authorChecklist/index.js +++ b/.github/actions/javascript/authorChecklist/index.js @@ -16771,7 +16771,7 @@ function partitionWithChecklist(body) { async function getNumberOfItemsFromAuthorChecklist() { const response = await fetch(pathToAuthorChecklist); const fileContents = await response.text(); - const checklist = partitionWithChecklist(fileContents)[1]; + const checklist = partitionWithChecklist(fileContents).at(1) ?? ''; const numberOfChecklistItems = (checklist.match(/\[ \]/g) ?? []).length; return numberOfChecklistItems; } @@ -17180,7 +17180,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -17258,7 +17262,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -17342,7 +17346,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -17416,7 +17420,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -17484,7 +17488,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/awaitStagingDeploys/index.js b/.github/actions/javascript/awaitStagingDeploys/index.js index 561cc980a4e5..cfc7e8b4cc4a 100644 --- a/.github/actions/javascript/awaitStagingDeploys/index.js +++ b/.github/actions/javascript/awaitStagingDeploys/index.js @@ -12421,7 +12421,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -12499,7 +12503,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -12583,7 +12587,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -12657,7 +12661,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -12725,7 +12729,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/bumpVersion/index.js b/.github/actions/javascript/bumpVersion/index.js index c8360931845a..5e8bd5f4ac37 100644 --- a/.github/actions/javascript/bumpVersion/index.js +++ b/.github/actions/javascript/bumpVersion/index.js @@ -3565,7 +3565,7 @@ exports.updateAndroidVersion = updateAndroidVersion; * Updates the CFBundleShortVersionString and the CFBundleVersion. */ function updateiOSVersion(version) { - const shortVersion = version.split('-')[0]; + const shortVersion = version.split('-').at(0); const cfVersion = version.includes('-') ? version.replace('-', '.') : `${version}.0`; console.log('Updating iOS', `CFBundleShortVersionString: ${shortVersion}`, `CFBundleVersion: ${cfVersion}`); // Update Plists diff --git a/.github/actions/javascript/checkDeployBlockers/index.js b/.github/actions/javascript/checkDeployBlockers/index.js index 74cd1509fbfa..1e9626511e5e 100644 --- a/.github/actions/javascript/checkDeployBlockers/index.js +++ b/.github/actions/javascript/checkDeployBlockers/index.js @@ -11704,7 +11704,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11782,7 +11786,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11866,7 +11870,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -11940,7 +11944,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -12008,7 +12012,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.ts b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.ts index 57afa326ea01..1964b143146d 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.ts +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/createOrUpdateStagingDeploy.ts @@ -32,7 +32,7 @@ async function run(): Promise { const mostRecentChecklist = recentDeployChecklists.at(0); if (!mostRecentChecklist) { - return; + throw new Error('Could not find the most recent checklist'); } const shouldCreateNewDeployChecklist = mostRecentChecklist.state !== 'open'; @@ -44,7 +44,7 @@ async function run(): Promise { } if (!previousChecklist) { - return; + throw new Error('Could not find the previous checklist'); } // Parse the data from the previous and current checklists into the format used to generate the checklist diff --git a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js index d3e249ee6f47..4958be79c466 100644 --- a/.github/actions/javascript/createOrUpdateStagingDeploy/index.js +++ b/.github/actions/javascript/createOrUpdateStagingDeploy/index.js @@ -14229,15 +14229,21 @@ async function run() { }); // Look at the state of the most recent StagingDeployCash, // if it is open then we'll update the existing one, otherwise, we'll create a new one. - const mostRecentChecklist = recentDeployChecklists[0]; + const mostRecentChecklist = recentDeployChecklists.at(0); + if (!mostRecentChecklist) { + return; + } const shouldCreateNewDeployChecklist = mostRecentChecklist.state !== 'open'; - const previousChecklist = shouldCreateNewDeployChecklist ? mostRecentChecklist : recentDeployChecklists[1]; + const previousChecklist = shouldCreateNewDeployChecklist ? mostRecentChecklist : recentDeployChecklists.at(1); if (shouldCreateNewDeployChecklist) { console.log('Latest StagingDeployCash is closed, creating a new one.', mostRecentChecklist); } else { console.log('Latest StagingDeployCash is open, updating it instead of creating a new one.', 'Current:', mostRecentChecklist, 'Previous:', previousChecklist); } + if (!previousChecklist) { + return; + } // Parse the data from the previous and current checklists into the format used to generate the checklist const previousChecklistData = GithubUtils_1.default.getStagingDeployCashData(previousChecklist); const currentChecklistData = shouldCreateNewDeployChecklist ? undefined : GithubUtils_1.default.getStagingDeployCashData(mostRecentChecklist); @@ -14735,7 +14741,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -14813,7 +14823,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -14897,7 +14907,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -14971,7 +14981,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -15039,7 +15049,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/getArtifactInfo/index.js b/.github/actions/javascript/getArtifactInfo/index.js index 82bf90ef6d2b..76cacef0221f 100644 --- a/.github/actions/javascript/getArtifactInfo/index.js +++ b/.github/actions/javascript/getArtifactInfo/index.js @@ -11665,7 +11665,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11743,7 +11747,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11827,7 +11831,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -11901,7 +11905,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -11969,7 +11973,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/getDeployPullRequestList/index.js b/.github/actions/javascript/getDeployPullRequestList/index.js index 918d631778d3..cde96b76b6e6 100644 --- a/.github/actions/javascript/getDeployPullRequestList/index.js +++ b/.github/actions/javascript/getDeployPullRequestList/index.js @@ -12027,7 +12027,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -12105,7 +12109,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -12189,7 +12193,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -12263,7 +12267,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -12331,7 +12335,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/getPullRequestDetails/index.js b/.github/actions/javascript/getPullRequestDetails/index.js index 8580842b380c..b1c096ed0be8 100644 --- a/.github/actions/javascript/getPullRequestDetails/index.js +++ b/.github/actions/javascript/getPullRequestDetails/index.js @@ -11767,7 +11767,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11845,7 +11849,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11929,7 +11933,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -12003,7 +12007,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -12071,7 +12075,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/isStagingDeployLocked/index.js b/.github/actions/javascript/isStagingDeployLocked/index.js index 9e823e8da5ae..d7196cad32f7 100644 --- a/.github/actions/javascript/isStagingDeployLocked/index.js +++ b/.github/actions/javascript/isStagingDeployLocked/index.js @@ -11665,7 +11665,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11743,7 +11747,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11827,7 +11831,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -11901,7 +11905,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -11969,7 +11973,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/index.js b/.github/actions/javascript/markPullRequestsAsDeployed/index.js index 9f97e4a72d20..7107e4f71749 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/index.js +++ b/.github/actions/javascript/markPullRequestsAsDeployed/index.js @@ -12733,7 +12733,7 @@ async function run() { labels: CONST_1.default.LABELS.STAGING_DEPLOY, state: 'closed', }); - const previousChecklistID = deployChecklists[0].number; + const previousChecklistID = deployChecklists.at(0)?.number ?? 0; // who closed the last deploy checklist? const deployer = await GithubUtils_1.default.getActorWhoClosedIssue(previousChecklistID); // Create comment on each pull request (one at a time to avoid throttling issues) @@ -13049,7 +13049,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -13127,7 +13131,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -13211,7 +13215,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -13285,7 +13289,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -13353,7 +13357,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts b/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts index 1a69c29078a1..986c6c12afb9 100644 --- a/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts +++ b/.github/actions/javascript/markPullRequestsAsDeployed/markPullRequestsAsDeployed.ts @@ -78,7 +78,10 @@ async function run() { labels: CONST.LABELS.STAGING_DEPLOY, state: 'closed', }); - const previousChecklistID = deployChecklists.at(0)?.number ?? 0; + const previousChecklistID = deployChecklists.at(0)?.number; + if (!previousChecklistID) { + throw new Error('Could not find the previous checklist ID'); + } // who closed the last deploy checklist? const deployer = await GithubUtils.getActorWhoClosedIssue(previousChecklistID); diff --git a/.github/actions/javascript/postTestBuildComment/index.js b/.github/actions/javascript/postTestBuildComment/index.js index 4f62879a4419..f1dfbc249cdd 100644 --- a/.github/actions/javascript/postTestBuildComment/index.js +++ b/.github/actions/javascript/postTestBuildComment/index.js @@ -9095,1303 +9095,1303 @@ exports.parseURL = __nccwpck_require__(33).parseURL; /***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { "use strict"; - -const punycode = __nccwpck_require__(5477); -const tr46 = __nccwpck_require__(2299); - -const specialSchemes = { - ftp: 21, - file: null, - gopher: 70, - http: 80, - https: 443, - ws: 80, - wss: 443 -}; - -const failure = Symbol("failure"); - -function countSymbols(str) { - return punycode.ucs2.decode(str).length; -} - -function at(input, idx) { - const c = input[idx]; - return isNaN(c) ? undefined : String.fromCodePoint(c); -} - -function isASCIIDigit(c) { - return c >= 0x30 && c <= 0x39; -} - -function isASCIIAlpha(c) { - return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); -} - -function isASCIIAlphanumeric(c) { - return isASCIIAlpha(c) || isASCIIDigit(c); -} - -function isASCIIHex(c) { - return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); -} - -function isSingleDot(buffer) { - return buffer === "." || buffer.toLowerCase() === "%2e"; -} - -function isDoubleDot(buffer) { - buffer = buffer.toLowerCase(); - return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; -} - -function isWindowsDriveLetterCodePoints(cp1, cp2) { - return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); -} - -function isWindowsDriveLetterString(string) { - return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); -} - -function isNormalizedWindowsDriveLetterString(string) { - return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; -} - -function containsForbiddenHostCodePoint(string) { - return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; -} - -function containsForbiddenHostCodePointExcludingPercent(string) { - return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; -} - -function isSpecialScheme(scheme) { - return specialSchemes[scheme] !== undefined; -} - -function isSpecial(url) { - return isSpecialScheme(url.scheme); -} - -function defaultPort(scheme) { - return specialSchemes[scheme]; -} - -function percentEncode(c) { - let hex = c.toString(16).toUpperCase(); - if (hex.length === 1) { - hex = "0" + hex; - } - - return "%" + hex; -} - -function utf8PercentEncode(c) { - const buf = new Buffer(c); - - let str = ""; - - for (let i = 0; i < buf.length; ++i) { - str += percentEncode(buf[i]); - } - - return str; -} - -function utf8PercentDecode(str) { - const input = new Buffer(str); - const output = []; - for (let i = 0; i < input.length; ++i) { - if (input[i] !== 37) { - output.push(input[i]); - } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { - output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); - i += 2; - } else { - output.push(input[i]); - } - } - return new Buffer(output).toString(); -} - -function isC0ControlPercentEncode(c) { - return c <= 0x1F || c > 0x7E; -} - -const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); -function isPathPercentEncode(c) { - return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); -} - -const extraUserinfoPercentEncodeSet = - new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); -function isUserinfoPercentEncode(c) { - return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); -} - -function percentEncodeChar(c, encodeSetPredicate) { - const cStr = String.fromCodePoint(c); - - if (encodeSetPredicate(c)) { - return utf8PercentEncode(cStr); - } - - return cStr; -} - -function parseIPv4Number(input) { - let R = 10; - - if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { - input = input.substring(2); - R = 16; - } else if (input.length >= 2 && input.charAt(0) === "0") { - input = input.substring(1); - R = 8; - } - - if (input === "") { - return 0; - } - - const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); - if (regex.test(input)) { - return failure; - } - - return parseInt(input, R); -} - -function parseIPv4(input) { - const parts = input.split("."); - if (parts[parts.length - 1] === "") { - if (parts.length > 1) { - parts.pop(); - } - } - - if (parts.length > 4) { - return input; - } - - const numbers = []; - for (const part of parts) { - if (part === "") { - return input; - } - const n = parseIPv4Number(part); - if (n === failure) { - return input; - } - - numbers.push(n); - } - - for (let i = 0; i < numbers.length - 1; ++i) { - if (numbers[i] > 255) { - return failure; - } - } - if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { - return failure; - } - - let ipv4 = numbers.pop(); - let counter = 0; - - for (const n of numbers) { - ipv4 += n * Math.pow(256, 3 - counter); - ++counter; - } - - return ipv4; -} - -function serializeIPv4(address) { - let output = ""; - let n = address; - - for (let i = 1; i <= 4; ++i) { - output = String(n % 256) + output; - if (i !== 4) { - output = "." + output; - } - n = Math.floor(n / 256); - } - - return output; -} - -function parseIPv6(input) { - const address = [0, 0, 0, 0, 0, 0, 0, 0]; - let pieceIndex = 0; - let compress = null; - let pointer = 0; - - input = punycode.ucs2.decode(input); - - if (input[pointer] === 58) { - if (input[pointer + 1] !== 58) { - return failure; - } - - pointer += 2; - ++pieceIndex; - compress = pieceIndex; - } - - while (pointer < input.length) { - if (pieceIndex === 8) { - return failure; - } - - if (input[pointer] === 58) { - if (compress !== null) { - return failure; - } - ++pointer; - ++pieceIndex; - compress = pieceIndex; - continue; - } - - let value = 0; - let length = 0; - - while (length < 4 && isASCIIHex(input[pointer])) { - value = value * 0x10 + parseInt(at(input, pointer), 16); - ++pointer; - ++length; - } - - if (input[pointer] === 46) { - if (length === 0) { - return failure; - } - - pointer -= length; - - if (pieceIndex > 6) { - return failure; - } - - let numbersSeen = 0; - - while (input[pointer] !== undefined) { - let ipv4Piece = null; - - if (numbersSeen > 0) { - if (input[pointer] === 46 && numbersSeen < 4) { - ++pointer; - } else { - return failure; - } - } - - if (!isASCIIDigit(input[pointer])) { - return failure; - } - - while (isASCIIDigit(input[pointer])) { - const number = parseInt(at(input, pointer)); - if (ipv4Piece === null) { - ipv4Piece = number; - } else if (ipv4Piece === 0) { - return failure; - } else { - ipv4Piece = ipv4Piece * 10 + number; - } - if (ipv4Piece > 255) { - return failure; - } - ++pointer; - } - - address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; - - ++numbersSeen; - - if (numbersSeen === 2 || numbersSeen === 4) { - ++pieceIndex; - } - } - - if (numbersSeen !== 4) { - return failure; - } - - break; - } else if (input[pointer] === 58) { - ++pointer; - if (input[pointer] === undefined) { - return failure; - } - } else if (input[pointer] !== undefined) { - return failure; - } - - address[pieceIndex] = value; - ++pieceIndex; - } - - if (compress !== null) { - let swaps = pieceIndex - compress; - pieceIndex = 7; - while (pieceIndex !== 0 && swaps > 0) { - const temp = address[compress + swaps - 1]; - address[compress + swaps - 1] = address[pieceIndex]; - address[pieceIndex] = temp; - --pieceIndex; - --swaps; - } - } else if (compress === null && pieceIndex !== 8) { - return failure; - } - - return address; -} - -function serializeIPv6(address) { - let output = ""; - const seqResult = findLongestZeroSequence(address); - const compress = seqResult.idx; - let ignore0 = false; - - for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { - if (ignore0 && address[pieceIndex] === 0) { - continue; - } else if (ignore0) { - ignore0 = false; - } - - if (compress === pieceIndex) { - const separator = pieceIndex === 0 ? "::" : ":"; - output += separator; - ignore0 = true; - continue; - } - - output += address[pieceIndex].toString(16); - - if (pieceIndex !== 7) { - output += ":"; - } - } - - return output; -} - -function parseHost(input, isSpecialArg) { - if (input[0] === "[") { - if (input[input.length - 1] !== "]") { - return failure; - } - - return parseIPv6(input.substring(1, input.length - 1)); - } - - if (!isSpecialArg) { - return parseOpaqueHost(input); - } - - const domain = utf8PercentDecode(input); - const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); - if (asciiDomain === null) { - return failure; - } - - if (containsForbiddenHostCodePoint(asciiDomain)) { - return failure; - } - - const ipv4Host = parseIPv4(asciiDomain); - if (typeof ipv4Host === "number" || ipv4Host === failure) { - return ipv4Host; - } - - return asciiDomain; -} - -function parseOpaqueHost(input) { - if (containsForbiddenHostCodePointExcludingPercent(input)) { - return failure; - } - - let output = ""; - const decoded = punycode.ucs2.decode(input); - for (let i = 0; i < decoded.length; ++i) { - output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); - } - return output; -} - -function findLongestZeroSequence(arr) { - let maxIdx = null; - let maxLen = 1; // only find elements > 1 - let currStart = null; - let currLen = 0; - - for (let i = 0; i < arr.length; ++i) { - if (arr[i] !== 0) { - if (currLen > maxLen) { - maxIdx = currStart; - maxLen = currLen; - } - - currStart = null; - currLen = 0; - } else { - if (currStart === null) { - currStart = i; - } - ++currLen; - } - } - - // if trailing zeros - if (currLen > maxLen) { - maxIdx = currStart; - maxLen = currLen; - } - - return { - idx: maxIdx, - len: maxLen - }; -} - -function serializeHost(host) { - if (typeof host === "number") { - return serializeIPv4(host); - } - - // IPv6 serializer - if (host instanceof Array) { - return "[" + serializeIPv6(host) + "]"; - } - - return host; -} - -function trimControlChars(url) { - return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); -} - -function trimTabAndNewline(url) { - return url.replace(/\u0009|\u000A|\u000D/g, ""); -} - -function shortenPath(url) { - const path = url.path; - if (path.length === 0) { - return; - } - if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { - return; - } - - path.pop(); -} - -function includesCredentials(url) { - return url.username !== "" || url.password !== ""; -} - -function cannotHaveAUsernamePasswordPort(url) { - return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; -} - -function isNormalizedWindowsDriveLetter(string) { - return /^[A-Za-z]:$/.test(string); -} - -function URLStateMachine(input, base, encodingOverride, url, stateOverride) { - this.pointer = 0; - this.input = input; - this.base = base || null; - this.encodingOverride = encodingOverride || "utf-8"; - this.stateOverride = stateOverride; - this.url = url; - this.failure = false; - this.parseError = false; - - if (!this.url) { - this.url = { - scheme: "", - username: "", - password: "", - host: null, - port: null, - path: [], - query: null, - fragment: null, - - cannotBeABaseURL: false - }; - - const res = trimControlChars(this.input); - if (res !== this.input) { - this.parseError = true; - } - this.input = res; - } - - const res = trimTabAndNewline(this.input); - if (res !== this.input) { - this.parseError = true; - } - this.input = res; - - this.state = stateOverride || "scheme start"; - - this.buffer = ""; - this.atFlag = false; - this.arrFlag = false; - this.passwordTokenSeenFlag = false; - - this.input = punycode.ucs2.decode(this.input); - - for (; this.pointer <= this.input.length; ++this.pointer) { - const c = this.input[this.pointer]; - const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); - - // exec state machine - const ret = this["parse " + this.state](c, cStr); - if (!ret) { - break; // terminate algorithm - } else if (ret === failure) { - this.failure = true; - break; - } - } -} - -URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { - if (isASCIIAlpha(c)) { - this.buffer += cStr.toLowerCase(); - this.state = "scheme"; - } else if (!this.stateOverride) { - this.state = "no scheme"; - --this.pointer; - } else { - this.parseError = true; - return failure; - } - - return true; -}; - -URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { - if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { - this.buffer += cStr.toLowerCase(); - } else if (c === 58) { - if (this.stateOverride) { - if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { - return false; - } - - if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { - return false; - } - - if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { - return false; - } - - if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { - return false; - } - } - this.url.scheme = this.buffer; - this.buffer = ""; - if (this.stateOverride) { - return false; - } - if (this.url.scheme === "file") { - if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { - this.parseError = true; - } - this.state = "file"; - } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { - this.state = "special relative or authority"; - } else if (isSpecial(this.url)) { - this.state = "special authority slashes"; - } else if (this.input[this.pointer + 1] === 47) { - this.state = "path or authority"; - ++this.pointer; - } else { - this.url.cannotBeABaseURL = true; - this.url.path.push(""); - this.state = "cannot-be-a-base-URL path"; - } - } else if (!this.stateOverride) { - this.buffer = ""; - this.state = "no scheme"; - this.pointer = -1; - } else { - this.parseError = true; - return failure; - } - - return true; -}; - -URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { - if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { - return failure; - } else if (this.base.cannotBeABaseURL && c === 35) { - this.url.scheme = this.base.scheme; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.url.cannotBeABaseURL = true; - this.state = "fragment"; - } else if (this.base.scheme === "file") { - this.state = "file"; - --this.pointer; - } else { - this.state = "relative"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = "special authority ignore slashes"; - ++this.pointer; - } else { - this.parseError = true; - this.state = "relative"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { - if (c === 47) { - this.state = "authority"; - } else { - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse relative"] = function parseRelative(c) { - this.url.scheme = this.base.scheme; - if (isNaN(c)) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - } else if (c === 47) { - this.state = "relative slash"; - } else if (c === 63) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.state = "fragment"; - } else if (isSpecial(this.url) && c === 92) { - this.parseError = true; - this.state = "relative slash"; - } else { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.url.path = this.base.path.slice(0, this.base.path.length - 1); - - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { - if (isSpecial(this.url) && (c === 47 || c === 92)) { - if (c === 92) { - this.parseError = true; - } - this.state = "special authority ignore slashes"; - } else if (c === 47) { - this.state = "authority"; - } else { - this.url.username = this.base.username; - this.url.password = this.base.password; - this.url.host = this.base.host; - this.url.port = this.base.port; - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = "special authority ignore slashes"; - ++this.pointer; - } else { - this.parseError = true; - this.state = "special authority ignore slashes"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { - if (c !== 47 && c !== 92) { - this.state = "authority"; - --this.pointer; - } else { - this.parseError = true; - } - - return true; -}; - -URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { - if (c === 64) { - this.parseError = true; - if (this.atFlag) { - this.buffer = "%40" + this.buffer; - } - this.atFlag = true; - - // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars - const len = countSymbols(this.buffer); - for (let pointer = 0; pointer < len; ++pointer) { - const codePoint = this.buffer.codePointAt(pointer); - - if (codePoint === 58 && !this.passwordTokenSeenFlag) { - this.passwordTokenSeenFlag = true; - continue; - } - const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); - if (this.passwordTokenSeenFlag) { - this.url.password += encodedCodePoints; - } else { - this.url.username += encodedCodePoints; - } - } - this.buffer = ""; - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92)) { - if (this.atFlag && this.buffer === "") { - this.parseError = true; - return failure; - } - this.pointer -= countSymbols(this.buffer) + 1; - this.buffer = ""; - this.state = "host"; - } else { - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse hostname"] = -URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { - if (this.stateOverride && this.url.scheme === "file") { - --this.pointer; - this.state = "file host"; - } else if (c === 58 && !this.arrFlag) { - if (this.buffer === "") { - this.parseError = true; - return failure; - } - - const host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - - this.url.host = host; - this.buffer = ""; - this.state = "port"; - if (this.stateOverride === "hostname") { - return false; - } - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92)) { - --this.pointer; - if (isSpecial(this.url) && this.buffer === "") { - this.parseError = true; - return failure; - } else if (this.stateOverride && this.buffer === "" && - (includesCredentials(this.url) || this.url.port !== null)) { - this.parseError = true; - return false; - } - - const host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - - this.url.host = host; - this.buffer = ""; - this.state = "path start"; - if (this.stateOverride) { - return false; - } - } else { - if (c === 91) { - this.arrFlag = true; - } else if (c === 93) { - this.arrFlag = false; - } - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { - if (isASCIIDigit(c)) { - this.buffer += cStr; - } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || - (isSpecial(this.url) && c === 92) || - this.stateOverride) { - if (this.buffer !== "") { - const port = parseInt(this.buffer); - if (port > Math.pow(2, 16) - 1) { - this.parseError = true; - return failure; - } - this.url.port = port === defaultPort(this.url.scheme) ? null : port; - this.buffer = ""; - } - if (this.stateOverride) { - return false; - } - this.state = "path start"; - --this.pointer; - } else { - this.parseError = true; - return failure; - } - - return true; -}; - -const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); - -URLStateMachine.prototype["parse file"] = function parseFile(c) { - this.url.scheme = "file"; - - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true; - } - this.state = "file slash"; - } else if (this.base !== null && this.base.scheme === "file") { - if (isNaN(c)) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - } else if (c === 63) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - this.url.query = this.base.query; - this.url.fragment = ""; - this.state = "fragment"; - } else { - if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points - !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || - (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points - !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { - this.url.host = this.base.host; - this.url.path = this.base.path.slice(); - shortenPath(this.url); - } else { - this.parseError = true; - } - - this.state = "path"; - --this.pointer; - } - } else { - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true; - } - this.state = "file host"; - } else { - if (this.base !== null && this.base.scheme === "file") { - if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { - this.url.path.push(this.base.path[0]); - } else { - this.url.host = this.base.host; - } - } - this.state = "path"; - --this.pointer; - } - - return true; -}; - -URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { - if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { - --this.pointer; - if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { - this.parseError = true; - this.state = "path"; - } else if (this.buffer === "") { - this.url.host = ""; - if (this.stateOverride) { - return false; - } - this.state = "path start"; - } else { - let host = parseHost(this.buffer, isSpecial(this.url)); - if (host === failure) { - return failure; - } - if (host === "localhost") { - host = ""; - } - this.url.host = host; - - if (this.stateOverride) { - return false; - } - - this.buffer = ""; - this.state = "path start"; - } - } else { - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { - if (isSpecial(this.url)) { - if (c === 92) { - this.parseError = true; - } - this.state = "path"; - - if (c !== 47 && c !== 92) { - --this.pointer; - } - } else if (!this.stateOverride && c === 63) { - this.url.query = ""; - this.state = "query"; - } else if (!this.stateOverride && c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } else if (c !== undefined) { - this.state = "path"; - if (c !== 47) { - --this.pointer; - } - } - - return true; -}; - -URLStateMachine.prototype["parse path"] = function parsePath(c) { - if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || - (!this.stateOverride && (c === 63 || c === 35))) { - if (isSpecial(this.url) && c === 92) { - this.parseError = true; - } - - if (isDoubleDot(this.buffer)) { - shortenPath(this.url); - if (c !== 47 && !(isSpecial(this.url) && c === 92)) { - this.url.path.push(""); - } - } else if (isSingleDot(this.buffer) && c !== 47 && - !(isSpecial(this.url) && c === 92)) { - this.url.path.push(""); - } else if (!isSingleDot(this.buffer)) { - if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { - if (this.url.host !== "" && this.url.host !== null) { - this.parseError = true; - this.url.host = ""; - } - this.buffer = this.buffer[0] + ":"; - } - this.url.path.push(this.buffer); - } - this.buffer = ""; - if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { - while (this.url.path.length > 1 && this.url.path[0] === "") { - this.parseError = true; - this.url.path.shift(); - } - } - if (c === 63) { - this.url.query = ""; - this.state = "query"; - } - if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.buffer += percentEncodeChar(c, isPathPercentEncode); - } - - return true; -}; - -URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { - if (c === 63) { - this.url.query = ""; - this.state = "query"; - } else if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } else { - // TODO: Add: not a URL code point - if (!isNaN(c) && c !== 37) { - this.parseError = true; - } - - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - if (!isNaN(c)) { - this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); - } - } - - return true; -}; - -URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { - if (isNaN(c) || (!this.stateOverride && c === 35)) { - if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { - this.encodingOverride = "utf-8"; - } - - const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead - for (let i = 0; i < buffer.length; ++i) { - if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || - buffer[i] === 0x3C || buffer[i] === 0x3E) { - this.url.query += percentEncode(buffer[i]); - } else { - this.url.query += String.fromCodePoint(buffer[i]); - } - } - - this.buffer = ""; - if (c === 35) { - this.url.fragment = ""; - this.state = "fragment"; - } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.buffer += cStr; - } - - return true; -}; - -URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { - if (isNaN(c)) { // do nothing - } else if (c === 0x0) { - this.parseError = true; - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if (c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2]))) { - this.parseError = true; - } - - this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); - } - - return true; -}; - -function serializeURL(url, excludeFragment) { - let output = url.scheme + ":"; - if (url.host !== null) { - output += "//"; - - if (url.username !== "" || url.password !== "") { - output += url.username; - if (url.password !== "") { - output += ":" + url.password; - } - output += "@"; - } - - output += serializeHost(url.host); - - if (url.port !== null) { - output += ":" + url.port; - } - } else if (url.host === null && url.scheme === "file") { - output += "//"; - } - - if (url.cannotBeABaseURL) { - output += url.path[0]; - } else { - for (const string of url.path) { - output += "/" + string; - } - } - - if (url.query !== null) { - output += "?" + url.query; - } - - if (!excludeFragment && url.fragment !== null) { - output += "#" + url.fragment; - } - - return output; -} - -function serializeOrigin(tuple) { - let result = tuple.scheme + "://"; - result += serializeHost(tuple.host); - - if (tuple.port !== null) { - result += ":" + tuple.port; - } - - return result; -} - -module.exports.serializeURL = serializeURL; - -module.exports.serializeURLOrigin = function (url) { - // https://url.spec.whatwg.org/#concept-url-origin - switch (url.scheme) { - case "blob": - try { - return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); - } catch (e) { - // serializing an opaque origin returns "null" - return "null"; - } - case "ftp": - case "gopher": - case "http": - case "https": - case "ws": - case "wss": - return serializeOrigin({ - scheme: url.scheme, - host: url.host, - port: url.port - }); - case "file": - // spec says "exercise to the reader", chrome says "file://" - return "file://"; - default: - // serializing an opaque origin returns "null" - return "null"; - } -}; - -module.exports.basicURLParse = function (input, options) { - if (options === undefined) { - options = {}; - } - - const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); - if (usm.failure) { - return "failure"; - } - - return usm.url; -}; - -module.exports.setTheUsername = function (url, username) { - url.username = ""; - const decoded = punycode.ucs2.decode(username); - for (let i = 0; i < decoded.length; ++i) { - url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); - } -}; - -module.exports.setThePassword = function (url, password) { - url.password = ""; - const decoded = punycode.ucs2.decode(password); - for (let i = 0; i < decoded.length; ++i) { - url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); - } -}; - -module.exports.serializeHost = serializeHost; - -module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; - -module.exports.serializeInteger = function (integer) { - return String(integer); -}; - -module.exports.parseURL = function (input, options) { - if (options === undefined) { - options = {}; - } - - // We don't handle blobs, so this just delegates: - return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); -}; + +const punycode = __nccwpck_require__(5477); +const tr46 = __nccwpck_require__(2299); + +const specialSchemes = { + ftp: 21, + file: null, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443 +}; + +const failure = Symbol("failure"); + +function countSymbols(str) { + return punycode.ucs2.decode(str).length; +} + +function at(input, idx) { + const c = input[idx]; + return isNaN(c) ? undefined : String.fromCodePoint(c); +} + +function isASCIIDigit(c) { + return c >= 0x30 && c <= 0x39; +} + +function isASCIIAlpha(c) { + return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); +} + +function isASCIIAlphanumeric(c) { + return isASCIIAlpha(c) || isASCIIDigit(c); +} + +function isASCIIHex(c) { + return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); +} + +function isSingleDot(buffer) { + return buffer === "." || buffer.toLowerCase() === "%2e"; +} + +function isDoubleDot(buffer) { + buffer = buffer.toLowerCase(); + return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; +} + +function isWindowsDriveLetterCodePoints(cp1, cp2) { + return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); +} + +function isWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); +} + +function isNormalizedWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; +} + +function containsForbiddenHostCodePoint(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; +} + +function containsForbiddenHostCodePointExcludingPercent(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; +} + +function isSpecialScheme(scheme) { + return specialSchemes[scheme] !== undefined; +} + +function isSpecial(url) { + return isSpecialScheme(url.scheme); +} + +function defaultPort(scheme) { + return specialSchemes[scheme]; +} + +function percentEncode(c) { + let hex = c.toString(16).toUpperCase(); + if (hex.length === 1) { + hex = "0" + hex; + } + + return "%" + hex; +} + +function utf8PercentEncode(c) { + const buf = new Buffer(c); + + let str = ""; + + for (let i = 0; i < buf.length; ++i) { + str += percentEncode(buf[i]); + } + + return str; +} + +function utf8PercentDecode(str) { + const input = new Buffer(str); + const output = []; + for (let i = 0; i < input.length; ++i) { + if (input[i] !== 37) { + output.push(input[i]); + } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { + output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); + i += 2; + } else { + output.push(input[i]); + } + } + return new Buffer(output).toString(); +} + +function isC0ControlPercentEncode(c) { + return c <= 0x1F || c > 0x7E; +} + +const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); +function isPathPercentEncode(c) { + return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); +} + +const extraUserinfoPercentEncodeSet = + new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); +function isUserinfoPercentEncode(c) { + return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); +} + +function percentEncodeChar(c, encodeSetPredicate) { + const cStr = String.fromCodePoint(c); + + if (encodeSetPredicate(c)) { + return utf8PercentEncode(cStr); + } + + return cStr; +} + +function parseIPv4Number(input) { + let R = 10; + + if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { + input = input.substring(2); + R = 16; + } else if (input.length >= 2 && input.charAt(0) === "0") { + input = input.substring(1); + R = 8; + } + + if (input === "") { + return 0; + } + + const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); + if (regex.test(input)) { + return failure; + } + + return parseInt(input, R); +} + +function parseIPv4(input) { + const parts = input.split("."); + if (parts[parts.length - 1] === "") { + if (parts.length > 1) { + parts.pop(); + } + } + + if (parts.length > 4) { + return input; + } + + const numbers = []; + for (const part of parts) { + if (part === "") { + return input; + } + const n = parseIPv4Number(part); + if (n === failure) { + return input; + } + + numbers.push(n); + } + + for (let i = 0; i < numbers.length - 1; ++i) { + if (numbers[i] > 255) { + return failure; + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + return failure; + } + + let ipv4 = numbers.pop(); + let counter = 0; + + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter); + ++counter; + } + + return ipv4; +} + +function serializeIPv4(address) { + let output = ""; + let n = address; + + for (let i = 1; i <= 4; ++i) { + output = String(n % 256) + output; + if (i !== 4) { + output = "." + output; + } + n = Math.floor(n / 256); + } + + return output; +} + +function parseIPv6(input) { + const address = [0, 0, 0, 0, 0, 0, 0, 0]; + let pieceIndex = 0; + let compress = null; + let pointer = 0; + + input = punycode.ucs2.decode(input); + + if (input[pointer] === 58) { + if (input[pointer + 1] !== 58) { + return failure; + } + + pointer += 2; + ++pieceIndex; + compress = pieceIndex; + } + + while (pointer < input.length) { + if (pieceIndex === 8) { + return failure; + } + + if (input[pointer] === 58) { + if (compress !== null) { + return failure; + } + ++pointer; + ++pieceIndex; + compress = pieceIndex; + continue; + } + + let value = 0; + let length = 0; + + while (length < 4 && isASCIIHex(input[pointer])) { + value = value * 0x10 + parseInt(at(input, pointer), 16); + ++pointer; + ++length; + } + + if (input[pointer] === 46) { + if (length === 0) { + return failure; + } + + pointer -= length; + + if (pieceIndex > 6) { + return failure; + } + + let numbersSeen = 0; + + while (input[pointer] !== undefined) { + let ipv4Piece = null; + + if (numbersSeen > 0) { + if (input[pointer] === 46 && numbersSeen < 4) { + ++pointer; + } else { + return failure; + } + } + + if (!isASCIIDigit(input[pointer])) { + return failure; + } + + while (isASCIIDigit(input[pointer])) { + const number = parseInt(at(input, pointer)); + if (ipv4Piece === null) { + ipv4Piece = number; + } else if (ipv4Piece === 0) { + return failure; + } else { + ipv4Piece = ipv4Piece * 10 + number; + } + if (ipv4Piece > 255) { + return failure; + } + ++pointer; + } + + address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; + + ++numbersSeen; + + if (numbersSeen === 2 || numbersSeen === 4) { + ++pieceIndex; + } + } + + if (numbersSeen !== 4) { + return failure; + } + + break; + } else if (input[pointer] === 58) { + ++pointer; + if (input[pointer] === undefined) { + return failure; + } + } else if (input[pointer] !== undefined) { + return failure; + } + + address[pieceIndex] = value; + ++pieceIndex; + } + + if (compress !== null) { + let swaps = pieceIndex - compress; + pieceIndex = 7; + while (pieceIndex !== 0 && swaps > 0) { + const temp = address[compress + swaps - 1]; + address[compress + swaps - 1] = address[pieceIndex]; + address[pieceIndex] = temp; + --pieceIndex; + --swaps; + } + } else if (compress === null && pieceIndex !== 8) { + return failure; + } + + return address; +} + +function serializeIPv6(address) { + let output = ""; + const seqResult = findLongestZeroSequence(address); + const compress = seqResult.idx; + let ignore0 = false; + + for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { + if (ignore0 && address[pieceIndex] === 0) { + continue; + } else if (ignore0) { + ignore0 = false; + } + + if (compress === pieceIndex) { + const separator = pieceIndex === 0 ? "::" : ":"; + output += separator; + ignore0 = true; + continue; + } + + output += address[pieceIndex].toString(16); + + if (pieceIndex !== 7) { + output += ":"; + } + } + + return output; +} + +function parseHost(input, isSpecialArg) { + if (input[0] === "[") { + if (input[input.length - 1] !== "]") { + return failure; + } + + return parseIPv6(input.substring(1, input.length - 1)); + } + + if (!isSpecialArg) { + return parseOpaqueHost(input); + } + + const domain = utf8PercentDecode(input); + const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); + if (asciiDomain === null) { + return failure; + } + + if (containsForbiddenHostCodePoint(asciiDomain)) { + return failure; + } + + const ipv4Host = parseIPv4(asciiDomain); + if (typeof ipv4Host === "number" || ipv4Host === failure) { + return ipv4Host; + } + + return asciiDomain; +} + +function parseOpaqueHost(input) { + if (containsForbiddenHostCodePointExcludingPercent(input)) { + return failure; + } + + let output = ""; + const decoded = punycode.ucs2.decode(input); + for (let i = 0; i < decoded.length; ++i) { + output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); + } + return output; +} + +function findLongestZeroSequence(arr) { + let maxIdx = null; + let maxLen = 1; // only find elements > 1 + let currStart = null; + let currLen = 0; + + for (let i = 0; i < arr.length; ++i) { + if (arr[i] !== 0) { + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + currStart = null; + currLen = 0; + } else { + if (currStart === null) { + currStart = i; + } + ++currLen; + } + } + + // if trailing zeros + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + return { + idx: maxIdx, + len: maxLen + }; +} + +function serializeHost(host) { + if (typeof host === "number") { + return serializeIPv4(host); + } + + // IPv6 serializer + if (host instanceof Array) { + return "[" + serializeIPv6(host) + "]"; + } + + return host; +} + +function trimControlChars(url) { + return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); +} + +function trimTabAndNewline(url) { + return url.replace(/\u0009|\u000A|\u000D/g, ""); +} + +function shortenPath(url) { + const path = url.path; + if (path.length === 0) { + return; + } + if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { + return; + } + + path.pop(); +} + +function includesCredentials(url) { + return url.username !== "" || url.password !== ""; +} + +function cannotHaveAUsernamePasswordPort(url) { + return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; +} + +function isNormalizedWindowsDriveLetter(string) { + return /^[A-Za-z]:$/.test(string); +} + +function URLStateMachine(input, base, encodingOverride, url, stateOverride) { + this.pointer = 0; + this.input = input; + this.base = base || null; + this.encodingOverride = encodingOverride || "utf-8"; + this.stateOverride = stateOverride; + this.url = url; + this.failure = false; + this.parseError = false; + + if (!this.url) { + this.url = { + scheme: "", + username: "", + password: "", + host: null, + port: null, + path: [], + query: null, + fragment: null, + + cannotBeABaseURL: false + }; + + const res = trimControlChars(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + } + + const res = trimTabAndNewline(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + + this.state = stateOverride || "scheme start"; + + this.buffer = ""; + this.atFlag = false; + this.arrFlag = false; + this.passwordTokenSeenFlag = false; + + this.input = punycode.ucs2.decode(this.input); + + for (; this.pointer <= this.input.length; ++this.pointer) { + const c = this.input[this.pointer]; + const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); + + // exec state machine + const ret = this["parse " + this.state](c, cStr); + if (!ret) { + break; // terminate algorithm + } else if (ret === failure) { + this.failure = true; + break; + } + } +} + +URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { + if (isASCIIAlpha(c)) { + this.buffer += cStr.toLowerCase(); + this.state = "scheme"; + } else if (!this.stateOverride) { + this.state = "no scheme"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { + if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { + this.buffer += cStr.toLowerCase(); + } else if (c === 58) { + if (this.stateOverride) { + if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { + return false; + } + + if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { + return false; + } + + if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { + return false; + } + + if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { + return false; + } + } + this.url.scheme = this.buffer; + this.buffer = ""; + if (this.stateOverride) { + return false; + } + if (this.url.scheme === "file") { + if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { + this.parseError = true; + } + this.state = "file"; + } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { + this.state = "special relative or authority"; + } else if (isSpecial(this.url)) { + this.state = "special authority slashes"; + } else if (this.input[this.pointer + 1] === 47) { + this.state = "path or authority"; + ++this.pointer; + } else { + this.url.cannotBeABaseURL = true; + this.url.path.push(""); + this.state = "cannot-be-a-base-URL path"; + } + } else if (!this.stateOverride) { + this.buffer = ""; + this.state = "no scheme"; + this.pointer = -1; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { + if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { + return failure; + } else if (this.base.cannotBeABaseURL && c === 35) { + this.url.scheme = this.base.scheme; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.url.cannotBeABaseURL = true; + this.state = "fragment"; + } else if (this.base.scheme === "file") { + this.state = "file"; + --this.pointer; + } else { + this.state = "relative"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "relative"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { + if (c === 47) { + this.state = "authority"; + } else { + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse relative"] = function parseRelative(c) { + this.url.scheme = this.base.scheme; + if (isNaN(c)) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 47) { + this.state = "relative slash"; + } else if (c === 63) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else if (isSpecial(this.url) && c === 92) { + this.parseError = true; + this.state = "relative slash"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(0, this.base.path.length - 1); + + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { + if (isSpecial(this.url) && (c === 47 || c === 92)) { + if (c === 92) { + this.parseError = true; + } + this.state = "special authority ignore slashes"; + } else if (c === 47) { + this.state = "authority"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "special authority ignore slashes"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { + if (c !== 47 && c !== 92) { + this.state = "authority"; + --this.pointer; + } else { + this.parseError = true; + } + + return true; +}; + +URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { + if (c === 64) { + this.parseError = true; + if (this.atFlag) { + this.buffer = "%40" + this.buffer; + } + this.atFlag = true; + + // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars + const len = countSymbols(this.buffer); + for (let pointer = 0; pointer < len; ++pointer) { + const codePoint = this.buffer.codePointAt(pointer); + + if (codePoint === 58 && !this.passwordTokenSeenFlag) { + this.passwordTokenSeenFlag = true; + continue; + } + const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); + if (this.passwordTokenSeenFlag) { + this.url.password += encodedCodePoints; + } else { + this.url.username += encodedCodePoints; + } + } + this.buffer = ""; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + if (this.atFlag && this.buffer === "") { + this.parseError = true; + return failure; + } + this.pointer -= countSymbols(this.buffer) + 1; + this.buffer = ""; + this.state = "host"; + } else { + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse hostname"] = +URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { + if (this.stateOverride && this.url.scheme === "file") { + --this.pointer; + this.state = "file host"; + } else if (c === 58 && !this.arrFlag) { + if (this.buffer === "") { + this.parseError = true; + return failure; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "port"; + if (this.stateOverride === "hostname") { + return false; + } + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + --this.pointer; + if (isSpecial(this.url) && this.buffer === "") { + this.parseError = true; + return failure; + } else if (this.stateOverride && this.buffer === "" && + (includesCredentials(this.url) || this.url.port !== null)) { + this.parseError = true; + return false; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "path start"; + if (this.stateOverride) { + return false; + } + } else { + if (c === 91) { + this.arrFlag = true; + } else if (c === 93) { + this.arrFlag = false; + } + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { + if (isASCIIDigit(c)) { + this.buffer += cStr; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92) || + this.stateOverride) { + if (this.buffer !== "") { + const port = parseInt(this.buffer); + if (port > Math.pow(2, 16) - 1) { + this.parseError = true; + return failure; + } + this.url.port = port === defaultPort(this.url.scheme) ? null : port; + this.buffer = ""; + } + if (this.stateOverride) { + return false; + } + this.state = "path start"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); + +URLStateMachine.prototype["parse file"] = function parseFile(c) { + this.url.scheme = "file"; + + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file slash"; + } else if (this.base !== null && this.base.scheme === "file") { + if (isNaN(c)) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 63) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else { + if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points + !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || + (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points + !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + shortenPath(this.url); + } else { + this.parseError = true; + } + + this.state = "path"; + --this.pointer; + } + } else { + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file host"; + } else { + if (this.base !== null && this.base.scheme === "file") { + if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { + this.url.path.push(this.base.path[0]); + } else { + this.url.host = this.base.host; + } + } + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { + if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { + --this.pointer; + if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { + this.parseError = true; + this.state = "path"; + } else if (this.buffer === "") { + this.url.host = ""; + if (this.stateOverride) { + return false; + } + this.state = "path start"; + } else { + let host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + if (host === "localhost") { + host = ""; + } + this.url.host = host; + + if (this.stateOverride) { + return false; + } + + this.buffer = ""; + this.state = "path start"; + } + } else { + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { + if (isSpecial(this.url)) { + if (c === 92) { + this.parseError = true; + } + this.state = "path"; + + if (c !== 47 && c !== 92) { + --this.pointer; + } + } else if (!this.stateOverride && c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (!this.stateOverride && c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else if (c !== undefined) { + this.state = "path"; + if (c !== 47) { + --this.pointer; + } + } + + return true; +}; + +URLStateMachine.prototype["parse path"] = function parsePath(c) { + if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || + (!this.stateOverride && (c === 63 || c === 35))) { + if (isSpecial(this.url) && c === 92) { + this.parseError = true; + } + + if (isDoubleDot(this.buffer)) { + shortenPath(this.url); + if (c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } + } else if (isSingleDot(this.buffer) && c !== 47 && + !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } else if (!isSingleDot(this.buffer)) { + if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { + if (this.url.host !== "" && this.url.host !== null) { + this.parseError = true; + this.url.host = ""; + } + this.buffer = this.buffer[0] + ":"; + } + this.url.path.push(this.buffer); + } + this.buffer = ""; + if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { + while (this.url.path.length > 1 && this.url.path[0] === "") { + this.parseError = true; + this.url.path.shift(); + } + } + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += percentEncodeChar(c, isPathPercentEncode); + } + + return true; +}; + +URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else { + // TODO: Add: not a URL code point + if (!isNaN(c) && c !== 37) { + this.parseError = true; + } + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + if (!isNaN(c)) { + this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); + } + } + + return true; +}; + +URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { + if (isNaN(c) || (!this.stateOverride && c === 35)) { + if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { + this.encodingOverride = "utf-8"; + } + + const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || + buffer[i] === 0x3C || buffer[i] === 0x3E) { + this.url.query += percentEncode(buffer[i]); + } else { + this.url.query += String.fromCodePoint(buffer[i]); + } + } + + this.buffer = ""; + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { + if (isNaN(c)) { // do nothing + } else if (c === 0x0) { + this.parseError = true; + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); + } + + return true; +}; + +function serializeURL(url, excludeFragment) { + let output = url.scheme + ":"; + if (url.host !== null) { + output += "//"; + + if (url.username !== "" || url.password !== "") { + output += url.username; + if (url.password !== "") { + output += ":" + url.password; + } + output += "@"; + } + + output += serializeHost(url.host); + + if (url.port !== null) { + output += ":" + url.port; + } + } else if (url.host === null && url.scheme === "file") { + output += "//"; + } + + if (url.cannotBeABaseURL) { + output += url.path[0]; + } else { + for (const string of url.path) { + output += "/" + string; + } + } + + if (url.query !== null) { + output += "?" + url.query; + } + + if (!excludeFragment && url.fragment !== null) { + output += "#" + url.fragment; + } + + return output; +} + +function serializeOrigin(tuple) { + let result = tuple.scheme + "://"; + result += serializeHost(tuple.host); + + if (tuple.port !== null) { + result += ":" + tuple.port; + } + + return result; +} + +module.exports.serializeURL = serializeURL; + +module.exports.serializeURLOrigin = function (url) { + // https://url.spec.whatwg.org/#concept-url-origin + switch (url.scheme) { + case "blob": + try { + return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); + } catch (e) { + // serializing an opaque origin returns "null" + return "null"; + } + case "ftp": + case "gopher": + case "http": + case "https": + case "ws": + case "wss": + return serializeOrigin({ + scheme: url.scheme, + host: url.host, + port: url.port + }); + case "file": + // spec says "exercise to the reader", chrome says "file://" + return "file://"; + default: + // serializing an opaque origin returns "null" + return "null"; + } +}; + +module.exports.basicURLParse = function (input, options) { + if (options === undefined) { + options = {}; + } + + const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); + if (usm.failure) { + return "failure"; + } + + return usm.url; +}; + +module.exports.setTheUsername = function (url, username) { + url.username = ""; + const decoded = punycode.ucs2.decode(username); + for (let i = 0; i < decoded.length; ++i) { + url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } +}; + +module.exports.setThePassword = function (url, password) { + url.password = ""; + const decoded = punycode.ucs2.decode(password); + for (let i = 0; i < decoded.length; ++i) { + url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } +}; + +module.exports.serializeHost = serializeHost; + +module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; + +module.exports.serializeInteger = function (integer) { + return String(integer); +}; + +module.exports.parseURL = function (input, options) { + if (options === undefined) { + options = {}; + } + + // We don't handle blobs, so this just delegates: + return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); +}; /***/ }), diff --git a/.github/actions/javascript/proposalPoliceComment/index.js b/.github/actions/javascript/proposalPoliceComment/index.js index 9b5b56f11a11..a3c613a7018c 100644 --- a/.github/actions/javascript/proposalPoliceComment/index.js +++ b/.github/actions/javascript/proposalPoliceComment/index.js @@ -18026,7 +18026,7 @@ async function run() { if (assistantResponse.includes(`[${CONST_1.default.NO_ACTION}]`)) { // extract the text after [NO_ACTION] from assistantResponse since this is a // bot related action keyword - const noActionContext = assistantResponse.split(`[${CONST_1.default.NO_ACTION}] `)?.[1]?.replace('"', ''); + const noActionContext = assistantResponse.split(`[${CONST_1.default.NO_ACTION}] `)?.at(1)?.replace('"', ''); console.log('[NO_ACTION] w/ context: ', noActionContext); return; } @@ -18047,10 +18047,10 @@ async function run() { else if (assistantResponse.includes('[EDIT_COMMENT]') && !payload.comment?.body.includes('Edited by **proposal-police**')) { // extract the text after [EDIT_COMMENT] from assistantResponse since this is a // bot related action keyword - let extractedNotice = assistantResponse.split('[EDIT_COMMENT] ')?.[1]?.replace('"', ''); + let extractedNotice = assistantResponse.split('[EDIT_COMMENT] ').at(1)?.replace('"', ''); // format the date like: 2024-01-24 13:15:24 UTC not 2024-01-28 18:18:28.000 UTC - const formattedDate = `${date.toISOString()?.split('.')?.[0]?.replace('T', ' ')} UTC`; - extractedNotice = extractedNotice.replace('{updated_timestamp}', formattedDate); + const formattedDate = `${date.toISOString()?.split('.').at(0)?.replace('T', ' ')} UTC`; + extractedNotice = extractedNotice?.replace('{updated_timestamp}', formattedDate); console.log('ProposalPoliceâ„¢ editing issue comment...', payload.comment.id); await GithubUtils_1.default.octokit.issues.updateComment({ ...github_1.context.repo, @@ -18253,7 +18253,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -18331,7 +18335,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -18415,7 +18419,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -18489,7 +18493,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -18557,7 +18561,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/reopenIssueWithComment/index.js b/.github/actions/javascript/reopenIssueWithComment/index.js index 83131f363ef8..9c97e3c612a9 100644 --- a/.github/actions/javascript/reopenIssueWithComment/index.js +++ b/.github/actions/javascript/reopenIssueWithComment/index.js @@ -11675,7 +11675,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11753,7 +11757,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11837,7 +11841,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -11911,7 +11915,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -11979,7 +11983,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/reviewerChecklist/index.js b/.github/actions/javascript/reviewerChecklist/index.js index 2a0977db8016..93a3ccf1a0f3 100644 --- a/.github/actions/javascript/reviewerChecklist/index.js +++ b/.github/actions/javascript/reviewerChecklist/index.js @@ -11549,14 +11549,14 @@ function checkIssueForCompletedChecklist(numberOfChecklistItems) { break; } const whitespace = /([\n\r])/gm; - const comment = combinedComments[i].replace(whitespace, ''); - console.log(`Comment ${i} starts with: ${comment.slice(0, 20)}...`); + const comment = combinedComments.at(i)?.replace(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) { + if (comment?.indexOf(reviewerChecklistContains) !== -1) { console.log('Found the reviewer checklist!'); foundReviewerChecklist = true; - numberOfFinishedChecklistItems = (comment.match(/- \[x\]/gi) ?? []).length; - numberOfUnfinishedChecklistItems = (comment.match(/- \[ \]/g) ?? []).length; + numberOfFinishedChecklistItems = (comment?.match(/- \[x\]/gi) ?? []).length; + numberOfUnfinishedChecklistItems = (comment?.match(/- \[ \]/g) ?? []).length; } } if (!foundReviewerChecklist) { @@ -11767,7 +11767,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11845,7 +11849,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11929,7 +11933,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -12003,7 +12007,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -12071,7 +12075,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/actions/javascript/validateReassureOutput/index.js b/.github/actions/javascript/validateReassureOutput/index.js index 99881e8ad9db..616826aabc02 100644 --- a/.github/actions/javascript/validateReassureOutput/index.js +++ b/.github/actions/javascript/validateReassureOutput/index.js @@ -1,3 +1,6 @@ +/** + * NOTE: This is a compiled file. DO NOT directly edit this file. + */ /** * NOTE: This is a compiled file. DO NOT directly edit this file. */ diff --git a/.github/actions/javascript/validateReassureOutput/validateReassureOutput.ts b/.github/actions/javascript/validateReassureOutput/validateReassureOutput.ts index 0299958dd6ed..24901ca55aee 100644 --- a/.github/actions/javascript/validateReassureOutput/validateReassureOutput.ts +++ b/.github/actions/javascript/validateReassureOutput/validateReassureOutput.ts @@ -15,19 +15,12 @@ const run = (): boolean => { console.log(`Processing ${regressionOutput.countChanged.length} measurements...`); for (let i = 0; i < regressionOutput.countChanged.length; i++) { -<<<<<<< HEAD const measurement = regressionOutput.countChanged.at(i); if (!measurement) { continue; } -======= - const measurement = regressionOutput.countChanged[i]; -<<<<<<< HEAD ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa const baseline: MeasureEntry = measurement.baseline; const current: MeasureEntry = measurement.current; @@ -57,4 +50,4 @@ if (require.main === module) { run(); } -export default run; \ No newline at end of file +export default run; diff --git a/.github/actions/javascript/verifySignedCommits/index.js b/.github/actions/javascript/verifySignedCommits/index.js index 49a4341b84af..8920086eea46 100644 --- a/.github/actions/javascript/verifySignedCommits/index.js +++ b/.github/actions/javascript/verifySignedCommits/index.js @@ -11707,7 +11707,11 @@ class GithubUtils { if (data.length > 1) { throw new Error(`Found more than one ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); } - return this.getStagingDeployCashData(data[0]); + const issue = data.at(0); + if (!issue) { + throw new Error(`Found an undefined ${CONST_1.default.LABELS.STAGING_DEPLOY} issue.`); + } + return this.getStagingDeployCashData(issue); }); } /** @@ -11785,7 +11789,7 @@ class GithubUtils { } internalQASection = internalQASection[1]; const internalQAPRs = [...internalQASection.matchAll(new RegExp(`- \\[([ x])]\\s(${CONST_1.default.PULL_REQUEST_REGEX.source})`, 'g'))].map((match) => ({ - url: match[2].split('-')[0].trim(), + url: match[2].split('-').at(0)?.trim() ?? '', number: Number.parseInt(match[3], 10), isResolved: match[1] === 'x', })); @@ -11869,7 +11873,7 @@ class GithubUtils { * Fetch all pull requests given a list of PR numbers. */ static fetchAllPullRequests(pullRequestNumbers) { - const oldestPR = pullRequestNumbers.sort((a, b) => a - b)[0]; + const oldestPR = pullRequestNumbers.sort((a, b) => a - b).at(0); return this.paginate(this.octokit.pulls.list, { owner: CONST_1.default.GITHUB_OWNER, repo: CONST_1.default.APP_REPO, @@ -11943,7 +11947,7 @@ class GithubUtils { repo: CONST_1.default.APP_REPO, workflow_id: workflow, }) - .then((response) => response.data.workflow_runs[0]?.id); + .then((response) => response.data.workflow_runs.at(0)?.id ?? -1); } /** * Generate the URL of an New Expensify pull request given the PR number. @@ -12011,7 +12015,7 @@ class GithubUtils { per_page: 1, name: artifactName, }) - .then((response) => response.data.artifacts[0]); + .then((response) => response.data.artifacts.at(0)); } /** * Given an artifact ID, returns the download URL to a zip file containing the artifact. diff --git a/.github/scripts/createDocsRoutes.ts b/.github/scripts/createDocsRoutes.ts index 5f93f772c2c6..264422e27b99 100644 --- a/.github/scripts/createDocsRoutes.ts +++ b/.github/scripts/createDocsRoutes.ts @@ -94,7 +94,10 @@ function pushOrCreateEntry(hubs: Hub[], hub: string, function getOrderFromArticleFrontMatter(path: string): number | undefined { const frontmatter = fs.readFileSync(path, 'utf8').split('---').at(1); - const frontmatterObject = yaml.load(frontmatter ?? '') as Record; + if (!frontmatter) { + return; + } + const frontmatterObject = yaml.load(frontmatter) as Record; return frontmatterObject.order as number | undefined; } diff --git a/src/components/AccountSwitcher.tsx b/src/components/AccountSwitcher.tsx index a9e223e56632..92ebd1dea503 100644 --- a/src/components/AccountSwitcher.tsx +++ b/src/components/AccountSwitcher.tsx @@ -48,7 +48,7 @@ function AccountSwitcher() { const canSwitchAccounts = canUseNewDotCopilot && (delegators.length > 0 || isActingAsDelegate); const createBaseMenuItem = (personalDetails: PersonalDetails | undefined, errors?: Errors, additionalProps: MenuItemWithLink = {}): MenuItemWithLink => { - const error = Object.values(errors ?? {})[0] ?? ''; + const error = Object.values(errors ?? {}).at(0) ?? ''; return { title: personalDetails?.displayName ?? personalDetails?.login, description: Str.removeSMSDomain(personalDetails?.login ?? ''), diff --git a/src/components/Attachments/AttachmentCarousel/index.native.tsx b/src/components/Attachments/AttachmentCarousel/index.native.tsx index cd77db4d9805..aae621d0197f 100644 --- a/src/components/Attachments/AttachmentCarousel/index.native.tsx +++ b/src/components/Attachments/AttachmentCarousel/index.native.tsx @@ -73,10 +73,9 @@ function AttachmentCarousel({report, reportActions, parentReportActions, source, setPage(newPageIndex); if (item) { setActiveSource(item.source); - } - - if (onNavigate && item) { - onNavigate(item); + if (onNavigate) { + onNavigate(item); + } } }, [setShouldShowArrows, attachments, onNavigate], diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index ba1c37a29aba..05d15a2ad995 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -13,6 +13,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {PersonalDetailsList, Policy, Report, ReportActions} from '@src/types/onyx'; +import fallbackIcon from '@src/utils/getDefaultIcon'; import CaretWrapper from './CaretWrapper'; import DisplayNames from './DisplayNames'; import MultipleAvatars from './MultipleAvatars'; diff --git a/src/components/ButtonWithDropdownMenu/index.tsx b/src/components/ButtonWithDropdownMenu/index.tsx index e492e052abc2..2fdbaad73c4e 100644 --- a/src/components/ButtonWithDropdownMenu/index.tsx +++ b/src/components/ButtonWithDropdownMenu/index.tsx @@ -166,21 +166,11 @@ function ButtonWithDropdownMenu({ style={[styles.w100, style]} disabledStyle={disabledStyle} isLoading={isLoading} - text={selectedItem.text} -<<<<<<< HEAD + text={selectedItem?.text} onPress={(event) => { const option = options.at(0); return option ? onPress(event, option.value) : undefined; }} -======= - onPress={(event) => onPress(event, options[0].value)} -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa large={buttonSize === CONST.DROPDOWN_BUTTON_SIZE.LARGE} medium={buttonSize === CONST.DROPDOWN_BUTTON_SIZE.MEDIUM} small={buttonSize === CONST.DROPDOWN_BUTTON_SIZE.SMALL} diff --git a/src/components/DatePicker/CalendarPicker/generateMonthMatrix.ts b/src/components/DatePicker/CalendarPicker/generateMonthMatrix.ts index 692e150c6303..9a5cf7d7f741 100644 --- a/src/components/DatePicker/CalendarPicker/generateMonthMatrix.ts +++ b/src/components/DatePicker/CalendarPicker/generateMonthMatrix.ts @@ -50,15 +50,9 @@ export default function generateMonthMatrix(year: number, month: number) { matrix.push(currentWeek); } - const initial = matrix.at(0); - - if (!initial) { - return; - } - // Add null values for days before the first day of the month - for (let i = initial.length; i < 7; i++) { - initial.unshift(undefined); + for (let i = matrix.at(0)?.length ?? 0; i < 7; i++) { + matrix.at(0)?.unshift(undefined); } return matrix; diff --git a/src/components/EmojiPicker/EmojiPickerMenu/index.tsx b/src/components/EmojiPicker/EmojiPickerMenu/index.tsx index 89c337c24a26..4c7483e55a6b 100755 --- a/src/components/EmojiPicker/EmojiPickerMenu/index.tsx +++ b/src/components/EmojiPicker/EmojiPickerMenu/index.tsx @@ -178,13 +178,13 @@ function EmojiPickerMenu({onEmojiSelected, activeEmoji}: EmojiPickerMenuProps, r indexToSelect = 0; } - const item = filteredEmojis[indexToSelect]; + const item = filteredEmojis.at(indexToSelect); if (!item) { return; } if ('types' in item || 'name' in item) { - const emoji = typeof preferredSkinTone === 'number' && item?.types?.[preferredSkinTone] ? item?.types?.[preferredSkinTone] : item.code; - onEmojiSelected(emoji, item); + const emoji = typeof preferredSkinTone === 'number' && item?.types?.[preferredSkinTone] ? item?.types.at(preferredSkinTone) : item.code; + onEmojiSelected(emoji ?? '', item); } }, {shouldPreventDefault: true, shouldStopPropagation: true}, diff --git a/src/components/FilePicker/index.native.tsx b/src/components/FilePicker/index.native.tsx index b74a68432cab..cc9c73d72c56 100644 --- a/src/components/FilePicker/index.native.tsx +++ b/src/components/FilePicker/index.native.tsx @@ -112,7 +112,7 @@ function FilePicker({children}: FilePickerProps) { onCanceled.current(); return Promise.resolve(); } - const fileData = files[0]; + const fileData = files.at(0); if (!fileData) { onCanceled.current(); diff --git a/src/components/ImportColumn.tsx b/src/components/ImportColumn.tsx index 49601787a207..94cdfd8a4df6 100644 --- a/src/components/ImportColumn.tsx +++ b/src/components/ImportColumn.tsx @@ -161,7 +161,7 @@ function ImportColumn({column, columnName, columnRoles, columnIndex}: ImportColu const columnValuesString = column.slice(containsHeader ? 1 : 0).join(', '); - const colName = findColumnName(column[0]); + const colName = findColumnName(column.at(0) ?? ''); const defaultSelectedIndex = columnRoles.findIndex((item) => item.value === colName); useEffect(() => { @@ -172,7 +172,7 @@ function ImportColumn({column, columnName, columnRoles, columnIndex}: ImportColu // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps -- we don't want this effect to run again }, []); - const columnHeader = containsHeader ? column[0] : translate('spreadsheet.column', columnName); + const columnHeader = containsHeader ? column.at(0) : translate('spreadsheet.column', columnName); return ( diff --git a/src/components/ImportSpreadsheetColumns.tsx b/src/components/ImportSpreadsheetColumns.tsx index a38e3c636e86..81a4513720de 100644 --- a/src/components/ImportSpreadsheetColumns.tsx +++ b/src/components/ImportSpreadsheetColumns.tsx @@ -73,9 +73,9 @@ function ImportSpreeadsheetColumns({spreadsheetColumns, columnNames, columnRoles {spreadsheetColumns.map((column, index) => { return ( diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 86ada5585b1b..8865ab103d11 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -209,18 +209,6 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti if (!event) { return; } -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD -======= - ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa // Prevent composer blur on left click event.preventDefault(); }} @@ -255,23 +243,8 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti (optionItem.shouldShowSubscript ? ( >>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - mainAvatar={optionItem.icons[0]} - secondaryAvatar={optionItem.icons[1]} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - mainAvatar={optionItem.icons[0]} - secondaryAvatar={optionItem.icons[1]} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa size={isInFocusMode ? CONST.AVATAR_SIZE.SMALL : CONST.AVATAR_SIZE.DEFAULT} /> ) : ( diff --git a/src/components/OptionsList/BaseOptionsList.tsx b/src/components/OptionsList/BaseOptionsList.tsx index f78aa546441c..d7c625e7837c 100644 --- a/src/components/OptionsList/BaseOptionsList.tsx +++ b/src/components/OptionsList/BaseOptionsList.tsx @@ -141,10 +141,10 @@ function BaseOptionsList( if (!flattenedData.current.at(flatDataArrayIndex)) { flattenedData.current = buildFlatSectionArray(); } - const targetItem = flattenedData.current.at(flatDataArrayIndex) ?? {length: 0, offset: 0}; + const targetItem = flattenedData.current.at(flatDataArrayIndex); return { - length: targetItem?.length, - offset: targetItem?.offset, + length: targetItem?.length ?? 0, + offset: targetItem?.offset ?? 0, index: flatDataArrayIndex, }; }; diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index fcf620db9aa4..2108797ed3fd 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -200,13 +200,14 @@ function MoneyRequestPreviewContent({ } if (shouldShowRBR && transaction) { - const violations = TransactionUtils.getTransactionViolations(transaction.transactionID, transactionViolations)?.sort((a) => - a.type === CONST.VIOLATION_TYPES.VIOLATION ? -1 : 0, - ); - if (violations?.at(0)) { - const violation = violations.at(0); - const violationMessage = violation ? ViolationsUtils.getViolationTranslation(violation, translate) : ''; - const violationsCount = violations.filter((v) => v.type === CONST.VIOLATION_TYPES.VIOLATION).length; + const violations = TransactionUtils.getTransactionViolations(transaction.transactionID, transactionViolations); + if (shouldShowHoldMessage) { + return `${message} ${CONST.DOT_SEPARATOR} ${translate('violations.hold')}`; + } + const firstViolation = violations?.at(0); + if (firstViolation) { + const violationMessage = ViolationsUtils.getViolationTranslation(firstViolation, translate); + const violationsCount = violations?.filter((v) => v.type === CONST.VIOLATION_TYPES.VIOLATION).length ?? 0; const isTooLong = violationsCount > 1 || violationMessage.length > 15; const hasViolationsAndFieldErrors = violationsCount > 0 && hasFieldErrors; diff --git a/src/components/ReportActionItem/MoneyRequestView.tsx b/src/components/ReportActionItem/MoneyRequestView.tsx index bc4d07ff22c4..3cf47ea9fcab 100644 --- a/src/components/ReportActionItem/MoneyRequestView.tsx +++ b/src/components/ReportActionItem/MoneyRequestView.tsx @@ -42,10 +42,7 @@ import * as Report from '@src/libs/actions/Report'; import * as ReportActions from '@src/libs/actions/ReportActions'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -// eslint-disable-next-line import/no-duplicates import type * as OnyxTypes from '@src/types/onyx'; -// eslint-disable-next-line import/no-duplicates -import type {TransactionViolation} from '@src/types/onyx'; import type {TransactionPendingFieldsKey} from '@src/types/onyx/Transaction'; import ReportActionItemImage from './ReportActionItemImage'; @@ -307,9 +304,12 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals // Return violations if there are any if (hasViolations(field, data, policyHasDependentTags, tagValue)) { - const violations = getViolationsForField(field, data, policyHasDependentTags, tagValue) as TransactionViolation[]; - // eslint-disable-next-line rulesdir/prefer-at - return ViolationsUtils.getViolationTranslation(violations[0], translate); + const violations = getViolationsForField(field, data, policyHasDependentTags, tagValue) as OnyxTypes.TransactionViolation[]; + const firstViolation = violations.at(0); + + if (firstViolation) { + return ViolationsUtils.getViolationTranslation(firstViolation, translate); + } } return ''; @@ -647,7 +647,7 @@ function MoneyRequestView({report, shouldShowAnimatedBackground, readonly = fals {translate('common.billable')} {!!getErrorForField('billable') && ( navigateToAvatarPage(icons[0])} + onPress={() => navigateToAvatarPage(icon)} accessibilityRole={CONST.ROLE.BUTTON} -<<<<<<< HEAD -<<<<<<< HEAD accessibilityLabel={icon.name ?? ''} disabled={icon.source === Expensicons.FallbackAvatar} -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - accessibilityLabel={icons[0].name ?? ''} - disabled={icons[0].source === Expensicons.FallbackAvatar} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa > (searchTerm && !sections[0].data.length ? translate('common.noResultsFound') : ''), [searchTerm, sections, translate]); + const headerMessage = useMemo(() => (searchTerm && !sections.at(0)?.data.length ? translate('common.noResultsFound') : ''), [searchTerm, sections, translate]); return ( ({bodyContent, on }, [bodyContent]); return { - // eslint-disable-next-line rulesdir/prefer-at - componentToRender: bodyContent[screenIndex], + // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style + componentToRender: bodyContent.at(screenIndex) as ComponentType, isEditing: isEditing.current, screenIndex, prevScreen, diff --git a/src/languages/en.ts b/src/languages/en.ts index f36db113a2aa..b8f43a4ab76a 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -3939,11 +3939,11 @@ export default { removedFromApprovalWorkflow: ({submittersNames}: {submittersNames: string[]}) => { let joinedNames = ''; if (submittersNames.length === 1) { - joinedNames = submittersNames[0]; + joinedNames = submittersNames.at(0) ?? ''; } else if (submittersNames.length === 2) { joinedNames = submittersNames.join(' and '); } else if (submittersNames.length > 2) { - joinedNames = `${submittersNames.slice(0, submittersNames.length - 1).join(', ')} and ${submittersNames[submittersNames.length - 1]}`; + joinedNames = `${submittersNames.slice(0, submittersNames.length - 1).join(', ')} and ${submittersNames.at(submittersNames.length - 1)}`; } const workflowWord = Str.pluralize('workflow', 'workflows', submittersNames.length); const chatWord = Str.pluralize('chat', 'chats', submittersNames.length); diff --git a/src/languages/es.ts b/src/languages/es.ts index 8a18c6c002e0..09489d8e4331 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -3990,11 +3990,11 @@ export default { removedFromApprovalWorkflow: ({submittersNames}: {submittersNames: string[]}) => { let joinedNames = ''; if (submittersNames.length === 1) { - joinedNames = submittersNames[0]; + joinedNames = submittersNames.at(0) ?? ''; } else if (submittersNames.length === 2) { joinedNames = submittersNames.join(' y '); } else if (submittersNames.length > 2) { - joinedNames = `${submittersNames.slice(0, submittersNames.length - 1).join(', ')} y ${submittersNames[submittersNames.length - 1]}`; + joinedNames = `${submittersNames.slice(0, submittersNames.length - 1).join(', ')} y ${submittersNames.at(submittersNames.length - 1)}`; } const workflowWord = Str.pluralize('del flujo', 'de los flujos', submittersNames.length); const chatWord = Str.pluralize('del chat', 'de los chats', submittersNames.length); diff --git a/src/libs/ModifiedExpenseMessage.ts b/src/libs/ModifiedExpenseMessage.ts index e11bc9ceaf19..20c5f6d7dce9 100644 --- a/src/libs/ModifiedExpenseMessage.ts +++ b/src/libs/ModifiedExpenseMessage.ts @@ -100,11 +100,11 @@ function getForDistanceRequest(newMerchant: string, oldMerchant: string, newAmou if (CONST.REGEX.DISTANCE_MERCHANT.test(newMerchant) && CONST.REGEX.DISTANCE_MERCHANT.test(oldMerchant)) { const oldValues = oldMerchant.split('@'); - const oldDistance = oldValues[0]?.trim() || ''; - const oldRate = oldValues[1]?.trim() || ''; + const oldDistance = oldValues.at(0)?.trim() ?? ''; + const oldRate = oldValues.at(1)?.trim() ?? ''; const newValues = newMerchant.split('@'); - const newDistance = newValues[0]?.trim() || ''; - const newRate = newValues[1]?.trim() || ''; + const newDistance = newValues.at(0)?.trim() ?? ''; + const newRate = newValues.at(1)?.trim() ?? ''; if (oldDistance === newDistance && oldRate !== newRate) { changedField = 'rate'; diff --git a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx index 40bd1181da81..009a11875e83 100644 --- a/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx +++ b/src/libs/Navigation/AppNavigator/createCustomStackNavigator/index.tsx @@ -71,15 +71,17 @@ function ResponsiveStackNavigator(props: ResponsiveStackNavigatorProps) { // On narrow layout, if we are on /search route we want to hide all central pane routes and show only the bottom tab navigator. if (lastSearchCentralPane) { - return { - stateToRender: { - ...state, - index: 0, - // eslint-disable-next-line rulesdir/prefer-at - routes: [filteredRoutes[0]], - }, - searchRoute: lastSearchCentralPane, - }; + const filteredRoute = filteredRoutes.at(0); + if (filteredRoute) { + return { + stateToRender: { + ...state, + index: 0, + routes: [filteredRoute], + }, + searchRoute: lastSearchCentralPane, + }; + } } return { diff --git a/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts b/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts index b8531ba9f292..5e1dfbc9076b 100644 --- a/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts +++ b/src/libs/Navigation/linkingConfig/getMatchingCentralPaneRouteForState.ts @@ -1,5 +1,5 @@ import getTopmostBottomTabRoute from '@libs/Navigation/getTopmostBottomTabRoute'; -import type {AuthScreensParamList, CentralPaneName, CentralPaneScreensParamList, NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types'; +import type {AuthScreensParamList, CentralPaneName, NavigationPartialRoute, RootStackParamList, State} from '@libs/Navigation/types'; import NAVIGATORS from '@src/NAVIGATORS'; import SCREENS from '@src/SCREENS'; import TAB_TO_CENTRAL_PANE_MAPPING from './TAB_TO_CENTRAL_PANE_MAPPING'; @@ -55,6 +55,10 @@ function getMatchingCentralPaneRouteForState(state: State, r const centralPaneName = TAB_TO_CENTRAL_PANE_MAPPING[topmostBottomTabRoute.name].at(0); + if (!centralPaneName) { + return; + } + if (topmostBottomTabRoute.name === SCREENS.SETTINGS.ROOT) { // When we go back to the settings tab without switching the workspace id, we want to return to the previously opened screen const screen = getAlreadyOpenedSettingsScreen(rootState) ?? centralPaneName; @@ -62,10 +66,10 @@ function getMatchingCentralPaneRouteForState(state: State, r } if (topmostBottomTabRoute.name === SCREENS.HOME) { - return {name: centralPaneName ?? ({} as keyof CentralPaneScreensParamList), params: {reportID: getTopMostReportIDFromRHP(state)}}; + return {name: centralPaneName, params: {reportID: getTopMostReportIDFromRHP(state)}}; } - return {name: centralPaneName ?? ({} as keyof CentralPaneScreensParamList)}; + return {name: centralPaneName}; } export default getMatchingCentralPaneRouteForState; diff --git a/src/libs/Network/SequentialQueue.ts b/src/libs/Network/SequentialQueue.ts index ebcbac1cf49f..2f7dc236ab7a 100644 --- a/src/libs/Network/SequentialQueue.ts +++ b/src/libs/Network/SequentialQueue.ts @@ -81,7 +81,6 @@ function process(): Promise { } const requestToProcess = persistedRequests.at(0); - if (!requestToProcess) { return Promise.resolve(); } diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index eadde71c0f92..0483d2220679 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -298,7 +298,6 @@ Onyx.connect({ // Iterate over the report actions to build the sorted and lastVisible report actions objects Object.entries(allReportActions).forEach((reportActions) => { const reportID = reportActions[0].split('_').at(1); - if (!reportID) { return; } @@ -316,7 +315,6 @@ Onyx.connect({ } const firstReportAction = sortedReportActions.at(0); - if (!firstReportAction) { return; } diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 0ab1af40c3d1..897cb1c58d2f 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -144,9 +144,11 @@ function getRateDisplayValue(value: number, toLocaleDigit: (arg: string) => stri } if (withDecimals) { - const decimalPart = numValue.toString().split('.')[1]; - const fixedDecimalPoints = decimalPart.length > 2 && !decimalPart.endsWith('0') ? 3 : 2; - return Number(numValue).toFixed(fixedDecimalPoints).toString().replace('.', toLocaleDigit('.')); + const decimalPart = numValue.toString().split('.').at(1); + if (decimalPart) { + const fixedDecimalPoints = decimalPart.length > 2 && !decimalPart.endsWith('0') ? 3 : 2; + return Number(numValue).toFixed(fixedDecimalPoints).toString().replace('.', toLocaleDigit('.')); + } } return numValue.toString().replace('.', toLocaleDigit('.')).substring(0, value.toString().length); diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index b7c7d6a7617f..ea57d833607a 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -715,10 +715,12 @@ function replaceBaseURLInPolicyChangeLogAction(reportAction: ReportAction): Repo return updatedReportAction; } - // eslint-disable-next-line rulesdir/prefer-at - if (Array.isArray(updatedReportAction.message) && updatedReportAction.message[0]) { - // eslint-disable-next-line rulesdir/prefer-at - updatedReportAction.message[0].html = getReportActionHtml(reportAction)?.replace('%baseURL', environmentURL); + if (Array.isArray(updatedReportAction.message)) { + const message = updatedReportAction.message.at(0); + + if (message) { + message.html = getReportActionHtml(reportAction)?.replace('%baseURL', environmentURL); + } } return updatedReportAction; @@ -835,7 +837,7 @@ function getFirstVisibleReportActionID(sortedReportActions: ReportAction[] = [], return ''; } const sortedFilterReportActions = sortedReportActions.filter((action) => !isDeletedAction(action) || (action?.childVisibleActionCount ?? 0) > 0 || isOffline); - return sortedFilterReportActions.length > 1 ? sortedFilterReportActions.at(sortedFilterReportActions.length - 2)?.reportActionID ?? '' : ''; + return sortedFilterReportActions.length > 1 ? sortedFilterReportActions.at(sortedFilterReportActions.length - 2)?.reportActionID ?? '-1' : ''; } /** diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index e51327e2b97e..27f66489ade3 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4244,10 +4244,11 @@ function buildOptimisticTaskCommentReportAction( createdOffset = 0, ): OptimisticReportAction { const reportAction = buildOptimisticAddCommentReportAction(text, undefined, undefined, createdOffset, undefined, taskReportID); - // eslint-disable-next-line rulesdir/prefer-at - if (Array.isArray(reportAction.reportAction.message) && reportAction.reportAction.message[0]) { - // eslint-disable-next-line rulesdir/prefer-at - reportAction.reportAction.message[0].taskReportID = taskReportID; + if (Array.isArray(reportAction.reportAction.message)) { + const message = reportAction.reportAction.message.at(0); + if (message) { + message.taskReportID = taskReportID; + } } else if (!Array.isArray(reportAction.reportAction.message) && reportAction.reportAction.message) { reportAction.reportAction.message.taskReportID = taskReportID; } diff --git a/src/libs/SearchUtils.ts b/src/libs/SearchUtils.ts index d291ba7ea82f..901758572acb 100644 --- a/src/libs/SearchUtils.ts +++ b/src/libs/SearchUtils.ts @@ -355,7 +355,7 @@ function getSortedTransactionData(data: TransactionListItemType[], sortBy?: Sear } function getReportNewestTransactionDate(report: ReportListItemType) { - return report.transactions?.reduce((max, curr) => (curr.modifiedCreated ?? curr.created > max.created ? curr : max), report.transactions[0])?.created; + return report.transactions?.reduce((max, curr) => (curr.modifiedCreated ?? curr.created > (max?.created ?? '') ? curr : max), report.transactions.at(0))?.created; } function getSortedReportData(data: ReportListItemType[]) { @@ -714,17 +714,7 @@ function buildFilterString(filterName: string, queryFilters: QueryFilter[], deli let filterValueString = ''; queryFilters.forEach((queryFilter, index) => { // If the previous queryFilter has the same operator (this rule applies only to eq and neq operators) then append the current value -<<<<<<< HEAD - if ((queryFilter.operator === 'eq' && queryFilters.at(index - 1)?.operator === 'eq') || (queryFilter.operator === 'neq' && queryFilters.at(index - 1)?.operator === 'neq')) { -======= - if ((queryFilter.operator === 'eq' && queryFilters[index - 1]?.operator === 'eq') || (queryFilter.operator === 'neq' && queryFilters[index - 1]?.operator === 'neq')) { -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa + if ((queryFilter.operator === 'eq' && queryFilters?.at(index - 1)?.operator === 'eq') || (queryFilter.operator === 'neq' && queryFilters.at(index - 1)?.operator === 'neq')) { filterValueString += `${delimiter}${sanitizeString(queryFilter.value.toString())}`; } else { filterValueString += ` ${filterName}${operatorToSignMap[queryFilter.operator]}${sanitizeString(queryFilter.value.toString())}`; @@ -755,7 +745,7 @@ function getSearchHeaderTitle( .filter(([, taxRateKeys]) => taxRateKeys.some((taxID) => taxRateIDs.includes(taxID))) .map(([taxRate]) => taxRate); displayQueryFilters = taxRateNames.map((taxRate) => ({ - operator: queryFilter[0].operator, + operator: queryFilter.at(0)?.operator ?? 'and', value: taxRate, })); } else { diff --git a/src/libs/SidebarUtils.ts b/src/libs/SidebarUtils.ts index 2c526c31f7e5..bb7707207750 100644 --- a/src/libs/SidebarUtils.ts +++ b/src/libs/SidebarUtils.ts @@ -303,17 +303,7 @@ function getOptionData({ const visibleParticipantAccountIDs = ReportUtils.getParticipantsAccountIDsForDisplay(report, true); const participantPersonalDetailList = Object.values(OptionsListUtils.getPersonalDetailsForAccountIDs(participantAccountIDs, personalDetails)); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD const personalDetail = participantPersonalDetailList.at(0) ?? ({} as PersonalDetails); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - const personalDetail = participantPersonalDetailList[0] ?? {}; ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 const hasErrors = Object.keys(result.allReportErrors ?? {}).length !== 0; result.isThread = ReportUtils.isChatThread(report); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 533de7b72487..f7616bd53b55 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3868,7 +3868,7 @@ function trackExpense( function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { // The existing chat report could be passed as reportID or exist on the sole "participant" (in this case a report option) - const existingChatReportID = existingSplitChatReportID || (participants.at(0)?.reportID ?? ''); + const existingChatReportID = existingSplitChatReportID || (participants.at(0)?.reportID ?? '-1'); // Check if the report is available locally if we do have one let existingSplitChatReport = existingChatReportID ? ReportConnection.getAllReports()?.[`${ONYXKEYS.COLLECTION.REPORT}${existingChatReportID}`] : null; @@ -7514,7 +7514,7 @@ function completePaymentOnboarding(paymentSelected: ValueOf { - if (!Array.isArray(data) || !Array.isArray(data[0])) { + if (!Array.isArray(data) || !Array.isArray(data.at(0))) { return Promise.reject(new Error('Invalid data format')); } - const transposedData = data[0].map((_, colIndex) => data.map((row) => row[colIndex])); - const columnNames: Record = data[0].reduce((acc: Record, _, colIndex) => { - acc[colIndex] = CONST.CSV_IMPORT_COLUMNS.IGNORE; - return acc; - }, {}); + const transposedData = data.at(0)?.map((_, colIndex) => data.map((row) => row.at(colIndex) ?? '')); + const columnNames: Record = + data.at(0)?.reduce((acc: Record, _, colIndex) => { + acc[colIndex] = CONST.CSV_IMPORT_COLUMNS.IGNORE; + return acc; + }, {}) ?? {}; return Onyx.merge(ONYXKEYS.IMPORTED_SPREADSHEET, {data: transposedData, columns: columnNames}); } diff --git a/src/libs/actions/Policy/Category.ts b/src/libs/actions/Policy/Category.ts index 5716eed8947d..8b99dc1a360e 100644 --- a/src/libs/actions/Policy/Category.ts +++ b/src/libs/actions/Policy/Category.ts @@ -1169,7 +1169,10 @@ function setPolicyCategoryApprover(policyID: string, categoryName: string, appro newApprover = ''; } else { const indexToUpdate = updatedApprovalRules.indexOf(existingCategoryApproverRule); - updatedApprovalRules[indexToUpdate].approver = approver; + const approvalRule = updatedApprovalRules.at(indexToUpdate); + if (approvalRule) { + approvalRule.approver = approver; + } } const onyxData: OnyxData = { @@ -1253,7 +1256,11 @@ function setPolicyCategoryTax(policyID: string, categoryName: string, taxID: str }); } else { const indexToUpdate = updatedExpenseRules.indexOf(existingCategoryExpenseRule); - updatedExpenseRules[indexToUpdate].tax.field_id_TAX.externalID = taxID; + const expenseRule = updatedExpenseRules.at(indexToUpdate); + + if (expenseRule) { + expenseRule.tax.field_id_TAX.externalID = taxID; + } } const onyxData: OnyxData = { diff --git a/src/libs/actions/Policy/Tag.ts b/src/libs/actions/Policy/Tag.ts index 251be17998df..e78f2f3af3a0 100644 --- a/src/libs/actions/Policy/Tag.ts +++ b/src/libs/actions/Policy/Tag.ts @@ -451,7 +451,6 @@ function renamePolicyTag(policyID: string, policyTag: {oldName: string; newName: ...tag, name: newTagName, pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment pendingFields: { ...tag.pendingFields, name: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 1dcedd99deca..5862ebf52ac3 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -859,18 +859,19 @@ function openReport( if (isCreatingNewReport) { // Change the method to set for new reports because it doesn't exist yet, is faster, // and we need the data to be available when we navigate to the chat page - // eslint-disable-next-line rulesdir/prefer-at - optimisticData[0].onyxMethod = Onyx.METHOD.SET; - // eslint-disable-next-line rulesdir/prefer-at - optimisticData[0].value = { - ...optimisticReport, - reportName: CONST.REPORT.DEFAULT_REPORT_NAME, - ...newReportObject, - pendingFields: { - createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, - }, - isOptimisticReport: true, - }; + const optimisticDataItem = optimisticData.at(0); + if (optimisticDataItem) { + optimisticDataItem.onyxMethod = Onyx.METHOD.SET; + optimisticDataItem.value = { + ...optimisticReport, + reportName: CONST.REPORT.DEFAULT_REPORT_NAME, + ...newReportObject, + pendingFields: { + createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, + }, + isOptimisticReport: true, + }; + } let emailCreatingAction: string = CONST.REPORT.OWNER_EMAIL_FAKE; if (newReportObject.ownerAccountID && newReportObject.ownerAccountID !== CONST.REPORT.OWNER_ACCOUNT_ID_FAKE) { diff --git a/src/libs/actions/Welcome/OnboardingFlow.ts b/src/libs/actions/Welcome/OnboardingFlow.ts index 4e780090299d..4c275dfdd062 100644 --- a/src/libs/actions/Welcome/OnboardingFlow.ts +++ b/src/libs/actions/Welcome/OnboardingFlow.ts @@ -46,7 +46,7 @@ function adaptOnboardingRouteState() { const rootState = navigationRef.getRootState(); const adaptedState = rootState; const lastRouteIndex = (adaptedState?.routes?.length ?? 0) - 1; - const onBoardingModalNavigatorState = adaptedState?.routes[lastRouteIndex]?.state; + const onBoardingModalNavigatorState = adaptedState?.routes.at(lastRouteIndex)?.state; if (!onBoardingModalNavigatorState || onBoardingModalNavigatorState?.routes?.length > 1) { return; } @@ -80,7 +80,11 @@ function adaptOnboardingRouteState() { } as Readonly>; } - adaptedState.routes[lastRouteIndex].state = adaptedOnboardingModalNavigatorState; + const route = adaptedState.routes.at(lastRouteIndex); + + if (route) { + route.state = adaptedOnboardingModalNavigatorState; + } navigationRef.resetRoot(adaptedState); } diff --git a/src/libs/actions/Workflow.ts b/src/libs/actions/Workflow.ts index 3ca6172decd7..9731b62838f5 100644 --- a/src/libs/actions/Workflow.ts +++ b/src/libs/actions/Workflow.ts @@ -122,17 +122,7 @@ function updateApprovalWorkflow(policyID: string, approvalWorkflow: ApprovalWork } const previousDefaultApprover = policy.approver ?? policy.owner; -<<<<<<< HEAD const newDefaultApprover = approvalWorkflow.isDefault ? approvalWorkflow.approvers.at(0)?.email : undefined; -======= - const newDefaultApprover = approvalWorkflow.isDefault ? approvalWorkflow.approvers[0].email : undefined; -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa const previousEmployeeList = Object.fromEntries(Object.entries(policy.employeeList ?? {}).map(([key, value]) => [key, {...value, pendingAction: null}])); const updatedEmployees = convertApprovalWorkflowToPolicyEmployees({ previousEmployeeList, diff --git a/src/libs/memoize/cache/ArrayCache.ts b/src/libs/memoize/cache/ArrayCache.ts index 64ebb00344bf..209250e47675 100644 --- a/src/libs/memoize/cache/ArrayCache.ts +++ b/src/libs/memoize/cache/ArrayCache.ts @@ -16,8 +16,8 @@ function ArrayCache(config: CacheConfig): Cache { */ function getKeyIndex(key: K): number { for (let i = cache.length - 1; i >= 0; i--) { - // eslint-disable-next-line rulesdir/prefer-at - if (keyComparator(cache[i][0], key)) { + const cacheItem = cache.at(i)?.at(0); + if (cacheItem && keyComparator(cacheItem as K, key)) { return i; } } diff --git a/src/pages/Search/SearchTypeMenuNarrow.tsx b/src/pages/Search/SearchTypeMenuNarrow.tsx index 0158a15bfc41..269cca9eac23 100644 --- a/src/pages/Search/SearchTypeMenuNarrow.tsx +++ b/src/pages/Search/SearchTypeMenuNarrow.tsx @@ -101,8 +101,8 @@ function SearchTypeMenuNarrow({typeMenuItems, activeItemIndex, queryJSON, title, return items; }, [typeMenuItems, activeItemIndex, title, theme, singleExecution, closeMenu, currentSavedSearch]); - const menuIcon = useMemo(() => (title ? Expensicons.Filters : popoverMenuItems[activeItemIndex]?.icon ?? Expensicons.Receipt), [activeItemIndex, popoverMenuItems, title]); - const menuTitle = useMemo(() => title ?? popoverMenuItems[activeItemIndex]?.text, [activeItemIndex, popoverMenuItems, title]); + const menuIcon = useMemo(() => (title ? Expensicons.Filters : popoverMenuItems.at(activeItemIndex)?.icon ?? Expensicons.Receipt), [activeItemIndex, popoverMenuItems, title]); + const menuTitle = useMemo(() => title ?? popoverMenuItems.at(activeItemIndex)?.text, [activeItemIndex, popoverMenuItems, title]); const titleViewStyles = useMemo(() => (title ? {...styles.flex1, ...styles.justifyContentCenter} : {}), [title, styles]); const savedSearchItems = savedSearchesMenuItems.map((item) => ({ @@ -139,7 +139,7 @@ function SearchTypeMenuNarrow({typeMenuItems, activeItemIndex, queryJSON, title, >>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - const mostRecentReportAction = reportActions[0]; ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - const mostRecentReportAction = reportActions[0]; ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa const shouldShowMostRecentReportAction = !!mostRecentReportAction && !ReportActionsUtils.isActionOfType(mostRecentReportAction, CONST.REPORT.ACTIONS.TYPE.CREATED) && diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 5ec59c10cc78..340624247dee 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -283,17 +283,7 @@ function ReportActionsList({ return; } -<<<<<<< HEAD const mostRecentReportActionCreated = sortedVisibleReportActions.at(0)?.created ?? ''; -======= - const mostRecentReportActionCreated = sortedVisibleReportActions[0]?.created ?? ''; -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa if (mostRecentReportActionCreated === unreadMarkerTime) { return; } diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index 2b9ebf88f0cf..452e5bf539b9 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -403,7 +403,7 @@ function ReportActionsView({ didLoadNewerChats.current = true; if ((reportActionID && indexOfLinkedAction > -1) || !reportActionID) { - handleReportActionPagination({firstReportActionID: newestReportAction?.reportActionID ?? ''}); + handleReportActionPagination({firstReportActionID: newestReportAction?.reportActionID ?? '-1'}); } }, [ diff --git a/src/pages/settings/Security/AddDelegate/ValidateCodeForm/BaseValidateCodeForm.tsx b/src/pages/settings/Security/AddDelegate/ValidateCodeForm/BaseValidateCodeForm.tsx index c9816862ad35..5b01568d018e 100644 --- a/src/pages/settings/Security/AddDelegate/ValidateCodeForm/BaseValidateCodeForm.tsx +++ b/src/pages/settings/Security/AddDelegate/ValidateCodeForm/BaseValidateCodeForm.tsx @@ -161,7 +161,7 @@ function BaseValidateCodeForm({autoComplete = 'one-time-code', innerRef = () => name="validateCode" value={validateCode} onChangeText={onTextInput} - errorText={formError?.validateCode ? translate(formError?.validateCode) : Object.values(validateLoginError ?? {})[0] ?? ''} + errorText={formError?.validateCode ? translate(formError?.validateCode) : Object.values(validateLoginError ?? {}).at(0) ?? ''} hasError={!isEmptyObject(validateLoginError)} onFulfill={validateAndSubmitForm} autoFocus={false} diff --git a/src/pages/settings/Wallet/PaymentMethodList.tsx b/src/pages/settings/Wallet/PaymentMethodList.tsx index 56815de92f74..df6fdc2f9dcd 100644 --- a/src/pages/settings/Wallet/PaymentMethodList.tsx +++ b/src/pages/settings/Wallet/PaymentMethodList.tsx @@ -244,11 +244,12 @@ function PaymentMethodList({ // The card should be grouped to a specific domain and such domain already exists in a assignedCardsGrouped if (assignedCardsGrouped.some((item) => item.isGroupedCardDomain && item.description === card.domainName) && !isAdminIssuedVirtualCard) { const domainGroupIndex = assignedCardsGrouped.findIndex((item) => item.isGroupedCardDomain && item.description === card.domainName); - // eslint-disable-next-line rulesdir/prefer-at - assignedCardsGrouped[domainGroupIndex].errors = {...assignedCardsGrouped.at(domainGroupIndex)?.errors, ...card.errors}; - if (card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN || card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL) { - // eslint-disable-next-line rulesdir/prefer-at - assignedCardsGrouped[domainGroupIndex].brickRoadIndicator = CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR; + const assignedCardsGroupedItem = assignedCardsGrouped.at(domainGroupIndex); + if (assignedCardsGroupedItem) { + assignedCardsGroupedItem.errors = {...assignedCardsGrouped.at(domainGroupIndex)?.errors, ...card.errors}; + if (card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.DOMAIN || card.fraud === CONST.EXPENSIFY_CARD.FRAUD_TYPES.INDIVIDUAL) { + assignedCardsGroupedItem.brickRoadIndicator = CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR; + } } return; } diff --git a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx index e7b9876f4a99..2ac7dca70cb4 100644 --- a/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx +++ b/src/pages/workspace/accounting/qbo/advanced/QuickbooksAdvancedPage.tsx @@ -152,19 +152,7 @@ function QuickbooksAdvancedPage({policy}: WithPolicyConnectionsProps) { policyID, CONST.POLICY.CONNECTIONS.NAME.QBO, CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID, -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD - isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions].at(0)?.id, -======= - isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions][0].id, ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions][0].id, ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions][0].id, ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa + isSyncReimbursedSwitchOn ? '' : [...qboAccountOptions, ...invoiceAccountCollectionOptions]?.at(0)?.id, qboConfig?.collectionAccountID, ), subscribedSetting: CONST.QUICKBOOKS_CONFIG.COLLECTION_ACCOUNT_ID, diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx index 82b25dd9c3ed..e8b74ae9ce46 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksCompanyCardExpenseAccountSelectCardPage.tsx @@ -71,19 +71,7 @@ function QuickbooksCompanyCardExpenseAccountSelectCardPage({policy}: WithPolicyC CONST.POLICY.CONNECTIONS.NAME.QBO, { [CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSES_EXPORT_DESTINATION]: row.value, -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD [CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts.at(0), -======= - [CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts[0], ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - [CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts[0], ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - [CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts[0], ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa [CONST.QUICKBOOKS_CONFIG.NON_REIMBURSABLE_BILL_DEFAULT_VENDOR]: row.defaultVendor, }, { @@ -108,19 +96,7 @@ function QuickbooksCompanyCardExpenseAccountSelectCardPage({policy}: WithPolicyC listItem={RadioListItem} onSelectRow={(selection: SelectorType) => selectExportCompanyCard(selection as MenuItem)} shouldSingleExecuteRowSelect -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD initiallyFocusedOptionKey={sections.at(0)?.data.find((mode) => mode.isSelected)?.keyForList} -======= - initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT.getRoute(policyID))} listFooterContent={ diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx index d8ce343b74a2..d9656c41f069 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksNonReimbursableDefaultVendorSelectPage.tsx @@ -74,19 +74,7 @@ function QuickbooksNonReimbursableDefaultVendorSelectPage({policy}: WithPolicyCo listItem={RadioListItem} onSelectRow={selectVendor} shouldSingleExecuteRowSelect -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD initiallyFocusedOptionKey={sections.at(0)?.data.find((mode) => mode.isSelected)?.keyForList} -======= - initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - initiallyFocusedOptionKey={sections[0]?.data.find((mode) => mode.isSelected)?.keyForList} ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa listEmptyContent={listEmptyContent} connectionName={CONST.POLICY.CONNECTIONS.NAME.QBO} onBackButtonPress={() => Navigation.goBack(ROUTES.POLICY_ACCOUNTING_QUICKBOOKS_ONLINE_COMPANY_CARD_EXPENSE_ACCOUNT.getRoute(policyID))} diff --git a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx index 4e77421ce884..0fd977fb5b13 100644 --- a/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx +++ b/src/pages/workspace/accounting/qbo/export/QuickbooksOutOfPocketExpenseEntitySelectPage.tsx @@ -90,19 +90,7 @@ function QuickbooksOutOfPocketExpenseEntitySelectPage({policy}: WithPolicyConnec CONST.POLICY.CONNECTIONS.NAME.QBO, { [CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_EXPORT_DESTINATION]: row.value, -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD [CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts.at(0), -======= - [CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts[0], ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - [CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts[0], ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - [CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_ACCOUNT]: row.accounts[0], ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }, { [CONST.QUICKBOOKS_CONFIG.REIMBURSABLE_EXPENSES_EXPORT_DESTINATION]: qboConfig?.reimbursableExpensesExportDestination, diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx index b1876c17efd5..75f7672199cb 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardFeedSelectorPage.tsx @@ -57,7 +57,7 @@ function WorkspaceCompanyCardFeedSelectorPage({route}: WorkspaceCompanyCardFeedS const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); const cardFeeds = mockedData; - const defaultFeed = Object.keys(cardFeeds?.companyCards ?? {})[0]; + const defaultFeed = Object.keys(cardFeeds?.companyCards ?? {}).at(0); const selectedFeed = lastSelectedFeed ?? defaultFeed; const feeds: CardFeedListItem[] = Object.entries(cardFeeds?.companyCardNicknames ?? {}).map(([key, value]) => ({ diff --git a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx index c197d5174e43..b2dbafbdcaba 100644 --- a/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx +++ b/src/pages/workspace/companyCards/WorkspaceCompanyCardsPage.tsx @@ -132,7 +132,7 @@ function WorkspaceCompanyCardPage({route}: WorkspaceCompanyCardPageProps) { // const [cardFeeds] = useOnyx(`${ONYXKEYS.COLLECTION.SHARED_NVP_PRIVATE_DOMAIN_MEMBER}${workspaceAccountID}`); const cardFeeds = mockedFeeds; const [lastSelectedFeed] = useOnyx(`${ONYXKEYS.COLLECTION.LAST_SELECTED_FEED}${policyID}`); - const defaultFeed = Object.keys(cardFeeds?.companyCards ?? {})[0]; + const defaultFeed = Object.keys(cardFeeds?.companyCards ?? {}).at(0); const selectedFeed = lastSelectedFeed ?? defaultFeed; // TODO: use data form onyx instead of mocked one when API is implemented @@ -196,7 +196,7 @@ function WorkspaceCompanyCardPage({route}: WorkspaceCompanyCardPageProps) { {isFeedAdded && ( )} {!isFeedAdded && } diff --git a/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx b/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx index 6ed985ca4259..e6c3a1b4a058 100644 --- a/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx +++ b/src/pages/workspace/tags/WorkspaceTagsSettingsPage.tsx @@ -74,9 +74,6 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag {!isMultiLevelTags && ( Tag.clearPolicyTagListErrors(policyID, policyTagLists.at(0)?.orderWeight ?? 0)} pendingAction={policyTags?.[policyTagLists.at(0)?.name ?? '']?.pendingAction} @@ -115,50 +112,6 @@ function WorkspaceTagsSettingsPage({route, policyTags}: WorkspaceTagsSettingsPag onToggle={() => toggleBillableExpenses(policy)} /> -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - errors={policyTags?.[policyTagLists[0]?.name]?.errors} - onClose={() => Tag.clearPolicyTagListErrors(policyID, policyTagLists[0].orderWeight)} - pendingAction={policyTags?.[policyTagLists[0]?.name]?.pendingAction} - errorRowStyles={styles.mh5} - > - Navigation.navigate(ROUTES.WORKSPACE_EDIT_TAGS.getRoute(policyID, policyTagLists[0].orderWeight))} - shouldShowRightIcon - /> ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 - - )} - - - {translate('workspace.tags.requiresTag')} - - - - {canUseWorkspaceRules && policy?.areRulesEnabled && ( - - - {translate('workspace.tags.trackBillable')} - toggleBillableExpenses(policy)} - /> - )} { if (selectedApproverEmail) { @@ -214,54 +214,6 @@ function WorkspaceWorkflowsApprovalsApproverPage({policy, personalDetails, isLoa [translate, styles.textSupporting, styles.pb10], ); - const listEmptyContent = useMemo( - () => ( - - ), - [translate, styles.textSupporting, styles.pb10], - ); - - const listEmptyContent = useMemo( - () => ( - - ), - [translate, styles.textSupporting, styles.pb10], - ); - - const listEmptyContent = useMemo( - () => ( - - ), - [translate, styles.textSupporting, styles.pb10], - ); - return ( >>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa setIsDeleteModalVisible(false); Navigation.dismissModal(); InteractionManager.runAfterInteractions(() => { // Remove the approval workflow using the initial data as it could be already edited Workflow.removeApprovalWorkflow(route.params.policyID, initialApprovalWorkflow); }); -<<<<<<< HEAD ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }, [initialApprovalWorkflow, route.params.policyID]); const {currentApprovalWorkflow, defaultWorkflowMembers, usedApproverEmails} = useMemo(() => { diff --git a/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsExpensesFromPage.tsx b/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsExpensesFromPage.tsx index 3823b9fb1489..917ef5b8d2ff 100644 --- a/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsExpensesFromPage.tsx +++ b/src/pages/workspace/workflows/approvals/WorkspaceWorkflowsApprovalsExpensesFromPage.tsx @@ -194,54 +194,6 @@ function WorkspaceWorkflowsApprovalsExpensesFromPage({policy, isLoadingReportDat [translate, styles.textSupporting, styles.pb10], ); - const listEmptyContent = useMemo( - () => ( - - ), - [translate, styles.textSupporting, styles.pb10], - ); - - const listEmptyContent = useMemo( - () => ( - - ), - [translate, styles.textSupporting, styles.pb10], - ); - - const listEmptyContent = useMemo( - () => ( - - ), - [translate, styles.textSupporting, styles.pb10], - ); - return ( {}, +}; + // Arguments can be passed to the component by binding // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args const Default: StoryType = Template.bind({}); Default.args = { - promotedActions: [promotedActions[0]], + promotedActions: [promotedActions.at(0) ?? defaultPromotedAction], }; const TwoPromotedActions: StoryType = Template.bind({}); TwoPromotedActions.args = { - promotedActions: [promotedActions[0], promotedActions[1]], + promotedActions: [promotedActions.at(0) ?? defaultPromotedAction, promotedActions.at(1) ?? defaultPromotedAction], }; const ThreePromotedActions: StoryType = Template.bind({}); ThreePromotedActions.args = { - promotedActions: [promotedActions[0], promotedActions[1], promotedActions[2]], + promotedActions: [promotedActions.at(0) ?? defaultPromotedAction, promotedActions.at(1) ?? defaultPromotedAction, promotedActions.at(2) ?? defaultPromotedAction], }; export default story; diff --git a/tests/perf-test/ReportActionsList.perf-test.tsx b/tests/perf-test/ReportActionsList.perf-test.tsx index 8f4c39d5f7a2..2928f73c53ce 100644 --- a/tests/perf-test/ReportActionsList.perf-test.tsx +++ b/tests/perf-test/ReportActionsList.perf-test.tsx @@ -82,7 +82,7 @@ beforeEach(() => { function ReportActionsListWrapper() { const reportActions = ReportTestUtils.getMockedSortedReportActions(500); - const lastVisibleActionCreated = reportActions[0].created; + const lastVisibleActionCreated = reportActions.at(0)?.created; const report = { ...LHNTestUtilsModule.getFakeReport(), lastVisibleActionCreated, diff --git a/tests/unit/SidebarOrderTest.ts b/tests/unit/SidebarOrderTest.ts index 3dffe02f185f..1de2654c09bf 100644 --- a/tests/unit/SidebarOrderTest.ts +++ b/tests/unit/SidebarOrderTest.ts @@ -135,27 +135,9 @@ describe('Sidebar', () => { const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -206,27 +188,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Two'); // this has `hasDraft` flag enabled so it will be on top expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); -======= - expect(displayNames[0]).toHaveTextContent('Email Two'); // this has `hasDraft` flag enabled so it will be on top - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Two'); // this has `hasDraft` flag enabled so it will be on top - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Two'); // this has `hasDraft` flag enabled so it will be on top - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -275,27 +239,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Two'); expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); -======= - expect(displayNames[0]).toHaveTextContent('Email Two'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Two'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Two'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -347,23 +293,10 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent(taskReportName); expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent(taskReportName); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Two'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -434,29 +367,10 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Four owes $100.00'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Two'); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Four owes $100.00'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Two'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -532,29 +446,10 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email One'); expect(displayNames.at(1)).toHaveTextContent('Workspace-Test-001 owes $100.00'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Two'); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - expect(displayNames[0]).toHaveTextContent('Email One'); - expect(displayNames[1]).toHaveTextContent('Workspace-Test-001 owes $100.00'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Two'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -611,27 +506,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Three'); expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent('Email Three'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Three'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Three'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -797,29 +674,10 @@ describe('Sidebar', () => { expect(displayNames).toHaveLength(4); expect(screen.queryAllByTestId('Pin Icon')).toHaveLength(1); expect(screen.queryAllByTestId('Pencil Icon')).toHaveLength(1); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Two'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Five'); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Two'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Five'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -869,27 +727,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) // When a new report is added @@ -900,29 +740,10 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Five'); expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Two'); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - expect(displayNames[0]).toHaveTextContent('Email Five'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Two'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -975,27 +796,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) // When a new report is added @@ -1013,29 +816,10 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Five'); expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Two'); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - expect(displayNames[0]).toHaveTextContent('Email Five'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Two'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -1087,27 +871,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Report (archived)'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Report (archived)'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Report (archived)'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Report (archived)'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -1148,27 +914,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -1206,27 +954,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Email Two'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Email Two'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) // When a new report is added @@ -1237,29 +967,10 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(4); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Five'); expect(displayNames.at(1)).toHaveTextContent('Email Four'); expect(displayNames.at(2)).toHaveTextContent('Email Three'); expect(displayNames.at(3)).toHaveTextContent('Email Two'); -======= -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa - expect(displayNames[0]).toHaveTextContent('Email Five'); - expect(displayNames[1]).toHaveTextContent('Email Four'); - expect(displayNames[2]).toHaveTextContent('Email Three'); - expect(displayNames[3]).toHaveTextContent('Email Two'); -<<<<<<< HEAD -<<<<<<< HEAD ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); @@ -1310,27 +1021,9 @@ describe('Sidebar', () => { const hintText = Localize.translateLocal('accessibilityHints.chatUserDisplayNames'); const displayNames = screen.queryAllByLabelText(hintText); expect(displayNames).toHaveLength(3); -<<<<<<< HEAD -<<<<<<< HEAD -<<<<<<< HEAD expect(displayNames.at(0)).toHaveTextContent('Email Four'); expect(displayNames.at(1)).toHaveTextContent('Email Three'); expect(displayNames.at(2)).toHaveTextContent('Report (archived)'); -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Report (archived)'); ->>>>>>> 0c618acc8b5a0b77eb27dfa049a18e3135c51c52 -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Report (archived)'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa -======= - expect(displayNames[0]).toHaveTextContent('Email Four'); - expect(displayNames[1]).toHaveTextContent('Email Three'); - expect(displayNames[2]).toHaveTextContent('Report (archived)'); ->>>>>>> 4a9725c73b9338a3901a9dfdf13d14916f33f4aa }) ); }); diff --git a/tests/unit/WorkflowUtilsTest.ts b/tests/unit/WorkflowUtilsTest.ts index f64251c7279a..8508ab6466ba 100644 --- a/tests/unit/WorkflowUtilsTest.ts +++ b/tests/unit/WorkflowUtilsTest.ts @@ -1,4 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ + /* eslint-disable rulesdir/prefer-at */ import * as WorkflowUtils from '@src/libs/WorkflowUtils'; import type {Approver, Member} from '@src/types/onyx/ApprovalWorkflow';