koishi-plugin-wikit-querier-remodified 0.0.1

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.
@@ -0,0 +1,6 @@
1
+ export declare const queries: {
2
+ titleQuery: string;
3
+ userQuery: string;
4
+ userGlobalQuery: string;
5
+ userRankQuery: string;
6
+ };
package/lib/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import { Context, Schema } from "koishi";
2
+ declare module "koishi" {
3
+ interface Tables {
4
+ wikitQuerier: WikitQuerierTable;
5
+ }
6
+ }
7
+ interface WikitQuerierTable {
8
+ id?: number;
9
+ platform: string;
10
+ channelId: string;
11
+ defaultwiki: string;
12
+ }
13
+ export declare const name: string;
14
+ export declare const inject: string[];
15
+ export interface Config {
16
+ bannedUsers: string[];
17
+ bannedTitles: string[];
18
+ bannedTags: string[];
19
+ }
20
+ export declare const Config: Schema<Config>;
21
+ export declare function apply(ctx: Context, config: Config): void;
22
+ export {};
package/lib/index.js ADDED
@@ -0,0 +1,421 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
+ var __export = (target, all) => {
7
+ for (var name2 in all)
8
+ __defProp(target, name2, { get: all[name2], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.tsx
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ Config: () => Config,
24
+ apply: () => apply,
25
+ inject: () => inject,
26
+ name: () => name
27
+ });
28
+ module.exports = __toCommonJS(src_exports);
29
+ var import_koishi = require("koishi");
30
+
31
+ // src/graphql/index.ts
32
+ var gql = /* @__PURE__ */ __name((query, ...substitutions) => String.raw(query, ...substitutions), "gql");
33
+ var queries = {
34
+ titleQuery: gql`
35
+ query titleQuery($anyBaseUrl: [String], $query: String) {
36
+ articles(wiki: $anyBaseUrl, titleKeyword: $query, page: 1, pageSize: 20) {
37
+ nodes {
38
+ title
39
+ url
40
+ author
41
+ rating
42
+ }
43
+ pageInfo {
44
+ total
45
+ page
46
+ pageSize
47
+ hasNextPage
48
+ }
49
+ }
50
+ }
51
+ `,
52
+ userQuery: gql`
53
+ query userQuery($query: String!, $baseUrl: String!) {
54
+ authorWikiRank(
55
+ wiki: $baseUrl
56
+ name: $query
57
+ by: RATING
58
+ ) {
59
+ rank
60
+ name
61
+ value
62
+ }
63
+
64
+ articles(
65
+ author: $query
66
+ wiki: [$baseUrl]
67
+ ) {
68
+ pageInfo {
69
+ total
70
+ }
71
+ }
72
+ }
73
+ `,
74
+ userGlobalQuery: gql`
75
+ query userGlobalQuery($query: String!) {
76
+ authorGlobalRank(
77
+ name: $query
78
+ by: RATING
79
+ ) {
80
+ rank
81
+ name
82
+ value
83
+ }
84
+
85
+ articles(author: $query) {
86
+ pageInfo {
87
+ total
88
+ }
89
+ }
90
+ }
91
+ `,
92
+ userRankQuery: gql`
93
+ query userRankQuery($baseUrl: String) {
94
+ authorRanking(wiki: $baseUrl, by: RATING) {
95
+ rank
96
+ name
97
+ value
98
+ }
99
+ }
100
+ `
101
+ };
102
+
103
+ // src/lib.ts
104
+ var apiList = [
105
+ "https://wikit.unitreaty.org/apiv1/graphql",
106
+ "https://wikittest.unitreaty.org/apiv1/graphql"
107
+ ];
108
+ var wikiInfo = {
109
+ /* 维基名称格式:"站点简写": { wiki: "Wikit里的Wiki全名" }, 例如:"ubmh": { wiki: "ubmh" } */
110
+ "ubmh": { wiki: "ubmh" },
111
+ "scp-cloud": { wiki: "scp-wiki-cloud" },
112
+ "cloud": { wiki: "backroom-wiki-cn" },
113
+ "scr": { wiki: "scr-wiki" },
114
+ "dfc": { wiki: "deep-forest-club" },
115
+ "rule": { wiki: "rule-wiki" },
116
+ "as": { wiki: "asbackroom" },
117
+ "lm": { wiki: "lostmedia" },
118
+ "if": { wiki: "if-backrooms" },
119
+ "rpc": { wiki: "rpc-wiki-cn" },
120
+ "warma": { wiki: "warma-world" },
121
+ "fr": { wiki: "backrooms-split-library" },
122
+ "f": { wiki: "backrooms-f" }
123
+ };
124
+ function levenshtein(a, b) {
125
+ const matrix = Array.from({ length: a.length + 1 }, () => Array(b.length + 1).fill(0));
126
+ for (let i = 0; i <= a.length; i++) matrix[i][0] = i;
127
+ for (let j = 0; j <= b.length; j++) matrix[0][j] = j;
128
+ for (let i = 1; i <= a.length; i++) {
129
+ for (let j = 1; j <= b.length; j++) {
130
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
131
+ matrix[i][j] = Math.min(
132
+ matrix[i - 1][j] + 1,
133
+ matrix[i][j - 1] + 1,
134
+ matrix[i - 1][j - 1] + cost
135
+ );
136
+ }
137
+ }
138
+ return matrix[a.length][b.length];
139
+ }
140
+ __name(levenshtein, "levenshtein");
141
+ async function wikitApiRequest(param, name2, endpointIndex = 0, queryString) {
142
+ if (endpointIndex >= apiList.length) {
143
+ throw new Error("所有API端点均已尝试但均失败");
144
+ }
145
+ let variables = {};
146
+ const wikiLongName = wikiInfo[name2]?.wiki;
147
+ if (queryString.includes("query titleQuery")) {
148
+ variables = { query: param, anyBaseUrl: wikiLongName ? [wikiLongName] : null };
149
+ } else if (queryString.includes("query userQuery")) {
150
+ variables = { query: param, baseUrl: wikiLongName };
151
+ } else if (queryString.includes("query userRankQuery")) {
152
+ variables = { baseUrl: wikiLongName };
153
+ } else if (queryString.includes("query userGlobalQuery")) {
154
+ variables = { query: param };
155
+ }
156
+ try {
157
+ const response = await fetch(apiList[endpointIndex], {
158
+ method: "POST",
159
+ headers: { "Content-Type": "application/json" },
160
+ body: JSON.stringify({ query: queryString, variables })
161
+ });
162
+ if (!response.ok) {
163
+ throw new Error(`请求失败,状态码: ${response.status}`);
164
+ }
165
+ const { data, errors } = await response.json();
166
+ if (errors && errors.length > 0) {
167
+ return await wikitApiRequest(param, name2, endpointIndex + 1, queryString);
168
+ }
169
+ if (queryString.includes("query titleQuery") && data.articles?.nodes?.length) {
170
+ const articles = data.articles.nodes;
171
+ const lowerParam = param.toLowerCase();
172
+ let bestArticle = null;
173
+ let minDistance = Infinity;
174
+ for (const article of articles) {
175
+ const distance = levenshtein(
176
+ lowerParam,
177
+ article.title.toLowerCase()
178
+ );
179
+ if (distance < minDistance) {
180
+ minDistance = distance;
181
+ bestArticle = article;
182
+ }
183
+ }
184
+ if (bestArticle) {
185
+ return {
186
+ articles: { nodes: [bestArticle] }
187
+ };
188
+ }
189
+ return { articles: { nodes: [] } };
190
+ }
191
+ return data;
192
+ } catch (error) {
193
+ if (endpointIndex < apiList.length - 1) {
194
+ return await wikitApiRequest(param, name2, endpointIndex + 1, queryString);
195
+ }
196
+ throw error;
197
+ }
198
+ }
199
+ __name(wikitApiRequest, "wikitApiRequest");
200
+
201
+ // src/index.tsx
202
+ var import_jsx_runtime = require("@satorijs/element/jsx-runtime");
203
+ var name = "wikit-querier";
204
+ var inject = ["database"];
205
+ var Config = import_koishi.Schema.object({
206
+ bannedUsers: import_koishi.Schema.array(import_koishi.Schema.string()).description("禁止查询的用户列表"),
207
+ bannedTitles: import_koishi.Schema.array(import_koishi.Schema.string()).description("禁止查询的文章列表"),
208
+ bannedTags: import_koishi.Schema.array(import_koishi.Schema.string()).description("禁止查询的标签列表")
209
+ }).description("禁止查询配置");
210
+ function apply(ctx, config) {
211
+ ctx.model.extend("wikitQuerier", {
212
+ id: "unsigned",
213
+ platform: "string(64)",
214
+ channelId: "string(64)",
215
+ defaultwiki: "string(64)"
216
+ });
217
+ const normalizeUrl = /* @__PURE__ */ __name((url) => url.replace(/^https?:\/\/backrooms-wiki-cn.wikidot.com/, "https://brcn.backroomswiki.cn").replace(/^https?:\/\/scp-wiki-cn.wikidot.com/, "https://scpcn.backroomswiki.cn").replace(/^https?:\/\/([a-z]+-wiki-cn|nationarea)/, "https://$1"), "normalizeUrl");
218
+ const getDefaultwiki = /* @__PURE__ */ __name(async (session) => {
219
+ const platform = session.event.platform;
220
+ const channelId = session.event.channel.id;
221
+ const data = await ctx.database.get("wikitQuerier", {
222
+ platform,
223
+ channelId
224
+ });
225
+ if (data.length > 0) {
226
+ return data[0].defaultwiki;
227
+ }
228
+ return void 0;
229
+ }, "getDefaultwiki");
230
+ let cmd = ctx;
231
+ cmd.command("wikitre", "(重制版)作者及页面信息查询");
232
+ cmd.command("wikitre.about", "此插件的相关信息。").action(async (argv) => {
233
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("template", { children: [
234
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("quote", { id: argv.session.event.message.id }),
235
+ "此组件由 lestday233 基于 Wikit API 编写",
236
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
237
+ "修改自 https://github.com/Laimuslime/koishi-plugin-crom-querier-modified"
238
+ ] });
239
+ });
240
+ cmd.command("wikitre.suppost-list", "列出所有支持的网站及对应的地址。").alias("wikitre-list").alias("wikitre.list").action(async (argv) => {
241
+ const entries = Object.entries(wikiInfo);
242
+ if (entries.length === 0) return "当前没有配置任何维基信息。";
243
+ const lines = entries.map(([key, value]) => `${key} → https://${value.wiki}.wikidot.com/`);
244
+ return `支持的维基列表:
245
+ ${lines.join("\n")}`;
246
+ });
247
+ cmd.command("wikitre.default-wiki <维基名称:string>", "设置默认维基。").alias("wikitre-db").action(async (argv, wiki) => {
248
+ const platform = argv.session.event.platform;
249
+ const channelId = argv.session.event.channel.id;
250
+ if (!wiki || !Object.keys(wikiInfo).includes(wiki) || wiki === "all") {
251
+ return "维基名称不正确。";
252
+ }
253
+ ctx.database.upsert("wikitQuerier", [{ channelId, platform, defaultwiki: wiki }], ["platform", "channelId"]);
254
+ return `已将本群默认查询维基设置为: ${wiki}`;
255
+ });
256
+ cmd.command("wikitre.author <作者:string> [维基名称:string]", "查询作者信息。默认搜索所有支持的维基。").alias("wikitre-au").action(async (argv, author, wiki) => {
257
+ const isRankQuery = /^#[0-9]{1,15}$/.test(author);
258
+ const rankNumber = isRankQuery ? Number(author.slice(1)) : null;
259
+ let queryString = isRankQuery ? queries.userRankQuery : queries.userQuery;
260
+ const validwikies = ["all", ...Object.keys(wikiInfo)];
261
+ const authorName = wiki && !validwikies.includes(wiki) || !author ? validwikies.includes(argv.args.at(-1)) ? argv.args.slice(0, -1).join(" ") : argv.args.join(" ") : author;
262
+ const User = /* @__PURE__ */ __name(({ object }) => {
263
+ const dataArray = object.authorRanking ? object.authorRanking : object.authorGlobalRank ? [object.authorGlobalRank] : object.authorWikiRank ? [object.authorWikiRank] : [];
264
+ if (!dataArray || dataArray.length === 0) {
265
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("template", { children: "未找到用户。" });
266
+ }
267
+ let user;
268
+ if (rankNumber !== null) {
269
+ user = dataArray.find(
270
+ (u) => u.rank === rankNumber && !config.bannedUsers.includes(u.name)
271
+ );
272
+ } else {
273
+ user = dataArray.find(
274
+ (u) => !config.bannedUsers.includes(u.name)
275
+ );
276
+ }
277
+ if (!user) {
278
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("template", { children: "未找到用户。" });
279
+ }
280
+ const total = object.articles?.pageInfo?.total ?? "未知";
281
+ let average = "未知";
282
+ if (typeof total === "number" && total > 0) {
283
+ average = (user.value / total).toFixed(2);
284
+ } else if (total === 0) {
285
+ average = 0;
286
+ }
287
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("template", { children: [
288
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("quote", { id: argv.session.event.message.id }),
289
+ "🙎‍♂️ ",
290
+ user.name,
291
+ " (#",
292
+ user.rank,
293
+ ")",
294
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
295
+ "⭐ 总分:",
296
+ user.value,
297
+ " | 📑 页面数:",
298
+ total,
299
+ " | 📈 平均分:",
300
+ average
301
+ ] });
302
+ }, "User");
303
+ try {
304
+ let finalwiki = wiki;
305
+ if (!finalwiki) {
306
+ finalwiki = await getDefaultwiki(argv.session);
307
+ }
308
+ if (!finalwiki || finalwiki === "all") {
309
+ queryString = isRankQuery ? queries.userRankQuery : queries.userGlobalQuery;
310
+ finalwiki = "all";
311
+ }
312
+ let result = await wikitApiRequest(authorName, finalwiki, 0, queryString);
313
+ if (isRankQuery && result.authorRanking) {
314
+ const rankData = result;
315
+ const matchedUser = rankData.authorRanking.find(
316
+ (u) => u.rank === rankNumber && !config.bannedUsers.includes(u.name)
317
+ );
318
+ if (matchedUser) {
319
+ let secondQuery = !finalwiki || finalwiki === "all" ? queries.userGlobalQuery : queries.userQuery;
320
+ result = await wikitApiRequest(matchedUser.name, finalwiki, 0, secondQuery);
321
+ }
322
+ }
323
+ const response = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(User, { object: result });
324
+ const sentMessages = await argv.session.send(response);
325
+ scheduleChecks(0, argv.session, sentMessages[0]);
326
+ return;
327
+ } catch (err) {
328
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("template", { children: [
329
+ "查询失败: ",
330
+ err.message || "未知错误"
331
+ ] });
332
+ }
333
+ });
334
+ cmd.command("wikitre.search <标题:string> [维基名称:string]", "查询文章信息。默认搜索所有支持的维基。").alias("wikitre-sr").action(async (argv, title, wiki) => {
335
+ const titleName = wiki && !Object.keys(wikiInfo).includes(wiki) || !title ? Object.keys(wikiInfo).includes(argv.args.at(-1)) ? argv.args.slice(0, -1).join(" ") : argv.args.join(" ") : title;
336
+ const Author = /* @__PURE__ */ __name(({ authorName }) => {
337
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("template", { children: [
338
+ "🙎‍♂️作者:",
339
+ authorName || "已注销用户"
340
+ ] });
341
+ }, "Author");
342
+ const TitleProceed = /* @__PURE__ */ __name(({ titleData }) => {
343
+ const articles = titleData?.articles?.nodes;
344
+ if (!articles || articles.length === 0) {
345
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("template", { children: "未找到文章。" });
346
+ }
347
+ const selectedIndex = articles.findIndex((article2) => {
348
+ const isBannedTitle = config.bannedTitles.includes(article2.title);
349
+ const isBannedUser = config.bannedUsers.includes(article2.author);
350
+ return !(isBannedTitle || isBannedUser);
351
+ });
352
+ if (selectedIndex === -1) {
353
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("template", { children: "未找到符合条件的文章。" });
354
+ }
355
+ const article = articles[selectedIndex];
356
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("template", { children: [
357
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("quote", { id: argv.session.event.message.id }),
358
+ "📝页面:",
359
+ article.title,
360
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
361
+ "⭐评分:",
362
+ article.rating,
363
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
364
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Author, { authorName: article.author }),
365
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("br", {}),
366
+ "🔗",
367
+ normalizeUrl(article.url)
368
+ ] });
369
+ }, "TitleProceed");
370
+ try {
371
+ let finalwiki = wiki;
372
+ if (!finalwiki) {
373
+ finalwiki = await getDefaultwiki(argv.session);
374
+ }
375
+ const result = await wikitApiRequest(titleName, wiki, 0, queries.titleQuery);
376
+ const response = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleProceed, { titleData: result });
377
+ const sentMessages = await argv.session.send(response);
378
+ scheduleChecks(0, argv.session, sentMessages[0]);
379
+ return;
380
+ } catch (err) {
381
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("template", { children: [
382
+ "查询失败:",
383
+ err.message || "未知错误"
384
+ ] });
385
+ }
386
+ });
387
+ const checkTimes = [1e4, 3e4, 6e4, 9e4, 11e3, 12e3];
388
+ const checkAndDelete = /* @__PURE__ */ __name(async (session, sentMessage) => {
389
+ try {
390
+ const message = await session.onebot.getMsg(session.messageId);
391
+ if (message?.raw_message === "") {
392
+ await session.onebot.deleteMsg(sentMessage);
393
+ return true;
394
+ }
395
+ return false;
396
+ } catch (error) {
397
+ ctx.logger("wikit-querier").warn("检测或撤回消息失败:", error);
398
+ return false;
399
+ }
400
+ }, "checkAndDelete");
401
+ const scheduleChecks = /* @__PURE__ */ __name((index, session, sentMessage) => {
402
+ if (index >= checkTimes.length) return;
403
+ ctx.setTimeout(
404
+ async () => {
405
+ const deleted = await checkAndDelete(session, sentMessage);
406
+ if (!deleted) {
407
+ scheduleChecks(index + 1, session, sentMessage);
408
+ }
409
+ },
410
+ index === 0 ? checkTimes[0] : checkTimes[index] - checkTimes[index - 1]
411
+ );
412
+ }, "scheduleChecks");
413
+ }
414
+ __name(apply, "apply");
415
+ // Annotate the CommonJS export names for ESM import in node:
416
+ 0 && (module.exports = {
417
+ Config,
418
+ apply,
419
+ inject,
420
+ name
421
+ });
package/lib/lib.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { TitleQueryResponse, UserQueryResponse, UserRankQueryResponse } from "./types";
2
+ export declare const wikiInfo: Record<string, {
3
+ wiki: string;
4
+ }>;
5
+ export declare function wikitApiRequest(param: string, name: string, endpointIndex: number, queryString: string): Promise<TitleQueryResponse | UserQueryResponse | UserRankQueryResponse>;
package/lib/types.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ export interface Article {
2
+ title: string;
3
+ url: string;
4
+ author: string;
5
+ rating: number;
6
+ }
7
+ export interface PageInfo {
8
+ total: number;
9
+ page: number;
10
+ pageSize: number;
11
+ hasNextPage: boolean;
12
+ }
13
+ export interface TitleQueryResponse {
14
+ articles: {
15
+ nodes: Article[];
16
+ pageInfo: PageInfo;
17
+ };
18
+ }
19
+ export interface AuthorRank {
20
+ total: number;
21
+ rank: number;
22
+ name: string;
23
+ value: number;
24
+ }
25
+ export interface UserQueryResponse {
26
+ authorWikiRank?: AuthorRank;
27
+ authorGlobalRank?: AuthorRank;
28
+ articles?: {
29
+ pageInfo: {
30
+ total: number;
31
+ };
32
+ };
33
+ }
34
+ export interface UserRankQueryResponse {
35
+ authorRanking: AuthorRank[];
36
+ }
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "koishi-plugin-wikit-querier-remodified",
3
+ "description": "Wikit,修改版,自用",
4
+ "version": "0.0.1",
5
+ "main": "lib/index.js",
6
+ "typings": "lib/index.d.ts",
7
+ "files": [
8
+ "lib",
9
+ "dist"
10
+ ],
11
+ "license": "MIT",
12
+ "homepage": "https://github.com/lest-day/koishi-plugin-wikit-querier-remodified.git",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/lest-day/koishi-plugin-wikit-querier-remodified.git"
16
+ },
17
+ "keywords": [
18
+ "chatbot",
19
+ "koishi",
20
+ "plugin"
21
+ ],
22
+ "peerDependencies": {
23
+ "koishi": "^4.18.7"
24
+ },
25
+ "dependencies": {
26
+ "@satorijs/element": "^3.1.8",
27
+ "koishi-plugin-adapter-onebot": "^6.8.0"
28
+ }
29
+ }
package/readme.md ADDED
@@ -0,0 +1,6 @@
1
+ # koishi-plugin-wikit-querier-remodified
2
+
3
+ [![npm](https://img.shields.io/npm/v/koishi-plugin-wikit-querier-remodified?style=flat-square)](https://www.npmjs.com/package/koishi-plugin-wikit-querier-remodified)
4
+
5
+ "# koishi-plugin-wikit-querier"
6
+ "# koishi-plugin-crom-querier-modified"