Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Mar 11, 2020
2 parents 5664647 + 1eaf9b0 commit ff65e7e
Show file tree
Hide file tree
Showing 26 changed files with 177 additions and 100 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ Koishi 在开发时借助了下面的工具:

### 对比

| 特性 | [koishi<br>1.3.0](https://www.npmjs.com/package/koishi/v/1.3.0) | [cqhttp<br>1.2.0](https://www.npmjs.com/package/cqhttp/v/1.2.0) | [cq-websocket<br>2.0.2](https://www.npmjs.com/package/cq-websocket/v/2.0.2) | [lemon-bot<br>0.6.0](https://www.npmjs.com/package/lemon-bot/v/0.6.0) | [@ionjs/core<br>0.6.5](https://www.npmjs.com/package/@ionjs/core/v/0.6.5) |
| 特性 | [koishi<br>1.10.0](https://www.npmjs.com/package/koishi/v/1.10.0) | [cqhttp<br>1.2.0](https://www.npmjs.com/package/cqhttp/v/1.2.0) | [cq-websocket<br>2.0.2](https://www.npmjs.com/package/cq-websocket/v/2.0.2) | [lemon-bot<br>0.6.0](https://www.npmjs.com/package/lemon-bot/v/0.6.0) | [@ionjs/core<br>0.6.5](https://www.npmjs.com/package/@ionjs/core/v/0.6.5) |
|:--:|:--:|:--:|:--:|:--:|:--:|
| 依赖数量 | [10](http://npm.anvaka.com/#/view/2d/koishi-core/1.3.0) / [21](http://npm.anvaka.com/#/view/2d/koishi/1.3.0) | [62](http://npm.anvaka.com/#/view/2d/cqhttp/1.1.1) | [37](http://npm.anvaka.com/#/view/2d/cq-websocket/2.0.2) | [65](http://npm.anvaka.com/#/view/2d/lemon-bot/0.6.0) | [73](http://npm.anvaka.com/#/view/2d/%2540ionjs%252Fcore/0.6.5) |
| 安装体积 (MB) | [0.78](https://packagephobia.now.sh/result?p=koishi-core@1.3.0) / [2.14](https://packagephobia.now.sh/result?p=koishi@1.3.0) | [1.86](https://packagephobia.now.sh/result?p=cqhttp@1.1.1) | [2.82](https://packagephobia.now.sh/result?p=cq-websocket) | [2.56](https://packagephobia.now.sh/result?p=lemon-bot) | [2.32](https://packagephobia.now.sh/result?p=@ionjs/core) |
| 依赖数量 | [10](http://npm.anvaka.com/#/view/2d/koishi-core/1.10.0) / [21](http://npm.anvaka.com/#/view/2d/koishi/1.10.0) | [62](http://npm.anvaka.com/#/view/2d/cqhttp/1.1.1) | [37](http://npm.anvaka.com/#/view/2d/cq-websocket/2.0.2) | [65](http://npm.anvaka.com/#/view/2d/lemon-bot/0.6.0) | [73](http://npm.anvaka.com/#/view/2d/%2540ionjs%252Fcore/0.6.5) |
| 安装体积 (MB) | [0.78](https://packagephobia.now.sh/result?p=koishi-core@1.10.0) / [2.28](https://packagephobia.now.sh/result?p=koishi@1.10.0) | [1.86](https://packagephobia.now.sh/result?p=cqhttp@1.1.1) | [2.82](https://packagephobia.now.sh/result?p=cq-websocket) | [2.56](https://packagephobia.now.sh/result?p=lemon-bot) | [2.32](https://packagephobia.now.sh/result?p=@ionjs/core) |
| HTTP | ✔️ | ✔️ || ✔️ | ✔️ |
| WebSocket | ✔️ || ✔️ |||
| 反向 WebSocket ||||||
Expand Down
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,21 @@
"version": "1.0.0",
"license": "MIT",
"devDependencies": {
"@octokit/rest": "^17.0.0",
"@octokit/rest": "^17.0.1",
"@types/cross-spawn": "^6.0.1",
"@types/fs-extra": "^8.1.0",
"@types/jest": "^25.1.3",
"@types/node": "^13.7.7",
"@types/jest": "^25.1.4",
"@types/node": "^13.9.0",
"@types/semver": "^7.1.0",
"@typescript-eslint/eslint-plugin": "^2.22.0",
"@typescript-eslint/parser": "^2.22.0",
"cac": "^6.5.6",
"@typescript-eslint/eslint-plugin": "^2.23.0",
"@typescript-eslint/parser": "^2.23.0",
"cac": "^6.5.7",
"cross-spawn": "^7.0.1",
"del": "^5.1.0",
"eslint": "^6.8.0",
"eslint-config-standard": "^14.1.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-jest": "^23.8.1",
"eslint-plugin-jest": "^23.8.2",
"eslint-plugin-node": "^11.0.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.1",
Expand All @@ -47,9 +47,9 @@
"jest": "^25.1.0",
"kleur": "^3.0.3",
"latest-version": "^5.1.0",
"open": "^7.0.2",
"open": "^7.0.3",
"ora": "^4.0.3",
"p-map": "^3.0.0",
"p-map": "^4.0.0",
"prompts": "^2.3.1",
"semver": "^7.1.3",
"ts-jest": "^25.2.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/database-level/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-database-level",
"description": "Leveldb support for Koishi",
"version": "1.1.4",
"version": "1.1.5",
"main": "dist/index.js",
"files": [
"dist"
Expand Down Expand Up @@ -33,10 +33,10 @@
"leveldb"
],
"devDependencies": {
"koishi-test-utils": "^3.1.3"
"koishi-test-utils": "^3.1.4"
},
"peerDependencies": {
"koishi-core": "^1.10.1"
"koishi-core": "^1.11.0"
},
"dependencies": {
"@types/leveldown": "^4.0.2",
Expand Down
4 changes: 2 additions & 2 deletions packages/database-memory/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-database-memory",
"description": "An in-memory database implementation for Koishi",
"version": "1.1.4",
"version": "1.1.5",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand All @@ -22,7 +22,7 @@
},
"homepage": "https://github.com/koishijs/koishi/tree/master/packages/database-memory#readme",
"peerDependencies": {
"koishi-core": "^1.10.1"
"koishi-core": "^1.11.0"
},
"dependencies": {
"koishi-utils": "^1.0.4"
Expand Down
4 changes: 2 additions & 2 deletions packages/database-mysql/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-database-mysql",
"description": "MySQL support for Koishi",
"version": "1.1.4",
"version": "1.1.5",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand Down Expand Up @@ -35,7 +35,7 @@
"@types/mysql": "^2.15.9"
},
"peerDependencies": {
"koishi-core": "^1.10.1"
"koishi-core": "^1.11.0"
},
"dependencies": {
"koishi-utils": "^1.0.4",
Expand Down
6 changes: 3 additions & 3 deletions packages/database-sqlite/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "koishi-database-sqlite",
"version": "1.0.0-alpha.10",
"version": "1.0.0-alpha.11",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand All @@ -22,10 +22,10 @@
"homepage": "https://github.com/koishijs/koishi/tree/master/packages/database-sqlite#readme",
"devDependencies": {
"@types/sqlite3": "^3.1.6",
"koishi-test-utils": "^3.1.3"
"koishi-test-utils": "^3.1.4"
},
"peerDependencies": {
"koishi-core": "^1.10.1"
"koishi-core": "^1.11.0"
},
"dependencies": {
"koishi-utils": "^1.0.4",
Expand Down
6 changes: 3 additions & 3 deletions packages/koishi-cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ Koishi 在开发时借助了下面的工具:

### 对比

| 特性 | [koishi<br>1.3.0](https://www.npmjs.com/package/koishi/v/1.3.0) | [cqhttp<br>1.2.0](https://www.npmjs.com/package/cqhttp/v/1.2.0) | [cq-websocket<br>2.0.2](https://www.npmjs.com/package/cq-websocket/v/2.0.2) | [lemon-bot<br>0.6.0](https://www.npmjs.com/package/lemon-bot/v/0.6.0) | [@ionjs/core<br>0.6.5](https://www.npmjs.com/package/@ionjs/core/v/0.6.5) |
| 特性 | [koishi<br>1.10.0](https://www.npmjs.com/package/koishi/v/1.10.0) | [cqhttp<br>1.2.0](https://www.npmjs.com/package/cqhttp/v/1.2.0) | [cq-websocket<br>2.0.2](https://www.npmjs.com/package/cq-websocket/v/2.0.2) | [lemon-bot<br>0.6.0](https://www.npmjs.com/package/lemon-bot/v/0.6.0) | [@ionjs/core<br>0.6.5](https://www.npmjs.com/package/@ionjs/core/v/0.6.5) |
|:--:|:--:|:--:|:--:|:--:|:--:|
| 依赖数量 | [10](http://npm.anvaka.com/#/view/2d/koishi-core/1.3.0) / [21](http://npm.anvaka.com/#/view/2d/koishi/1.3.0) | [62](http://npm.anvaka.com/#/view/2d/cqhttp/1.1.1) | [37](http://npm.anvaka.com/#/view/2d/cq-websocket/2.0.2) | [65](http://npm.anvaka.com/#/view/2d/lemon-bot/0.6.0) | [73](http://npm.anvaka.com/#/view/2d/%2540ionjs%252Fcore/0.6.5) |
| 安装体积 (MB) | [0.78](https://packagephobia.now.sh/result?p=koishi-core@1.3.0) / [2.14](https://packagephobia.now.sh/result?p=koishi@1.3.0) | [1.86](https://packagephobia.now.sh/result?p=cqhttp@1.1.1) | [2.82](https://packagephobia.now.sh/result?p=cq-websocket) | [2.56](https://packagephobia.now.sh/result?p=lemon-bot) | [2.32](https://packagephobia.now.sh/result?p=@ionjs/core) |
| 依赖数量 | [10](http://npm.anvaka.com/#/view/2d/koishi-core/1.10.0) / [21](http://npm.anvaka.com/#/view/2d/koishi/1.10.0) | [62](http://npm.anvaka.com/#/view/2d/cqhttp/1.1.1) | [37](http://npm.anvaka.com/#/view/2d/cq-websocket/2.0.2) | [65](http://npm.anvaka.com/#/view/2d/lemon-bot/0.6.0) | [73](http://npm.anvaka.com/#/view/2d/%2540ionjs%252Fcore/0.6.5) |
| 安装体积 (MB) | [0.78](https://packagephobia.now.sh/result?p=koishi-core@1.10.0) / [2.28](https://packagephobia.now.sh/result?p=koishi@1.10.0) | [1.86](https://packagephobia.now.sh/result?p=cqhttp@1.1.1) | [2.82](https://packagephobia.now.sh/result?p=cq-websocket) | [2.56](https://packagephobia.now.sh/result?p=lemon-bot) | [2.32](https://packagephobia.now.sh/result?p=@ionjs/core) |
| HTTP | ✔️ | ✔️ || ✔️ | ✔️ |
| WebSocket | ✔️ || ✔️ |||
| 反向 WebSocket ||||||
Expand Down
12 changes: 6 additions & 6 deletions packages/koishi-cli/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi",
"description": "A QQ bot framework based on CQHTTP",
"version": "1.10.1",
"version": "1.11.0",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand Down Expand Up @@ -32,15 +32,15 @@
],
"devDependencies": {
"@types/js-yaml": "^3.12.2",
"@types/prompts": "^2.0.3"
"@types/prompts": "^2.0.5"
},
"dependencies": {
"cac": "^6.5.6",
"cac": "^6.5.7",
"js-yaml": "^3.13.1",
"kleur": "^3.0.3",
"koishi-core": "^1.10.1",
"koishi-plugin-common": "^2.1.5",
"koishi-plugin-schedule": "^1.0.10",
"koishi-core": "^1.11.0",
"koishi-plugin-common": "^2.1.6",
"koishi-plugin-schedule": "^1.0.11",
"koishi-utils": "^1.0.4",
"prompts": "^2.3.1"
}
Expand Down
3 changes: 1 addition & 2 deletions packages/koishi-cli/src/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ if (process.env.KOISHI_LOG_LEVEL !== undefined) {
}

function handleException (error: any) {
const message = types.isNativeError(error) ? error.stack : String(error)
logger.error(message, baseLogLevel)
logger.error(error, baseLogLevel)
process.exit(1)
}

Expand Down
9 changes: 5 additions & 4 deletions packages/koishi-core/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "koishi-core",
"description": "Core features for Koishi",
"version": "1.10.1",
"version": "1.11.0",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"files": [
Expand Down Expand Up @@ -35,15 +35,16 @@
"@types/debug": "^4.1.5",
"@types/ws": "^7.2.2",
"get-port": "^5.1.1",
"koishi-database-memory": "^1.1.4",
"koishi-test-utils": "^3.1.3"
"koishi-database-memory": "^1.1.5",
"koishi-test-utils": "^3.1.4"
},
"dependencies": {
"axios": "^0.19.2",
"debug": "^4.1.1",
"escape-string-regexp": "^2.0.0",
"koishi-utils": "^1.0.4",
"leven": "^3.1.0",
"ws": "^7.2.1"
"ms": "^2.1.2",
"ws": "^7.2.3"
}
}
9 changes: 8 additions & 1 deletion packages/koishi-core/src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,11 @@ export interface AppOptions {
type?: ServerType
database?: DatabaseConfig
nickname?: string | string[]
retryTimes?: number
retryInterval?: number
maxMiddlewares?: number
commandPrefix?: string | string[]
defaultAuthority?: number | ((meta: Meta) => number)
quickOperationTimeout?: number
similarityCoefficient?: number
}
Expand Down Expand Up @@ -75,6 +78,7 @@ function createLeadingRE (patterns: string[], prefix = '', suffix = '') {

const defaultOptions: AppOptions = {
maxMiddlewares: 64,
retryInterval: 5000,
}

export enum Status { closed, opening, open, closing }
Expand Down Expand Up @@ -375,7 +379,10 @@ export class App extends Context {
// attach user data
const userFields = new Set<UserField>(['flag'])
this.emitEvent(meta, 'before-user', userFields, meta.$argv)
const user = await this.database.observeUser(meta.userId, Array.from(userFields))
const defaultAuthority = typeof this.options.defaultAuthority === 'function'
? this.options.defaultAuthority(meta)
: this.options.defaultAuthority || 0
const user = await this.database.observeUser(meta.userId, defaultAuthority, Array.from(userFields))
Object.defineProperty(meta, '$user', { value: user, writable: true })

// emit attach event
Expand Down
2 changes: 1 addition & 1 deletion packages/koishi-core/src/command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ export class Command {
option (rawName: string, description: string, config?: OptionConfig): this
option (rawName: string, ...args: [OptionConfig?] | [string, OptionConfig?]) {
const description = typeof args[0] === 'string' ? args.shift() as string : undefined
const config = args[0] as CommandConfig || {}
const config = args[0] as OptionConfig || {}
const option = parseOption(rawName, description, config, this._optsDef)
this._options.push(option)
for (const name of option.names) {
Expand Down
7 changes: 4 additions & 3 deletions packages/koishi-core/src/sender.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,11 @@ import {
} from './meta'

export class SenderError extends Error {
constructor (args: Record<string, any>, url: string, retcode: number) {
constructor (args: Record<string, any>, url: string, retcode: number, selfId: number) {
super(`Error when trying to send to ${url}, args: ${JSON.stringify(args)}, retcode: ${retcode}`)
Object.defineProperties(this, {
name: { value: 'SenderError' },
selfId: { value: selfId },
code: { value: retcode },
args: { value: args },
url: { value: url },
Expand Down Expand Up @@ -77,9 +78,9 @@ export class Sender {
if (retcode === 0 && !silent) {
return camelCase(data)
} else if (retcode < 0 && !silent) {
throw new SenderError(params, action, retcode)
throw new SenderError(params, action, retcode, this.app.selfId)
} else if (retcode > 1) {
throw new SenderError(params, action, retcode)
throw new SenderError(params, action, retcode, this.app.selfId)
}
}

Expand Down
33 changes: 28 additions & 5 deletions packages/koishi-core/src/server.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import ms from 'ms'
import WebSocket from 'ws'
import * as http from 'http'
import { errors } from './messages'
Expand Down Expand Up @@ -29,7 +30,7 @@ export abstract class Server {
}

protected debug (format: any, ...params: any[]) {
this.app?.logger('koishi:sender').debug(format, ...params)
this.app?.logger('koishi:server').debug(format, ...params)
}

protected prepareMeta (data: any) {
Expand Down Expand Up @@ -277,6 +278,7 @@ let counter = 0

export class WsClient extends Server {
public socket: WebSocket
private _retryCount = 0
private _listeners: Record<number, (response: CQResponse) => void> = {}

send (data: any): Promise<CQResponse> {
Expand All @@ -290,16 +292,33 @@ export class WsClient extends Server {
}

_listen (): Promise<void> {
return new Promise((resolve, reject) => {
const connect = (resolve: () => void, reject: (reason: Error) => void) => {
this.debug('websocket client opening')
const headers: Record<string, string> = {}
const { token, server } = this.app.options
const { token, server, retryInterval, retryTimes } = this.app.options
if (token) headers.Authorization = `Bearer ${token}`
this.socket = new WebSocket(server, { headers })

this.socket.once('error', reject)
this.socket.on('error', error => this.debug(error))

this.socket.once('close', (code) => {
if (!this.isListening || code === 1005) return

const message = `failed to connect to ${server}`
if (!retryInterval || this._retryCount >= retryTimes) {
return reject(new Error(message))
}

this._retryCount++
this.debug(`${message}, will retry in ${ms(retryInterval)}...`)
setTimeout(() => {
if (this.isListening) connect(resolve, reject)
}, retryInterval)
})

this.socket.once('open', () => {
this._retryCount = 0

this.socket.send(JSON.stringify({
action: 'get_version_info',
echo: -1,
Expand All @@ -317,11 +336,13 @@ export class WsClient extends Server {
} catch (error) {
return reject(new Error(data))
}

if (!resolved) {
resolved = true
this.debug('connect to ws server:', this.app.options.server)
resolve()
}

if ('post_type' in parsed) {
const meta = this.prepareMeta(parsed)
if (meta) this.dispatchMeta(meta)
Expand All @@ -333,11 +354,13 @@ export class WsClient extends Server {
}
})
})
})
}
return new Promise(connect)
}

_close () {
this.socket.close()
this._retryCount = 0
this.debug('websocket client closed')
}
}
Expand Down
13 changes: 10 additions & 3 deletions packages/koishi-core/tests/ws-client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,13 @@ let app1: App, app2: App

beforeAll(async () => {
server = await createWsServer()
app1 = server.createBoundApp()
app2 = server.createBoundApp({ selfId: BASE_SELF_ID + 1 })
app1 = server.createBoundApp({
retryTimes: 1,
retryInterval: 100,
})
app2 = server.createBoundApp({
selfId: BASE_SELF_ID + 1,
})
})

afterAll(() => server.close())
Expand All @@ -28,8 +33,10 @@ describe('WebSocket Server', () => {
await expect(app1.start()).rejects.toHaveProperty('message', 'authorization failed')
app1.options.token = 'token'
await expect(app1.start()).resolves.toBeUndefined()
await server.close()
await expect(app1.start()).rejects.toHaveProperty('message')
server.token = null
await app1.stop()
server.open()
await expect(app1.start()).resolves.toBeUndefined()
})

Expand Down

0 comments on commit ff65e7e

Please sign in to comment.