Skip to content

Commit 73fc4ae

Browse files
authored
Merge pull request #104 from koreanbots/node16
BREAKING: Koreanbots JS/TS SDK v3.1
2 parents e6b8bcd + 29aba39 commit 73fc4ae

31 files changed

+2066
-3801
lines changed

.eslintrc.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,18 @@
55
},
66
"extends": [
77
"eslint:recommended",
8-
"plugin:@typescript-eslint/recommended"
8+
"plugin:@typescript-eslint/recommended",
9+
"plugin:import/recommended",
10+
"plugin:import/typescript"
911
],
1012
"parser": "@typescript-eslint/parser",
1113
"parserOptions": {
1214
"ecmaVersion": 2020,
1315
"sourceType": "module"
1416
},
1517
"plugins": [
16-
"@typescript-eslint"
18+
"@typescript-eslint",
19+
"import"
1720
],
1821
"rules": {
1922
"indent": [

.github/workflows/commitlint.yml

Lines changed: 0 additions & 16 deletions
This file was deleted.

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ $ yarn add koreanbots
3838

3939
## 사용 조건
4040

41-
> Node.js v12 이상이 권장됩니다.
41+
> 3.1 버전 이상은 Node.js v16.6.0 이상이 필요합니다.
42+
> 그 이하 버전은 Node.js v12부터 지원됩니다.
4243
4344
| discord.js version | supported | planned to support |
4445
|---------------------------|-----------|--------------------|
@@ -106,8 +107,8 @@ client.login("토큰")
106107
107108
👤 **zero734kr**
108109
109-
* 개인 Github: [@zero734kr](https://github.com/zero734kr)
110-
* Organization Github: [@koreanbots](https://github.com/koreanbots)
110+
* 개인 GitHub: [@zero734kr](https://github.com/zero734kr)
111+
* Organization GitHub: [@koreanbots](https://github.com/koreanbots)
111112
112113
113114
## 🤝 도움주기

package.json

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
{
22
"name": "koreanbots",
3-
"version": "3.0.0",
3+
"version": "3.1.0-rc.1",
44
"description": "JavaScript/TypeScript SDK for KOREANBOTS",
55
"main": "dist/src/index.js",
66
"typings": "dist/src/index.d.ts",
77
"license": "MIT",
88
"scripts": {
9-
"test": "cross-env NODE_ENV=test jest --forceExit --detectOpenHandles",
9+
"test": "cross-env NODE_ENV=test jest --forceExit",
1010
"test:local": "node tests/local/index.js",
1111
"coverage": "yarn test --coverage",
1212
"prepack": "yarn install -D && tsc",
1313
"lint": "eslint .",
1414
"lint:fix": "eslint . --fix",
1515
"commit": "git-cz",
16-
"docgen": "typedoc src/index.ts --out web --darkHighlightTheme github-dark --lightHighlightTheme github-light --includeVersion"
16+
"docgen": "typedoc --options ./typedoc.json"
1717
},
1818
"repository": {
1919
"type": "git",
@@ -31,33 +31,31 @@
3131
}
3232
],
3333
"engines": {
34-
"node": ">=12.0.0"
34+
"node": ">=16.6.0"
3535
},
3636
"dependencies": {
37-
"abort-controller": "^3.0.0",
38-
"discord.js": ">=12",
39-
"node-fetch": "^2.6.1"
37+
"discord.js": ">=13",
38+
"undici": "^4.7.0"
4039
},
4140
"devDependencies": {
4241
"@next/env": "^11.0.1",
4342
"@swc-node/jest": "^1.3.0",
4443
"@swc-node/register": "^1.3.0",
4544
"@tsconfig/recommended": "^1.0.1",
4645
"@types/jest": "^26.0.24",
47-
"@types/node": "^14.14.6",
48-
"@types/node-fetch": "^2.5.7",
49-
"@types/sharp": "^0.27.1",
46+
"@types/node": "^16.10.2",
47+
"@types/sharp": "^0.29.2",
5048
"@typescript-eslint/eslint-plugin": "^4.6.0",
5149
"@typescript-eslint/parser": "^4.6.0",
52-
"commitizen": "^4.2.2",
5350
"cross-env": "^7.0.3",
5451
"eslint": "^7.12.1",
52+
"eslint-plugin-import": "^2.24.2",
5553
"husky": "^5.1.3",
56-
"jest": "^26.6.3",
57-
"typedoc": "^0.22.2",
58-
"typescript": "^4.3.5"
54+
"jest": "^27.2.4",
55+
"typedoc": "^0.22.4",
56+
"typescript": "^4.4.3"
5957
},
6058
"optionalDependencies": {
61-
"sharp": "^0.28.3"
59+
"sharp": "^0.29.1"
6260
}
6361
}

src/client/Koreanbots.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
import { snowflakeRegex } from "../utils/Constants"
22
import APIRouter from "../rest/APIRouter"
3+
34
import { Mybot } from "../managers/Mybot"
45
import { BotManager } from "../managers/BotManager"
56
import { UserManager } from "../managers/UserManager"
67
import { WidgetManager } from "../managers/WidgetManager"
78

8-
import type { BotManagerOptions, KoreanbotsOptions, ProxyValidator, UserManagerOptions, WidgetManagerOptions } from "../utils/types"
9+
import type {
10+
BotManagerOptions,
11+
KoreanbotsOptions,
12+
ProxyValidator,
13+
UserManagerOptions,
14+
WidgetManagerOptions
15+
} from "../utils/types"
916

10-
const defaultMaxOption = 100
11-
const defaultMaxAgeOption = 10000
17+
const defaultCacheMaxSize = 100
18+
const defaultCacheSweepInterval = 10000
1219

1320
export class Koreanbots {
1421
public readonly options!: KoreanbotsOptions
@@ -39,16 +46,16 @@ export class Koreanbots {
3946
* ```js
4047
* new Koreanbots({
4148
* clientID: process.env.CLIENT_ID,
42-
* apiOptions: {
49+
* api: {
4350
* token: process.env.KOREANBOTS_TOKEN
4451
* },
4552
* // 글로벌 캐시 옵션이며, 누락할 경우 모든 캐시 옵션이 각각의 기본 값으로 설정됩니다 (로컬 캐시 옵션이 우선권을 가집니다)
46-
* max: 250, // (기본값: 100) 캐시에 최대 250개의 내용을 저장
47-
* maxAge: 60000 * 15, // (기본값: 10000 = 10초) 캐시에 저장한 내용을 15분 뒤에 삭제합니다.
53+
* maxSize: 250, // (기본값: 100) 캐시에 최대 250개의 내용을 저장
54+
* sweepInterval: 60000 * 15, // (기본값: 10000 = 10초) 캐시에 저장한 내용을 15분 뒤에 삭제합니다.
4855
* users: {
4956
* cache: { // 이 캐시 설정은 로컬이므로 앞서 적은 글로벌 캐시 옵션보다 우선권을 갖습니다.
50-
* max: 500, // (기본값: 100)
51-
* maxAge: 60000 * 30 // (기본값: 60000 * 60)
57+
* maxSize: 500, // (기본값: 100)
58+
* sweepInterval: 60000 * 30 // (기본값: 60000 * 60)
5259
* }
5360
* }
5461
* })
@@ -66,8 +73,8 @@ export class Koreanbots {
6673

6774
optionsProxy.clientID = options.clientID
6875

69-
this.options.max = options.max ?? defaultMaxOption
70-
this.options.maxAge = options.maxAge ?? defaultMaxAgeOption
76+
if (!this.options?.maxSize) this.options.maxSize = defaultCacheMaxSize
77+
if (!this.options?.sweepInterval) this.options.sweepInterval = defaultCacheSweepInterval
7178

7279
this.bots = new BotManager(this, this.getOptions(options.bots))
7380
this.users = new UserManager(this, this.getOptions(options.users))

src/managers/BotManager.ts

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,25 @@
1-
import LifetimeCollection from "../utils/Collection"
1+
import { LimitedCollection } from "discord.js"
22
import { Bot } from "../structures/Bot"
3-
import { CacheOptionsValidator } from "../utils"
43

54
import type {
6-
BotManagerOptions, FetchResponse, Nullable, RawBotInstance,
5+
BotManagerOptions,
6+
Nullable,
77
FetchOptions
88
} from "../utils/types"
99
import type { Koreanbots } from "../client/Koreanbots"
10-
import type { RequestInit } from "node-fetch"
1110

12-
interface BotQuery {
13-
bots(botID: string): {
14-
get(options?: RequestInit): Promise<FetchResponse<RawBotInstance>>
15-
}
16-
}
1711

1812
const defaultCacheMaxSize = 100
19-
const defaultCacheMaxAge = 60000 * 60
13+
const defaultCacheSweepInterval = 60000 * 60
14+
const defaultOptions = {
15+
cache: {
16+
maxSize: defaultCacheMaxSize,
17+
sweepInterval: defaultCacheSweepInterval
18+
}
19+
}
2020

2121
export class BotManager {
22-
public cache: LifetimeCollection<string, Nullable<Bot>>
22+
public cache: LimitedCollection<string, Nullable<Bot>>
2323

2424
/**
2525
* 새로운 BotManager 인스턴스를 만듭니다.
@@ -33,23 +33,22 @@ export class BotManager {
3333
* })),
3434
* {
3535
* cache: {
36-
* max: 150,
37-
* maxAge: 60000
36+
* maxSize: 150,
37+
* sweepInterval: 60000
3838
* }
3939
* }
4040
* )
4141
* ```
4242
*/
4343
constructor(public readonly koreanbots: Koreanbots, public readonly options?: BotManagerOptions) {
44-
this.options = options ?? { cache: {} }
45-
const optionsProxy = new Proxy(this.options, CacheOptionsValidator<BotManagerOptions>())
44+
this.options = options ?? defaultOptions
4645

47-
optionsProxy.cache.max = options?.cache?.max ?? defaultCacheMaxSize
48-
optionsProxy.cache.maxAge = options?.cache?.maxAge ?? defaultCacheMaxAge
46+
if (!this.options?.cache.maxSize) this.options.cache.maxSize = defaultCacheMaxSize
47+
if (!this.options?.cache.sweepInterval) this.options.cache.sweepInterval = defaultCacheSweepInterval
4948

50-
this.cache = new LifetimeCollection({
51-
max: this.options.cache.max,
52-
maxAge: this.options.cache.maxAge
49+
this.cache = new LimitedCollection({
50+
maxSize: this.options.cache.maxSize,
51+
sweepInterval: this.options.cache.sweepInterval
5352
})
5453
}
5554

@@ -78,12 +77,12 @@ export class BotManager {
7877
* ```
7978
*/
8079
async fetch(botID: string, options: FetchOptions = { cache: true, force: false }): Promise<Bot> {
81-
if (!botID || typeof botID !== "string") throw new Error(`"botID" 값은 주어지지 않았거나 문자열이어야 합니다. (받은 타입: ${typeof botID})`)
80+
if (!botID || typeof botID !== "string") throw new Error(`"botID" 값이 주어지지 않았거나 문자열이어야 합니다. (받은 타입: ${typeof botID})`)
8281

8382
const cache = this.cache.get(botID)
8483
if (!options?.force && cache) return cache
8584

86-
const res = await this.koreanbots.api<BotQuery>().bots(botID).get()
85+
const res = await this.koreanbots.api().bots(botID).get()
8786
if (res.code !== 200 || !res.data) throw new Error(res.message || `API에서 알 수 없는 응답이 돌아왔습니다. ${JSON.stringify(res.data)}`)
8887

8988
const bot = new Bot(this.koreanbots, res.data)

src/managers/Mybot.ts

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,20 @@
1+
import { LimitedCollection } from "discord.js"
12
import { URLSearchParams } from "url"
23
import { Bot } from "../structures/Bot"
34
import { KoreanbotsInternal } from "../utils/Constants"
45

56
import type { Koreanbots } from "../client/Koreanbots"
6-
import type { FetchResponse, RawBotInstance, RequestInitWithInternals, Vote } from "../utils/types"
7-
import LifetimeCollection from "../utils/Collection"
8-
9-
export interface UpdateResponse {
10-
code: number
11-
version: number
12-
message: string
13-
servers?: number
14-
}
7+
import type { UpdateResponse, Vote } from "../utils/types"
158

16-
interface BotQuery {
17-
bots(clientID: string): {
18-
get(options?: RequestInitWithInternals): Promise<FetchResponse<RawBotInstance>>
19-
vote: {
20-
get(options?: RequestInitWithInternals): Promise<FetchResponse<Vote>>
21-
}
22-
stats: {
23-
post(options?: RequestInitWithInternals): Promise<FetchResponse<UpdateResponse>>
24-
}
25-
}
26-
}
9+
const defaultCacheSweepInterval = 10000
2710

2811
export class Mybot {
2912
public bot: Bot | null
3013

3114
public lastGuildCount?: number
3215
public updatedAt?: Date
3316
public updatedTimestamp?: number
34-
public votes: LifetimeCollection<string, Vote>
17+
public votes: LimitedCollection<string, Vote>
3518

3619
/**
3720
* 새로운 Mybot 인스턴스를 생성합니다.
@@ -41,15 +24,15 @@ export class Mybot {
4124
constructor(public readonly koreanbots: Koreanbots, public readonly clientID: string) {
4225
this.bot = null
4326

44-
this.votes = new LifetimeCollection({
45-
maxAge: 10000
27+
this.votes = new LimitedCollection({
28+
sweepInterval: koreanbots.options.sweepInterval ?? defaultCacheSweepInterval
4629
})
4730

4831
this.mybotInit()
4932
}
5033

5134
protected async mybotInit(): Promise<Bot> {
52-
const res = await this.koreanbots.api<BotQuery>().bots(this.clientID).get()
35+
const res = await this.koreanbots.api().bots(this.clientID).get()
5336

5437
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
5538
return this.bot = new Bot(this.koreanbots, res.data!)
@@ -76,7 +59,7 @@ export class Mybot {
7659
const query = new URLSearchParams()
7760
query.append("userID", id)
7861

79-
const res = await this.koreanbots.api<BotQuery>().bots(this.clientID).vote.get({
62+
const res = await this.koreanbots.api().bots(this.clientID).vote.get({
8063
[KoreanbotsInternal]: {
8164
query
8265
}
@@ -111,7 +94,7 @@ export class Mybot {
11194
servers: servers,
11295
shards
11396
})
114-
const response = await this.koreanbots.api<BotQuery>().bots(this.clientID).stats.post({
97+
const response = await this.koreanbots.api().bots(this.clientID).stats.post({
11598
body
11699
})
117100

0 commit comments

Comments
 (0)