@neuroinfoapi-client/core 2.6.1 → 2.8.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.
@@ -78,6 +78,11 @@ export declare class NeuroInfoApiClient {
78
78
  * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/twitch.md#current-stream-status-1
79
79
  */
80
80
  getCurrentStream: () => Promise<ApiResult<TwitchStreamState>>;
81
+ /**
82
+ * Fetches the channels that are watched right now because a schedule entry takes place on them.
83
+ * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/twitch.md#schedule-linked-streams-1
84
+ */
85
+ getScheduleLinkedStreams: () => Promise<ApiResult<ScheduleLinkedStreamInfo[]>>;
81
86
  /**
82
87
  * Fetches all VODs (Video on Demand).
83
88
  * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/twitch.md#all-vods-1
@@ -137,6 +142,10 @@ export declare class NeuroInfoApiClient {
137
142
  * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/x-feed.md#endpoint
138
143
  */
139
144
  getXFeed: (user: XFeedAccount) => Promise<ApiResult<XFeedEntry[]>>;
145
+ /** Fetches the full shop catalog. Requires an API token. Prices optionally use the requested currency. */
146
+ getShopProducts: (currency?: string) => Promise<ApiResult<ShopProduct[]>>;
147
+ /** Fetches a shop product by ID. Requires an API token. Price currencyCode identifies the returned currency. */
148
+ getShopProduct: (id: string, currency?: string) => Promise<ApiResult<ShopProduct>>;
140
149
  }
141
150
  /**
142
151
  * Event-based wrapper for the NeuroInfo API.
@@ -325,6 +334,52 @@ export declare namespace Utils {
325
334
  function isScheduleEntryOffline(entry: ScheduleEntry): boolean;
326
335
  function isScheduleEntryUnknown(entry: ScheduleEntry): boolean;
327
336
  function hasScheduleImage(entry: ScheduleData): boolean;
337
+ /** The schedule entry takes place on this channel instead of the main channel, e.g. `(on secretneuroaccount) Evil Stream`. */
338
+ function isLinkTypeOn(data: {
339
+ linkType: ScheduleLinkType;
340
+ }): boolean;
341
+ /** The channel is linked as a collab partner, e.g. `w/ [Filian](...)`. */
342
+ function isLinkTypeCollab(data: {
343
+ linkType: ScheduleLinkType;
344
+ }): boolean;
345
+ /** The channel went live while it was watched. */
346
+ function isTriggerStreamStart(data: {
347
+ trigger: ScheduleLinkedStreamOnlineTrigger;
348
+ }): boolean;
349
+ /** The channel was already live when watching started (e.g. it started early or the server restarted). */
350
+ function isTriggerFetch(data: {
351
+ trigger: ScheduleLinkedStreamOnlineTrigger;
352
+ }): boolean;
353
+ /** The scheduled time was reached. Sent once per entry whether the channel is live or not, see {@link isLinkedStreamLive}. */
354
+ function isTriggerScheduleTime(data: {
355
+ trigger: ScheduleLinkedStreamOnlineTrigger;
356
+ }): boolean;
357
+ /** The stream ended. */
358
+ function isReasonStreamEnd(data: {
359
+ reason: ScheduleLinkedStreamOfflineReason;
360
+ }): boolean;
361
+ /** The channel did not go live after the scheduled time (collabs: 15 minutes after the main stream ended, otherwise after 4 hours). */
362
+ function isReasonNoShow(data: {
363
+ reason: ScheduleLinkedStreamOfflineReason;
364
+ }): boolean;
365
+ /** The schedule entry was removed while the channel was not live. */
366
+ function isReasonScheduleRemoved(data: {
367
+ reason: ScheduleLinkedStreamOfflineReason;
368
+ }): boolean;
369
+ /** The channel was still live at the maximum watch time; the stream may continue without further events. */
370
+ function isReasonTimeout(data: {
371
+ reason: ScheduleLinkedStreamOfflineReason;
372
+ }): boolean;
373
+ /** The linked stream actually happened, i.e. it was live at some point (`streamEnd` or `timeout`). */
374
+ function didLinkedStreamHappen(data: {
375
+ reason: ScheduleLinkedStreamOfflineReason;
376
+ }): boolean;
377
+ /** The channel is live. Narrows `stream` to the live data, e.g. for `scheduleTime` events or `getScheduleLinkedStreams()` entries. */
378
+ function isLinkedStreamLive<T extends {
379
+ stream: WsStreamOnlineData | WsStreamOfflineData;
380
+ }>(data: T): data is T & {
381
+ stream: WsStreamOnlineData;
382
+ };
328
383
  }
329
384
  export interface NeuroInfoApiBaseOptions {
330
385
  /** Host and API path without protocol. HTTP(S)/WS(S) protocols are accepted temporarily for compatibility and will be removed in a future major version. Default: `neuroinfoapi.dev/api/v2`. */
@@ -408,6 +463,58 @@ export interface WsStreamOnlineData extends StreamMetadata {
408
463
  export interface WsStreamOfflineData {
409
464
  isLive: false;
410
465
  }
466
+ /** Twitch channel a schedule entry takes place on. */
467
+ export interface ScheduleLinkedChannel {
468
+ id: string;
469
+ name: string;
470
+ displayName: string;
471
+ }
472
+ /**
473
+ * How a channel is linked in a schedule entry.
474
+ * - `on`: the entry explicitly takes place on that channel, e.g. `(on [secretneuroaccount](...)) Evil Stream`
475
+ * - `collab`: any other Twitch link, usually a collab partner, e.g. `w/ [Filian](...)`
476
+ */
477
+ export type ScheduleLinkType = "on" | "collab";
478
+ /**
479
+ * Why `scheduleLinkedStreamOnline` was sent.
480
+ * - `streamStart`: the channel went live while it was watched
481
+ * - `fetch`: the channel was already live when watching started
482
+ * - `scheduleTime`: the scheduled time was reached; always sent once per entry, check `stream.isLive`
483
+ */
484
+ export type ScheduleLinkedStreamOnlineTrigger = "streamStart" | "scheduleTime" | "fetch";
485
+ /** Why `scheduleLinkedStreamOffline` was sent. */
486
+ export type ScheduleLinkedStreamOfflineReason = "streamEnd" | "noShow" | "scheduleRemoved" | "timeout";
487
+ /** Event data for scheduleLinkedStreamOnline event. */
488
+ export interface WsScheduleLinkedStreamOnlineData {
489
+ trigger: ScheduleLinkedStreamOnlineTrigger;
490
+ channel: ScheduleLinkedChannel;
491
+ linkType: ScheduleLinkType;
492
+ scheduleEntry: ScheduleEntry;
493
+ stream: WsStreamOnlineData | WsStreamOfflineData;
494
+ }
495
+ /** Event data for scheduleLinkedStreamUpdate event. */
496
+ export interface WsScheduleLinkedStreamUpdateData {
497
+ channel: ScheduleLinkedChannel;
498
+ linkType: ScheduleLinkType;
499
+ scheduleEntry: ScheduleEntry;
500
+ stream: StreamMetadata;
501
+ }
502
+ /** Event data for scheduleLinkedStreamOffline event. */
503
+ export interface WsScheduleLinkedStreamOfflineData {
504
+ reason: ScheduleLinkedStreamOfflineReason;
505
+ channel: ScheduleLinkedChannel;
506
+ linkType: ScheduleLinkType;
507
+ scheduleEntry: ScheduleEntry;
508
+ stream: WsStreamOfflineData;
509
+ }
510
+ /** Entry of `GET /twitch/scheduleLinkedStreams`. */
511
+ export interface ScheduleLinkedStreamInfo {
512
+ status: "live" | "waiting";
513
+ channel: ScheduleLinkedChannel;
514
+ linkType: ScheduleLinkType;
515
+ scheduleEntry: ScheduleEntry;
516
+ stream: WsStreamOnlineData | WsStreamOfflineData;
517
+ }
411
518
  /** Event data for raid events. */
412
519
  export interface WsStreamRaidData {
413
520
  channel: {
@@ -485,8 +592,70 @@ export interface WsSubathonGoalUpdateData {
485
592
  goal: SubathonGoal;
486
593
  subcount: number;
487
594
  }
595
+ export interface ShopImage {
596
+ url: string;
597
+ altText: string | null;
598
+ width: number;
599
+ height: number;
600
+ }
601
+ export interface ShopMoney {
602
+ amount: string;
603
+ currencyCode: string;
604
+ }
605
+ export interface ShopProduct {
606
+ id: string;
607
+ title: string;
608
+ handle: string;
609
+ url: string;
610
+ description: string;
611
+ descriptionHtml: string;
612
+ vendor: string;
613
+ productType: string;
614
+ tags: string[];
615
+ availableForSale: boolean;
616
+ createdAt: number;
617
+ updatedAt: number;
618
+ publishedAt: number;
619
+ seo: {
620
+ title: string | null;
621
+ description: string | null;
622
+ };
623
+ options: {
624
+ name: string;
625
+ values: string[];
626
+ }[];
627
+ images: ShopImage[];
628
+ variants: {
629
+ id: string;
630
+ title: string;
631
+ sku: string | null;
632
+ availableForSale: boolean;
633
+ price: ShopMoney;
634
+ compareAtPrice: ShopMoney | null;
635
+ selectedOptions: {
636
+ name: string;
637
+ value: string;
638
+ }[];
639
+ image: ShopImage | null;
640
+ }[];
641
+ collections: {
642
+ id: string;
643
+ title: string;
644
+ }[];
645
+ metafields: {
646
+ namespace: string;
647
+ key: string;
648
+ type: string;
649
+ value: string;
650
+ reference: Record<string, unknown> | null;
651
+ }[];
652
+ }
653
+ export interface ShopProductsUpdateData {
654
+ products: ShopProduct[];
655
+ }
488
656
  /** Mapping of event types to their data structures. */
489
657
  export interface WsEventDataMap {
658
+ shopProductsUpdate: ShopProductsUpdateData;
490
659
  blogFeedUpdate: BlogFeedData;
491
660
  xFeedNewEntries: XFeedNewEntriesData;
492
661
  /** @deprecated Subscribe to xFeedNewEntries instead. */
@@ -495,6 +664,9 @@ export interface WsEventDataMap {
495
664
  streamOffline: WsStreamOfflineData;
496
665
  streamUpdate: StreamMetadata;
497
666
  secretneuroaccountOnline: WsStreamOnlineData;
667
+ scheduleLinkedStreamOnline: WsScheduleLinkedStreamOnlineData;
668
+ scheduleLinkedStreamUpdate: WsScheduleLinkedStreamUpdateData;
669
+ scheduleLinkedStreamOffline: WsScheduleLinkedStreamOfflineData;
498
670
  streamRaidIncoming: WsStreamRaidData;
499
671
  streamRaidOutgoing: WsStreamRaidData;
500
672
  scheduleUpdate: ScheduleData;
@@ -1,5 +1,5 @@
1
1
  const apiVersion = "v2";
2
- const clientVersion = "2.6.1";
2
+ const clientVersion = "2.8.0";
3
3
  const userAgent = `niac_js@${clientVersion}`;
4
4
  const defaultApiBaseUrl = `neuroinfoapi.dev/api/${apiVersion}`;
5
5
  function invokeSafely(callback, ...args) {
@@ -187,6 +187,11 @@ export class NeuroInfoApiClient {
187
187
  * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/twitch.md#current-stream-status-1
188
188
  */
189
189
  this.getCurrentStream = () => this.request("/twitch/stream");
190
+ /**
191
+ * Fetches the channels that are watched right now because a schedule entry takes place on them.
192
+ * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/twitch.md#schedule-linked-streams-1
193
+ */
194
+ this.getScheduleLinkedStreams = () => this.request("/twitch/scheduleLinkedStreams");
190
195
  /**
191
196
  * Fetches all VODs (Video on Demand).
192
197
  * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/twitch.md#all-vods-1
@@ -253,6 +258,10 @@ export class NeuroInfoApiClient {
253
258
  * @docs https://github.com/Appstun/NeuroInfoAPI-Docs/blob/master/x-feed.md#endpoint
254
259
  */
255
260
  this.getXFeed = (user) => this.request("/x-feed", { user });
261
+ /** Fetches the full shop catalog. Requires an API token. Prices optionally use the requested currency. */
262
+ this.getShopProducts = (currency) => this.request("/shop/products", currency === undefined ? undefined : { currency });
263
+ /** Fetches a shop product by ID. Requires an API token. Price currencyCode identifies the returned currency. */
264
+ this.getShopProduct = (id, currency) => this.request("/shop/product", { id, ...(currency === undefined ? {} : { currency }) });
256
265
  const apiUrl = options.apiBaseUrl != null ? createClientUrls(options.apiBaseUrl, options.useTls).api : (options.baseUrl ?? createClientUrls().api);
257
266
  this.apiInstance = new HttpClient({
258
267
  baseURL: apiUrl,
@@ -1237,8 +1246,65 @@ export var Utils;
1237
1246
  return entry.imageUrl !== null && entry.imageUrl.trim() !== "";
1238
1247
  }
1239
1248
  Utils.hasScheduleImage = hasScheduleImage;
1249
+ // ----- Schedule-linked streams -----
1250
+ /** The schedule entry takes place on this channel instead of the main channel, e.g. `(on secretneuroaccount) Evil Stream`. */
1251
+ function isLinkTypeOn(data) {
1252
+ return data.linkType === "on";
1253
+ }
1254
+ Utils.isLinkTypeOn = isLinkTypeOn;
1255
+ /** The channel is linked as a collab partner, e.g. `w/ [Filian](...)`. */
1256
+ function isLinkTypeCollab(data) {
1257
+ return data.linkType === "collab";
1258
+ }
1259
+ Utils.isLinkTypeCollab = isLinkTypeCollab;
1260
+ /** The channel went live while it was watched. */
1261
+ function isTriggerStreamStart(data) {
1262
+ return data.trigger === "streamStart";
1263
+ }
1264
+ Utils.isTriggerStreamStart = isTriggerStreamStart;
1265
+ /** The channel was already live when watching started (e.g. it started early or the server restarted). */
1266
+ function isTriggerFetch(data) {
1267
+ return data.trigger === "fetch";
1268
+ }
1269
+ Utils.isTriggerFetch = isTriggerFetch;
1270
+ /** The scheduled time was reached. Sent once per entry whether the channel is live or not, see {@link isLinkedStreamLive}. */
1271
+ function isTriggerScheduleTime(data) {
1272
+ return data.trigger === "scheduleTime";
1273
+ }
1274
+ Utils.isTriggerScheduleTime = isTriggerScheduleTime;
1275
+ /** The stream ended. */
1276
+ function isReasonStreamEnd(data) {
1277
+ return data.reason === "streamEnd";
1278
+ }
1279
+ Utils.isReasonStreamEnd = isReasonStreamEnd;
1280
+ /** The channel did not go live after the scheduled time (collabs: 15 minutes after the main stream ended, otherwise after 4 hours). */
1281
+ function isReasonNoShow(data) {
1282
+ return data.reason === "noShow";
1283
+ }
1284
+ Utils.isReasonNoShow = isReasonNoShow;
1285
+ /** The schedule entry was removed while the channel was not live. */
1286
+ function isReasonScheduleRemoved(data) {
1287
+ return data.reason === "scheduleRemoved";
1288
+ }
1289
+ Utils.isReasonScheduleRemoved = isReasonScheduleRemoved;
1290
+ /** The channel was still live at the maximum watch time; the stream may continue without further events. */
1291
+ function isReasonTimeout(data) {
1292
+ return data.reason === "timeout";
1293
+ }
1294
+ Utils.isReasonTimeout = isReasonTimeout;
1295
+ /** The linked stream actually happened, i.e. it was live at some point (`streamEnd` or `timeout`). */
1296
+ function didLinkedStreamHappen(data) {
1297
+ return data.reason === "streamEnd" || data.reason === "timeout";
1298
+ }
1299
+ Utils.didLinkedStreamHappen = didLinkedStreamHappen;
1300
+ /** The channel is live. Narrows `stream` to the live data, e.g. for `scheduleTime` events or `getScheduleLinkedStreams()` entries. */
1301
+ function isLinkedStreamLive(data) {
1302
+ return data.stream.isLive;
1303
+ }
1304
+ Utils.isLinkedStreamLive = isLinkedStreamLive;
1240
1305
  })(Utils || (Utils = {}));
1241
1306
  const wsEventTypes = new Set([
1307
+ "shopProductsUpdate",
1242
1308
  "blogFeedUpdate",
1243
1309
  "xFeedNewEntries",
1244
1310
  "xFeedUpdate",
@@ -1249,6 +1315,9 @@ const wsEventTypes = new Set([
1249
1315
  "streamUpdate",
1250
1316
  "streamOffline",
1251
1317
  "secretneuroaccountOnline",
1318
+ "scheduleLinkedStreamOnline",
1319
+ "scheduleLinkedStreamUpdate",
1320
+ "scheduleLinkedStreamOffline",
1252
1321
  "streamRaidIncoming",
1253
1322
  "streamRaidOutgoing",
1254
1323
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neuroinfoapi-client/core",
3
- "version": "2.6.1",
3
+ "version": "2.8.0",
4
4
  "description": "Shared HTTP client, types and WebSocket protocol logic for NeuroInfoAPI-Client (Bun, Node.js, Native)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -20,7 +20,6 @@
20
20
  "scripts": {
21
21
  "build": "tsc -b && node ../../scripts/helpers/setClientVersion.mjs",
22
22
  "typecheck": "tsc -p tsconfig.json --noEmit",
23
- "publishPackage": "powershell -NoProfile -ExecutionPolicy Bypass -File ../../scripts/publishAsk.ps1 -Package core",
24
23
  "deprecatePackage": "powershell -NoProfile -ExecutionPolicy Bypass -File ../../scripts/deprecateAsk.ps1 -Package core"
25
24
  },
26
25
  "publishConfig": {
@@ -30,11 +29,11 @@
30
29
  "license": "MIT",
31
30
  "repository": {
32
31
  "type": "git",
33
- "url": "https://github.com/NeuroInfoAPI/NPM-Package.git",
32
+ "url": "https://github.com/NeuroInfoAPI/NPM-Packages.git",
34
33
  "directory": "packages/core"
35
34
  },
36
35
  "bugs": {
37
- "url": "https://github.com/NeuroInfoAPI/NPM-Package/issues"
36
+ "url": "https://github.com/NeuroInfoAPI/NPM-Packages/issues"
38
37
  },
39
38
  "homepage": "https://neuroinfoapi.dev/api/docs"
40
39
  }