@nekosuneprojects/nekosunevrtools 1.1.0 → 1.1.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.
- package/README.md +111 -0
- package/package.json +14 -3
- package/src/cli.js +728 -14
- package/src/downloader/client.js +126 -0
- package/src/downloader/provider/compatible.js +127 -0
- package/src/downloader/providers.js +15 -0
- package/src/games/client.js +162 -0
- package/src/games/provider/nekosune-api.js +329 -0
- package/src/games/providers.js +14 -0
- package/src/index.d.ts +140 -0
- package/src/index.js +26 -2
- package/src/livestream/client.js +70 -0
- package/src/livestream/provider/nekosune-api.js +56 -0
- package/src/livestream/providers.js +14 -0
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
function createGamesProvider(baseUrl) {
|
|
2
|
+
const root = String(baseUrl || "https://api.nekosunevr.co.uk").replace(/\/+$/, "");
|
|
3
|
+
|
|
4
|
+
async function getClashOfClansClan(context) {
|
|
5
|
+
const { http, apiKey, clanTag } = context;
|
|
6
|
+
assertApiKey(apiKey);
|
|
7
|
+
const tag = normalizeTag(clanTag, "clanTag");
|
|
8
|
+
|
|
9
|
+
const response = await http.get(`${root}/v5/games/api/clashofclans/clans/${encodeURIComponent(tag)}`, {
|
|
10
|
+
headers: buildHeaders(apiKey)
|
|
11
|
+
});
|
|
12
|
+
return response.data || {};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function getClashOfClansPlayer(context) {
|
|
16
|
+
const { http, apiKey, playerTag } = context;
|
|
17
|
+
assertApiKey(apiKey);
|
|
18
|
+
const tag = normalizeTag(playerTag, "playerTag");
|
|
19
|
+
|
|
20
|
+
const response = await http.get(`${root}/v5/games/api/clashofclans/players/${encodeURIComponent(tag)}`, {
|
|
21
|
+
headers: buildHeaders(apiKey)
|
|
22
|
+
});
|
|
23
|
+
return response.data || {};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
async function getDivision2Player(context) {
|
|
27
|
+
const { http, apiKey, username, platform } = context;
|
|
28
|
+
assertApiKey(apiKey);
|
|
29
|
+
|
|
30
|
+
const normalizedUsername = String(username || "").trim();
|
|
31
|
+
if (!normalizedUsername) {
|
|
32
|
+
throw new Error("Missing username.");
|
|
33
|
+
}
|
|
34
|
+
const normalizedPlatform = String(platform || "psn").trim().toLowerCase();
|
|
35
|
+
if (!normalizedPlatform) {
|
|
36
|
+
throw new Error("Missing platform.");
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const payload = new URLSearchParams();
|
|
40
|
+
payload.set("username", normalizedUsername);
|
|
41
|
+
payload.set("platform", normalizedPlatform);
|
|
42
|
+
|
|
43
|
+
const response = await http.post(`${root}/v5/games/api/division2/player`, payload.toString(), {
|
|
44
|
+
headers: {
|
|
45
|
+
...buildHeaders(apiKey),
|
|
46
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
return response.data || {};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function getFortnitePlayer(context) {
|
|
53
|
+
const { http, apiKey, username, timeWindow } = context;
|
|
54
|
+
assertApiKey(apiKey);
|
|
55
|
+
|
|
56
|
+
const normalizedUsername = String(username || "").trim();
|
|
57
|
+
if (!normalizedUsername) {
|
|
58
|
+
throw new Error("Missing username.");
|
|
59
|
+
}
|
|
60
|
+
const normalizedTimeWindow = String(timeWindow || "lifetime").trim().toLowerCase();
|
|
61
|
+
if (!normalizedTimeWindow) {
|
|
62
|
+
throw new Error("Missing timeWindow.");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const payload = new URLSearchParams();
|
|
66
|
+
payload.set("username", normalizedUsername);
|
|
67
|
+
payload.set("timeWindow", normalizedTimeWindow);
|
|
68
|
+
|
|
69
|
+
const response = await http.post(`${root}/v5/games/api/fortnite/player`, payload.toString(), {
|
|
70
|
+
headers: {
|
|
71
|
+
...buildHeaders(apiKey),
|
|
72
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return response.data || {};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async function getFortniteCreatorCode(context) {
|
|
79
|
+
const { http, apiKey, creatorCode } = context;
|
|
80
|
+
assertApiKey(apiKey);
|
|
81
|
+
|
|
82
|
+
const normalizedCreatorCode = String(creatorCode || "").trim();
|
|
83
|
+
if (!normalizedCreatorCode) {
|
|
84
|
+
throw new Error("Missing creatorCode.");
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const response = await http.get(`${root}/v5/games/api/fortnite/creatorcode/${encodeURIComponent(normalizedCreatorCode)}`, {
|
|
88
|
+
headers: buildHeaders(apiKey)
|
|
89
|
+
});
|
|
90
|
+
return response.data || {};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
async function getFortniteItemShop(context) {
|
|
94
|
+
const { http, apiKey } = context;
|
|
95
|
+
assertApiKey(apiKey);
|
|
96
|
+
|
|
97
|
+
const response = await http.get(`${root}/v5/games/api/fortnite/item-shop`, {
|
|
98
|
+
headers: buildHeaders(apiKey)
|
|
99
|
+
});
|
|
100
|
+
return response.data || {};
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function getWynncraftProfile(context) {
|
|
104
|
+
const { http, apiKey, username } = context;
|
|
105
|
+
assertApiKey(apiKey);
|
|
106
|
+
|
|
107
|
+
const normalizedUsername = String(username || "").trim();
|
|
108
|
+
if (!normalizedUsername) {
|
|
109
|
+
throw new Error("Missing username.");
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const response = await http.get(`${root}/v5/games/api/wynncraft/profile/${encodeURIComponent(normalizedUsername)}`, {
|
|
113
|
+
headers: buildHeaders(apiKey)
|
|
114
|
+
});
|
|
115
|
+
return response.data || {};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
async function getHypixelProfile(context) {
|
|
119
|
+
const { http, apiKey, username } = context;
|
|
120
|
+
assertApiKey(apiKey);
|
|
121
|
+
|
|
122
|
+
const normalizedUsername = String(username || "").trim();
|
|
123
|
+
if (!normalizedUsername) {
|
|
124
|
+
throw new Error("Missing username.");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const response = await http.get(`${root}/v5/games/api/hypixel/profile/${encodeURIComponent(normalizedUsername)}`, {
|
|
128
|
+
headers: buildHeaders(apiKey)
|
|
129
|
+
});
|
|
130
|
+
return response.data || {};
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function getRocketLeaguePlayer(context) {
|
|
134
|
+
const { http, apiKey, username, platform } = context;
|
|
135
|
+
assertApiKey(apiKey);
|
|
136
|
+
|
|
137
|
+
const normalizedUsername = String(username || "").trim();
|
|
138
|
+
if (!normalizedUsername) {
|
|
139
|
+
throw new Error("Missing username.");
|
|
140
|
+
}
|
|
141
|
+
const normalizedPlatform = String(platform || "psn").trim().toLowerCase();
|
|
142
|
+
if (!normalizedPlatform) {
|
|
143
|
+
throw new Error("Missing platform.");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const payload = new URLSearchParams();
|
|
147
|
+
payload.set("username", normalizedUsername);
|
|
148
|
+
payload.set("platform", normalizedPlatform);
|
|
149
|
+
|
|
150
|
+
const response = await http.post(`${root}/v5/games/api/rocketleague/player`, payload.toString(), {
|
|
151
|
+
headers: {
|
|
152
|
+
...buildHeaders(apiKey),
|
|
153
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return response.data || {};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async function getApexLegendsPlayer(context) {
|
|
160
|
+
const { http, apiKey, username, platform } = context;
|
|
161
|
+
assertApiKey(apiKey);
|
|
162
|
+
|
|
163
|
+
const normalizedUsername = String(username || "").trim();
|
|
164
|
+
if (!normalizedUsername) {
|
|
165
|
+
throw new Error("Missing username.");
|
|
166
|
+
}
|
|
167
|
+
const normalizedPlatform = String(platform || "psn").trim().toLowerCase();
|
|
168
|
+
if (!normalizedPlatform) {
|
|
169
|
+
throw new Error("Missing platform.");
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const payload = new URLSearchParams();
|
|
173
|
+
payload.set("username", normalizedUsername);
|
|
174
|
+
payload.set("platform", normalizedPlatform);
|
|
175
|
+
|
|
176
|
+
const response = await http.post(`${root}/v5/games/api/apexlegends/player`, payload.toString(), {
|
|
177
|
+
headers: {
|
|
178
|
+
...buildHeaders(apiKey),
|
|
179
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return response.data || {};
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
async function getBattlefield1Player(context) {
|
|
186
|
+
const { http, apiKey, username, platform } = context;
|
|
187
|
+
assertApiKey(apiKey);
|
|
188
|
+
|
|
189
|
+
const normalizedUsername = String(username || "").trim();
|
|
190
|
+
if (!normalizedUsername) {
|
|
191
|
+
throw new Error("Missing username.");
|
|
192
|
+
}
|
|
193
|
+
const normalizedPlatform = String(platform || "psn").trim().toLowerCase();
|
|
194
|
+
if (!normalizedPlatform) {
|
|
195
|
+
throw new Error("Missing platform.");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const payload = new URLSearchParams();
|
|
199
|
+
payload.set("username", normalizedUsername);
|
|
200
|
+
payload.set("platform", normalizedPlatform);
|
|
201
|
+
|
|
202
|
+
const response = await http.post(`${root}/v5/games/api/battlefield1/player`, payload.toString(), {
|
|
203
|
+
headers: {
|
|
204
|
+
...buildHeaders(apiKey),
|
|
205
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
return response.data || {};
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
async function getBattlefield5Player(context) {
|
|
212
|
+
const { http, apiKey, username, platform } = context;
|
|
213
|
+
assertApiKey(apiKey);
|
|
214
|
+
|
|
215
|
+
const normalizedUsername = String(username || "").trim();
|
|
216
|
+
if (!normalizedUsername) {
|
|
217
|
+
throw new Error("Missing username.");
|
|
218
|
+
}
|
|
219
|
+
const normalizedPlatform = String(platform || "psn").trim().toLowerCase();
|
|
220
|
+
if (!normalizedPlatform) {
|
|
221
|
+
throw new Error("Missing platform.");
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const payload = new URLSearchParams();
|
|
225
|
+
payload.set("username", normalizedUsername);
|
|
226
|
+
payload.set("platform", normalizedPlatform);
|
|
227
|
+
|
|
228
|
+
const response = await http.post(`${root}/v5/games/api/battlefield5/player`, payload.toString(), {
|
|
229
|
+
headers: {
|
|
230
|
+
...buildHeaders(apiKey),
|
|
231
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
232
|
+
}
|
|
233
|
+
});
|
|
234
|
+
return response.data || {};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function getBattlefield2042Player(context) {
|
|
238
|
+
const { http, apiKey, username, platform } = context;
|
|
239
|
+
assertApiKey(apiKey);
|
|
240
|
+
|
|
241
|
+
const normalizedUsername = String(username || "").trim();
|
|
242
|
+
if (!normalizedUsername) {
|
|
243
|
+
throw new Error("Missing username.");
|
|
244
|
+
}
|
|
245
|
+
const normalizedPlatform = String(platform || "ea").trim().toLowerCase();
|
|
246
|
+
if (!normalizedPlatform) {
|
|
247
|
+
throw new Error("Missing platform.");
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
const payload = new URLSearchParams();
|
|
251
|
+
payload.set("username", normalizedUsername);
|
|
252
|
+
payload.set("platform", normalizedPlatform);
|
|
253
|
+
|
|
254
|
+
const response = await http.post(`${root}/v5/games/api/battlefield2042/player`, payload.toString(), {
|
|
255
|
+
headers: {
|
|
256
|
+
...buildHeaders(apiKey),
|
|
257
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
return response.data || {};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
async function getBattlefield6Player(context) {
|
|
264
|
+
const { http, apiKey, username, platform } = context;
|
|
265
|
+
assertApiKey(apiKey);
|
|
266
|
+
|
|
267
|
+
const normalizedUsername = String(username || "").trim();
|
|
268
|
+
if (!normalizedUsername) {
|
|
269
|
+
throw new Error("Missing username.");
|
|
270
|
+
}
|
|
271
|
+
const normalizedPlatform = String(platform || "psn").trim().toLowerCase();
|
|
272
|
+
if (!normalizedPlatform) {
|
|
273
|
+
throw new Error("Missing platform.");
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
const payload = new URLSearchParams();
|
|
277
|
+
payload.set("username", normalizedUsername);
|
|
278
|
+
payload.set("platform", normalizedPlatform);
|
|
279
|
+
|
|
280
|
+
const response = await http.post(`${root}/v5/games/api/battlefield6/player`, payload.toString(), {
|
|
281
|
+
headers: {
|
|
282
|
+
...buildHeaders(apiKey),
|
|
283
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
return response.data || {};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
getClashOfClansClan,
|
|
291
|
+
getClashOfClansPlayer,
|
|
292
|
+
getDivision2Player,
|
|
293
|
+
getFortnitePlayer,
|
|
294
|
+
getFortniteCreatorCode,
|
|
295
|
+
getFortniteItemShop,
|
|
296
|
+
getWynncraftProfile,
|
|
297
|
+
getHypixelProfile,
|
|
298
|
+
getRocketLeaguePlayer,
|
|
299
|
+
getApexLegendsPlayer,
|
|
300
|
+
getBattlefield1Player,
|
|
301
|
+
getBattlefield5Player,
|
|
302
|
+
getBattlefield2042Player,
|
|
303
|
+
getBattlefield6Player
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
function normalizeTag(tag, fieldName) {
|
|
308
|
+
if (!tag) {
|
|
309
|
+
throw new Error(`Missing ${fieldName}.`);
|
|
310
|
+
}
|
|
311
|
+
return String(tag).replace(/^#/, "").trim().toUpperCase();
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
function assertApiKey(apiKey) {
|
|
315
|
+
if (!apiKey) {
|
|
316
|
+
throw new Error("Missing API key. Pass apiKey in client options or method options.");
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function buildHeaders(apiKey) {
|
|
321
|
+
return {
|
|
322
|
+
"nekosunevr-api-key": apiKey,
|
|
323
|
+
Authorization: `Bearer ${apiKey}`
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
module.exports = {
|
|
328
|
+
createGamesProvider
|
|
329
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const { createGamesProvider } = require("./provider/nekosune-api");
|
|
2
|
+
|
|
3
|
+
const presets = {
|
|
4
|
+
nekosune: "https://api.nekosunevr.co.uk"
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const providers = {
|
|
8
|
+
nekosune: createGamesProvider
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
presets,
|
|
13
|
+
providers
|
|
14
|
+
};
|
package/src/index.d.ts
CHANGED
|
@@ -88,6 +88,54 @@ export interface DoodstreamProvider extends VideoProviderAdapter {
|
|
|
88
88
|
remoteUploadActions(context: unknown): Promise<{ provider: "doodstream"; success: boolean; raw: unknown }>;
|
|
89
89
|
}
|
|
90
90
|
|
|
91
|
+
export interface DownloadJobState {
|
|
92
|
+
job_id: string;
|
|
93
|
+
status: string;
|
|
94
|
+
url?: string | null;
|
|
95
|
+
download?: { percent?: number; label?: string };
|
|
96
|
+
convert?: { percent?: number; label?: string };
|
|
97
|
+
upload?: { percent?: number; label?: string };
|
|
98
|
+
[key: string]: unknown;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export interface DownloaderCreateJobResult {
|
|
102
|
+
provider: string;
|
|
103
|
+
jobId: string;
|
|
104
|
+
raw: unknown;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
export interface DownloaderClientOptions {
|
|
108
|
+
apiKey?: string;
|
|
109
|
+
baseUrl?: string;
|
|
110
|
+
preset?: string;
|
|
111
|
+
timeoutMs?: number;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export interface DownloaderJobOptions {
|
|
115
|
+
apiKey?: string;
|
|
116
|
+
uploadDest?: "cdn" | "thirdparty" | "ipfs" | string;
|
|
117
|
+
timeoutMs?: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export interface DownloaderWaitOptions extends DownloaderJobOptions {
|
|
121
|
+
intervalMs?: number;
|
|
122
|
+
onProgress?: (state: DownloadJobState) => void;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export declare class DownloaderClient {
|
|
126
|
+
constructor(options?: DownloaderClientOptions);
|
|
127
|
+
useBaseUrl(baseUrl: string): this;
|
|
128
|
+
usePreset(name: string): this;
|
|
129
|
+
createMp3Job(link: string, options?: DownloaderJobOptions): Promise<DownloaderCreateJobResult>;
|
|
130
|
+
createMp4Job(link: string, options?: DownloaderJobOptions): Promise<DownloaderCreateJobResult>;
|
|
131
|
+
getJob(jobId: string, options?: DownloaderJobOptions): Promise<DownloadJobState>;
|
|
132
|
+
waitForJob(jobId: string, options?: DownloaderWaitOptions): Promise<DownloadJobState>;
|
|
133
|
+
getInfo(url: string, options?: { flat?: boolean; flatPlaylist?: boolean; fields?: "basic" | "full"; cache?: 0 | 1 | number; timeoutMs?: number }): Promise<unknown>;
|
|
134
|
+
searchYouTube(query: string, options?: { limit?: number; timeoutMs?: number }): Promise<unknown>;
|
|
135
|
+
getStreamUrl(url: string): string;
|
|
136
|
+
stream(url: string, options?: { responseType?: string; timeoutMs?: number }): Promise<unknown>;
|
|
137
|
+
}
|
|
138
|
+
|
|
91
139
|
export interface UploadAndShortenResult {
|
|
92
140
|
success: true;
|
|
93
141
|
upload: UploadResult;
|
|
@@ -150,6 +198,74 @@ export declare const platforms: {
|
|
|
150
198
|
};
|
|
151
199
|
|
|
152
200
|
export declare const shortenerPresets: Record<string, string>;
|
|
201
|
+
export declare const downloaderPresets: Record<string, string>;
|
|
202
|
+
|
|
203
|
+
export interface LivestreamClientOptions {
|
|
204
|
+
apiKey?: string;
|
|
205
|
+
baseUrl?: string;
|
|
206
|
+
preset?: string;
|
|
207
|
+
timeoutMs?: number;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export interface LivestreamResult {
|
|
211
|
+
statusCode?: number;
|
|
212
|
+
status?: string;
|
|
213
|
+
username?: string;
|
|
214
|
+
displayname?: string;
|
|
215
|
+
avatar?: string;
|
|
216
|
+
livestream?: {
|
|
217
|
+
online?: boolean;
|
|
218
|
+
bg?: string | null;
|
|
219
|
+
title?: string | null;
|
|
220
|
+
viewer?: number | null;
|
|
221
|
+
game?: string | null;
|
|
222
|
+
preview?: string | null;
|
|
223
|
+
created_at?: string | null;
|
|
224
|
+
};
|
|
225
|
+
followers?: number;
|
|
226
|
+
[key: string]: unknown;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export declare class LivestreamClient {
|
|
230
|
+
constructor(options?: LivestreamClientOptions);
|
|
231
|
+
useBaseUrl(baseUrl: string): this;
|
|
232
|
+
usePreset(name: string): this;
|
|
233
|
+
getKick(username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<LivestreamResult>;
|
|
234
|
+
getTwitch(username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<LivestreamResult>;
|
|
235
|
+
getDlive(username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<LivestreamResult>;
|
|
236
|
+
getTrovo(username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<LivestreamResult>;
|
|
237
|
+
getByPlatform(platform: string, username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<LivestreamResult>;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
export interface GamesClientOptions {
|
|
241
|
+
apiKey?: string;
|
|
242
|
+
baseUrl?: string;
|
|
243
|
+
preset?: string;
|
|
244
|
+
timeoutMs?: number;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export declare class GamesClient {
|
|
248
|
+
constructor(options?: GamesClientOptions);
|
|
249
|
+
useBaseUrl(baseUrl: string): this;
|
|
250
|
+
usePreset(name: string): this;
|
|
251
|
+
getClashOfClansClan(clanTag: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
252
|
+
getClashOfClansPlayer(playerTag: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
253
|
+
getDivision2Player(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
254
|
+
getFortnitePlayer(username: string, timeWindow?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
255
|
+
getFortniteCreatorCode(creatorCode: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
256
|
+
getFortniteItemShop(options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
257
|
+
getWynncraftProfile(username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
258
|
+
getHypixelProfile(username: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
259
|
+
getRocketLeaguePlayer(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
260
|
+
getApexLegendsPlayer(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
261
|
+
getBattlefield1Player(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
262
|
+
getBattlefield5Player(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
263
|
+
getBattlefield2042Player(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
264
|
+
getBattlefield6Player(username: string, platform?: string, options?: { apiKey?: string; timeoutMs?: number }): Promise<unknown>;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export declare const livestreamPresets: Record<string, string>;
|
|
268
|
+
export declare const gamesPresets: Record<string, string>;
|
|
153
269
|
|
|
154
270
|
export declare const upload: {
|
|
155
271
|
Client: typeof UploadClient;
|
|
@@ -169,6 +285,30 @@ export declare const video: {
|
|
|
169
285
|
};
|
|
170
286
|
};
|
|
171
287
|
|
|
288
|
+
export declare const downloader: {
|
|
289
|
+
Client: typeof DownloaderClient;
|
|
290
|
+
providers: {
|
|
291
|
+
compatible: unknown;
|
|
292
|
+
};
|
|
293
|
+
presets: typeof downloaderPresets;
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
export declare const livestream: {
|
|
297
|
+
Client: typeof LivestreamClient;
|
|
298
|
+
providers: {
|
|
299
|
+
nekosune: unknown;
|
|
300
|
+
};
|
|
301
|
+
presets: typeof livestreamPresets;
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export declare const games: {
|
|
305
|
+
Client: typeof GamesClient;
|
|
306
|
+
providers: {
|
|
307
|
+
nekosune: unknown;
|
|
308
|
+
};
|
|
309
|
+
presets: typeof gamesPresets;
|
|
310
|
+
};
|
|
311
|
+
|
|
172
312
|
export declare const earnings: {
|
|
173
313
|
Client: typeof EarningsClient;
|
|
174
314
|
};
|
package/src/index.js
CHANGED
|
@@ -2,6 +2,9 @@ const { UploadClient, providers: uploadProviders } = require("./upload/client");
|
|
|
2
2
|
const { EarningsClient, shortenerPresets } = require("./earnings");
|
|
3
3
|
const { providers: shorturlProviders } = require("./shorturl/providers");
|
|
4
4
|
const videoProviders = require("./video/providers");
|
|
5
|
+
const { DownloaderClient, presets: downloaderPresets, providers: downloaderProviders } = require("./downloader/client");
|
|
6
|
+
const { LivestreamClient, presets: livestreamPresets, providers: livestreamProviders } = require("./livestream/client");
|
|
7
|
+
const { GamesClient, presets: gamesPresets, providers: gamesProviders } = require("./games/client");
|
|
5
8
|
|
|
6
9
|
module.exports = {
|
|
7
10
|
upload: {
|
|
@@ -15,11 +18,32 @@ module.exports = {
|
|
|
15
18
|
video: {
|
|
16
19
|
providers: videoProviders
|
|
17
20
|
},
|
|
21
|
+
downloader: {
|
|
22
|
+
Client: DownloaderClient,
|
|
23
|
+
providers: downloaderProviders,
|
|
24
|
+
presets: downloaderPresets
|
|
25
|
+
},
|
|
26
|
+
livestream: {
|
|
27
|
+
Client: LivestreamClient,
|
|
28
|
+
providers: livestreamProviders,
|
|
29
|
+
presets: livestreamPresets
|
|
30
|
+
},
|
|
31
|
+
games: {
|
|
32
|
+
Client: GamesClient,
|
|
33
|
+
providers: gamesProviders,
|
|
34
|
+
presets: gamesPresets
|
|
35
|
+
},
|
|
18
36
|
earnings: {
|
|
19
37
|
Client: EarningsClient
|
|
20
38
|
},
|
|
21
39
|
UploadClient,
|
|
22
40
|
platforms: uploadProviders,
|
|
23
41
|
EarningsClient,
|
|
24
|
-
shortenerPresets
|
|
25
|
-
|
|
42
|
+
shortenerPresets,
|
|
43
|
+
DownloaderClient,
|
|
44
|
+
downloaderPresets,
|
|
45
|
+
LivestreamClient,
|
|
46
|
+
livestreamPresets,
|
|
47
|
+
GamesClient,
|
|
48
|
+
gamesPresets
|
|
49
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
const axios = require("axios");
|
|
2
|
+
const { presets, providers } = require("./providers");
|
|
3
|
+
|
|
4
|
+
class LivestreamClient {
|
|
5
|
+
constructor(options = {}) {
|
|
6
|
+
this.timeoutMs = options.timeoutMs || 60000;
|
|
7
|
+
this.apiKey = options.apiKey || null;
|
|
8
|
+
this.baseUrl = resolveBaseUrl(options.baseUrl, options.preset || "nekosune");
|
|
9
|
+
this.provider = providers.nekosune(this.baseUrl);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
useBaseUrl(baseUrl) {
|
|
13
|
+
this.baseUrl = resolveBaseUrl(baseUrl);
|
|
14
|
+
this.provider = providers.nekosune(this.baseUrl);
|
|
15
|
+
return this;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
usePreset(name) {
|
|
19
|
+
this.baseUrl = resolveBaseUrl(null, name);
|
|
20
|
+
this.provider = providers.nekosune(this.baseUrl);
|
|
21
|
+
return this;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
getKick(username, options = {}) {
|
|
25
|
+
return this.provider.getKick(this.buildContext(username, options));
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
getTwitch(username, options = {}) {
|
|
29
|
+
return this.provider.getTwitch(this.buildContext(username, options));
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
getDlive(username, options = {}) {
|
|
33
|
+
return this.provider.getDlive(this.buildContext(username, options));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
getTrovo(username, options = {}) {
|
|
37
|
+
return this.provider.getTrovo(this.buildContext(username, options));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
getByPlatform(platform, username, options = {}) {
|
|
41
|
+
return this.provider.getByPlatform({
|
|
42
|
+
...this.buildContext(username, options),
|
|
43
|
+
platform
|
|
44
|
+
}, platform);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
buildContext(username, options) {
|
|
48
|
+
return {
|
|
49
|
+
http: axios.create({ timeout: options.timeoutMs || this.timeoutMs }),
|
|
50
|
+
apiKey: options.apiKey || this.apiKey,
|
|
51
|
+
username
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function resolveBaseUrl(baseUrl, preset) {
|
|
57
|
+
if (baseUrl) {
|
|
58
|
+
return String(baseUrl).replace(/\/+$/, "");
|
|
59
|
+
}
|
|
60
|
+
if (preset && presets[preset]) {
|
|
61
|
+
return presets[preset];
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`Unknown livestream preset "${preset}". Available: ${Object.keys(presets).join(", ")}`);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
module.exports = {
|
|
67
|
+
LivestreamClient,
|
|
68
|
+
presets,
|
|
69
|
+
providers
|
|
70
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
function createLivestreamProvider(baseUrl) {
|
|
2
|
+
const root = String(baseUrl || "https://api.nekosunevr.co.uk").replace(/\/+$/, "");
|
|
3
|
+
|
|
4
|
+
async function getKick(context) {
|
|
5
|
+
return getByPlatform(context, "kick");
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
async function getTwitch(context) {
|
|
9
|
+
return getByPlatform(context, "twitch");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async function getDlive(context) {
|
|
13
|
+
return getByPlatform(context, "dlive");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async function getTrovo(context) {
|
|
17
|
+
return getByPlatform(context, "trovo");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async function getByPlatform(context, platform) {
|
|
21
|
+
const { http, apiKey, username } = context;
|
|
22
|
+
assertApiKey(apiKey);
|
|
23
|
+
if (!username) {
|
|
24
|
+
throw new Error(`Missing username for livestream platform "${platform}".`);
|
|
25
|
+
}
|
|
26
|
+
const response = await http.get(`${root}/v5/social/api/${platform}/${encodeURIComponent(username)}`, {
|
|
27
|
+
headers: buildHeaders(apiKey)
|
|
28
|
+
});
|
|
29
|
+
return response.data || {};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return {
|
|
33
|
+
getKick,
|
|
34
|
+
getTwitch,
|
|
35
|
+
getDlive,
|
|
36
|
+
getTrovo,
|
|
37
|
+
getByPlatform
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function assertApiKey(apiKey) {
|
|
42
|
+
if (!apiKey) {
|
|
43
|
+
throw new Error("Missing API key. Pass apiKey in client options or method options.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function buildHeaders(apiKey) {
|
|
48
|
+
return {
|
|
49
|
+
"nekosunevr-api-key": apiKey,
|
|
50
|
+
Authorization: `Bearer ${apiKey}`
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = {
|
|
55
|
+
createLivestreamProvider
|
|
56
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
const { createLivestreamProvider } = require("./provider/nekosune-api");
|
|
2
|
+
|
|
3
|
+
const presets = {
|
|
4
|
+
nekosune: "https://api.nekosunevr.co.uk"
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
const providers = {
|
|
8
|
+
nekosune: createLivestreamProvider
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
module.exports = {
|
|
12
|
+
presets,
|
|
13
|
+
providers
|
|
14
|
+
};
|