worldstate-emitter 2.2.6 → 2.2.7
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/.mocharc.yml +1 -1
- package/index.js +15 -6
- package/package.json +5 -2
- package/resources/config.js +4 -1
- package/utilities/Cache.js +7 -1
- package/utilities/FetchProxy.js +73 -0
package/.mocharc.yml
CHANGED
package/index.js
CHANGED
|
@@ -4,6 +4,7 @@ import RSS from './handlers/RSS.js';
|
|
|
4
4
|
import Worldstate from './handlers/Worldstate.js';
|
|
5
5
|
import Twitter from './handlers/Twitter.js';
|
|
6
6
|
import { logger } from './utilities/index.js';
|
|
7
|
+
import { FEATURES } from './resources/config.js';
|
|
7
8
|
|
|
8
9
|
export default class WorldstateEmitter extends EventEmitter {
|
|
9
10
|
#locale;
|
|
@@ -28,10 +29,16 @@ export default class WorldstateEmitter extends EventEmitter {
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
async #init() {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
if (FEATURES.includes('rss')) {
|
|
33
|
+
this.#rss = new RSS(this);
|
|
34
|
+
}
|
|
35
|
+
if (FEATURES.includes('worldstate')) {
|
|
36
|
+
this.#worldstate = new Worldstate(this, this.#locale);
|
|
37
|
+
await this.#worldstate.init();
|
|
38
|
+
}
|
|
39
|
+
if (FEATURES.includes('twitter')) {
|
|
40
|
+
this.#twitter = new Twitter(this);
|
|
41
|
+
}
|
|
35
42
|
|
|
36
43
|
logger.silly('hey look, i started up...');
|
|
37
44
|
this.setupLogging();
|
|
@@ -58,6 +65,7 @@ export default class WorldstateEmitter extends EventEmitter {
|
|
|
58
65
|
* @returns {Object} [description]
|
|
59
66
|
*/
|
|
60
67
|
getRss() {
|
|
68
|
+
if (!this.#rss) return undefined;
|
|
61
69
|
return this.#rss.feeder.list.map((i) => ({ url: i.url, items: i.items }));
|
|
62
70
|
}
|
|
63
71
|
|
|
@@ -67,13 +75,14 @@ export default class WorldstateEmitter extends EventEmitter {
|
|
|
67
75
|
* @returns {Object} Requested worldstate
|
|
68
76
|
*/
|
|
69
77
|
getWorldstate(language = 'en') {
|
|
78
|
+
if (!this.#worldstate) return undefined;
|
|
70
79
|
return this.#worldstate?.get(language);
|
|
71
80
|
}
|
|
72
81
|
|
|
73
82
|
get debug() {
|
|
74
83
|
return {
|
|
75
|
-
rss: this.getRss(),
|
|
76
|
-
worldstate: this.#worldstate?.get(),
|
|
84
|
+
rss: FEATURES.includes('rss') ? this.getRss() : undefined,
|
|
85
|
+
worldstate: FEATURES.includes('worldstate') ? this.#worldstate?.get() : undefined,
|
|
77
86
|
twitter: this.#twitter?.clientInfoValid ? this.#twitter.getData() : undefined,
|
|
78
87
|
};
|
|
79
88
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "worldstate-emitter",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.7",
|
|
4
4
|
"description": "Event emitter for worldstate & other warframe events",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"warframe",
|
|
@@ -12,7 +12,10 @@
|
|
|
12
12
|
"bugs": {
|
|
13
13
|
"url": "https://github.com/wfcd/worldstate-emitter/issues"
|
|
14
14
|
},
|
|
15
|
-
"repository":
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/WFCD/worldstate-emitter.git"
|
|
18
|
+
},
|
|
16
19
|
"license": "Apache-2.0",
|
|
17
20
|
"author": "tobiah <tobiah@protonmail.com>",
|
|
18
21
|
"type": "module",
|
package/resources/config.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export const WORLDSTATE_URL = process.env.WORLDSTATE_URL ?? 'https://api.warframe.com/cdn/worldState.php';
|
|
2
2
|
export const KUVA_URL = process.env.KUVA_URL ?? 'https://10o.io/arbitrations.json';
|
|
3
|
-
export const SENTIENT_URL = process.env.SENTIENT_URL ?? 'https://semlar.com/anomaly.json';
|
|
3
|
+
export const SENTIENT_URL = process.env.SENTIENT_URL ?? 'https://semlar.com/anomaly.json';
|
|
4
|
+
export const PROXY_URL = process.env.PROXY_URL ?? undefined;
|
|
5
|
+
|
|
6
|
+
export const FEATURES = process.env.FEATURES ? process.env.FEATURES.split(',') : ['rss', 'twitter', 'worldstate'];
|
package/utilities/Cache.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
|
+
import { randomUUID } from 'node:crypto';
|
|
2
3
|
|
|
3
4
|
import { CronJob } from 'cron';
|
|
4
5
|
|
|
6
|
+
import fetch from './FetchProxy.js';
|
|
7
|
+
|
|
5
8
|
import { logger } from './index.js';
|
|
6
9
|
|
|
7
10
|
export default class CronCache extends EventEmitter {
|
|
@@ -41,7 +44,10 @@ export default class CronCache extends EventEmitter {
|
|
|
41
44
|
|
|
42
45
|
async #fetch() {
|
|
43
46
|
logger.silly(`fetching... ${this.#url}`);
|
|
44
|
-
const updated = await fetch(this.#url
|
|
47
|
+
const updated = await fetch(this.#url, {
|
|
48
|
+
session: `emitter-session-${randomUUID()}`,
|
|
49
|
+
contentType: 'text/html',
|
|
50
|
+
});
|
|
45
51
|
this.#data = await updated.text();
|
|
46
52
|
return this.#data;
|
|
47
53
|
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { PROXY_URL } from '../resources/config.js';
|
|
2
|
+
|
|
3
|
+
const isCI = process.env.CI === 'true';
|
|
4
|
+
const ciTimeout = process.env.CI_TIMEOUT ? parseInt(process.env.CI_TIMEOUT, 10) : 600000;
|
|
5
|
+
const localTimeout = process.env.LOCAL_TIMEOUT ? parseInt(process.env.LOCAL_TIMEOUT, 10) : 12000000;
|
|
6
|
+
|
|
7
|
+
export default async (
|
|
8
|
+
url,
|
|
9
|
+
{ session = 'parser-session', contentType = 'application/json' } = {
|
|
10
|
+
session: 'parser-session',
|
|
11
|
+
contentType: 'application/json',
|
|
12
|
+
}
|
|
13
|
+
) => {
|
|
14
|
+
if (PROXY_URL) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const timeout = setTimeout(
|
|
17
|
+
() => {
|
|
18
|
+
controller.abort();
|
|
19
|
+
},
|
|
20
|
+
isCI ? ciTimeout : localTimeout
|
|
21
|
+
);
|
|
22
|
+
let res;
|
|
23
|
+
try {
|
|
24
|
+
res = await fetch(`${PROXY_URL}/v1`, {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: { 'Content-Type': 'application/json' },
|
|
27
|
+
signal: controller.signal,
|
|
28
|
+
body: JSON.stringify({
|
|
29
|
+
cmd: 'request.get',
|
|
30
|
+
url,
|
|
31
|
+
session,
|
|
32
|
+
maxTimeout: isCI ? ciTimeout : localTimeout,
|
|
33
|
+
returnOnlyCookies: false,
|
|
34
|
+
returnPageContent: true,
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
37
|
+
} catch (error) {
|
|
38
|
+
if (error.name === 'AbortError') {
|
|
39
|
+
throw new Error(`Request timed out after ${isCI ? ciTimeout : localTimeout}ms`);
|
|
40
|
+
}
|
|
41
|
+
throw new Error(`Proxy request failed: ${error.message}`);
|
|
42
|
+
} finally {
|
|
43
|
+
clearTimeout(timeout);
|
|
44
|
+
}
|
|
45
|
+
const text = await res.text();
|
|
46
|
+
const { solution } = JSON.parse(text);
|
|
47
|
+
if (!solution?.response) {
|
|
48
|
+
throw solution;
|
|
49
|
+
}
|
|
50
|
+
if (contentType === 'application/json') {
|
|
51
|
+
return {
|
|
52
|
+
ok: solution.responseCode === 200,
|
|
53
|
+
status: solution.responseCode,
|
|
54
|
+
json: async () => {
|
|
55
|
+
try {
|
|
56
|
+
return JSON.parse(solution.response);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
if (contentType === 'text/html') {
|
|
64
|
+
return {
|
|
65
|
+
ok: solution.responseCode === 200,
|
|
66
|
+
status: solution.responseCode,
|
|
67
|
+
text: async () => solution.response.replace(/<\/?[^>]+(>|$)/g, ''),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
return solution.response;
|
|
71
|
+
}
|
|
72
|
+
return fetch(url);
|
|
73
|
+
};
|