Skip to content

Commit

Permalink
refa: enhance typings
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Jan 22, 2025
1 parent 9617ec2 commit d93003a
Show file tree
Hide file tree
Showing 11 changed files with 73 additions and 74 deletions.
6 changes: 3 additions & 3 deletions adapters/discord/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ export class DiscordBot<C extends Context = Context> extends Bot<C, DiscordBot.C
static inject = ['http']

public http: HTTP
public internal: Internal
public webhooks: Record<string, Webhook> = {}
public internal: Internal<C>
public webhooks: Record<string, Webhook | null> = {}
public webhookLock: Record<string, Promise<Webhook>> = {}
public commands: Universal.Command[] = []

Expand Down Expand Up @@ -122,7 +122,7 @@ export class DiscordBot<C extends Context = Context> extends Bot<C, DiscordBot.C
async getGuildMemberList(guildId: string, after?: string) {
const users = await this.internal.listGuildMembers(guildId, { after, limit: 1000 })
const data = users.map(v => Discord.decodeGuildMember(v))
return { data, next: data[999]?.user.id }
return { data, next: data[999]?.user!.id }
}

async getChannel(channelId: string) {
Expand Down
14 changes: 8 additions & 6 deletions adapters/discord/src/message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ export class DiscordMessageEncoder<C extends Context = Context> extends MessageE
private stack: State[] = [new State('message')]
private buffer: string = ''
private addition: Dict = {}
private figure: h = null
private figure?: h
private mode: RenderMode = 'default'
private listType: 'ol' | 'ul' = null
private listType?: 'ol' | 'ul'
private rows: ActionRow[] = []
private async getUrl() {
const input = this.options?.session?.discord
Expand Down Expand Up @@ -73,7 +73,9 @@ export class DiscordMessageEncoder<C extends Context = Context> extends MessageE
if (this.bot.http.isError(e) && e.response) {
if (e.response.data?.code === 10015) {
this.bot.logger.debug('webhook has been deleted, recreating..., %o', e.response.data)
if (!this.bot.webhookLock[this.channelId]) this.bot.webhooks[this.channelId] = null
if (!this.bot.webhookLock[this.channelId]) {
this.bot.webhooks[this.channelId] = null
}
await this.ensureWebhook()
return this.post(data, headers)
} else {
Expand Down Expand Up @@ -134,7 +136,7 @@ export class DiscordMessageEncoder<C extends Context = Context> extends MessageE
headers: { accept: type + '/*' },
timeout: 1000,
}).then(
(headers) => headers.get('content-type').startsWith(type),
(headers) => headers.get('content-type')?.startsWith(type),
() => false,
)
}
Expand Down Expand Up @@ -260,7 +262,7 @@ export class DiscordMessageEncoder<C extends Context = Context> extends MessageE
} else if (type === 'ul' || type === 'ol') {
this.listType = type
await this.render(children)
this.listType = null
this.listType = undefined
} else if (type === 'li') {
if (!this.buffer.endsWith('\n')) this.buffer += '\n'
if (this.listType === 'ol') {
Expand Down Expand Up @@ -343,7 +345,7 @@ export class DiscordMessageEncoder<C extends Context = Context> extends MessageE
if (this.stack[0].type === 'forward' && this.stack[0].fakeMessageMap[attrs.id]?.length >= 1) {
// quote to fake message, eg. 1st message has id (in channel or thread), later message quote to it
replyId = this.stack[0].fakeMessageMap[attrs.id][0].id
channelId = this.stack[0].fakeMessageMap[attrs.id][0].channel.id
channelId = this.stack[0].fakeMessageMap[attrs.id][0].channel!.id
}
const quote = await this.bot.getMessage(channelId, replyId)
if (!guildId) {
Expand Down
2 changes: 1 addition & 1 deletion adapters/discord/src/types/gateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export namespace Gateway {
/** opcode for the payload */
op: O
/** event data */
d?: D
d: D
/** the event name for this payload */
t?: T
/** sequence number, used for resuming sessions and heartbeats */
Expand Down
6 changes: 3 additions & 3 deletions adapters/discord/src/types/internal.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Dict, HTTP, makeArray } from '@satorijs/core'
import { Context, Dict, HTTP, makeArray } from '@satorijs/core'
import { DiscordBot } from '../bot'

export class Internal {
constructor(private bot: DiscordBot) {}
export class Internal<C extends Context = Context> {
constructor(private bot: DiscordBot<C>) {}

static define(routes: Dict<Partial<Record<HTTP.Method, string | string[]>>>) {
for (const path in routes) {
Expand Down
26 changes: 13 additions & 13 deletions adapters/discord/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const decodeGuildMember = (member: Partial<Discord.GuildMember>): Univers
user: member.user && decodeUser(member.user),
nick: member.nick,
roles: member.roles,
joinedAt: member.joined_at && new Date(member.joined_at).valueOf(),
joinedAt: member.joined_at ? new Date(member.joined_at).valueOf() : undefined,
})

export const decodeGuild = (data: Discord.Guild): Universal.Guild => ({
Expand All @@ -56,11 +56,11 @@ export const decodeRole = (role: Discord.Role): Universal.GuildRole => ({

export const encodeRole = (role: Partial<Universal.GuildRole>): Partial<Discord.Role> => ({
...role,
permissions: role.permissions && '' + role.permissions,
permissions: role.permissions ? '' + role.permissions : undefined,
})

export async function decodeMessage(
bot: DiscordBot,
export async function decodeMessage<C extends Context = Context>(
bot: DiscordBot<C>,
data: Discord.Message,
message: Universal.Message,
payload: Universal.MessageLike = message,
Expand Down Expand Up @@ -167,11 +167,11 @@ export async function decodeMessage(
// THREAD_STARTER_MESSAGE (21) 事件下,message_reference 有 message_id
if (details && data.message_reference?.message_id) {
const { message_id, channel_id } = data.message_reference
message.quote = await bot.getMessage(channel_id, message_id, false)
message.quote = await bot.getMessage(channel_id!, message_id, false)
}

message.createdAt = new Date(data.timestamp).valueOf()
message.updatedAt = data.edited_timestamp && new Date(data.edited_timestamp).valueOf()
message.updatedAt = data.edited_timestamp ? new Date(data.edited_timestamp).valueOf() : undefined
if (!payload) return message
payload.channel = {
id: data.channel_id,
Expand All @@ -183,7 +183,7 @@ export async function decodeMessage(
return message
}

export function setupMessageGuildId(session: Session, guildId: string) {
export function setupMessageGuildId(session: Session, guildId?: string) {
session.guildId = guildId
session.isDirect = !guildId
session.subtype = guildId ? 'group' : 'private'
Expand Down Expand Up @@ -226,11 +226,11 @@ export async function adaptSession<C extends Context>(bot: DiscordBot<C>, input:
// if (!session.content) return
} else if (input.t === 'MESSAGE_UPDATE') {
session.type = 'message-updated'
const message = await bot._getMessage(input.d.channel_id, input.d.id)
const message = await bot._getMessage(input.d.channel_id!, input.d.id!)
// Unlike creates, message updates may contain only a subset of the full message object payload
// https://discord.com/developers/docs/topics/gateway-events#message-update
await decodeMessage(bot, message, session.event.message = {}, session.event)
const channel = await bot.internal.getChannel(input.d.channel_id)
const channel = await bot.internal.getChannel(input.d.channel_id!)
setupMessageGuildId(session, channel.guild_id)
// if (!session.content) return
} else if (input.t === 'MESSAGE_DELETE') {
Expand Down Expand Up @@ -279,7 +279,7 @@ export async function adaptSession<C extends Context>(bot: DiscordBot<C>, input:
session.subtype = input.d.guild_id ? 'group' : 'private'
session.channelId = input.d.channel_id
session.guildId = input.d.guild_id
session.userId = session.isDirect ? input.d.user.id : input.d.member.user.id
session.userId = session.isDirect ? input.d.user!.id : input.d.member!.user!.id
session.messageId = input.d.id
session.content = ''
session.event.argv = decodeArgv(data, command)
Expand All @@ -296,7 +296,7 @@ export async function adaptSession<C extends Context>(bot: DiscordBot<C>, input:
session.subtype = input.d.guild_id ? 'group' : 'private'
session.channelId = input.d.channel_id
session.guildId = input.d.guild_id
session.userId = session.isDirect ? input.d.user.id : input.d.member.user.id
session.userId = session.isDirect ? input.d.user!.id : input.d.member!.user!.id
session.messageId = input.d.id
session.content = user_input
} else if (input.t === 'INTERACTION_CREATE' && input.d.type === Discord.Interaction.Type.MESSAGE_COMPONENT) {
Expand Down Expand Up @@ -328,7 +328,7 @@ export async function adaptSession<C extends Context>(bot: DiscordBot<C>, input:
session.isDirect = !input.d.guild_id
session.channelId = input.d.channel_id
session.guildId = input.d.guild_id
session.userId = session.isDirect ? input.d.user.id : input.d.member.user.id
session.userId = session.isDirect ? input.d.user!.id : input.d.member!.user!.id
session.messageId = input.d.id
session.content = ''
session.event.button = {
Expand Down Expand Up @@ -441,5 +441,5 @@ export function encodeCommandOptions(cmd: Universal.Command): Discord.Applicatio
})
}
}
return result.sort((a, b) => +b.required - +a.required)
return result.sort((a, b) => +b.required! - +a.required!)
}
15 changes: 8 additions & 7 deletions adapters/discord/src/ws.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import { DiscordBot } from './bot'

export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, DiscordBot<C>> {
_d = 0
_ping: NodeJS.Timeout
_ping?: NodeJS.Timeout
_sessionId = ''
_resumeUrl: string
_resumeUrl?: string

async prepare() {
if (this._resumeUrl) {
Expand All @@ -18,6 +18,7 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, D
}

heartbeat() {
if (!this.socket) return
this.bot.logger.debug(`heartbeat d ${this._d}`)
this.socket.send(JSON.stringify({
op: Gateway.Opcode.HEARTBEAT,
Expand All @@ -26,7 +27,7 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, D
}

accept() {
this.socket.addEventListener('message', async ({ data }) => {
this.socket!.addEventListener('message', async ({ data }) => {
let parsed: Gateway.Payload
data = data.toString()
try {
Expand All @@ -44,7 +45,7 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, D
this._ping = setInterval(() => this.heartbeat(), parsed.d.heartbeat_interval)
if (this._sessionId) {
this.bot.logger.debug('resuming')
this.socket.send(JSON.stringify({
this.socket!.send(JSON.stringify({
op: Gateway.Opcode.RESUME,
d: {
token: this.bot.config.token,
Expand All @@ -53,7 +54,7 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, D
},
}))
} else {
this.socket.send(JSON.stringify({
this.socket!.send(JSON.stringify({
op: Gateway.Opcode.IDENTIFY,
d: {
token: this.bot.config.token,
Expand All @@ -75,7 +76,7 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, D
if (parsed.op === Gateway.Opcode.DISPATCH) {
this.bot.dispatch(this.bot.session({
type: 'internal',
_type: 'discord/' + parsed.t.toLowerCase().replace(/_/g, '-'),
_type: 'discord/' + parsed.t!.toLowerCase().replace(/_/g, '-'),
_data: parsed.d,
}))
if (parsed.t === 'READY') {
Expand All @@ -98,7 +99,7 @@ export class WsClient<C extends Context = Context> extends Adapter.WsClient<C, D
}
})

this.socket.addEventListener('close', () => {
this.socket!.addEventListener('close', () => {
clearInterval(this._ping)
})
}
Expand Down
2 changes: 1 addition & 1 deletion adapters/lark/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"@cordisjs/plugin-server": "^0.2.5",
"@satorijs/core": "^4.5.0",
"cordis": "^3.18.1",
"cosmokit": "^1.6.3",
"cosmokit": "^1.7.0",
"dedent": "^1.5.3"
},
"peerDependencies": {
Expand Down
22 changes: 6 additions & 16 deletions adapters/lark/src/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,10 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
static inject = ['server', 'http']
static MessageEncoder = LarkMessageEncoder

_token?: string
_refresher?: NodeJS.Timeout
http: HTTP
assetsQuester: HTTP
internal: Internal
internal: Internal<C>

constructor(ctx: C, config: LarkBot.Config) {
super(ctx, config, 'lark')
Expand Down Expand Up @@ -86,7 +85,7 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
app_secret: this.config.appSecret,
})
this.logger.debug('refreshed token %s', token)
this.token = token
this.http.config.headers!.Authorization = `Bearer ${token}`
} catch (error) {
this.logger.error('failed to refresh token, retrying in 10s')
this.logger.error(error)
Expand All @@ -97,15 +96,6 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>
this.online()
}

get token() {
return this._token
}

set token(v: string) {
this._token = v
this.http.config.headers.Authorization = `Bearer ${v}`
}

async editMessage(channelId: string, messageId: string, content: h.Fragment) {
const encoder = new LarkMessageEncoder(this, channelId)
encoder.editMessageIds = [messageId]
Expand All @@ -118,9 +108,9 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>

async getMessage(channelId: string, messageId: string, recursive = true) {
const data = await this.internal.getImMessage(messageId)
const message = await Utils.decodeMessage(this, data.items[0], recursive)
const message = await Utils.decodeMessage(this, data.items![0], recursive)
const im = await this.internal.getImChat(channelId)
message.channel.type = im.chat_mode === 'p2p' ? Universal.Channel.Type.DIRECT : Universal.Channel.Type.TEXT
message.channel!.type = im.chat_mode === 'p2p' ? Universal.Channel.Type.DIRECT : Universal.Channel.Type.TEXT
return message
}

Expand All @@ -132,7 +122,7 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>

async getUser(userId: string, guildId?: string) {
const data = await this.internal.getContactUser(userId)
return Utils.decodeUser(data.user)
return Utils.decodeUser(data.user!)
}

async getChannel(channelId: string) {
Expand All @@ -156,7 +146,7 @@ export class LarkBot<C extends Context = Context> extends Bot<C, LarkBot.Config>

async getGuildMemberList(guildId: string, after?: string) {
const members = await this.internal.getImChatMembers(guildId, { page_token: after })
const data = members.items.map(v => ({ user: { id: v.member_id, name: v.name }, name: v.name }))
const data = members.items!.map(v => ({ user: { id: v.member_id, name: v.name }, name: v.name }))
return { data, next: members.page_token }
}

Expand Down
2 changes: 1 addition & 1 deletion adapters/lark/src/http.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class HttpServer<C extends Context = Context> extends Adapter<C, LarkBot<
if (!header) return
const { app_id, event_type } = header
body.type = event_type // add type to body to ease typescript type narrowing
const bot = this.bots.find((bot) => bot.config.appId === app_id)
const bot = this.bots.find((bot) => bot.config.appId === app_id)!
const session = await adaptSession(bot, body)
bot.dispatch(session)
}
Expand Down
13 changes: 7 additions & 6 deletions adapters/lark/src/internal.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Dict, HTTP, makeArray } from '@satorijs/core'
import { Context, Dict, HTTP, makeArray } from '@satorijs/core'
import { LarkBot } from './bot'

export interface Internal {}
Expand Down Expand Up @@ -33,8 +33,8 @@ export interface InternalRoute {
type?: 'raw-json' | 'binary'
}

export class Internal {
constructor(private bot: LarkBot) {}
export class Internal<C extends Context = Context> {
constructor(private bot: LarkBot<C>) {}

private _assertResponse(response: HTTP.Response<BaseResponse>) {
if (!response.data.code) return
Expand Down Expand Up @@ -113,12 +113,13 @@ export class Internal {
const { argIndex, itemsKey = 'items', tokenKey = 'page_token' } = route.pagination
const iterArgs = [...args]
iterArgs[argIndex] = { ...args[argIndex] }
let pagination: { data: any[]; next?: any } | undefined
type Pagniation = { data: any[]; next?: any }
let pagination: Pagniation | undefined
result.next = async function () {
pagination ??= await this[Symbol.for('satori.pagination')]()
pagination ??= await this[Symbol.for('satori.pagination')]() as Pagniation
if (pagination.data.length) return { done: false, value: pagination.data.shift() }
if (!pagination.next) return { done: true, value: undefined }
pagination = await this[Symbol.for('satori.pagination')]()
pagination = await this[Symbol.for('satori.pagination')]() as Pagniation
return this.next()
}
result[Symbol.asyncIterator] = function () {
Expand Down
Loading

0 comments on commit d93003a

Please sign in to comment.