glitch-javascript-sdk 3.1.3 → 3.1.5

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.
@@ -882,6 +882,14 @@ class Scheduler {
882
882
  return Requests.processRoute(SchedulerRoute.routes.getTikTokTrendingKeywords, {}, { scheduler_id }, params);
883
883
  }
884
884
 
885
+ /**
886
+ * Get recommended search keywords on TikTok.
887
+ * @param params { is_personalized: boolean }
888
+ */
889
+ public static getTikTokRecommendedKeywords<T>(scheduler_id: string, params?: Record<string, any>): AxiosPromise<Response<T>> {
890
+ return Requests.processRoute(SchedulerRoute.routes.getTikTokRecommendedKeywords, {}, { scheduler_id }, params);
891
+ }
892
+
885
893
  }
886
894
 
887
895
  export default Scheduler;
@@ -0,0 +1,16 @@
1
+ import ServerOperationsRoute from "../routes/ServerOperationsRoute";
2
+ import Requests from "../util/Requests";
3
+ import Response from "../util/Response";
4
+ import { AxiosPromise } from "axios";
5
+
6
+ class ServerOperations {
7
+ public static listDeployments<T>(params?: Record<string, any>): AxiosPromise<Response<T>> {
8
+ return Requests.processRoute(ServerOperationsRoute.routes.listDeployments, undefined, undefined, params);
9
+ }
10
+
11
+ public static updatePolicy<T>(title_id: string, build_id: string, data: object): AxiosPromise<Response<T>> {
12
+ return Requests.processRoute(ServerOperationsRoute.routes.updatePolicy, data, { title_id, build_id });
13
+ }
14
+ }
15
+
16
+ export default ServerOperations;
package/src/api/Titles.ts CHANGED
@@ -3,6 +3,45 @@ import Requests from "../util/Requests";
3
3
  import Response from "../util/Response";
4
4
  import { AxiosPromise } from "axios";
5
5
 
6
+ export type GameReviewRecommendation = 'recommended' | 'not_recommended' | 'neutral';
7
+ export type GameReviewSentiment = 'positive' | 'mixed' | 'negative';
8
+ export type GameReviewVoteType = 'helpful' | 'funny' | 'detailed' | 'not_helpful';
9
+ export type GameReviewReportReason = 'abuse' | 'spam' | 'off_topic' | 'manipulation' | 'hate' | 'personal_info' | 'other';
10
+
11
+ export interface GameReviewRatings {
12
+ gameplay?: GameReviewSentiment;
13
+ performance?: GameReviewSentiment;
14
+ value?: GameReviewSentiment;
15
+ content?: GameReviewSentiment;
16
+ multiplayer?: GameReviewSentiment;
17
+ monetization?: GameReviewSentiment;
18
+ stability?: GameReviewSentiment;
19
+ localization?: GameReviewSentiment;
20
+ accessibility?: GameReviewSentiment;
21
+ }
22
+
23
+ export interface CreateGameReviewRequest {
24
+ recommendation: GameReviewRecommendation;
25
+ title: string;
26
+ body: string;
27
+ review_type?: 'first_impression' | 'full_review' | 'bug_performance_warning' | 'early_access_feedback' | 'multiplayer_community_feedback' | 'monetization_pricing_feedback' | 'changed_opinion_after_update';
28
+ liked?: string;
29
+ needs_work?: string;
30
+ audience?: string;
31
+ language?: string;
32
+ game_version?: string;
33
+ platform?: string;
34
+ acquisition_type?: 'purchased' | 'free_to_play' | 'free_copy' | 'promotional_key' | 'beta_key' | 'demo' | 'external_verified';
35
+ received_for_free?: boolean;
36
+ early_access?: boolean;
37
+ current_version_review?: boolean;
38
+ main_negative_reason?: 'bugs_crashes' | 'bad_performance' | 'not_enough_content' | 'misleading_marketing' | 'price_value' | 'monetization' | 'community_toxicity' | 'developer_business_decision' | 'localization' | 'server_network' | 'gameplay_design' | 'not_my_type' | 'other';
39
+ change_reason?: string;
40
+ ratings?: GameReviewRatings;
41
+ }
42
+
43
+ export type UpdateGameReviewRequest = Partial<CreateGameReviewRequest>;
44
+
6
45
  class Titles {
7
46
 
8
47
  /**
@@ -1226,8 +1265,9 @@ class Titles {
1226
1265
  * @param params
1227
1266
  * - window: number (hours, default 24)
1228
1267
  * - limit: number (default 10)
1268
+ * - is_nsfw: 1 for adult titles only, 0 for safe titles only
1229
1269
  */
1230
- public static getCommunityActivity<T>(params?: { window?: number, limit?: number }): AxiosPromise<Response<T>> {
1270
+ public static getCommunityActivity<T>(params?: { window?: number, limit?: number, is_nsfw?: number | boolean }): AxiosPromise<Response<T>> {
1231
1271
  return Requests.processRoute(TitlesRoute.routes.communityActivity, {}, {}, params);
1232
1272
  }
1233
1273
 
@@ -1238,8 +1278,9 @@ class Titles {
1238
1278
  * - type: 'influencer' (campaigns) or 'organic' (non-paid)
1239
1279
  * - window: number (hours, default 168)
1240
1280
  * - limit: number (default 10)
1281
+ * - is_nsfw: 1 for adult titles only, 0 for safe titles only
1241
1282
  */
1242
- public static getSocialTrending<T>(params: { type: 'influencer' | 'organic', window?: number, limit?: number }): AxiosPromise<Response<T>> {
1283
+ public static getSocialTrending<T>(params: { type: 'influencer' | 'organic', window?: number, limit?: number, is_nsfw?: number | boolean }): AxiosPromise<Response<T>> {
1243
1284
  return Requests.processRoute(TitlesRoute.routes.socialTrending, {}, {}, params);
1244
1285
  }
1245
1286
 
@@ -1249,8 +1290,9 @@ class Titles {
1249
1290
  * @param params
1250
1291
  * - limit: number (default 12)
1251
1292
  * - device_id: string (highly recommended for guest tracking)
1293
+ * - is_nsfw: 1 for adult titles only, 0 for safe titles only
1252
1294
  */
1253
- public static getDiscoveryQueue<T>(params?: { limit?: number, device_id?: string }): AxiosPromise<Response<T>> {
1295
+ public static getDiscoveryQueue<T>(params?: { limit?: number, device_id?: string, is_nsfw?: number | boolean }): AxiosPromise<Response<T>> {
1254
1296
  return Requests.processRoute(TitlesRoute.routes.discoveryQueue, {}, {}, params);
1255
1297
  }
1256
1298
 
@@ -1264,6 +1306,7 @@ class Titles {
1264
1306
  * - seed?: number (For consistent randomization)
1265
1307
  * - genres?: string[] (Filter by genre names)
1266
1308
  * - models?: string[] (premium, rental, subscription, free)
1309
+ * - is_nsfw?: 1 | 0 (1 for adult titles only, 0 for safe titles only)
1267
1310
  * - excluded_ids?: string[] (UUIDs to skip)
1268
1311
  * - page?: number
1269
1312
  * - per_page?: number
@@ -1314,6 +1357,76 @@ class Titles {
1314
1357
  public static wishlistDevices<T>(title_id: string, params?: Record<string, any>): AxiosPromise<Response<T>> {
1315
1358
  return Requests.processRoute(TitlesRoute.routes.wishlistDevices, undefined, { title_id }, params);
1316
1359
  }
1360
+
1361
+ /**
1362
+ * List public reviews for a title.
1363
+ *
1364
+ * @param title_id The UUID of the title.
1365
+ * @param params Optional filters: recommendation, language, current_version_only,
1366
+ * verified_only, platform, acquisition_type, complaint, playtime, sort, per_page.
1367
+ */
1368
+ public static listReviews<T>(title_id: string, params?: Record<string, any>): AxiosPromise<Response<T>> {
1369
+ return Requests.processRoute(TitlesRoute.routes.reviewsList, {}, { title_id }, params);
1370
+ }
1371
+
1372
+ /**
1373
+ * Get aggregate review scores and structured praise/complaint summaries.
1374
+ */
1375
+ public static reviewSummary<T>(title_id: string, params?: { language?: string }): AxiosPromise<Response<T>> {
1376
+ return Requests.processRoute(TitlesRoute.routes.reviewsSummary, {}, { title_id }, params);
1377
+ }
1378
+
1379
+ /**
1380
+ * Create the current user's review for a title. The backend verifies play/purchase eligibility.
1381
+ */
1382
+ public static createReview<T>(title_id: string, data: CreateGameReviewRequest): AxiosPromise<Response<T>> {
1383
+ return Requests.processRoute(TitlesRoute.routes.reviewsCreate, data, { title_id });
1384
+ }
1385
+
1386
+ /**
1387
+ * View a single review, including revision history when the backend includes it.
1388
+ */
1389
+ public static viewReview<T>(review_id: string, params?: Record<string, any>): AxiosPromise<Response<T>> {
1390
+ return Requests.processRoute(TitlesRoute.routes.reviewsShow, {}, { review_id }, params);
1391
+ }
1392
+
1393
+ /**
1394
+ * Update the current user's review and preserve a backend revision trail.
1395
+ */
1396
+ public static updateReview<T>(review_id: string, data: UpdateGameReviewRequest): AxiosPromise<Response<T>> {
1397
+ return Requests.processRoute(TitlesRoute.routes.reviewsUpdate, data, { review_id });
1398
+ }
1399
+
1400
+ /**
1401
+ * Delete the current user's review, or a title admin's moderated review.
1402
+ */
1403
+ public static deleteReview<T>(review_id: string): AxiosPromise<Response<T>> {
1404
+ return Requests.processRoute(TitlesRoute.routes.reviewsDelete, {}, { review_id });
1405
+ }
1406
+
1407
+ /**
1408
+ * Vote on a review as helpful, funny, detailed, or not helpful.
1409
+ */
1410
+ public static voteReview<T>(review_id: string, vote_type: GameReviewVoteType): AxiosPromise<Response<T>> {
1411
+ return Requests.processRoute(TitlesRoute.routes.reviewsVote, { vote_type }, { review_id });
1412
+ }
1413
+
1414
+ /**
1415
+ * Report a review for moderation.
1416
+ */
1417
+ public static reportReview<T>(review_id: string, data: { reason: GameReviewReportReason; notes?: string }): AxiosPromise<Response<T>> {
1418
+ return Requests.processRoute(TitlesRoute.routes.reviewsReport, data, { review_id });
1419
+ }
1420
+
1421
+ /**
1422
+ * Create or update the title developer's official response to a review.
1423
+ */
1424
+ public static respondToReview<T>(
1425
+ review_id: string,
1426
+ data: { body: string; linked_patch_note_id?: string; issue_marked_fixed?: boolean }
1427
+ ): AxiosPromise<Response<T>> {
1428
+ return Requests.processRoute(TitlesRoute.routes.reviewsDeveloperResponse, data, { review_id });
1429
+ }
1317
1430
  }
1318
1431
 
1319
- export default Titles;
1432
+ export default Titles;
package/src/api/index.ts CHANGED
@@ -42,6 +42,8 @@ import Raffles from "./Raffles";
42
42
  import DiscordMarketplace from "./DiscordMarketplace";
43
43
  import Education from "./Education";
44
44
  import Crm from "./Crm";
45
+ import Multiplayer from "./Multiplayer";
46
+ import ServerOperations from "./ServerOperations";
45
47
 
46
48
  export {Ads};
47
49
  export {AccessKeys};
@@ -86,4 +88,6 @@ export {TwitchReporting};
86
88
  export {Raffles};
87
89
  export {DiscordMarketplace};
88
90
  export {Education};
89
- export {Crm};
91
+ export {Crm};
92
+ export {Multiplayer};
93
+ export {ServerOperations};
@@ -1,8 +1,9 @@
1
1
  const HTTP_METHODS = {
2
2
  GET: 'GET',
3
3
  POST: 'POST',
4
+ PATCH: 'PATCH',
4
5
  PUT: 'PUT',
5
6
  DELETE: 'DELETE',
6
7
  } as const;
7
8
 
8
- export default HTTP_METHODS;
9
+ export default HTTP_METHODS;
package/src/index.ts CHANGED
@@ -46,6 +46,8 @@ import {Raffles} from './api'
46
46
  import {DiscordMarketplace} from './api';
47
47
  import {Education} from './api';
48
48
  import {Crm} from './api';
49
+ import {Multiplayer} from './api';
50
+ import {ServerOperations} from './api';
49
51
 
50
52
  import Requests from "./util/Requests";
51
53
  import Parser from "./util/Parser";
@@ -121,6 +123,8 @@ class Glitch {
121
123
  DiscordMarketplace : DiscordMarketplace,
122
124
  Education: Education,
123
125
  Crm : Crm,
126
+ Multiplayer : Multiplayer,
127
+ ServerOperations : ServerOperations,
124
128
  }
125
129
 
126
130
  public static util = {
@@ -153,4 +157,4 @@ class Glitch {
153
157
 
154
158
  }
155
159
 
156
- export default Glitch;
160
+ export default Glitch;
@@ -0,0 +1,46 @@
1
+ import Route from "./interface";
2
+ import HTTP_METHODS from "../constants/HttpMethods";
3
+
4
+ class MultiplayerRoute {
5
+
6
+ public static routes: { [key: string]: Route } = {
7
+ searchLobbies: { url: '/titles/{title_id}/multiplayer/lobbies', method: HTTP_METHODS.GET },
8
+ createLobby: { url: '/titles/{title_id}/multiplayer/lobbies', method: HTTP_METHODS.POST },
9
+ showLobby: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}', method: HTTP_METHODS.GET },
10
+ updateLobby: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}', method: HTTP_METHODS.PUT },
11
+ joinLobby: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}/join', method: HTTP_METHODS.POST },
12
+ leaveLobby: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}/leave', method: HTTP_METHODS.POST },
13
+ setLobbyServer: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}/server', method: HTTP_METHODS.POST },
14
+ listLobbyMessages: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}/messages', method: HTTP_METHODS.GET },
15
+ sendLobbyMessage: { url: '/titles/{title_id}/multiplayer/lobbies/{lobby_id}/messages', method: HTTP_METHODS.POST },
16
+
17
+ listVoiceRooms: { url: '/titles/{title_id}/multiplayer/voice/rooms', method: HTTP_METHODS.GET },
18
+ createVoiceRoom: { url: '/titles/{title_id}/multiplayer/voice/rooms', method: HTTP_METHODS.POST },
19
+ showVoiceRoom: { url: '/titles/{title_id}/multiplayer/voice/rooms/{voice_room_id}', method: HTTP_METHODS.GET },
20
+ updateVoiceRoom: { url: '/titles/{title_id}/multiplayer/voice/rooms/{voice_room_id}', method: HTTP_METHODS.PUT },
21
+ joinVoiceRoom: { url: '/titles/{title_id}/multiplayer/voice/rooms/{voice_room_id}/join', method: HTTP_METHODS.POST },
22
+ heartbeatVoice: { url: '/multiplayer/voice/heartbeat', method: HTTP_METHODS.POST },
23
+ leaveVoice: { url: '/multiplayer/voice/leave', method: HTTP_METHODS.POST },
24
+ sendVoicePacket: { url: '/multiplayer/voice/packets', method: HTTP_METHODS.POST },
25
+ pollVoicePackets: { url: '/multiplayer/voice/poll', method: HTTP_METHODS.POST },
26
+
27
+ browseServers: { url: '/titles/{title_id}/multiplayer/servers', method: HTTP_METHODS.GET },
28
+ registerServer: { url: '/titles/{title_id}/multiplayer/servers', method: HTTP_METHODS.POST },
29
+ heartbeatServer: { url: '/titles/{title_id}/multiplayer/servers/{server_id}/heartbeat', method: HTTP_METHODS.POST },
30
+ reserveServer: { url: '/titles/{title_id}/multiplayer/servers/{server_id}/reserve', method: HTTP_METHODS.POST },
31
+
32
+ heartbeatSession: { url: '/multiplayer/sessions/heartbeat', method: HTTP_METHODS.POST },
33
+ releaseSession: { url: '/multiplayer/sessions/release', method: HTTP_METHODS.POST },
34
+
35
+ issueAuthTicket: { url: '/titles/{title_id}/multiplayer/auth-tickets', method: HTTP_METHODS.POST },
36
+ validateAuthTicket: { url: '/titles/{title_id}/multiplayer/auth-tickets/validate', method: HTTP_METHODS.POST },
37
+ validateAuthTicketForServer: { url: '/titles/{title_id}/multiplayer/servers/{server_id}/auth-tickets/validate', method: HTTP_METHODS.POST },
38
+
39
+ listFavorites: { url: '/titles/{title_id}/multiplayer/favorites', method: HTTP_METHODS.GET },
40
+ addFavorite: { url: '/titles/{title_id}/multiplayer/favorites', method: HTTP_METHODS.POST },
41
+ deleteFavorite: { url: '/titles/{title_id}/multiplayer/favorites/{favorite_id}', method: HTTP_METHODS.DELETE },
42
+ };
43
+
44
+ }
45
+
46
+ export default MultiplayerRoute;
@@ -137,6 +137,7 @@ class SchedulerRoute {
137
137
  getTikTokTrendingHashtags: { url: '/schedulers/{scheduler_id}/tiktok/discovery/hashtags/trending', method: HTTP_METHODS.GET },
138
138
  getTikTokHashtagDetail: { url: '/schedulers/{scheduler_id}/tiktok/discovery/hashtags/detail', method: HTTP_METHODS.GET },
139
139
  getTikTokTrendingKeywords: { url: '/schedulers/{scheduler_id}/tiktok/discovery/search-keywords', method: HTTP_METHODS.GET },
140
+ getTikTokRecommendedKeywords: { url: '/schedulers/{scheduler_id}/tiktok/discovery/search-keywords/recommend', method: HTTP_METHODS.GET },
140
141
 
141
142
  };
142
143
  }
@@ -0,0 +1,17 @@
1
+ import Route from "./interface";
2
+ import HTTP_METHODS from "../constants/HttpMethods";
3
+
4
+ class ServerOperationsRoute {
5
+ public static routes: { [key: string]: Route } = {
6
+ listDeployments: {
7
+ url: '/admin/server-operations/deployments',
8
+ method: HTTP_METHODS.GET
9
+ },
10
+ updatePolicy: {
11
+ url: '/admin/server-operations/titles/{title_id}/builds/{build_id}/policy',
12
+ method: HTTP_METHODS.PUT
13
+ },
14
+ };
15
+ }
16
+
17
+ export default ServerOperationsRoute;
@@ -301,8 +301,19 @@ class TitlesRoute {
301
301
  wishlistGeo: { url: '/titles/{title_id}/wishlist/geo', method: HTTP_METHODS.GET },
302
302
  wishlistDevices: { url: '/titles/{title_id}/wishlist/devices', method: HTTP_METHODS.GET },
303
303
 
304
+ // Game Reviews
305
+ reviewsList: { url: '/titles/{title_id}/reviews', method: HTTP_METHODS.GET },
306
+ reviewsSummary: { url: '/titles/{title_id}/review-summary', method: HTTP_METHODS.GET },
307
+ reviewsCreate: { url: '/titles/{title_id}/reviews', method: HTTP_METHODS.POST },
308
+ reviewsShow: { url: '/reviews/{review_id}', method: HTTP_METHODS.GET },
309
+ reviewsUpdate: { url: '/reviews/{review_id}', method: HTTP_METHODS.PATCH },
310
+ reviewsDelete: { url: '/reviews/{review_id}', method: HTTP_METHODS.DELETE },
311
+ reviewsVote: { url: '/reviews/{review_id}/vote', method: HTTP_METHODS.POST },
312
+ reviewsReport: { url: '/reviews/{review_id}/report', method: HTTP_METHODS.POST },
313
+ reviewsDeveloperResponse: { url: '/reviews/{review_id}/developer-response', method: HTTP_METHODS.POST },
314
+
304
315
  };
305
316
 
306
317
  }
307
318
 
308
- export default TitlesRoute;
319
+ export default TitlesRoute;
@@ -29,7 +29,7 @@ class Requests {
29
29
  }
30
30
 
31
31
  private static request<T>(
32
- method: 'GET' | 'POST' | 'PUT' | 'DELETE',
32
+ method: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE',
33
33
  url: string,
34
34
  data?: any,
35
35
  fileData?: any
@@ -119,6 +119,24 @@ class Requests {
119
119
  return Requests.request<T>('PUT', url, data);
120
120
  }
121
121
 
122
+ public static patch<T>(url: string, data: any, params?: Record<string, any>): AxiosPromise<Response<T>> {
123
+ if (params && Object.keys(params).length > 0) {
124
+ const queryString = Object.entries(params)
125
+ .map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
126
+ .join('&');
127
+ url = `${url}?${queryString}`;
128
+ }
129
+
130
+ if (Requests.community_id) {
131
+ data = {
132
+ ...data,
133
+ community_id: Requests.community_id,
134
+ };
135
+ }
136
+
137
+ return Requests.request<T>('PATCH', url, data);
138
+ }
139
+
122
140
  public static delete<T>(url: string, params?: Record<string, any>): AxiosPromise<Response<T>> {
123
141
  if (params && Object.keys(params).length > 0) {
124
142
  const queryString = Object.entries(params)
@@ -323,6 +341,8 @@ class Requests {
323
341
  return Requests.get(url, params);
324
342
  } else if (route.method == HTTP_METHODS.POST) {
325
343
  return Requests.post(url, data, params);
344
+ } else if (route.method == HTTP_METHODS.PATCH) {
345
+ return Requests.patch(url, data, params);
326
346
  } else if (route.method == HTTP_METHODS.PUT) {
327
347
  return Requests.put(url, data, params);
328
348
  } else if (route.method == HTTP_METHODS.DELETE) {