Hey is a decentralized and permissionless social media app built with Lens Protocol 🌿

chore: enforce no explicit any rule (#5867)

authored by yoginth.com and committed by

GitHub cb03306d 41f9c31f

+79 -48
+8 -5
apps/api/src/routes/og/ogUtils.ts
··· 1 1 import apolloClient from "@hey/indexer/apollo/client"; 2 2 import type { Context } from "hono"; 3 3 import type { HtmlEscapedString } from "hono/utils/html"; 4 + 5 + type DocumentNode = unknown; 6 + 4 7 import defaultMetadata from "../../utils/defaultMetadata"; 5 8 import { getRedis, setRedis } from "../../utils/redis"; 6 9 7 10 export interface OgHelperOptions<T> { 8 11 ctx: Context; 9 12 cacheKey: string; 10 - query: any; 11 - variables: Record<string, any>; 12 - extractData: (data: any) => T | null; 13 - buildJsonLd: (data: T) => Record<string, any>; 13 + query: DocumentNode; 14 + variables: Record<string, unknown>; 15 + extractData: (data: unknown) => T | null; 16 + buildJsonLd: (data: T) => Record<string, unknown>; 14 17 buildHtml: ( 15 18 data: T, 16 19 escapedJsonLd: string ··· 34 37 35 38 const { data } = await apolloClient.query({ 36 39 fetchPolicy: "no-cache", 37 - query, 40 + query: query as DocumentNode, 38 41 variables 39 42 }); 40 43
+6 -5
apps/api/src/utils/lensPg.ts
··· 13 13 pg: IMain<unknown, pg.IClient>; 14 14 } 15 15 16 - type DatabaseParams = null | Record<string, any>; 16 + type DatabaseParams = null | Record<string, unknown> | unknown[]; 17 17 type DatabaseQuery = string; 18 18 19 19 class Database { ··· 42 42 connectionParameters: IConnectionParameters 43 43 ): InitializeDbResult { 44 44 const pgp = pgPromise({ 45 - error: (error: any) => { 46 - const errorMessage = error.message || error; 45 + error: (error: unknown) => { 46 + const errorMessage = 47 + error instanceof Error ? error.message : String(error); 47 48 console.error(`LENS POSTGRES ERROR WITH TRACE: ${errorMessage}`); 48 49 } 49 50 }); ··· 57 58 public multi( 58 59 query: DatabaseQuery, 59 60 params: DatabaseParams = null 60 - ): Promise<any[][]> { 61 + ): Promise<unknown[][]> { 61 62 return this._readDb.multi(query, params); 62 63 } 63 64 64 65 public query( 65 66 query: DatabaseQuery, 66 67 params: DatabaseParams = null 67 - ): Promise<any[]> { 68 + ): Promise<unknown[]> { 68 69 return this._readDb.query(query, params); 69 70 } 70 71 }
+1 -1
apps/api/src/utils/redis.ts
··· 52 52 53 53 export const setRedis = async ( 54 54 key: string, 55 - value: boolean | number | Record<string, any> | string, 55 + value: boolean | number | Record<string, unknown> | string, 56 56 expiry = generateSmallExpiry() 57 57 ) => { 58 58 if (!redisClient) {
+6 -2
apps/web/src/components/Account/FollowersYouKnowOverview.tsx
··· 1 1 import { TRANSFORMS } from "@hey/data/constants"; 2 2 import getAccount from "@hey/helpers/getAccount"; 3 3 import getAvatar from "@hey/helpers/getAvatar"; 4 - import { type Follower, useFollowersYouKnowQuery } from "@hey/indexer"; 4 + import { 5 + type AccountFragment, 6 + type Follower, 7 + useFollowersYouKnowQuery 8 + } from "@hey/indexer"; 5 9 import { type ReactNode, useEffect, useMemo, useState } from "react"; 6 10 import { useLocation } from "react-router"; 7 11 import FollowersYouKnow from "@/components/Shared/Modal/FollowersYouKnow"; ··· 39 43 40 44 const accountNames = useMemo(() => { 41 45 const names = accounts.map( 42 - (account) => getAccount(account.follower as any).name 46 + (account) => getAccount(account.follower as AccountFragment).name 43 47 ); 44 48 const count = names.length - 3; 45 49
+1 -1
apps/web/src/components/Composer/ChooseThumbnail.tsx
··· 49 49 getFileFromDataURL( 50 50 thumbnails[index].blobUrl, 51 51 "thumbnail.jpeg", 52 - async (file: any) => { 52 + async (file: File | null) => { 53 53 if (!file) { 54 54 return toast.error("Please upload a custom thumbnail"); 55 55 }
+5 -1
apps/web/src/components/Composer/LicensePicker.tsx
··· 13 13 label: getAssetLicense(type)?.label as string, 14 14 selected: license === type, 15 15 value: type 16 - })) as any; 16 + })) as Array<{ 17 + label: string; 18 + selected: boolean; 19 + value: MetadataLicenseType; 20 + }>; 17 21 18 22 const options = [ 19 23 {
+2 -1
apps/web/src/components/Composer/NewPublication.tsx
··· 1 1 import { ERRORS } from "@hey/data/errors"; 2 2 import getAccount from "@hey/helpers/getAccount"; 3 3 import type { PostFragment } from "@hey/indexer"; 4 + import type { ApolloClientError } from "@hey/types/errors"; 4 5 import type { IGif } from "@hey/types/giphy"; 5 6 import type { NewAttachment } from "@hey/types/misc"; 6 7 import { useEffect, useState } from "react"; ··· 125 126 reset(); 126 127 }; 127 128 128 - const onError = (error?: any) => { 129 + const onError = (error?: ApolloClientError) => { 129 130 setIsSubmitting(false); 130 131 errorToast(error); 131 132 };
+1 -1
apps/web/src/components/Post/Actions/Like.tsx
··· 30 30 post.stats.reactions 31 31 ); 32 32 33 - const updateCache = (cache: ApolloCache<any>) => { 33 + const updateCache = (cache: ApolloCache<unknown>) => { 34 34 if (!post.operations) { 35 35 return; 36 36 }
+1 -1
apps/web/src/components/Post/Actions/Menu/Bookmark.tsx
··· 22 22 const { pathname } = useLocation(); 23 23 const hasBookmarked = post.operations?.hasBookmarked; 24 24 25 - const updateCache = (cache: ApolloCache<any>, hasBookmarked: boolean) => { 25 + const updateCache = (cache: ApolloCache<unknown>, hasBookmarked: boolean) => { 26 26 if (!post.operations) { 27 27 return; 28 28 }
+2 -1
apps/web/src/components/Post/Actions/Menu/Edit.tsx
··· 3 3 import generateUUID from "@hey/helpers/generateUUID"; 4 4 import getPostData from "@hey/helpers/getPostData"; 5 5 import type { PostFragment } from "@hey/indexer"; 6 + import type { NewAttachment } from "@hey/types/misc"; 6 7 7 8 import cn from "@/helpers/cn"; 8 9 import stopEventPropagation from "@/helpers/stopEventPropagation"; ··· 24 25 setPostContent(data?.content || ""); 25 26 setEditingPost(post); 26 27 27 - const attachments = [] as any[]; 28 + const attachments: NewAttachment[] = []; 28 29 if (data?.asset) { 29 30 attachments.push({ 30 31 id: generateUUID(),
+1 -1
apps/web/src/components/Post/Actions/Menu/HideComment.tsx
··· 22 22 const { currentAccount } = useAccountStore(); 23 23 const { showHiddenComments } = useHiddenCommentFeedStore(); 24 24 25 - const updateCache = (cache: ApolloCache<any>) => { 25 + const updateCache = (cache: ApolloCache<unknown>) => { 26 26 cache.evict({ id: cache.identify(post) }); 27 27 }; 28 28
+1 -1
apps/web/src/components/Post/Actions/Menu/NotInterested.tsx
··· 24 24 post: post.id 25 25 }; 26 26 27 - const updateCache = (cache: ApolloCache<any>, notInterested: boolean) => { 27 + const updateCache = (cache: ApolloCache<unknown>, notInterested: boolean) => { 28 28 if (!post.operations) { 29 29 return; 30 30 }
+2 -1
apps/web/src/components/Post/Actions/Share/UndoRepost.tsx
··· 4 4 import { ERRORS } from "@hey/data/errors"; 5 5 import { isRepost } from "@hey/helpers/postHelpers"; 6 6 import { type AnyPostFragment, useDeletePostMutation } from "@hey/indexer"; 7 + import type { ApolloClientError } from "@hey/types/errors"; 7 8 import type { Dispatch, SetStateAction } from "react"; 8 9 import { toast } from "sonner"; 9 10 import cn from "@/helpers/cn"; ··· 46 47 toast.success("Undone repost"); 47 48 }; 48 49 49 - const onError = (error?: any) => { 50 + const onError = (error?: ApolloClientError) => { 50 51 setIsSubmitting(false); 51 52 errorToast(error); 52 53 };
+5 -2
apps/web/src/components/Post/OpenAction/CollectAction/CollectActionButton.tsx
··· 1 1 import { useApolloClient } from "@apollo/client"; 2 2 import { HEY_TREASURY } from "@hey/data/constants"; 3 + import type { SimpleCollectActionFragment } from "@hey/indexer"; 3 4 import { 4 5 type PostActionFragment, 5 6 type PostFragment, ··· 30 31 postAction, 31 32 post 32 33 }: CollectActionButtonProps) => { 33 - const collectAction = getCollectActionData(postAction as any); 34 + const collectAction = getCollectActionData( 35 + postAction as SimpleCollectActionFragment 36 + ); 34 37 const { currentAccount } = useAccountStore(); 35 38 const [isSubmitting, setIsSubmitting] = useState(false); 36 39 const [hasSimpleCollected, setHasSimpleCollected] = useState( ··· 42 45 const endTimestamp = collectAction?.endsAt; 43 46 const collectLimit = collectAction?.collectLimit; 44 47 const amount = collectAction?.price as number; 45 - const assetAddress = collectAction?.assetAddress as any; 48 + const assetAddress = collectAction?.assetAddress; 46 49 const assetSymbol = collectAction?.assetSymbol as string; 47 50 const isAllCollected = collectLimit ? collects >= collectLimit : false; 48 51 const isSaleEnded = endTimestamp
+5 -3
apps/web/src/components/Settings/Funds/TokenOperation.tsx
··· 7 7 import useWaitForTransactionToComplete from "@/hooks/useWaitForTransactionToComplete"; 8 8 9 9 interface TokenOperationProps { 10 - useMutationHook: any; 11 - buildRequest: (value: string) => any; 10 + useMutationHook: ( 11 + options: unknown 12 + ) => [(variables: unknown) => Promise<unknown>]; 13 + buildRequest: (value: string) => unknown; 12 14 resultKey: string; 13 15 buttonLabel: string; 14 16 title: string; ··· 47 49 }; 48 50 49 51 const [mutate] = useMutationHook({ 50 - onCompleted: async (data: any) => { 52 + onCompleted: async (data: unknown) => { 51 53 const result = data?.[resultKey]; 52 54 if (result?.__typename === "InsufficientFunds") { 53 55 return onError({ message: "Insufficient funds" });
+1 -1
apps/web/src/components/Settings/Personalize/Form.tsx
··· 134 134 ) 135 135 .map(({ key, type, value }) => ({ 136 136 key, 137 - type: MetadataAttributeType[type] as any, 137 + type, 138 138 value 139 139 })) || []; 140 140
+2 -1
apps/web/src/components/Shared/Account/SwitchAccounts.tsx
··· 5 5 useAccountsAvailableQuery, 6 6 useSwitchAccountMutation 7 7 } from "@hey/indexer"; 8 + import type { ApolloClientError } from "@hey/types/errors"; 8 9 import { useState } from "react"; 9 10 import { useAccount } from "wagmi"; 10 11 import Loader from "@/components/Shared/Loader"; ··· 23 24 ); 24 25 const { address } = useAccount(); 25 26 26 - const onError = (error?: any) => { 27 + const onError = (error?: ApolloClientError) => { 27 28 setIsSubmitting(false); 28 29 setLoggingInAccountId(null); 29 30 errorToast(error);
+2 -1
apps/web/src/components/Shared/Auth/Login.tsx
··· 8 8 useAuthenticateMutation, 9 9 useChallengeMutation 10 10 } from "@hey/indexer"; 11 + import type { ApolloClientError } from "@hey/types/errors"; 11 12 import { AnimatePresence, motion } from "motion/react"; 12 13 import type { Dispatch, SetStateAction } from "react"; 13 14 import { useState } from "react"; ··· 33 34 ); 34 35 const [isExpanded, setIsExpanded] = useState(true); 35 36 36 - const onError = (error?: any) => { 37 + const onError = (error?: ApolloClientError) => { 37 38 setIsSubmitting(false); 38 39 setLoggingInAccountId(null); 39 40 errorToast(error);
+2 -1
apps/web/src/components/Shared/Auth/Signup/ChooseUsername.tsx
··· 13 13 useChallengeMutation, 14 14 useCreateAccountWithUsernameMutation 15 15 } from "@hey/indexer"; 16 + import type { ApolloClientError } from "@hey/types/errors"; 16 17 import { account as accountMetadata } from "@lens-protocol/metadata"; 17 18 import { useState } from "react"; 18 19 import { toast } from "sonner"; ··· 56 57 const handleWrongNetwork = useHandleWrongNetwork(); 57 58 const form = useZodForm({ mode: "onChange", schema: ValidationSchema }); 58 59 59 - const onError = (error?: any) => { 60 + const onError = (error?: ApolloClientError) => { 60 61 setIsSubmitting(false); 61 62 errorToast(error); 62 63 };
+2 -2
apps/web/src/components/Shared/Auth/WalletSelector.tsx
··· 18 18 ]; 19 19 20 20 const filteredConnectors = connectors 21 - .filter((connector: any) => allowedConnectors.includes(connector.id)) 21 + .filter((connector) => allowedConnectors.includes(connector.id)) 22 22 .sort( 23 23 (a: Connector, b: Connector) => 24 24 allowedConnectors.indexOf(a.id) - allowedConnectors.indexOf(b.id) ··· 43 43 </div> 44 44 ) : ( 45 45 <div className="inline-block w-full space-y-3 overflow-hidden text-left align-middle"> 46 - {filteredConnectors.map((connector: any) => { 46 + {filteredConnectors.map((connector) => { 47 47 return ( 48 48 <button 49 49 className={cn(
+3 -1
apps/web/src/components/Shared/Markup/index.tsx
··· 28 28 } 29 29 30 30 const components = { 31 - a: (props: any) => <MarkupLink mentions={mentions} title={props.title} /> 31 + a: (props: { title?: string }) => ( 32 + <MarkupLink mentions={mentions} title={props.title} /> 33 + ) 32 34 }; 33 35 34 36 return (
+1 -3
apps/web/src/components/Shared/Post/Attachments.tsx
··· 103 103 {displayDecision === "displayVideoAsset" && ( 104 104 <Video 105 105 poster={asset?.cover as string} 106 - src={ 107 - getSrc(asset?.uri) || [{ src: asset?.uri, type: "video" } as any] 108 - } 106 + src={getSrc(asset?.uri) || [{ src: asset?.uri, type: "video" }]} 109 107 /> 110 108 )} 111 109 {displayDecision === "displayAudioAsset" && (
+1 -1
apps/web/src/components/Shared/UI/ErrorMessage.tsx
··· 4 4 5 5 interface ErrorMessageProps { 6 6 className?: string; 7 - error?: any; 7 + error?: unknown; 8 8 title?: string; 9 9 } 10 10
+2 -2
apps/web/src/components/Shared/UI/Form.tsx
··· 16 16 schema: T; 17 17 } 18 18 19 - export const useZodForm = <T extends ZodSchema<any>>({ 19 + export const useZodForm = <T extends ZodSchema<unknown>>({ 20 20 schema, 21 21 ...formConfig 22 22 }: UseZodFormProps<T>) => { 23 23 return useForm({ 24 24 ...formConfig, 25 - resolver: zodResolver(schema as any) 25 + resolver: zodResolver(schema) 26 26 }); 27 27 }; 28 28
+1 -1
apps/web/src/components/Shared/UI/Select.tsx
··· 15 15 className?: string; 16 16 defaultValue?: string; 17 17 iconClassName?: string; 18 - onChange: (value: any) => any; 18 + onChange: (value: unknown) => unknown; 19 19 options?: { 20 20 disabled?: boolean; 21 21 helper?: string;
+1 -1
apps/web/src/hooks/usePostMetadata.tsx
··· 14 14 import { usePostAudioStore } from "../store/non-persisted/post/usePostAudioStore"; 15 15 16 16 interface UsePostMetadataProps { 17 - baseMetadata: any; 17 + baseMetadata: Record<string, unknown>; 18 18 } 19 19 20 20 const usePostMetadata = () => {
+11 -3
apps/web/src/hooks/useTransactionLifecycle.tsx
··· 1 1 import { ERRORS } from "@hey/data/errors"; 2 2 import getTransactionData from "@hey/helpers/getTransactionData"; 3 + import type { 4 + SelfFundedTransactionRequest, 5 + SponsoredTransactionRequest, 6 + TransactionWillFail 7 + } from "@hey/indexer"; 3 8 import type { ApolloClientError } from "@hey/types/errors"; 4 9 import { sendEip712Transaction, sendTransaction } from "viem/zksync"; 5 10 import { useWalletClient } from "wagmi"; ··· 10 15 const handleWrongNetwork = useHandleWrongNetwork(); 11 16 12 17 const handleSponsoredTransaction = async ( 13 - transactionData: any, 18 + transactionData: SponsoredTransactionRequest, 14 19 onCompleted: (hash: string) => void 15 20 ) => { 16 21 await handleWrongNetwork(); ··· 24 29 }; 25 30 26 31 const handleSelfFundedTransaction = async ( 27 - transactionData: any, 32 + transactionData: SelfFundedTransactionRequest, 28 33 onCompleted: (hash: string) => void 29 34 ) => { 30 35 await handleWrongNetwork(); ··· 42 47 onCompleted, 43 48 onError 44 49 }: { 45 - transactionData: any; 50 + transactionData: 51 + | SponsoredTransactionRequest 52 + | SelfFundedTransactionRequest 53 + | TransactionWillFail; 46 54 onCompleted: (hash: string) => void; 47 55 onError: (error: ApolloClientError) => void; 48 56 }) => {
+1 -1
biome.json
··· 83 83 "suspicious": { 84 84 "noArrayIndexKey": "off", 85 85 "noAssignInExpressions": "off", 86 - "noExplicitAny": "off" 86 + "noExplicitAny": "error" 87 87 } 88 88 } 89 89 }
+2 -2
packages/helpers/getTransactionData.ts
··· 11 11 raw: Eip1559TransactionRequest | Eip712TransactionRequest, 12 12 options: GetTransactionDataOptions = {} 13 13 ) => { 14 - const data = { 14 + const data: Record<string, unknown> = { 15 15 data: raw.data, 16 16 gas: BigInt(raw.gasLimit), 17 17 maxFeePerGas: BigInt(raw.maxFeePerGas), ··· 19 19 nonce: raw.nonce, 20 20 to: raw.to, 21 21 value: BigInt(raw.value) 22 - } as any; 22 + }; 23 23 24 24 if (options.sponsored && "customData" in raw) { 25 25 data.paymaster = raw.customData.paymasterParams?.paymaster;