@hieuzest/koishi-plugin-market 2.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -0
- package/dist/style.css +1 -0
- package/lib/browser/index.d.ts +12 -0
- package/lib/browser/index.mjs +86 -0
- package/lib/browser/index.mjs.map +6 -0
- package/lib/browser/market.d.ts +12 -0
- package/lib/index.d.ts +1 -0
- package/lib/node/deps.d.ts +15 -0
- package/lib/node/index.d.ts +33 -0
- package/lib/node/index.js +715 -0
- package/lib/node/index.js.map +6 -0
- package/lib/node/installer.d.ts +108 -0
- package/lib/node/market.d.ts +40 -0
- package/lib/shared/index.d.ts +32 -0
- package/lib/shared/index.js +63 -0
- package/lib/shared/index.js.map +6 -0
- package/lib/shared/index.mjs +41 -0
- package/lib/shared/index.mjs.map +6 -0
- package/package.json +88 -0
- package/src/browser/index.ts +27 -0
- package/src/browser/market.ts +19 -0
- package/src/index.ts +2 -0
- package/src/node/deps.ts +26 -0
- package/src/node/index.ts +192 -0
- package/src/node/installer.ts +488 -0
- package/src/node/locales/message.de-DE.yml +25 -0
- package/src/node/locales/message.en-US.yml +25 -0
- package/src/node/locales/message.fr-FR.yml +25 -0
- package/src/node/locales/message.ja-JP.yml +25 -0
- package/src/node/locales/message.ru-RU.yml +25 -0
- package/src/node/locales/message.zh-CN.yml +28 -0
- package/src/node/locales/message.zh-TW.yml +25 -0
- package/src/node/locales/schema.de-DE.yml +9 -0
- package/src/node/locales/schema.en-US.yml +9 -0
- package/src/node/locales/schema.fr-FR.yml +9 -0
- package/src/node/locales/schema.ja-JP.yml +9 -0
- package/src/node/locales/schema.ru-RU.yml +9 -0
- package/src/node/locales/schema.zh-CN.yml +10 -0
- package/src/node/locales/schema.zh-TW.yml +9 -0
- package/src/node/market.ts +113 -0
- package/src/shared/index.ts +63 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
commands.plugin:
|
|
2
|
+
description: Plugin management
|
|
3
|
+
commands.plugin.install:
|
|
4
|
+
description: Install Plugins
|
|
5
|
+
messages:
|
|
6
|
+
expect-name: 请输入插件名。
|
|
7
|
+
already-installed: 该插件已安装。
|
|
8
|
+
not-found: 未找到该插件。
|
|
9
|
+
success: Installation Successful!
|
|
10
|
+
commands.plugin.uninstall:
|
|
11
|
+
description: Uninstall plugin
|
|
12
|
+
messages:
|
|
13
|
+
expect-name: 请输入插件名。
|
|
14
|
+
not-installed: 该插件未安装。
|
|
15
|
+
success: 卸载成功!
|
|
16
|
+
commands.plugin.upgrade:
|
|
17
|
+
description: Upgrade Plugin
|
|
18
|
+
options:
|
|
19
|
+
self: Upgrade Koishi core
|
|
20
|
+
messages:
|
|
21
|
+
all-updated: 所有插件已是最新版本。
|
|
22
|
+
available: 有可用的依赖更新:
|
|
23
|
+
prompt: 输入「Y」升级全部依赖,输入「N」取消操作。
|
|
24
|
+
cancelled: Operation canceled.
|
|
25
|
+
success: Upgrade Successful!
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
commands.plugin:
|
|
2
|
+
description: 插件管理
|
|
3
|
+
commands.plugin.install:
|
|
4
|
+
description: Installation de plugins
|
|
5
|
+
messages:
|
|
6
|
+
expect-name: 请输入插件名。
|
|
7
|
+
already-installed: 该插件已安装。
|
|
8
|
+
not-found: 未找到该插件。
|
|
9
|
+
success: 安装成功!
|
|
10
|
+
commands.plugin.uninstall:
|
|
11
|
+
description: 卸载插件
|
|
12
|
+
messages:
|
|
13
|
+
expect-name: 请输入插件名。
|
|
14
|
+
not-installed: 该插件未安装。
|
|
15
|
+
success: 卸载成功!
|
|
16
|
+
commands.plugin.upgrade:
|
|
17
|
+
description: 升级插件
|
|
18
|
+
options:
|
|
19
|
+
self: 升级 Koishi 本体
|
|
20
|
+
messages:
|
|
21
|
+
all-updated: 所有插件已是最新版本。
|
|
22
|
+
available: 有可用的依赖更新:
|
|
23
|
+
prompt: 输入「Y」升级全部依赖,输入「N」取消操作。
|
|
24
|
+
cancelled: 已取消操作。
|
|
25
|
+
success: 升级成功!
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
commands.plugin:
|
|
2
|
+
description: 插件管理
|
|
3
|
+
commands.plugin.install:
|
|
4
|
+
description: 安装插件
|
|
5
|
+
messages:
|
|
6
|
+
expect-name: 请输入插件名。
|
|
7
|
+
already-installed: 该插件已安装。
|
|
8
|
+
not-found: 未找到该插件。
|
|
9
|
+
success: 安装成功!
|
|
10
|
+
commands.plugin.uninstall:
|
|
11
|
+
description: 卸载插件
|
|
12
|
+
messages:
|
|
13
|
+
expect-name: 请输入插件名。
|
|
14
|
+
not-installed: 该插件未安装。
|
|
15
|
+
success: 卸载成功!
|
|
16
|
+
commands.plugin.upgrade:
|
|
17
|
+
description: 升级插件
|
|
18
|
+
options:
|
|
19
|
+
self: 升级 Koishi 本体
|
|
20
|
+
messages:
|
|
21
|
+
all-updated: 所有插件已是最新版本。
|
|
22
|
+
available: 有可用的依赖更新:
|
|
23
|
+
prompt: 输入「Y」升级全部依赖,输入「N」取消操作。
|
|
24
|
+
cancelled: 已取消操作。
|
|
25
|
+
success: 升级成功!
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
commands.plugin:
|
|
2
|
+
description: 插件管理
|
|
3
|
+
commands.plugin.install:
|
|
4
|
+
description: 安装插件
|
|
5
|
+
messages:
|
|
6
|
+
expect-name: 请输入插件名。
|
|
7
|
+
already-installed: 该插件已安装。
|
|
8
|
+
not-found: 未找到该插件。
|
|
9
|
+
success: 安装成功!
|
|
10
|
+
commands.plugin.uninstall:
|
|
11
|
+
description: 卸载插件
|
|
12
|
+
messages:
|
|
13
|
+
expect-name: 请输入插件名。
|
|
14
|
+
not-installed: 该插件未安装。
|
|
15
|
+
success: 卸载成功!
|
|
16
|
+
commands.plugin.upgrade:
|
|
17
|
+
description: 升级插件
|
|
18
|
+
options:
|
|
19
|
+
self: 升级 Koishi 本体
|
|
20
|
+
messages:
|
|
21
|
+
all-updated: 所有插件已是最新版本。
|
|
22
|
+
available: 有可用的依赖更新:
|
|
23
|
+
prompt: 输入「Y」升级全部依赖,输入「N」取消操作。
|
|
24
|
+
cancelled: 已取消操作。
|
|
25
|
+
success: 升级成功!
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
commands.plugin:
|
|
2
|
+
description: 插件管理
|
|
3
|
+
|
|
4
|
+
commands.plugin.install:
|
|
5
|
+
description: 安装插件
|
|
6
|
+
messages:
|
|
7
|
+
expect-name: 请输入插件名。
|
|
8
|
+
already-installed: 该插件已安装。
|
|
9
|
+
not-found: 未找到该插件。
|
|
10
|
+
success: 安装成功!
|
|
11
|
+
|
|
12
|
+
commands.plugin.uninstall:
|
|
13
|
+
description: 卸载插件
|
|
14
|
+
messages:
|
|
15
|
+
expect-name: 请输入插件名。
|
|
16
|
+
not-installed: 该插件未安装。
|
|
17
|
+
success: 卸载成功!
|
|
18
|
+
|
|
19
|
+
commands.plugin.upgrade:
|
|
20
|
+
description: 升级插件
|
|
21
|
+
options:
|
|
22
|
+
self: 升级 Koishi 本体
|
|
23
|
+
messages:
|
|
24
|
+
all-updated: 所有插件已是最新版本。
|
|
25
|
+
available: 有可用的依赖更新:
|
|
26
|
+
prompt: 输入「Y」升级全部依赖,输入「N」取消操作。
|
|
27
|
+
cancelled: 已取消操作。
|
|
28
|
+
success: 升级成功!
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
commands.plugin:
|
|
2
|
+
description: 外掛程式管理
|
|
3
|
+
commands.plugin.install:
|
|
4
|
+
description: 安裝外掛程式
|
|
5
|
+
messages:
|
|
6
|
+
expect-name: 请输入外掛程式名。
|
|
7
|
+
already-installed: 該外掛程式已安裝。
|
|
8
|
+
not-found: 未找到該外掛程式。
|
|
9
|
+
success: 安裝成功!
|
|
10
|
+
commands.plugin.uninstall:
|
|
11
|
+
description: 卸載外掛程式
|
|
12
|
+
messages:
|
|
13
|
+
expect-name: 请输入外掛程式名。
|
|
14
|
+
not-installed: 該外掛程式未安裝。
|
|
15
|
+
success: 卸載成功!
|
|
16
|
+
commands.plugin.upgrade:
|
|
17
|
+
description: 升級外掛程式
|
|
18
|
+
options:
|
|
19
|
+
self: 升級 Koishi 本體
|
|
20
|
+
messages:
|
|
21
|
+
all-updated: 所有外掛程式已是最新版本。
|
|
22
|
+
available: 有可用的依賴更新:
|
|
23
|
+
prompt: 輸入「Y」升級全部依賴,輸入「N」取消操作。
|
|
24
|
+
cancelled: 已取消操作。
|
|
25
|
+
success: 升級成功!
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { Context, Dict, HTTP, Schema, Time } from 'koishi'
|
|
2
|
+
import Scanner, { SearchObject, SearchResult } from '@koishijs/registry'
|
|
3
|
+
import { MarketProvider as BaseMarketProvider } from '../shared'
|
|
4
|
+
|
|
5
|
+
class MarketProvider extends BaseMarketProvider {
|
|
6
|
+
private http: HTTP
|
|
7
|
+
private failed: string[] = []
|
|
8
|
+
private scanner: Scanner
|
|
9
|
+
private fullCache: Dict<SearchObject> = {}
|
|
10
|
+
private tempCache: Dict<SearchObject> = {}
|
|
11
|
+
private flushData: () => void
|
|
12
|
+
|
|
13
|
+
constructor(ctx: Context, public config: MarketProvider.Config) {
|
|
14
|
+
super(ctx)
|
|
15
|
+
if (config.endpoint) this.http = ctx.http.extend(config)
|
|
16
|
+
this.flushData = ctx.throttle(() => {
|
|
17
|
+
ctx.console.broadcast('market/patch', {
|
|
18
|
+
data: this.tempCache,
|
|
19
|
+
failed: this.failed.length,
|
|
20
|
+
total: this.scanner.total,
|
|
21
|
+
progress: this.scanner.progress,
|
|
22
|
+
})
|
|
23
|
+
this.tempCache = {}
|
|
24
|
+
}, 500)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async start(refresh = false) {
|
|
28
|
+
this.failed = []
|
|
29
|
+
this.fullCache = {}
|
|
30
|
+
this.tempCache = {}
|
|
31
|
+
if (refresh) this.ctx.installer.refresh(true)
|
|
32
|
+
await this.prepare()
|
|
33
|
+
super.start()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async collect() {
|
|
37
|
+
const { timeout } = this.config
|
|
38
|
+
const registry = this.ctx.installer.http
|
|
39
|
+
|
|
40
|
+
this.failed = []
|
|
41
|
+
this.scanner = new Scanner(registry.get)
|
|
42
|
+
if (this.http) {
|
|
43
|
+
const result = await this.http.get<SearchResult>('')
|
|
44
|
+
this.scanner.objects = result.objects.filter(object => !object.ignored)
|
|
45
|
+
this.scanner.total = this.scanner.objects.length
|
|
46
|
+
this.scanner.version = result.version
|
|
47
|
+
} else {
|
|
48
|
+
await this.scanner.collect({ timeout })
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (!this.scanner.version) {
|
|
52
|
+
this.scanner.analyze({
|
|
53
|
+
version: '4',
|
|
54
|
+
onFailure: (name, reason) => {
|
|
55
|
+
this.failed.push(name)
|
|
56
|
+
if (registry.config.endpoint.startsWith('https://registry.npmmirror.com')) {
|
|
57
|
+
if (this.ctx.http.isError(reason) && reason.response?.status === 404) {
|
|
58
|
+
// ignore 404 error for npmmirror
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
onRegistry: (registry, versions) => {
|
|
63
|
+
this.ctx.installer.setPackage(registry.name, versions)
|
|
64
|
+
},
|
|
65
|
+
onSuccess: (object, versions) => {
|
|
66
|
+
// npmmirror lacks `links` field
|
|
67
|
+
object.package.links ||= {
|
|
68
|
+
npm: `${registry.config.endpoint.replace('registry.', 'www.')}/package/${object.package.name}`,
|
|
69
|
+
}
|
|
70
|
+
this.fullCache[object.package.name] = this.tempCache[object.package.name] = object
|
|
71
|
+
},
|
|
72
|
+
after: () => this.flushData(),
|
|
73
|
+
})
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return null
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async get() {
|
|
80
|
+
await this.prepare()
|
|
81
|
+
if (this._error) return { data: {}, failed: 0, total: 0, progress: 0 }
|
|
82
|
+
return this.scanner.version ? {
|
|
83
|
+
registry: this.ctx.installer.endpoint,
|
|
84
|
+
data: Object.fromEntries(this.scanner.objects.map(item => [item.package.name, item])),
|
|
85
|
+
failed: 0,
|
|
86
|
+
total: this.scanner.total,
|
|
87
|
+
progress: this.scanner.total,
|
|
88
|
+
gravatar: process.env.GRAVATAR_MIRROR,
|
|
89
|
+
} : {
|
|
90
|
+
registry: this.ctx.installer.endpoint,
|
|
91
|
+
data: this.fullCache,
|
|
92
|
+
failed: this.failed.length,
|
|
93
|
+
total: this.scanner.total,
|
|
94
|
+
progress: this.scanner.progress,
|
|
95
|
+
gravatar: process.env.GRAVATAR_MIRROR,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
namespace MarketProvider {
|
|
101
|
+
export interface Config {
|
|
102
|
+
endpoint?: string
|
|
103
|
+
timeout?: number
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export const Config: Schema<Config> = Schema.object({
|
|
107
|
+
endpoint: Schema.string().role('link'),
|
|
108
|
+
timeout: Schema.number().role('time').default(Time.second * 30),
|
|
109
|
+
proxyAgent: Schema.string().role('link'),
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
export default MarketProvider
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Awaitable, Context, Dict, Logger, Time } from 'koishi'
|
|
2
|
+
import { DataService } from '@koishijs/console'
|
|
3
|
+
import { SearchObject, SearchResult } from '@koishijs/registry'
|
|
4
|
+
|
|
5
|
+
declare module '@koishijs/console' {
|
|
6
|
+
interface Events {
|
|
7
|
+
'market/refresh'(): void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
namespace Console {
|
|
11
|
+
interface Services {
|
|
12
|
+
market: MarketProvider
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const logger = new Logger('market')
|
|
18
|
+
|
|
19
|
+
export abstract class MarketProvider extends DataService<MarketProvider.Payload> {
|
|
20
|
+
private _task: Promise<any>
|
|
21
|
+
private _timestamp = 0
|
|
22
|
+
protected _error: any
|
|
23
|
+
|
|
24
|
+
constructor(ctx: Context) {
|
|
25
|
+
super(ctx, 'market', { authority: 4 })
|
|
26
|
+
|
|
27
|
+
ctx.console.addListener('market/refresh', () => this.start(true), { authority: 4 })
|
|
28
|
+
|
|
29
|
+
ctx.on('console/connection', async (client) => {
|
|
30
|
+
if (!ctx.console.clients[client.id]) return
|
|
31
|
+
if (Date.now() - this._timestamp <= Time.hour * 12) return
|
|
32
|
+
if (await this.ctx.serial('console/intercept', client, { authority: 4 })) return
|
|
33
|
+
this.start()
|
|
34
|
+
})
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
start(refresh = false): Awaitable<void> {
|
|
38
|
+
this._task = null
|
|
39
|
+
this._error = null
|
|
40
|
+
this._timestamp = Date.now()
|
|
41
|
+
this.refresh()
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
abstract collect(): Promise<void | SearchResult>
|
|
45
|
+
|
|
46
|
+
async prepare(): Promise<SearchResult> {
|
|
47
|
+
return this._task ||= this.collect().catch((error) => {
|
|
48
|
+
logger.warn(error)
|
|
49
|
+
this._error = error
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export namespace MarketProvider {
|
|
55
|
+
export interface Payload {
|
|
56
|
+
registry?: string
|
|
57
|
+
data: Dict<SearchObject>
|
|
58
|
+
total: number
|
|
59
|
+
failed: number
|
|
60
|
+
progress: number
|
|
61
|
+
gravatar?: string
|
|
62
|
+
}
|
|
63
|
+
}
|