@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.
@@ -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
+ };