fandom.js 1.0.0 → 1.1.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/LICENSE +23 -0
- package/README.md +73 -1
- package/dist/client/client.d.ts +69 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +74 -0
- package/dist/enums/index.d.ts +7 -0
- package/dist/enums/index.d.ts.map +1 -0
- package/dist/enums/index.js +6 -0
- package/dist/enums/log-type.d.ts +20 -0
- package/dist/enums/log-type.d.ts.map +1 -0
- package/dist/enums/log-type.js +20 -0
- package/dist/enums/namespace.d.ts +25 -0
- package/dist/enums/namespace.d.ts.map +1 -0
- package/dist/enums/namespace.js +25 -0
- package/dist/enums/protection-level.d.ts +9 -0
- package/dist/enums/protection-level.d.ts.map +1 -0
- package/dist/enums/protection-level.js +9 -0
- package/dist/enums/rc-show.d.ts +16 -0
- package/dist/enums/rc-show.d.ts.map +1 -0
- package/dist/enums/rc-show.js +16 -0
- package/dist/enums/rc-type.d.ts +11 -0
- package/dist/enums/rc-type.d.ts.map +1 -0
- package/dist/enums/rc-type.js +11 -0
- package/dist/enums/token-type.d.ts +13 -0
- package/dist/enums/token-type.d.ts.map +1 -0
- package/dist/enums/token-type.js +13 -0
- package/dist/errors/api-error.d.ts +6 -0
- package/dist/errors/api-error.d.ts.map +1 -0
- package/dist/errors/api-error.js +8 -0
- package/dist/events/events.d.ts +14 -0
- package/dist/events/events.d.ts.map +1 -0
- package/dist/events/events.js +3 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/managers/base-manager.d.ts +16 -0
- package/dist/managers/base-manager.d.ts.map +1 -0
- package/dist/managers/base-manager.js +12 -0
- package/dist/managers/category-manager.d.ts +15 -0
- package/dist/managers/category-manager.d.ts.map +1 -0
- package/dist/managers/category-manager.js +27 -0
- package/dist/managers/event-manager.d.ts +48 -0
- package/dist/managers/event-manager.d.ts.map +1 -0
- package/dist/managers/event-manager.js +110 -0
- package/dist/managers/meta-manager.d.ts +14 -0
- package/dist/managers/meta-manager.d.ts.map +1 -0
- package/dist/managers/meta-manager.js +20 -0
- package/dist/managers/page-manager.d.ts +26 -0
- package/dist/managers/page-manager.d.ts.map +1 -0
- package/dist/managers/page-manager.js +86 -0
- package/dist/managers/revision-manager.d.ts +32 -0
- package/dist/managers/revision-manager.d.ts.map +1 -0
- package/dist/managers/revision-manager.js +69 -0
- package/dist/managers/search-manager.d.ts +14 -0
- package/dist/managers/search-manager.d.ts.map +1 -0
- package/dist/managers/search-manager.js +24 -0
- package/dist/managers/user-manager.d.ts +34 -0
- package/dist/managers/user-manager.d.ts.map +1 -0
- package/dist/managers/user-manager.js +66 -0
- package/dist/package-constants.d.ts +5 -0
- package/dist/package-constants.d.ts.map +1 -0
- package/dist/package-constants.js +4 -0
- package/dist/request/rate-limiter.d.ts +13 -0
- package/dist/request/rate-limiter.d.ts.map +1 -0
- package/dist/request/rate-limiter.js +28 -0
- package/dist/request/request-manager.d.ts +29 -0
- package/dist/request/request-manager.d.ts.map +1 -0
- package/dist/request/request-manager.js +106 -0
- package/dist/structures/base-structure.d.ts +24 -0
- package/dist/structures/base-structure.d.ts.map +1 -0
- package/dist/structures/base-structure.js +13 -0
- package/dist/structures/page-structure.d.ts +81 -0
- package/dist/structures/page-structure.d.ts.map +1 -0
- package/dist/structures/page-structure.js +164 -0
- package/dist/structures/revision-structure.d.ts +46 -0
- package/dist/structures/revision-structure.d.ts.map +1 -0
- package/dist/structures/revision-structure.js +41 -0
- package/dist/structures/user-structure.d.ts +45 -0
- package/dist/structures/user-structure.d.ts.map +1 -0
- package/dist/structures/user-structure.js +52 -0
- package/dist/types/api.d.ts +14 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +1 -0
- package/dist/types/client.d.ts +39 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/client.js +1 -0
- package/dist/types/events.d.ts +141 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +7 -0
- package/dist/types/page.d.ts +105 -0
- package/dist/types/page.d.ts.map +1 -0
- package/dist/types/page.js +1 -0
- package/dist/types/revision.d.ts +83 -0
- package/dist/types/revision.d.ts.map +1 -0
- package/dist/types/revision.js +1 -0
- package/dist/types/site.d.ts +290 -0
- package/dist/types/site.d.ts.map +1 -0
- package/dist/types/site.js +1 -0
- package/dist/types/user.d.ts +100 -0
- package/dist/types/user.d.ts.map +1 -0
- package/dist/types/user.js +1 -0
- package/package.json +54 -8
- package/src/index.js +0 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { Page } from "../structures/page-structure.js";
|
|
3
|
+
/**
|
|
4
|
+
* Manager for handling category-related operations.
|
|
5
|
+
*/
|
|
6
|
+
export class CategoryManager extends BaseManager {
|
|
7
|
+
/**
|
|
8
|
+
* Fetches members of a category.
|
|
9
|
+
* @param category - The name of the category.
|
|
10
|
+
* @param limit - The maximum number of members to fetch. Defaults to 50.
|
|
11
|
+
* @returns A Promise that resolves to an array of Page objects representing the category members.
|
|
12
|
+
*/
|
|
13
|
+
async fetchMembers(category, limit = 50) {
|
|
14
|
+
const res = await this.client.requestManager.get({
|
|
15
|
+
action: "query",
|
|
16
|
+
list: "categorymembers",
|
|
17
|
+
cmtitle: category.startsWith("Category:")
|
|
18
|
+
? category
|
|
19
|
+
: `Category:${category}`,
|
|
20
|
+
cmlimit: limit,
|
|
21
|
+
format: "json",
|
|
22
|
+
});
|
|
23
|
+
if (!res?.query?.categorymembers)
|
|
24
|
+
return [];
|
|
25
|
+
return res.query.categorymembers.map((data) => new Page(this.client, data));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { FandomEmitter } from "../events/events.js";
|
|
2
|
+
import type { Client } from "../client/client.js";
|
|
3
|
+
/**
|
|
4
|
+
* Manager for handling wiki events via polling.
|
|
5
|
+
*/
|
|
6
|
+
export declare class EventManager extends FandomEmitter {
|
|
7
|
+
/**
|
|
8
|
+
* The client instance.
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
private client;
|
|
12
|
+
/**
|
|
13
|
+
* The polling interval.
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
private interval;
|
|
17
|
+
/**
|
|
18
|
+
* The timestamp of the last processed change.
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
private lastTimestamp;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a new instance of the EventManager.
|
|
24
|
+
* @param client - The client instance.
|
|
25
|
+
*/
|
|
26
|
+
constructor(client: Client);
|
|
27
|
+
/**
|
|
28
|
+
* Starts polling for recent changes.
|
|
29
|
+
* @param intervalMs - The polling interval in milliseconds. Defaults to 5000.
|
|
30
|
+
*/
|
|
31
|
+
startPolling(intervalMs?: number): void;
|
|
32
|
+
/**
|
|
33
|
+
* Stops polling for recent changes.
|
|
34
|
+
*/
|
|
35
|
+
stopPolling(): void;
|
|
36
|
+
/**
|
|
37
|
+
* Polls for recent changes.
|
|
38
|
+
* @private
|
|
39
|
+
*/
|
|
40
|
+
private poll;
|
|
41
|
+
/**
|
|
42
|
+
* Processes a recent change and emits relevant events.
|
|
43
|
+
* @param change - The recent change to process.
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
private processChange;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=event-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"event-manager.d.ts","sourceRoot":"","sources":["../../src/managers/event-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD;;GAEG;AACH,qBAAa,YAAa,SAAQ,aAAa;IAC7C;;;OAGG;IACH,OAAO,CAAC,MAAM,CAAS;IACvB;;;OAGG;IACH,OAAO,CAAC,QAAQ,CAA+B;IAC/C;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAuB;IAE5C;;;OAGG;gBACS,MAAM,EAAE,MAAM;IAK1B;;;OAGG;IACI,YAAY,CAAC,UAAU,GAAE,MAAa;IAK7C;;OAEG;IACI,WAAW;IAOlB;;;OAGG;YACW,IAAI;IAsClB;;;;OAIG;IACH,OAAO,CAAC,aAAa;CAyBtB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { FandomEmitter } from "../events/events.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manager for handling wiki events via polling.
|
|
4
|
+
*/
|
|
5
|
+
export class EventManager extends FandomEmitter {
|
|
6
|
+
/**
|
|
7
|
+
* Creates a new instance of the EventManager.
|
|
8
|
+
* @param client - The client instance.
|
|
9
|
+
*/
|
|
10
|
+
constructor(client) {
|
|
11
|
+
super();
|
|
12
|
+
/**
|
|
13
|
+
* The polling interval.
|
|
14
|
+
* @private
|
|
15
|
+
*/
|
|
16
|
+
this.interval = null;
|
|
17
|
+
/**
|
|
18
|
+
* The timestamp of the last processed change.
|
|
19
|
+
* @private
|
|
20
|
+
*/
|
|
21
|
+
this.lastTimestamp = null;
|
|
22
|
+
this.client = client;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Starts polling for recent changes.
|
|
26
|
+
* @param intervalMs - The polling interval in milliseconds. Defaults to 5000.
|
|
27
|
+
*/
|
|
28
|
+
startPolling(intervalMs = 5000) {
|
|
29
|
+
if (this.interval)
|
|
30
|
+
return;
|
|
31
|
+
this.interval = setInterval(() => this.poll(), intervalMs);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Stops polling for recent changes.
|
|
35
|
+
*/
|
|
36
|
+
stopPolling() {
|
|
37
|
+
if (this.interval) {
|
|
38
|
+
clearInterval(this.interval);
|
|
39
|
+
this.interval = null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Polls for recent changes.
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
async poll() {
|
|
47
|
+
try {
|
|
48
|
+
const params = {
|
|
49
|
+
action: "query",
|
|
50
|
+
list: "recentchanges",
|
|
51
|
+
rcprop: "title|ids|timestamp|user|userid|comment|flags|loginfo",
|
|
52
|
+
rclimit: 50,
|
|
53
|
+
format: "json",
|
|
54
|
+
};
|
|
55
|
+
if (this.lastTimestamp) {
|
|
56
|
+
params.rcend = this.lastTimestamp;
|
|
57
|
+
}
|
|
58
|
+
const res = await this.client.requestManager.get(params);
|
|
59
|
+
const changes = res?.query?.recentchanges;
|
|
60
|
+
if (!changes || changes.length === 0)
|
|
61
|
+
return;
|
|
62
|
+
if (!this.lastTimestamp) {
|
|
63
|
+
this.lastTimestamp = changes[0].timestamp;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
for (const change of changes) {
|
|
67
|
+
if (change.timestamp <= this.lastTimestamp)
|
|
68
|
+
continue;
|
|
69
|
+
this.processChange(change);
|
|
70
|
+
}
|
|
71
|
+
this.lastTimestamp = changes[0].timestamp;
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error("Polling error:", err);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Processes a recent change and emits relevant events.
|
|
79
|
+
* @param change - The recent change to process.
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
processChange(change) {
|
|
83
|
+
if (change.type === "edit") {
|
|
84
|
+
this.emit("pageUpdate", change);
|
|
85
|
+
}
|
|
86
|
+
else if (change.type === "new") {
|
|
87
|
+
this.emit("pageCreate", change);
|
|
88
|
+
}
|
|
89
|
+
else if (change.type === "log") {
|
|
90
|
+
if (change.logtype === "upload") {
|
|
91
|
+
this.emit("fileUpload", {
|
|
92
|
+
title: change.title,
|
|
93
|
+
user: change.user,
|
|
94
|
+
timestamp: change.timestamp,
|
|
95
|
+
comment: change.comment,
|
|
96
|
+
url: "",
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
else if (change.logtype === "block") {
|
|
100
|
+
this.emit("userBlock", {
|
|
101
|
+
user: change.title.replace("User:", ""),
|
|
102
|
+
by: change.user,
|
|
103
|
+
timestamp: change.timestamp,
|
|
104
|
+
expiry: "",
|
|
105
|
+
reason: change.comment,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import type { SiteInfo } from "../types/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Manager for handling metadata-related operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare class MetaManager extends BaseManager {
|
|
7
|
+
/**
|
|
8
|
+
* Fetches site information.
|
|
9
|
+
* @param prop - The properties to fetch. Defaults to "general|namespaces|statistics".
|
|
10
|
+
* @returns A Promise that resolves to the site information.
|
|
11
|
+
*/
|
|
12
|
+
fetchSiteInfo(prop?: string): Promise<Partial<SiteInfo>>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=meta-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"meta-manager.d.ts","sourceRoot":"","sources":["../../src/managers/meta-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,KAAK,EAAe,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAC1C;;;;OAIG;IACU,aAAa,CACxB,IAAI,GAAE,MAAwC,GAC7C,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;CAY9B"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manager for handling metadata-related operations.
|
|
4
|
+
*/
|
|
5
|
+
export class MetaManager extends BaseManager {
|
|
6
|
+
/**
|
|
7
|
+
* Fetches site information.
|
|
8
|
+
* @param prop - The properties to fetch. Defaults to "general|namespaces|statistics".
|
|
9
|
+
* @returns A Promise that resolves to the site information.
|
|
10
|
+
*/
|
|
11
|
+
async fetchSiteInfo(prop = "general|namespaces|statistics") {
|
|
12
|
+
const res = await this.client.requestManager.get({
|
|
13
|
+
action: "query",
|
|
14
|
+
meta: "siteinfo",
|
|
15
|
+
siprop: prop,
|
|
16
|
+
format: "json",
|
|
17
|
+
});
|
|
18
|
+
return res?.query || {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { Page } from "../structures/page-structure.js";
|
|
3
|
+
import type { Client } from "../client/client.js";
|
|
4
|
+
/**
|
|
5
|
+
* Manager for handling page-related operations.
|
|
6
|
+
*/
|
|
7
|
+
export declare class PageManager extends BaseManager {
|
|
8
|
+
/**
|
|
9
|
+
* Cache for storing fetched pages.
|
|
10
|
+
* @private
|
|
11
|
+
*/
|
|
12
|
+
private cache;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new instance of the PageManager.
|
|
15
|
+
* @param client - The client instance.
|
|
16
|
+
*/
|
|
17
|
+
constructor(client: Client);
|
|
18
|
+
/**
|
|
19
|
+
* Fetches a page by its title.
|
|
20
|
+
* @param title - The title of the page to fetch.
|
|
21
|
+
* @returns A Promise that resolves to the fetched Page.
|
|
22
|
+
* @throws {Error} If no page data is found.
|
|
23
|
+
*/
|
|
24
|
+
fetch(title: string): Promise<Page>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=page-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"page-manager.d.ts","sourceRoot":"","sources":["../../src/managers/page-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAOvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAElD;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAC1C;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAyB;IAEtC;;;OAGG;gBACS,MAAM,EAAE,MAAM;IAO1B;;;;;OAKG;IACU,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CA+EjD"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { Page } from "../structures/page-structure.js";
|
|
3
|
+
import { LRUCache } from "lru-cache";
|
|
4
|
+
import { ARTICLES_DETAILS_PATH, DEFAULT_ABSTRACT_LENGTH, } from "../package-constants.js";
|
|
5
|
+
/**
|
|
6
|
+
* Manager for handling page-related operations.
|
|
7
|
+
*/
|
|
8
|
+
export class PageManager extends BaseManager {
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new instance of the PageManager.
|
|
11
|
+
* @param client - The client instance.
|
|
12
|
+
*/
|
|
13
|
+
constructor(client) {
|
|
14
|
+
super(client);
|
|
15
|
+
this.cache = new LRUCache({
|
|
16
|
+
max: this.client.options.cacheSize ?? 100,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Fetches a page by its title.
|
|
21
|
+
* @param title - The title of the page to fetch.
|
|
22
|
+
* @returns A Promise that resolves to the fetched Page.
|
|
23
|
+
* @throws {Error} If no page data is found.
|
|
24
|
+
*/
|
|
25
|
+
async fetch(title) {
|
|
26
|
+
const key = `page:${title}`;
|
|
27
|
+
const cached = this.cache.get(key);
|
|
28
|
+
if (cached)
|
|
29
|
+
return cached;
|
|
30
|
+
const res = await this.client.requestManager.get({
|
|
31
|
+
action: "query",
|
|
32
|
+
prop: "extracts|revisions|categories",
|
|
33
|
+
exintro: true,
|
|
34
|
+
explaintext: true,
|
|
35
|
+
rvprop: "content",
|
|
36
|
+
cllimit: "max",
|
|
37
|
+
redirects: true,
|
|
38
|
+
titles: title,
|
|
39
|
+
format: "json",
|
|
40
|
+
});
|
|
41
|
+
const pages = res?.query?.pages;
|
|
42
|
+
const firstPage = pages ? Object.values(pages)[0] : undefined;
|
|
43
|
+
if (!firstPage)
|
|
44
|
+
throw new Error("No page data");
|
|
45
|
+
const normalizedTitle = firstPage.title;
|
|
46
|
+
const redirectInfo = res?.query?.redirects;
|
|
47
|
+
const redirectTarget = redirectInfo?.length
|
|
48
|
+
? redirectInfo[redirectInfo.length - 1]?.to
|
|
49
|
+
: undefined;
|
|
50
|
+
const fallbackTitle = redirectTarget ?? normalizedTitle ?? title;
|
|
51
|
+
let extract = typeof firstPage.extract === "string"
|
|
52
|
+
? firstPage.extract.trim()
|
|
53
|
+
: undefined;
|
|
54
|
+
if (!extract) {
|
|
55
|
+
try {
|
|
56
|
+
const details = await this.client.requestManager.get({
|
|
57
|
+
titles: fallbackTitle,
|
|
58
|
+
abstract: DEFAULT_ABSTRACT_LENGTH,
|
|
59
|
+
}, { apiPath: ARTICLES_DETAILS_PATH });
|
|
60
|
+
const items = details?.items;
|
|
61
|
+
const firstItem = items ? Object.values(items)[0] : undefined;
|
|
62
|
+
const abstract = firstItem && typeof firstItem.abstract === "string"
|
|
63
|
+
? firstItem.abstract.trim()
|
|
64
|
+
: undefined;
|
|
65
|
+
if (abstract) {
|
|
66
|
+
extract = abstract;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// ignore fallback errors so we can still return basic page info
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
const pageSummary = {
|
|
74
|
+
pageid: firstPage.pageid,
|
|
75
|
+
ns: firstPage.ns,
|
|
76
|
+
title: fallbackTitle,
|
|
77
|
+
extract,
|
|
78
|
+
revisions: firstPage.revisions,
|
|
79
|
+
categories: firstPage.categories,
|
|
80
|
+
};
|
|
81
|
+
this.client.events.emit("pageFetched", pageSummary);
|
|
82
|
+
const page = new Page(this.client, pageSummary);
|
|
83
|
+
this.cache.set(key, page);
|
|
84
|
+
return page;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { Revision } from "../structures/revision-structure.js";
|
|
3
|
+
import type { Client } from "../client/client.js";
|
|
4
|
+
/**
|
|
5
|
+
* Manager for handling revision-related operations.
|
|
6
|
+
*/
|
|
7
|
+
export declare class RevisionManager extends BaseManager {
|
|
8
|
+
/**
|
|
9
|
+
* Cache for storing fetched revisions.
|
|
10
|
+
* @private
|
|
11
|
+
*/
|
|
12
|
+
private cache;
|
|
13
|
+
/**
|
|
14
|
+
* Creates a new instance of the RevisionManager.
|
|
15
|
+
* @param client - The client instance.
|
|
16
|
+
*/
|
|
17
|
+
constructor(client: Client);
|
|
18
|
+
/**
|
|
19
|
+
* Fetches a revision by its ID.
|
|
20
|
+
* @param id - The ID of the revision to fetch.
|
|
21
|
+
* @returns A Promise that resolves to the fetched Revision.
|
|
22
|
+
* @throws {Error} If the revision is not found.
|
|
23
|
+
*/
|
|
24
|
+
fetch(id: number): Promise<Revision>;
|
|
25
|
+
/**
|
|
26
|
+
* Fetches recent changes from the wiki.
|
|
27
|
+
* @param limit - The maximum number of recent changes to fetch. Defaults to 10.
|
|
28
|
+
* @returns A Promise that resolves to an array of Revision objects representing the recent changes.
|
|
29
|
+
*/
|
|
30
|
+
fetchRecent(limit?: number): Promise<Revision[]>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=revision-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"revision-manager.d.ts","sourceRoot":"","sources":["../../src/managers/revision-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,qCAAqC,CAAC;AAE/D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAGlD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,WAAW;IAC9C;;;OAGG;IACH,OAAO,CAAC,KAAK,CAA6B;IAE1C;;;OAGG;gBACS,MAAM,EAAE,MAAM;IAO1B;;;;;OAKG;IACU,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC;IA0BjD;;;;OAIG;IACU,WAAW,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;CAyBlE"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { Revision } from "../structures/revision-structure.js";
|
|
3
|
+
import { LRUCache } from "lru-cache";
|
|
4
|
+
/**
|
|
5
|
+
* Manager for handling revision-related operations.
|
|
6
|
+
*/
|
|
7
|
+
export class RevisionManager extends BaseManager {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new instance of the RevisionManager.
|
|
10
|
+
* @param client - The client instance.
|
|
11
|
+
*/
|
|
12
|
+
constructor(client) {
|
|
13
|
+
super(client);
|
|
14
|
+
this.cache = new LRUCache({
|
|
15
|
+
max: this.client.options.cacheSize ?? 100,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetches a revision by its ID.
|
|
20
|
+
* @param id - The ID of the revision to fetch.
|
|
21
|
+
* @returns A Promise that resolves to the fetched Revision.
|
|
22
|
+
* @throws {Error} If the revision is not found.
|
|
23
|
+
*/
|
|
24
|
+
async fetch(id) {
|
|
25
|
+
const cached = this.cache.get(id);
|
|
26
|
+
if (cached)
|
|
27
|
+
return cached;
|
|
28
|
+
const res = await this.client.requestManager.get({
|
|
29
|
+
action: "query",
|
|
30
|
+
prop: "revisions",
|
|
31
|
+
revids: id,
|
|
32
|
+
rvprop: "ids|timestamp|user|comment|content",
|
|
33
|
+
format: "json",
|
|
34
|
+
});
|
|
35
|
+
const pages = res?.query?.pages;
|
|
36
|
+
const firstPage = pages ? Object.values(pages)[0] : undefined;
|
|
37
|
+
const revisions = firstPage?.revisions;
|
|
38
|
+
const revisionData = revisions ? revisions[0] : undefined;
|
|
39
|
+
if (!revisionData)
|
|
40
|
+
throw new Error(`Revision ${id} not found`);
|
|
41
|
+
const revision = new Revision(this.client, revisionData);
|
|
42
|
+
this.cache.set(id, revision);
|
|
43
|
+
return revision;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Fetches recent changes from the wiki.
|
|
47
|
+
* @param limit - The maximum number of recent changes to fetch. Defaults to 10.
|
|
48
|
+
* @returns A Promise that resolves to an array of Revision objects representing the recent changes.
|
|
49
|
+
*/
|
|
50
|
+
async fetchRecent(limit = 10) {
|
|
51
|
+
const res = await this.client.requestManager.get({
|
|
52
|
+
action: "query",
|
|
53
|
+
list: "recentchanges",
|
|
54
|
+
rcprop: "ids|timestamp|user|comment|title",
|
|
55
|
+
rclimit: limit,
|
|
56
|
+
format: "json",
|
|
57
|
+
});
|
|
58
|
+
const changes = res?.query?.recentchanges;
|
|
59
|
+
if (!changes)
|
|
60
|
+
return [];
|
|
61
|
+
return changes.map((data) => new Revision(this.client, {
|
|
62
|
+
revid: data.revid,
|
|
63
|
+
timestamp: data.timestamp,
|
|
64
|
+
user: data.user,
|
|
65
|
+
comment: data.comment,
|
|
66
|
+
title: data.title,
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manager for handling search operations.
|
|
4
|
+
*/
|
|
5
|
+
export declare class SearchManager extends BaseManager {
|
|
6
|
+
/**
|
|
7
|
+
* Searches the wiki for pages matching the query.
|
|
8
|
+
* @param query - The search query.
|
|
9
|
+
* @param limit - The maximum number of results to return. Defaults to 10.
|
|
10
|
+
* @returns A Promise that resolves to an array of page titles matching the query.
|
|
11
|
+
*/
|
|
12
|
+
search(query: string, limit?: number): Promise<string[]>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=search-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search-manager.d.ts","sourceRoot":"","sources":["../../src/managers/search-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGhD;;GAEG;AACH,qBAAa,aAAc,SAAQ,WAAW;IAC5C;;;;;OAKG;IACU,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;CAe1E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
/**
|
|
3
|
+
* Manager for handling search operations.
|
|
4
|
+
*/
|
|
5
|
+
export class SearchManager extends BaseManager {
|
|
6
|
+
/**
|
|
7
|
+
* Searches the wiki for pages matching the query.
|
|
8
|
+
* @param query - The search query.
|
|
9
|
+
* @param limit - The maximum number of results to return. Defaults to 10.
|
|
10
|
+
* @returns A Promise that resolves to an array of page titles matching the query.
|
|
11
|
+
*/
|
|
12
|
+
async search(query, limit = 10) {
|
|
13
|
+
const res = await this.client.requestManager.get({
|
|
14
|
+
action: "query",
|
|
15
|
+
list: "search",
|
|
16
|
+
srsearch: query,
|
|
17
|
+
srlimit: limit,
|
|
18
|
+
format: "json",
|
|
19
|
+
});
|
|
20
|
+
if (!res?.query?.search)
|
|
21
|
+
return [];
|
|
22
|
+
return res.query.search.map((item) => item.title);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { User } from "../structures/user-structure.js";
|
|
3
|
+
import type { Client } from "../client/client.js";
|
|
4
|
+
import type { UserContribution } from "../types/index.js";
|
|
5
|
+
/**
|
|
6
|
+
* Manager for handling user-related operations.
|
|
7
|
+
*/
|
|
8
|
+
export declare class UserManager extends BaseManager {
|
|
9
|
+
/**
|
|
10
|
+
* Cache for storing fetched users.
|
|
11
|
+
* @private
|
|
12
|
+
*/
|
|
13
|
+
private cache;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a new instance of the UserManager.
|
|
16
|
+
* @param client - The client instance.
|
|
17
|
+
*/
|
|
18
|
+
constructor(client: Client);
|
|
19
|
+
/**
|
|
20
|
+
* Fetches a user by their username or ID.
|
|
21
|
+
* @param usernameOrID - The username or ID of the user to fetch.
|
|
22
|
+
* @returns A Promise that resolves to the fetched User.
|
|
23
|
+
* @throws {Error} If the user is not found.
|
|
24
|
+
*/
|
|
25
|
+
fetch(usernameOrID: string | number): Promise<User>;
|
|
26
|
+
/**
|
|
27
|
+
* Fetches contributions for a specific user.
|
|
28
|
+
* @param username - The username to fetch contributions for.
|
|
29
|
+
* @param limit - The maximum number of contributions to fetch. Defaults to 10.
|
|
30
|
+
* @returns A Promise that resolves to an array of UserContribution objects.
|
|
31
|
+
*/
|
|
32
|
+
fetchContributions(username: string, limit?: number): Promise<UserContribution[]>;
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=user-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-manager.d.ts","sourceRoot":"","sources":["../../src/managers/user-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAEvD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAGV,gBAAgB,EAEjB,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,qBAAa,WAAY,SAAQ,WAAW;IAC1C;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAyB;IAEtC;;;OAGG;gBACS,MAAM,EAAE,MAAM;IAO1B;;;;;OAKG;IACU,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiChE;;;;;OAKG;IACU,kBAAkB,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,GAAE,MAAW,GACjB,OAAO,CAAC,gBAAgB,EAAE,CAAC;CAa/B"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { BaseManager } from "./base-manager.js";
|
|
2
|
+
import { User } from "../structures/user-structure.js";
|
|
3
|
+
import { LRUCache } from "lru-cache";
|
|
4
|
+
/**
|
|
5
|
+
* Manager for handling user-related operations.
|
|
6
|
+
*/
|
|
7
|
+
export class UserManager extends BaseManager {
|
|
8
|
+
/**
|
|
9
|
+
* Creates a new instance of the UserManager.
|
|
10
|
+
* @param client - The client instance.
|
|
11
|
+
*/
|
|
12
|
+
constructor(client) {
|
|
13
|
+
super(client);
|
|
14
|
+
this.cache = new LRUCache({
|
|
15
|
+
max: this.client.options.cacheSize ?? 100,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetches a user by their username or ID.
|
|
20
|
+
* @param usernameOrID - The username or ID of the user to fetch.
|
|
21
|
+
* @returns A Promise that resolves to the fetched User.
|
|
22
|
+
* @throws {Error} If the user is not found.
|
|
23
|
+
*/
|
|
24
|
+
async fetch(usernameOrID) {
|
|
25
|
+
const key = `user:${usernameOrID}`;
|
|
26
|
+
const cached = this.cache.get(key);
|
|
27
|
+
if (cached)
|
|
28
|
+
return cached;
|
|
29
|
+
const params = {
|
|
30
|
+
action: "query",
|
|
31
|
+
list: "users",
|
|
32
|
+
usprop: "groups|registration",
|
|
33
|
+
format: "json",
|
|
34
|
+
};
|
|
35
|
+
if (typeof usernameOrID === "number") {
|
|
36
|
+
params.usids = usernameOrID;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
params.ususers = usernameOrID;
|
|
40
|
+
}
|
|
41
|
+
const res = await this.client.requestManager.get(params);
|
|
42
|
+
const user = res?.query?.users?.[0];
|
|
43
|
+
if (!user || "missing" in user) {
|
|
44
|
+
throw new Error("User not found");
|
|
45
|
+
}
|
|
46
|
+
const userObj = new User(this.client, user);
|
|
47
|
+
this.cache.set(key, userObj);
|
|
48
|
+
return userObj;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Fetches contributions for a specific user.
|
|
52
|
+
* @param username - The username to fetch contributions for.
|
|
53
|
+
* @param limit - The maximum number of contributions to fetch. Defaults to 10.
|
|
54
|
+
* @returns A Promise that resolves to an array of UserContribution objects.
|
|
55
|
+
*/
|
|
56
|
+
async fetchContributions(username, limit = 10) {
|
|
57
|
+
const res = await this.client.requestManager.get({
|
|
58
|
+
action: "query",
|
|
59
|
+
list: "usercontribs",
|
|
60
|
+
ucuser: username,
|
|
61
|
+
uclimit: limit,
|
|
62
|
+
format: "json",
|
|
63
|
+
});
|
|
64
|
+
return res?.query?.usercontribs || [];
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const USER_AGENT = "fandom.js/0.1.0 (https://github.com/fandomdevs/fandom.js)";
|
|
2
|
+
export declare const DEFAULT_API_PATH = "/api.php";
|
|
3
|
+
export declare const ARTICLES_DETAILS_PATH = "/api/v1/Articles/Details";
|
|
4
|
+
export declare const DEFAULT_ABSTRACT_LENGTH = 500;
|
|
5
|
+
//# sourceMappingURL=package-constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-constants.d.ts","sourceRoot":"","sources":["../src/package-constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU,8DAA8D,CAAC;AACtF,eAAO,MAAM,gBAAgB,aAAa,CAAC;AAC3C,eAAO,MAAM,qBAAqB,6BAA6B,CAAC;AAChE,eAAO,MAAM,uBAAuB,MAAM,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare class RateLimiter {
|
|
2
|
+
private tokens;
|
|
3
|
+
private last;
|
|
4
|
+
private capacity;
|
|
5
|
+
private refillRatePerMs;
|
|
6
|
+
constructor({ capacity, refillPerSecond }?: {
|
|
7
|
+
capacity?: number | undefined;
|
|
8
|
+
refillPerSecond?: number | undefined;
|
|
9
|
+
});
|
|
10
|
+
private refill;
|
|
11
|
+
removeTokens(n?: number): Promise<void>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=rate-limiter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/request/rate-limiter.ts"],"names":[],"mappings":"AAAA,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,eAAe,CAAS;gBAEpB,EAAE,QAAY,EAAE,eAAmB,EAAE;;;KAAK;IAOtD,OAAO,CAAC,MAAM;IAUD,YAAY,CAAC,CAAC,SAAI,GAAG,OAAO,CAAC,IAAI,CAAC;CAWhD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export class RateLimiter {
|
|
2
|
+
constructor({ capacity = 5, refillPerSecond = 1 } = {}) {
|
|
3
|
+
this.capacity = capacity;
|
|
4
|
+
this.tokens = capacity;
|
|
5
|
+
this.last = Date.now();
|
|
6
|
+
this.refillRatePerMs = refillPerSecond / 1000;
|
|
7
|
+
}
|
|
8
|
+
refill() {
|
|
9
|
+
const now = Date.now();
|
|
10
|
+
const dt = now - this.last;
|
|
11
|
+
const add = dt * this.refillRatePerMs;
|
|
12
|
+
if (add > 0) {
|
|
13
|
+
this.tokens = Math.min(this.capacity, this.tokens + add);
|
|
14
|
+
this.last = now;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async removeTokens(n = 1) {
|
|
18
|
+
while (true) {
|
|
19
|
+
this.refill();
|
|
20
|
+
if (this.tokens >= n) {
|
|
21
|
+
this.tokens -= n;
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// sleep a bit
|
|
25
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|