feat: add "strictNullChecks"

This commit is contained in:
Adhiraj Singh
2022-07-08 10:38:25 +05:30
parent 7426b7aa2f
commit 40a1e268aa
42 changed files with 350 additions and 339 deletions

View File

@@ -13,7 +13,8 @@ export const makeBusinessSocket = (config: SocketConfig) => {
} = sock
const getCatalog = async(jid?: string, limit = 10) => {
jid = jidNormalizedUser(jid || authState.creds.me?.id)
jid = jid || authState.creds.me?.id
jid = jidNormalizedUser(jid!)
const result = await query({
tag: 'iq',
attrs: {
@@ -52,7 +53,8 @@ export const makeBusinessSocket = (config: SocketConfig) => {
}
const getCollections = async(jid?: string, limit = 51) => {
jid = jidNormalizedUser(jid || authState.creds.me?.id)
jid = jid || authState.creds.me?.id
jid = jidNormalizedUser(jid!)
const result = await query({
tag: 'iq',
attrs: {
@@ -165,7 +167,7 @@ export const makeBusinessSocket = (config: SocketConfig) => {
const productCatalogEditNode = getBinaryNodeChild(result, 'product_catalog_edit')
const productNode = getBinaryNodeChild(productCatalogEditNode, 'product')
return parseProductNode(productNode)
return parseProductNode(productNode!)
}
const productCreate = async(create: ProductCreate) => {
@@ -191,7 +193,7 @@ export const makeBusinessSocket = (config: SocketConfig) => {
const productCatalogAddNode = getBinaryNodeChild(result, 'product_catalog_add')
const productNode = getBinaryNodeChild(productCatalogAddNode, 'product')
return parseProductNode(productNode)
return parseProductNode(productNode!)
}
const productDelete = async(productIds: string[]) => {
@@ -225,7 +227,7 @@ export const makeBusinessSocket = (config: SocketConfig) => {
const productCatalogDelNode = getBinaryNodeChild(result, 'product_catalog_delete')
return {
deleted: +productCatalogDelNode.attrs.deleted_count
deleted: +(productCatalogDelNode?.attrs.deleted_count || 0)
}
}

View File

@@ -67,7 +67,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
{ tag: 'privacy', attrs: { } }
]
})
privacySettings = reduceBinaryNodeToDictionary(content[0] as BinaryNode, 'category')
privacySettings = reduceBinaryNodeToDictionary(content?.[0] as BinaryNode, 'category')
}
return privacySettings
@@ -135,7 +135,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
return results.map(user => {
const contact = getBinaryNodeChild(user, 'contact')
return { exists: contact.attrs.type === 'in', jid: user.attrs.jid }
return { exists: contact?.attrs.type === 'in', jid: user.attrs.jid }
}).filter(item => item.exists)
}
@@ -147,8 +147,8 @@ export const makeChatsSocket = (config: SocketConfig) => {
if(result) {
const status = getBinaryNodeChild(result, 'status')
return {
status: status.content!.toString(),
setAt: new Date(+status.attrs.t * 1000)
status: status?.content!.toString(),
setAt: new Date(+(status?.attrs.t || 0) * 1000)
}
}
}
@@ -253,18 +253,19 @@ export const makeChatsSocket = (config: SocketConfig) => {
const category = getBinaryNodeChild(getBinaryNodeChild(profiles, 'categories'), 'category')
const business_hours = getBinaryNodeChild(profiles, 'business_hours')
const business_hours_config = business_hours && getBinaryNodeChildren(business_hours, 'business_hours_config')
const websiteStr = website?.content?.toString()
return {
wid: profiles.attrs?.jid,
address: address?.content.toString(),
description: description?.content.toString(),
website: [website?.content.toString()],
email: email?.content.toString(),
category: category?.content.toString(),
address: address?.content?.toString(),
description: description?.content?.toString() || '',
website: websiteStr ? [websiteStr] : [],
email: email?.content?.toString(),
category: category?.content?.toString(),
business_hours: {
timezone: business_hours?.attrs?.timezone,
business_config: business_hours_config?.map(({ attrs }) => attrs as unknown as WABusinessHoursConfig)
}
} as unknown as WABusinessProfile
}
}
}
@@ -296,7 +297,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
processSyncAction(
mutation,
ev,
authState.creds.me,
authState.creds.me!,
recvChats ? { recvChats, accountSettings: authState.creds.accountSettings } : undefined,
logger
)
@@ -402,7 +403,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
} catch(error) {
// if retry attempts overshoot
// or key not found
const isIrrecoverableError = attemptsMap[name] >= MAX_SYNC_ATTEMPTS || error.output?.statusCode === 404
const isIrrecoverableError = attemptsMap[name]! >= MAX_SYNC_ATTEMPTS || error.output?.statusCode === 404
logger.info({ name, error: error.stack }, `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`)
await authState.keys.set({ 'app-state-sync-version': { [name]: null } })
// increment number of retries
@@ -468,7 +469,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
tag: 'chatstate',
attrs: {
from: me!.id!,
to: toJid,
to: toJid!,
},
content: [
{
@@ -492,7 +493,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
)
const handlePresenceUpdate = ({ tag, attrs, content }: BinaryNode) => {
let presence: PresenceData
let presence: PresenceData | undefined
const jid = attrs.from
const participant = attrs.participant || attrs.from
if(tag === 'presence') {
@@ -606,8 +607,8 @@ export const makeChatsSocket = (config: SocketConfig) => {
const { onMutation } = newAppStateChunkHandler(undefined)
await decodePatches(
name,
[{ ...encodeResult.patch, version: { version: encodeResult.state.version }, }],
initial,
[{ ...encodeResult!.patch, version: { version: encodeResult!.state.version }, }],
initial!,
getAppStateSyncKey,
onMutation,
undefined,
@@ -698,10 +699,10 @@ export const makeChatsSocket = (config: SocketConfig) => {
if(!!msg.pushName) {
let jid = msg.key.fromMe ? authState.creds.me!.id : (msg.key.participant || msg.key.remoteJid)
jid = jidNormalizedUser(jid)
jid = jidNormalizedUser(jid!)
if(!msg.key.fromMe) {
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }])
ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName! }])
}
// update our pushname too
@@ -724,7 +725,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
}
)
const isAnyHistoryMsg = isHistoryMsg(msg.message)
const isAnyHistoryMsg = isHistoryMsg(msg.message!)
if(isAnyHistoryMsg) {
// we only want to sync app state once we've all the history
// restart the app state sync timeout
@@ -741,7 +742,7 @@ export const makeChatsSocket = (config: SocketConfig) => {
ws.on('CB:chatstate', handlePresenceUpdate)
ws.on('CB:ib,,dirty', async(node: BinaryNode) => {
const { attrs } = getBinaryNodeChild(node, 'dirty')
const { attrs } = getBinaryNodeChild(node, 'dirty')!
const type = attrs.type
switch (type) {
case 'account_sync':

View File

@@ -120,7 +120,9 @@ export const makeGroupsSocket = (config: SocketConfig) => {
...(description ? { id: generateMessageID() } : { delete: 'true' }),
...(prev ? { prev } : {})
},
content: description ? [{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }] : null
content: description ? [
{ tag: 'body', attrs: {}, content: Buffer.from(description, 'utf-8') }
] : undefined
}
]
)
@@ -128,17 +130,17 @@ export const makeGroupsSocket = (config: SocketConfig) => {
groupInviteCode: async(jid: string) => {
const result = await groupQuery(jid, 'get', [{ tag: 'invite', attrs: {} }])
const inviteNode = getBinaryNodeChild(result, 'invite')
return inviteNode.attrs.code
return inviteNode?.attrs.code
},
groupRevokeInvite: async(jid: string) => {
const result = await groupQuery(jid, 'set', [{ tag: 'invite', attrs: {} }])
const inviteNode = getBinaryNodeChild(result, 'invite')
return inviteNode.attrs.code
return inviteNode?.attrs.code
},
groupAcceptInvite: async(code: string) => {
const results = await groupQuery('@g.us', 'set', [{ tag: 'invite', attrs: { code } }])
const result = getBinaryNodeChild(results, 'group')
return result.attrs.jid
return result?.attrs.jid
},
/**
* accept a GroupInviteMessage
@@ -147,11 +149,11 @@ export const makeGroupsSocket = (config: SocketConfig) => {
*/
groupAcceptInviteV4: async(key: string | WAMessageKey, inviteMessage: proto.IGroupInviteMessage) => {
key = typeof key === 'string' ? { remoteJid: key } : key
const results = await groupQuery(inviteMessage.groupJid, 'set', [{
const results = await groupQuery(inviteMessage.groupJid!, 'set', [{
tag: 'accept',
attrs: {
code: inviteMessage.inviteCode,
expiration: inviteMessage.inviteExpiration.toString(),
code: inviteMessage.inviteCode!,
expiration: inviteMessage.inviteExpiration!.toString(),
admin: key.remoteJid!
}
}])
@@ -254,7 +256,7 @@ export const makeGroupsSocket = (config: SocketConfig) => {
export const extractGroupMetadata = (result: BinaryNode) => {
const group = getBinaryNodeChild(result, 'group')
const group = getBinaryNodeChild(result, 'group')!
const descChild = getBinaryNodeChild(group, 'description')
let desc: string | undefined
let descId: string | undefined

View File

@@ -76,7 +76,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
const isGroup = !!node.attrs.participant
const { account, signedPreKey, signedIdentityKey: identityKey } = authState.creds
const deviceIdentity = proto.ADVSignedDeviceIdentity.encode(account).finish()
const deviceIdentity = proto.ADVSignedDeviceIdentity.encode(account!).finish()
await authState.keys.transaction(
async() => {
const { update, preKeys } = await getNextPreKeys(authState, 1)
@@ -147,7 +147,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
const from = node.attrs.from
if(from === S_WHATSAPP_NET) {
const countChild = getBinaryNodeChild(node, 'count')
const count = +countChild.attrs.value
const count = +countChild!.attrs.value
const shouldUploadMorePreKeys = count < MIN_PREKEY_COUNT
logger.debug({ count, shouldUploadMorePreKeys }, 'recv pre-key count')
@@ -270,22 +270,23 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
const sendMessagesAgain = async(key: proto.IMessageKey, ids: string[]) => {
const msgs = await Promise.all(ids.map(id => getMessage({ ...key, id })))
const participant = key.participant || key.remoteJid
const remoteJid = key.remoteJid!
const participant = key.participant || remoteJid
// if it's the primary jid sending the request
// just re-send the message to everyone
// prevents the first message decryption failure
const sendToAll = !jidDecode(participant).device
const sendToAll = !jidDecode(participant)?.device
await assertSessions([participant], true)
if(isJidGroup(key.remoteJid)) {
await authState.keys.set({ 'sender-key-memory': { [key.remoteJid]: null } })
if(isJidGroup(remoteJid)) {
await authState.keys.set({ 'sender-key-memory': { [remoteJid]: null } })
}
logger.debug({ participant, sendToAll }, 'forced new session for retry recp')
for(let i = 0; i < msgs.length;i++) {
if(msgs[i]) {
const msg = msgs[i]
if(msg) {
updateSendMessageAgainCount(ids[i], participant)
const msgRelayOpts: MessageRelayOptions = { messageId: ids[i] }
@@ -295,7 +296,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
msgRelayOpts.participant = participant
}
await relayMessage(key.remoteJid, msgs[i], msgRelayOpts)
await relayMessage(key.remoteJid!, msg, msgRelayOpts)
} else {
logger.debug({ jid: key.remoteJid, id: ids[i] }, 'recv retry request, but message not available')
}
@@ -443,21 +444,21 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
} else if(msg.key.fromMe) { // message was sent by us from a different device
type = 'sender'
// need to specially handle this case
if(isJidUser(msg.key.remoteJid)) {
if(isJidUser(msg.key.remoteJid!)) {
participant = author
}
} else if(!sendActiveReceipts) {
type = 'inactive'
}
await sendReceipt(msg.key.remoteJid!, participant, [msg.key.id!], type)
await sendReceipt(msg.key.remoteJid!, participant!, [msg.key.id!], type)
// send ack for history message
const isAnyHistoryMsg = isHistoryMsg(msg.message)
const isAnyHistoryMsg = isHistoryMsg(msg.message!)
if(isAnyHistoryMsg) {
const jid = jidEncode(jidDecode(msg.key.remoteJid!).user, 'c.us')
await sendReceipt(jid, undefined, [msg.key.id], 'hist_sync')
const jid = jidNormalizedUser(msg.key.remoteJid!)
await sendReceipt(jid, undefined, [msg.key.id!], 'hist_sync')
}
}
@@ -516,7 +517,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
const key: WAMessageKey = { remoteJid: attrs.from, fromMe: true, id: attrs.id }
const msg = await getMessage(key)
if(msg) {
await relayMessage(key.remoteJid, msg, { messageId: key.id, useUserDevicesCache: false })
await relayMessage(key.remoteJid!, msg, { messageId: key.id!, useUserDevicesCache: false })
} else {
logger.warn({ attrs }, 'could not send message again, as it was not found')
}
@@ -539,7 +540,7 @@ export const makeMessagesRecvSocket = (config: SocketConfig) => {
// called when all offline notifs are handled
ws.on('CB:ib,,offline', async(node: BinaryNode) => {
const child = getBinaryNodeChild(node, 'offline')
const offlineNotifs = +child.attrs.count
const offlineNotifs = +(child?.attrs.count || 0)
logger.info(`handled ${offlineNotifs} offline messages/notifications`)
await ev.flush()

View File

@@ -48,8 +48,8 @@ export const makeMessagesSocket = (config: SocketConfig) => {
hosts: getBinaryNodeChildren(mediaConnNode, 'host').map(
item => item.attrs as any
),
auth: mediaConnNode.attrs.auth,
ttl: +mediaConnNode.attrs.ttl,
auth: mediaConnNode!.attrs.auth,
ttl: +mediaConnNode!.attrs.ttl,
fetchDate: new Date()
}
logger.debug('fetched media conn')
@@ -78,7 +78,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
if(type === 'sender' && isJidUser(jid)) {
node.attrs.recipient = jid
node.attrs.to = participant
node.attrs.to = participant!
} else {
node.attrs.to = jid
if(participant) {
@@ -134,10 +134,10 @@ export const makeMessagesSocket = (config: SocketConfig) => {
const users: BinaryNode[] = []
jids = Array.from(new Set(jids))
for(let jid of jids) {
const user = jidDecode(jid).user
const user = jidDecode(jid)?.user
jid = jidNormalizedUser(jid)
if(userDevicesCache.has(user) && useCache) {
const devices: JidWithDevice[] = userDevicesCache.get(user)
if(userDevicesCache.has(user!) && useCache) {
const devices = userDevicesCache.get<JidWithDevice[]>(user!)!
deviceResults.push(...devices)
logger.trace({ user }, 'using cache for devices')
@@ -278,7 +278,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
let shouldIncludeDeviceIdentity = false
const { user, server } = jidDecode(jid)
const { user, server } = jidDecode(jid)!
const isGroup = server === 'g.us'
msgId = msgId || generateMessageID()
useUserDevicesCache = useUserDevicesCache !== false
@@ -299,7 +299,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
additionalAttributes = { ...additionalAttributes, device_fanout: 'false' }
}
const { user, device } = jidDecode(participant)
const { user, device } = jidDecode(participant)!
devices.push({ user, device })
}
@@ -333,7 +333,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
if(!participant) {
const participantsList = groupData.participants.map(p => p.id)
const additionalDevices = await getUSyncDevices(participantsList, useUserDevicesCache, false)
const additionalDevices = await getUSyncDevices(participantsList, !!useUserDevicesCache, false)
devices.push(...additionalDevices)
}
@@ -376,7 +376,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
await authState.keys.set({ 'sender-key-memory': { [jid]: senderKeyMap } })
} else {
const { user: meUser } = jidDecode(meId)
const { user: meUser } = jidDecode(meId)!
const encodedMeMsg = encodeWAMessage({
deviceSentMessage: {
@@ -389,7 +389,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
devices.push({ user })
devices.push({ user: meUser })
const additionalDevices = await getUSyncDevices([ meId, jid ], useUserDevicesCache, true)
const additionalDevices = await getUSyncDevices([ meId, jid ], !!useUserDevicesCache, true)
devices.push(...additionalDevices)
}
@@ -434,7 +434,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
const stanza: BinaryNode = {
tag: 'message',
attrs: {
id: msgId,
id: msgId!,
type: 'text',
...(additionalAttributes || {})
},
@@ -461,7 +461,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
(stanza.content as BinaryNode[]).push({
tag: 'device-identity',
attrs: { },
content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account).finish()
content: proto.ADVSignedDeviceIdentity.encode(authState.creds.account!).finish()
})
logger.debug({ jid }, 'adding device identity')
@@ -538,7 +538,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
error = result.error
} else {
try {
const media = decryptMediaRetryData(result.media!, mediaKey, result.key.id)
const media = decryptMediaRetryData(result.media!, mediaKey, result.key.id!)
if(media.result !== proto.MediaRetryNotification.MediaRetryNotificationResultType.SUCCESS) {
const resultStr = proto.MediaRetryNotification.MediaRetryNotificationResultType[media.result]
throw new Boom(
@@ -612,7 +612,7 @@ export const makeMessagesSocket = (config: SocketConfig) => {
additionalAttributes.edit = '7'
}
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id!, cachedGroupMetadata: options.cachedGroupMetadata, additionalAttributes })
await relayMessage(jid, fullMsg.message!, { messageId: fullMsg.key.id!, cachedGroupMetadata: options.cachedGroupMetadata, additionalAttributes })
if(config.emitOwnEvents) {
process.nextTick(() => {
upsertMessage(fullMsg, 'append')

View File

@@ -104,7 +104,7 @@ export const makeSocket = ({
})
if(sendMsg) {
sendRawMessage(sendMsg).catch(onClose)
sendRawMessage(sendMsg).catch(onClose!)
}
return result
@@ -134,9 +134,9 @@ export const makeSocket = ({
)
return result as any
} finally {
ws.off(`TAG:${msgId}`, onRecv)
ws.off('close', onErr) // if the socket closes, you'll never receive the message
ws.off('error', onErr)
ws.off(`TAG:${msgId}`, onRecv!)
ws.off('close', onErr!) // if the socket closes, you'll never receive the message
ws.off('error', onErr!)
}
}
@@ -215,7 +215,7 @@ export const makeSocket = ({
]
})
const countChild = getBinaryNodeChild(result, 'count')
return +countChild.attrs.value
return +countChild!.attrs.value
}
/** generates and uploads a set of pre-keys to the server */
@@ -525,7 +525,7 @@ export const makeSocket = ({
logger.info({ name }, 'updated pushName')
sendNode({
tag: 'presence',
attrs: { name }
attrs: { name: name! }
})
.catch(err => {
logger.warn({ trace: err.stack }, 'error in sending presence update on name change')