From 00ecb933ac23973394113390b75be6884594c387 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 2 May 2023 08:26:07 -0700 Subject: [PATCH] test(lint): separate multiline comments (#6476) --- .eslintrc.js | 6 +++ .../MiniPortfolio/Pools/index.tsx | 12 ++--- .../LiquidityChartRangeInput/svg.tsx | 2 +- .../Tokens/TokenDetails/PriceChart.tsx | 8 ++- src/components/swap/SwapBuyFiatButton.tsx | 18 +++---- src/connection/activate.ts | 6 +-- src/constants/chains.ts | 2 +- src/constants/tokenSafety.tsx | 3 +- src/graphql/data/Token.ts | 14 +++-- src/hooks/useENSName.ts | 7 ++- .../useFilterPossiblyMaliciousPositions.ts | 2 +- src/hooks/useTokenInfoFromActiveList.ts | 4 +- src/nft/utils/urlParams.ts | 47 +++++++--------- src/pages/TokenDetails/index.tsx | 4 +- src/state/application/atoms.ts | 16 +++--- src/state/wallets/reducer.ts | 4 +- src/tracing/errors.ts | 53 +++++++------------ 17 files changed, 90 insertions(+), 118 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index fde23cece1..697196bbd7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,6 +5,12 @@ require('@uniswap/eslint-config/load') module.exports = { extends: '@uniswap/eslint-config/react', overrides: [ + { + files: ['**/*'], + rules: { + 'multiline-comment-style': ['error', 'separate-lines'], + }, + }, { // Configuration/typings typically export objects/definitions that are used outside of the transpiled package // (eg not captured by the tsconfig). Because it's typical and not exceptional, this is turned off entirely. diff --git a/src/components/AccountDrawer/MiniPortfolio/Pools/index.tsx b/src/components/AccountDrawer/MiniPortfolio/Pools/index.tsx index 40d021a061..38d07b3ff4 100644 --- a/src/components/AccountDrawer/MiniPortfolio/Pools/index.tsx +++ b/src/components/AccountDrawer/MiniPortfolio/Pools/index.tsx @@ -22,12 +22,12 @@ import { PositionInfo } from './cache' import { useFeeValues } from './hooks' import useMultiChainPositions from './useMultiChainPositions' -/* - This hook takes an array of PositionInfo objects (format used by the Uniswap Labs gql API). - The hook access PositionInfo.details (format used by the NFT position contract), - filters the PositionDetails data for malicious content, - and then returns the original data in its original format. -*/ +/** + * Takes an array of PositionInfo objects (format used by the Uniswap Labs gql API). + * The hook access PositionInfo.details (format used by the NFT position contract), + * filters the PositionDetails data for malicious content, + * and then returns the original data in its original format. + */ function useFilterPossiblyMaliciousPositionInfo(positions: PositionInfo[] | undefined): PositionInfo[] { const tokenIdsToPositionInfo: Record = useMemo( () => diff --git a/src/components/LiquidityChartRangeInput/svg.tsx b/src/components/LiquidityChartRangeInput/svg.tsx index fb064ab2bb..f8227b5c54 100644 --- a/src/components/LiquidityChartRangeInput/svg.tsx +++ b/src/components/LiquidityChartRangeInput/svg.tsx @@ -1,4 +1,4 @@ -/* +/** * Generates an SVG path for the east brush handle. * Apply `scale(-1, 1)` to generate west brush handle. * diff --git a/src/components/Tokens/TokenDetails/PriceChart.tsx b/src/components/Tokens/TokenDetails/PriceChart.tsx index cf2a65c35d..f78bd48629 100644 --- a/src/components/Tokens/TokenDetails/PriceChart.tsx +++ b/src/components/Tokens/TokenDetails/PriceChart.tsx @@ -262,11 +262,9 @@ export function PriceChart({ width, height, prices: originalPrices, timePeriod } const crosshairEdgeMax = width * 0.85 const crosshairAtEdge = !!crosshair && crosshair > crosshairEdgeMax - /* - * Default curve doesn't look good for the HOUR chart. - * Higher values make the curve more rigid, lower values smooth the curve but make it less "sticky" to real data points, - * making it unacceptable for shorter durations / smaller variances. - */ + // Default curve doesn't look good for the HOUR chart. + // Higher values make the curve more rigid, lower values smooth the curve but make it less "sticky" to real data points, + // making it unacceptable for shorter durations / smaller variances. const curveTension = timePeriod === TimePeriod.HOUR ? 1 : 0.9 const getX = useMemo(() => (p: PricePoint) => timeScale(p.timestamp), [timeScale]) diff --git a/src/components/swap/SwapBuyFiatButton.tsx b/src/components/swap/SwapBuyFiatButton.tsx index baa5937cce..4e0b3521cc 100644 --- a/src/components/swap/SwapBuyFiatButton.tsx +++ b/src/components/swap/SwapBuyFiatButton.tsx @@ -56,16 +56,14 @@ export default function SwapBuyFiatButton() { const [buyFiatFlowState, setBuyFiatFlowState] = useState(BuyFiatFlowState.INACTIVE) const [walletDrawerOpen, toggleWalletDrawer] = useAccountDrawer() - /* - * Depending on the current state of the buy fiat flow the user is in (buyFiatFlowState), - * the desired behavior of clicking the 'Buy' button is different. - * 1) Initially upon first click, need to check the availability of the feature in the user's - * region, and continue the flow. - * 2) If the feature is available in the user's region, need to connect a wallet, and continue - * the flow. - * 3) If the feature is available and a wallet account is connected, show fiat on ramp modal. - * 4) If the feature is unavailable, show feature unavailable tooltip. - */ + // Depending on the current state of the buy fiat flow the user is in (buyFiatFlowState), + // the desired behavior of clicking the 'Buy' button is different. + // 1) Initially upon first click, need to check the availability of the feature in the user's + // region, and continue the flow. + // 2) If the feature is available in the user's region, need to connect a wallet, and continue + // the flow. + // 3) If the feature is available and a wallet account is connected, show fiat on ramp modal. + // 4) If the feature is unavailable, show feature unavailable tooltip. const handleBuyCrypto = useCallback(() => { if (!fiatOnrampAvailabilityChecked) { setCheckFiatRegionAvailability(true) diff --git a/src/connection/activate.ts b/src/connection/activate.ts index 09dead9950..361aa9b32b 100644 --- a/src/connection/activate.ts +++ b/src/connection/activate.ts @@ -28,10 +28,8 @@ function useTryActivation() { return useCallback( async (connection: Connection, onSuccess: () => void) => { - /* - * Skips wallet connection if the connection should override the default - * behavior, i.e. install MetaMask or launch Coinbase app - */ + // Skips wallet connection if the connection should override the default + // behavior, i.e. install MetaMask or launch Coinbase app if (connection.overrideActivate?.()) return try { diff --git a/src/constants/chains.ts b/src/constants/chains.ts index 49becc93bf..bf5acac7a2 100644 --- a/src/constants/chains.ts +++ b/src/constants/chains.ts @@ -1,4 +1,4 @@ -/* +/** * SupportedChainId must be defined inline, without using @uniswap/sdk-core, so that its members are their own types * {@see https://www.typescriptlang.org/docs/handbook/enums.html#union-enums-and-enum-member-types}. This allows the * derived const arrays and their types (eg {@link L1_CHAIN_IDS}, {@link SupportedL1ChainId}) to be narrowed and used diff --git a/src/constants/tokenSafety.tsx b/src/constants/tokenSafety.tsx index b10c3247d1..d8e2f8af09 100644 --- a/src/constants/tokenSafety.tsx +++ b/src/constants/tokenSafety.tsx @@ -56,8 +56,7 @@ export function getWarningCopy(warning: Warning | null, plural = false) { export type Warning = { level: WARNING_LEVEL message: JSX.Element - /* canProceed determines whether triangle/slash alert icon is used, and - whether this token is supported/able to be traded */ + /** Determines whether triangle/slash alert icon is used, and whether this token is supported/able to be traded. */ canProceed: boolean } diff --git a/src/graphql/data/Token.ts b/src/graphql/data/Token.ts index bbf35ad7f4..dae4fe3e1e 100644 --- a/src/graphql/data/Token.ts +++ b/src/graphql/data/Token.ts @@ -5,14 +5,12 @@ import { WrappedTokenInfo } from 'state/lists/wrappedTokenInfo' import { TokenQuery } from './__generated__/types-and-hooks' import { CHAIN_NAME_TO_CHAIN_ID } from './util' -/* -The difference between Token and TokenProject: - Token: an on-chain entity referring to a contract (e.g. uni token on ethereum 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984) - TokenProject: an off-chain, aggregated entity that consists of a token and its bridged tokens (e.g. uni token on all chains) - TokenMarket and TokenProjectMarket then are market data entities for the above. - TokenMarket is per-chain market data for contracts pulled from the graph. - TokenProjectMarket is aggregated market data (aggregated over multiple dexes and centralized exchanges) that we get from coingecko. -*/ +// The difference between Token and TokenProject: +// Token: an on-chain entity referring to a contract (e.g. uni token on ethereum 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984) +// TokenProject: an off-chain, aggregated entity that consists of a token and its bridged tokens (e.g. uni token on all chains) +// TokenMarket and TokenProjectMarket then are market data entities for the above. +// TokenMarket is per-chain market data for contracts pulled from the graph. +// TokenProjectMarket is aggregated market data (aggregated over multiple dexes and centralized exchanges) that we get from coingecko. gql` query Token($chain: Chain!, $address: String = null) { token(chain: $chain, address: $address) { diff --git a/src/hooks/useENSName.ts b/src/hooks/useENSName.ts index df364d0477..62f3b35a4c 100644 --- a/src/hooks/useENSName.ts +++ b/src/hooks/useENSName.ts @@ -28,10 +28,9 @@ export default function useENSName(address?: string): { ENSName: string | null; const nameCallRes = useSingleCallResult(resolverContract, 'name', ensNodeArgument) const name = nameCallRes.result?.[0] - /* ENS does not enforce that an address owns a .eth domain before setting it as a reverse proxy - and recommends that you perform a match on the forward resolution - see: https://docs.ens.domains/dapp-developer-guide/resolving-names#reverse-resolution - */ + // ENS does not enforce that an address owns a .eth domain before setting it as a reverse proxy + // and recommends that you perform a match on the forward resolution + // see: https://docs.ens.domains/dapp-developer-guide/resolving-names#reverse-resolution const fwdAddr = useENSAddress(name) const checkedName = address === fwdAddr?.address ? name : null diff --git a/src/hooks/useFilterPossiblyMaliciousPositions.ts b/src/hooks/useFilterPossiblyMaliciousPositions.ts index 0e7dd6ab4d..eb8e1205d0 100644 --- a/src/hooks/useFilterPossiblyMaliciousPositions.ts +++ b/src/hooks/useFilterPossiblyMaliciousPositions.ts @@ -11,7 +11,7 @@ function getUniqueAddressesFromPositions(positions: PositionDetails[]): string[] new Set(positions.reduce((acc, position) => acc.concat(position.token0, position.token1), [])) ) } -/* +/** * This function is an attempt to filter out an observed phishing attack from LP list UIs. * Attackers would airdrop valueless LP positions with urls in the symbol to render phishing sites into users' LP position list view. * diff --git a/src/hooks/useTokenInfoFromActiveList.ts b/src/hooks/useTokenInfoFromActiveList.ts index f4a8548ba9..027f84da33 100644 --- a/src/hooks/useTokenInfoFromActiveList.ts +++ b/src/hooks/useTokenInfoFromActiveList.ts @@ -3,9 +3,7 @@ import { useWeb3React } from '@web3-react/core' import { useMemo } from 'react' import { useCombinedActiveList } from 'state/lists/hooks' -/** - * Returns a WrappedTokenInfo from the active token lists when possible, - * or the passed token otherwise. */ +/** Returns a WrappedTokenInfo from the active token lists when possible, or the passed token otherwise. */ export function useTokenInfoFromActiveList(currency: Currency) { const { chainId } = useWeb3React() const activeList = useCombinedActiveList() diff --git a/src/nft/utils/urlParams.ts b/src/nft/utils/urlParams.ts index fdfd9167a9..bbfbed32e3 100644 --- a/src/nft/utils/urlParams.ts +++ b/src/nft/utils/urlParams.ts @@ -44,11 +44,9 @@ const urlParamsUtils = { clonedQuery[key] = [] } - /* - query-string package treats arrays with one value as a string. - Here we're making sure that we have an array, not a string. Example: - const foo = 'hey' // => ['hey'] - */ + // query-string package treats arrays with one value as a string. + // Here we're making sure that we have an array, not a string. Example: + // const foo = 'hey' // => ['hey'] if (clonedQuery[key] && typeof clonedQuery[key] === 'string') { clonedQuery[key] = [clonedQuery[key]] } @@ -66,23 +64,20 @@ const urlParamsUtils = { clonedQuery['buyNow'] = !(clonedQuery['all'] === undefined ? !initialBuyNow : clonedQuery['all']) clonedQuery['search'] = clonedQuery['search'] === undefined ? initialSearchText : String(clonedQuery['search']) - /* - Handling an edge case caused by query-string's bad array parsing, when user - only selects one trait and reloads the page. - Here's the general data-structure for our traits in URL: - `traits=("trait_type","trait_value"),("trait_type","trait_value")` - - Expected behavior: When user selects one trait, there should be an array - containing one element. - - Actual behavior: It creates an array with two elements, first element being - trait_type & the other trait_value. This causes confusion since we don't know - whether user has selected two traits (cause we have two elements in our array) - or it's only one. - - Using this block of code, we'll identify if that's the case. - */ - + // Handling an edge case caused by query-string's bad array parsing, when user + // only selects one trait and reloads the page. + // Here's the general data-structure for our traits in URL: + // `traits=("trait_type","trait_value"),("trait_type","trait_value")` + // + // Expected behavior: When user selects one trait, there should be an array + // containing one element. + // + // Actual behavior: It creates an array with two elements, first element being + // trait_type & the other trait_value. This causes confusion since we don't know + // whether user has selected two traits (cause we have two elements in our array) + // or it's only one. + // + // Using this block of code, we'll identify if that's the case. if (clonedQuery['traits'].length === 2) { const [trait_type, trait_value] = clonedQuery['traits'] as [string, string] const fullTrait = `${trait_type}${trait_value}` @@ -104,11 +99,9 @@ const urlParamsUtils = { collectionStats.traits && collectionStats.traits[trait_type].find((trait) => trait.trait_value === trait_value) - /* - For most cases, `traitInStats` is assigned. In case the trait - does not exist in our store, e.g "Number of traits", we have to - manually create an object for it. - */ + // For most cases, `traitInStats` is assigned. In case the trait + // does not exist in our store, e.g "Number of traits", we have to + // manually create an object for it. const trait = traitInStats ?? { trait_type, trait_value, trait_count: 0 } return trait as Trait diff --git a/src/pages/TokenDetails/index.tsx b/src/pages/TokenDetails/index.tsx index cdd2a02d8d..c25b02c07c 100644 --- a/src/pages/TokenDetails/index.tsx +++ b/src/pages/TokenDetails/index.tsx @@ -21,8 +21,8 @@ export default function TokenDetailsPage() { const isNative = tokenAddress === NATIVE_CHAIN_ID const [timePeriod, setTimePeriod] = useAtom(pageTimePeriodAtom) const [detailedTokenAddress, duration] = useMemo( - /* tokenAddress will always be defined in the path for for this page to render, but useParams will always - return optional arguments; nullish coalescing operator is present here to appease typechecker */ + // tokenAddress will always be defined in the path for for this page to render, but useParams will always + // return optional arguments; nullish coalescing operator is present here to appease typechecker () => [isNative ? getNativeTokenDBAddress(chain) : tokenAddress ?? '', toHistoryDuration(timePeriod)], [chain, isNative, timePeriod, tokenAddress] ) diff --git a/src/state/application/atoms.ts b/src/state/application/atoms.ts index 8a0dfa2aec..ae271c9cf8 100644 --- a/src/state/application/atoms.ts +++ b/src/state/application/atoms.ts @@ -1,14 +1,12 @@ import { atomWithStorage, createJSONStorage } from 'jotai/utils' -/* - Note: - We should consider a generic sessionStorage abstraction if this pattern becomes common. (i.e., Future promo dismissals like the tax service discounts or Fiat Onramp launch notification may use this.) - This would be something similar to the current feature flag implementation, but utilizing session instead - - Motivation: - some dapp browsers need to be able to disable the NFT portion of the app in order to pass Apple's app store review - this atom persists the inclusion of the `disableNFTs=boolean` query parameter via the webview's session storage -*/ +// Note: +// We should consider a generic sessionStorage abstraction if this pattern becomes common. (i.e., Future promo dismissals like the tax service discounts or Fiat Onramp launch notification may use this.) +// This would be something similar to the current feature flag implementation, but utilizing session instead +// +// Motivation: +// some dapp browsers need to be able to disable the NFT portion of the app in order to pass Apple's app store review +// this atom persists the inclusion of the `disableNFTs=boolean` query parameter via the webview's session storage const storage = createJSONStorage(() => sessionStorage) export const shouldDisableNFTRoutesAtom = atomWithStorage('shouldDisableNFTRoutes', false, storage) diff --git a/src/state/wallets/reducer.ts b/src/state/wallets/reducer.ts index 84cbdc67d2..cc7cc3d3af 100644 --- a/src/state/wallets/reducer.ts +++ b/src/state/wallets/reducer.ts @@ -3,8 +3,8 @@ import { shallowEqual } from 'react-redux' import { Wallet } from './types' -/* Used to track wallets that have been connected by the user in current session, and remove them when deliberately disconnected. - Used to compute is_reconnect event property for analytics */ +// Used to track wallets that have been connected by the user in current session, and remove them when deliberately disconnected. +// Used to compute is_reconnect event property for analytics interface WalletState { connectedWallets: Wallet[] } diff --git a/src/tracing/errors.ts b/src/tracing/errors.ts index 893613e0f8..c836477882 100644 --- a/src/tracing/errors.ts +++ b/src/tracing/errors.ts @@ -1,9 +1,8 @@ import { ClientOptions, ErrorEvent, EventHint } from '@sentry/types' import { didUserReject } from 'utils/swapErrorToUserReadableMessage' -/* `responseStatus` is only currently supported on certain browsers. - * see: https://caniuse.com/mdn-api_performanceresourcetiming_responsestatus - */ +// `responseStatus` is only currently supported on certain browsers. +// see: https://caniuse.com/mdn-api_performanceresourcetiming_responsestatus declare global { interface PerformanceEntry { responseStatus?: number @@ -16,12 +15,10 @@ function isEthersRequestError(error: Error): error is Error & { requestBody: str } export function beforeSend(event: ErrorEvent, hint: EventHint) { - /* - * Since the interface currently uses HashRouter, URLs will have a # before the path. - * This leads to issues when we send the URL into Sentry, as the path gets parsed as a "fragment". - * Instead, this logic removes the # part of the URL. - * See https://romain-clement.net/articles/sentry-url-fragments/#url-fragments - **/ + // Since the interface currently uses HashRouter, URLs will have a # before the path. + // This leads to issues when we send the URL into Sentry, as the path gets parsed as a "fragment". + // Instead, this logic removes the # part of the URL. + // See https://romain-clement.net/articles/sentry-url-fragments/#url-fragments if (event.request?.url) { event.request.url = event.request.url.replace('/#', '') } @@ -34,11 +31,9 @@ function shouldFilterChunkError(asset?: string) { const resource = entries?.find(({ name }) => name === asset) const status = resource?.responseStatus - /* - * If the status if 499, then we ignore. - * If there's no status (meaning the browser doesn't support `responseStatus`) then we also ignore. - * These errors are likely also 499 errors, and we can catch any spikes in non-499 chunk errors via other browsers. - */ + // If the status if 499, then we ignore. + // If there's no status (meaning the browser doesn't support `responseStatus`) then we also ignore. + // These errors are likely also 499 errors, and we can catch any spikes in non-499 chunk errors via other browsers. return !status || status === 499 } @@ -62,11 +57,9 @@ export const filterKnownErrors: Required['beforeSend'] = (event: // If the error is based on a user rejecting, it should not be considered an exception. if (didUserReject(error)) return null - /* - * This ignores 499 errors, which are caused by Cloudflare when a request is cancelled. - * CF claims that some number of these is expected, and that they should be ignored. - * See https://groups.google.com/a/uniswap.org/g/cloudflare-eng/c/t3xvAiJFujY. - */ + // This ignores 499 errors, which are caused by Cloudflare when a request is cancelled. + // CF claims that some number of these is expected, and that they should be ignored. + // See https://groups.google.com/a/uniswap.org/g/cloudflare-eng/c/t3xvAiJFujY. if (error.message.match(/Loading chunk \d+ failed\. \(([a-zA-Z]+): .+\.chunk\.js\)/)) { const asset = error.message.match(/https?:\/\/.+?\.chunk\.js/)?.[0] if (shouldFilterChunkError(asset)) return null @@ -78,24 +71,18 @@ export const filterKnownErrors: Required['beforeSend'] = (event: if (shouldFilterChunkError(asset)) return null } - /* - * This is caused by HTML being returned for a chunk from Cloudflare. - * Usually, it's the result of a 499 exception right before it, which should be handled. - * Therefore, this can be ignored. - */ + // This is caused by HTML being returned for a chunk from Cloudflare. + // Usually, it's the result of a 499 exception right before it, which should be handled. + // Therefore, this can be ignored. if (error.message.match(/Unexpected token '<'/)) return null - /* - * Errors coming from OneKey (a desktop wallet) can be ignored for now. - * These errors are either application-specific, or they will be thrown separately outside of OneKey. - */ + // Errors coming from OneKey (a desktop wallet) can be ignored for now. + // These errors are either application-specific, or they will be thrown separately outside of OneKey. if (error.stack?.match(/OneKey/i)) return null - /* - * Content security policy 'unsafe-eval' errors can be filtered out because there are expected failures. - * For example, if a user runs an eval statement in console this error would still get thrown. - * TODO(INFRA-176): We should extend this to filter out any type of CSP error. - */ + // Content security policy 'unsafe-eval' errors can be filtered out because there are expected failures. + // For example, if a user runs an eval statement in console this error would still get thrown. + // TODO(INFRA-176): We should extend this to filter out any type of CSP error. if (error.message.match(/'unsafe-eval'.*content security policy/i)) { return null }