Skip to content

type-safe nodejs/browser library for bilibili api based on axios and mitt, accorded from Bilibili-API-Collect

License

Notifications You must be signed in to change notification settings

eric2788/bilibili-api

Repository files navigation

Important

该项目为概念半成品,主要用于测试日后维护和扩展API的可行性。

假设你觉得这个项目可行,欢迎贡献代码,让这个项目更加完善! 当进度足够完善时,将会发布到 npm 上。

Bilibili-API

适用于 nodejs/browser 的 bilibili api 类型安全库

基于 mittaxios

Note

这些 API 都是根据 bilibili-API-collect 来的,如果有任何不匹配,欢迎开 issue 或 PR。

特性

  • 类型安全
  • 开箱即用
  • 易于扩展/维护

安装

(尚未发布)

npm install bilibili-api

使用

简单示例

import { ApiClient } from "bilibili-api";

const client = await ApiClient.create()

client.live.emit("info/room", { room_id: 1 }).then((res) => {
  console.log(res)
})

client.video.emit("action/like/web", { bvid: "1mK4y1C7Bz", like: 1, csrf: "" }).then((res) => {
  console.log(res)
})

// 监听事件
client.live.on("info/room", (res) => {
    // res 是类型安全的
    console.log(res)
})

部分引入

import { LiveClient, VideoClient } from "bilibili-api"
import axiosFactory from 'axios'

// 在 nodejs 中,你需要使用外部库来支持 axios 中的 cookie
const axios = axiosFactory.create({ withCredentials: true })
const live = new LiveClient(axios)
const video = new VideoClient(axios)

// emit 键是类型安全的
live.emit("info/room", { room_id: 1 }).then((res) => {
    // res 是类型安全的
    console.log(res)
})

video
    .emit("action/like/web", { // 输入是类型安全的
        bvid: "1mK4y1C7Bz",
        like: 1,
        csrf: "",
    })
    .then((res) => {
        // res 是类型安全的
        console.log(res)
    })
// 监听事件
live.on("info/room", (res) => {
    // res 是类型安全的
    console.log(res)
})

维护/扩展/贡献

架构

参考:src/schema

live/info/user 为例:

文件:live/info/user.ts

// 信息来源于 https://github.com/SocialSisterYi/bilibili-API-collect/blob/master/docs/live/info.md#获取用户对应的直播间状态
export namespace User {

    export type Schema = HttpSchema<Input, Output>

    // 定义
    export const defines: HttpDefine = {
        method: 'GET',
        url: 'https://api.live.bilibili.com/room/v1/Room/getRoomInfoOld',
        params: ['mid']
    }

    // 输入架构
    type Input = {
        mid: number
    }

    // 输出架构
    type Output = V1Response<{
        roomStatus: number
        roundStatus: number
        live_status: number
        url: string
        title: string
        cover: string
        online: number
        roomid: number
        broadcast_type: number
        online_hidden: number
    }>

}

文件:live/info/index.ts

export * from './init'
export * from './room'
export * from './stream'
export * from './streamer'
export * from './user' // 已添加

文件:live/index.ts

import * as info from './info'
import { Area } from './area'
import { Stream } from './stream'
import { HttpDefine } from '@schemas/common'

export type Schema = {
    'info/init': info.Init.Schema
    'info/room': info.Room.Schema
    'info/stream': info.Stream.Schema
    'info/streamer': info.Streamer.Schema
    'info/user': info.User.Schema // 已添加
    'area': Area.Schema
    'stream': Stream.Schema
}

export type SchemaKey = keyof Schema
export const defines: Record<SchemaKey, HttpDefine> = {
    'info/init': info.Init.defines,
    'info/room': info.Room.defines,
    'info/stream': info.Stream.defines,
    'info/streamer': info.Streamer.defines,
    'info/user': info.User.defines, // 已添加
    'area': Area.defines,
    'stream': Stream.defines
}

添加后,类型安全现已就绪

import { LiveClient } from "bilibili-api"

const live = new LiveClient(axios)

live.emit("info/user", { mid: 1 }).then((res) => {
    // res 是类型安全的
    console.log(res)
})

客户端

参考:src/clients

新增一个新的客户端类别时使用。例如 schames/live

文件:clients/live.ts

import { HttpDefine } from "@schemas/common"
import { defines, Schema, SchemaKey } from "@schemas/live"
import { BaseClient, RequestConfig } from "./base"

// Schema 是基于 该文件夹的架构定义的 (这里的例子为 live )
export class LiveClient extends BaseClient<Schema> {

    async emit<K extends SchemaKey, Input extends Schema[K]['input'], Output extends Schema[K]['output']>(key: K, data: Input = undefined, options: RequestConfig = {}): Promise<Output> {
        return super.emit(key, data, options)
    }

    on<K extends SchemaKey, Data extends Schema[K]['output']>(key: K, handler: (data: Data) => void) {
        super.on(key, handler)
    }

    off<K extends SchemaKey, Data extends Schema[K]['output']>(key: K, handler: (data: Data) => void) {
        super.off(key, handler)
    }

    protected get defines(): Record<keyof Schema, HttpDefine> {
        return defines
    }

}

文件:index.ts

import { LiveClient } from "@clients/live" // 已添加
import { LoginClient } from "@clients/login"
import { VideoClient } from "@clients/video"
import { AxiosInstance } from 'axios'
export class ApiClient {

    /**
     * 根据环境创建 ApiClient 实例。
     * 
     * @returns {ApiClient} 创建的 ApiClient 实例。
     */
    static create(): ApiClient {
        let create: Function
        if (typeof window === 'undefined') {
            const fromNodeJS = require('@factories/node').default
            create = fromNodeJS
        } else {
            const fromBrowser = require('@factories/browser').default
            create = fromBrowser
        }
        return create()
    }

    public constructor(axios: AxiosInstance) {
        this.login = new LoginClient(axios)
        this.video = new VideoClient(axios)
        this.live = new LiveClient(axios) // 已添加
    }

    public readonly login: LoginClient
    public readonly video: VideoClient
    public readonly live: LiveClient // 已添加

}

export {
    LiveClient, // 为部分引入而添加
    LoginClient,
    VideoClient
}

使用方法

import { ApiClient, LiveClient } from "bilibili-api"

// 使用 ApiClient
const api = ApiClient.create()
api.live.emit("info/user", { mid: 1 }).then((res) => {
    // res 是类型安全的
    console.log(res)
})

// 使用 LiveClient
const axios = axios.create()
const live = new LiveClient(axios)
live.emit("info/user", { mid: 1 }).then((res) => {
    // res 是类型安全的
    console.log(res)
})

注意事项:

  • 所有实现都是从 BaseClient 预设的
  • 重新声明函数只是为了类型安全

Note

目前每个客户端的实现似乎都是一样的,只是为了类型安全,如果你有更好的想法,欢迎 PR

About

type-safe nodejs/browser library for bilibili api based on axios and mitt, accorded from Bilibili-API-Collect

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published