smule.js 1.1.1 → 1.2.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/dist/index.cjs CHANGED
@@ -49,7 +49,9 @@ __export(index_exports, {
49
49
  SingUserProfileRequest: () => SingUserProfileRequest,
50
50
  Smule: () => Smule,
51
51
  SmuleDotCom: () => SmuleDotCom,
52
+ SmuleEffects: () => SmuleEffects,
52
53
  SmuleErrorCode: () => SmuleErrorCode,
54
+ SmuleRegisterErrorCode: () => SmuleRegisterErrorCode,
53
55
  SmuleSession: () => SmuleSession,
54
56
  SmuleUrls: () => SmuleUrls,
55
57
  SmuleUserSinging: () => SmuleUserSinging,
@@ -190,8 +192,8 @@ var LoginAsGuestRequest = class {
190
192
  }
191
193
  };
192
194
  var LoginRequest = class {
195
+ loginCommon = new LoginCommonData();
193
196
  data = {
194
- ...new LoginCommonData(),
195
197
  email: "",
196
198
  password: ""
197
199
  };
@@ -199,10 +201,13 @@ var LoginRequest = class {
199
201
  this.data.email = email;
200
202
  this.data.password = password;
201
203
  if (loginCommon)
202
- this.data = { ...this.data, ...loginCommon };
204
+ this.loginCommon = loginCommon;
203
205
  }
204
206
  toJSON() {
205
- return this.data;
207
+ return {
208
+ ...this.loginCommon,
209
+ ...this.data
210
+ };
206
211
  }
207
212
  };
208
213
  var SearchRequest = class {
@@ -577,7 +582,14 @@ var SmuleErrorCode = {
577
582
  1012: "VIP required",
578
583
  1013: "Subscription error / VIP required",
579
584
  10: "No result?",
580
- 1052: "Not enough coins"
585
+ 1052: "Not enough coins",
586
+ 2017: "Group waiting period not expired",
587
+ // unsure what this actually means
588
+ 2013: "Banned from group",
589
+ 1044: "Group join limit reached"
590
+ };
591
+ var SmuleRegisterErrorCode = {
592
+ 13: "Account already exists"
581
593
  };
582
594
 
583
595
  // src/util.ts
@@ -673,6 +685,23 @@ var SmuleUtil;
673
685
  return subApps.filter((s) => ["sing_google", "sing"].includes(s)).length > 0;
674
686
  }
675
687
  SmuleUtil2.isVIP = isVIP;
688
+ function getGroupMembershipType(membership) {
689
+ switch (membership) {
690
+ case 1:
691
+ return "ADMIN";
692
+ case 2:
693
+ return "MEMBER";
694
+ case 3:
695
+ return "PENDING_INVTN";
696
+ case 4:
697
+ return "PENDING_RQST";
698
+ case 5:
699
+ return "GUEST";
700
+ default:
701
+ return "UNKNOWN";
702
+ }
703
+ }
704
+ SmuleUtil2.getGroupMembershipType = getGroupMembershipType;
676
705
  function getFilesFromArr(arr) {
677
706
  return {
678
707
  preview: arr.normResources.find((r) => r.role == "preview")?.url,
@@ -1013,6 +1042,7 @@ var SmuleUrls;
1013
1042
  SmuleUrls2.SfamMembershipInvitationReject = SmuleUrls2.baseUrl + "/sfam/mbrship/invtn/reject";
1014
1043
  SmuleUrls2.SfamMembershipInvitationSend = SmuleUrls2.baseUrl + "/sfam/mbrship/invtn/send";
1015
1044
  SmuleUrls2.SfamMembershipRequestRoles = SmuleUrls2.baseUrl + "/sfam/mbrship/rqst/roles";
1045
+ SmuleUrls2.SfamMembershipRequestSend = SmuleUrls2.baseUrl + "/sfam/mbrship/rqst/send";
1016
1046
  SmuleUrls2.SfamPostAdd = SmuleUrls2.baseUrl + "/sfam/post/add";
1017
1047
  SmuleUrls2.SfamPostFeed = SmuleUrls2.baseUrl + "/sfam/post/feed";
1018
1048
  SmuleUrls2.SfamPostRemove = SmuleUrls2.baseUrl + "/sfam/post/remove";
@@ -1059,6 +1089,7 @@ var SmuleUrls;
1059
1089
  SmuleUrls2.UserLogin = SmuleUrls2.baseUrl + "/user/login";
1060
1090
  SmuleUrls2.UserLookup = SmuleUrls2.baseUrl + "/user/lookup";
1061
1091
  SmuleUrls2.UserPasswordReset = SmuleUrls2.baseUrl + "/user/password/reset";
1092
+ SmuleUrls2.UserPersonalUpdate = SmuleUrls2.baseUrl + "/user/personal/update";
1062
1093
  SmuleUrls2.UserProfileUpdate = SmuleUrls2.baseUrl + "/user/personal/update";
1063
1094
  SmuleUrls2.UserPhoneConnect = SmuleUrls2.baseUrl + "/user/phone/connect";
1064
1095
  SmuleUrls2.UserPictureDelete = SmuleUrls2.baseUrl + "/user/picture/delete";
@@ -1295,6 +1326,7 @@ var SmuleUrls;
1295
1326
  SmuleUrls2.UserEmailUpdateConfirm,
1296
1327
  SmuleUrls2.UserEmailUpdateResend,
1297
1328
  SmuleUrls2.UserPasswordReset,
1329
+ SmuleUrls2.UserPersonalUpdate,
1298
1330
  SmuleUrls2.UserProfileUpdate,
1299
1331
  SmuleUrls2.UserPhoneConnect,
1300
1332
  SmuleUrls2.UserPictureDelete,
@@ -2674,7 +2706,7 @@ var SmuleDigest;
2674
2706
  SmuleDigest2._calculateDigest = _calculateDigest;
2675
2707
  function _getDigestParameters(parameters, needsSession = false, isGetRequest = false, multiPartBody = null) {
2676
2708
  let neededParameters = {};
2677
- let required = ["appVersion", "app", "appVariant", "msgId"];
2709
+ const required = ["appVersion", "app", "appVariant", "msgId"];
2678
2710
  if (needsSession) required.push("session");
2679
2711
  for (let param of required) {
2680
2712
  if (!parameters[param])
@@ -2758,7 +2790,7 @@ var Smule = class {
2758
2790
  }
2759
2791
  }
2760
2792
  if (response.request && response.request.path) {
2761
- _warn(`[${response.request.path}] Got ${response.status} - ${response.statusText}`);
2793
+ _warn(`[${response.request.path}] Got ${response.status} - ${response.status == 418 ? "Unauthorized" : response.statusText}`);
2762
2794
  _warn(response.data);
2763
2795
  } else {
2764
2796
  _warn(`[NO REQUEST?] Got ${response.status} - ${response.statusText}`);
@@ -2766,9 +2798,10 @@ var Smule = class {
2766
2798
  }
2767
2799
  return false;
2768
2800
  },
2769
- _createRequestMultiPart: async (url, pop, body, checkSession = true) => {
2801
+ _createRequestMultiPart: async (url, body, pop, checkSession = true) => {
2770
2802
  let params = new URLSearchParams();
2771
- params.append("pop", pop);
2803
+ if (pop)
2804
+ params.append("pop", pop);
2772
2805
  if (checkSession && this.session && this.session.sessionToken && !this.session.expired) {
2773
2806
  params.append("session", decodeURIComponent(this.session.sessionToken));
2774
2807
  }
@@ -2827,7 +2860,7 @@ var Smule = class {
2827
2860
  _error("You cannot create a new performance as a guest");
2828
2861
  return;
2829
2862
  }
2830
- let req = await this.internal._createRequest(SmuleUrls.PerfPreupload, new PreuploadRequest(arrKey, compType, ensembleType, uploadType, false, seedKey));
2863
+ const req = await this.internal._createRequest(SmuleUrls.PerfPreupload, new PreuploadRequest(arrKey, compType, ensembleType, uploadType, false, seedKey));
2831
2864
  if (!this.internal._handleNon200(req)) return;
2832
2865
  return this.internal._getResponseData(req);
2833
2866
  },
@@ -2840,7 +2873,7 @@ var Smule = class {
2840
2873
  _error("You cannot create a new performance as a guest");
2841
2874
  return;
2842
2875
  }
2843
- let req = await this.internal._createRequest(SmuleUrls.PerfCreate, perfReq);
2876
+ const req = await this.internal._createRequest(SmuleUrls.PerfCreate, perfReq);
2844
2877
  if (!this.internal._handleNon200(req)) return;
2845
2878
  return this.internal._getResponseData(req);
2846
2879
  },
@@ -2853,7 +2886,7 @@ var Smule = class {
2853
2886
  _error("You cannot join a new performance as a guest");
2854
2887
  return;
2855
2888
  }
2856
- let req = await this.internal._createRequest(SmuleUrls.PerfJoin, perfReq);
2889
+ const req = await this.internal._createRequest(SmuleUrls.PerfJoin, perfReq);
2857
2890
  if (!this.internal._handleNon200(req)) return;
2858
2891
  return this.internal._getResponseData(req);
2859
2892
  },
@@ -2871,15 +2904,15 @@ var Smule = class {
2871
2904
  form.set("file1", file1, "application/octet-stream", "hi..m4a");
2872
2905
  form.set("file2", file2, "application/octet-stream", "hi.." + (file3 ? ".jpg" : ".bin"));
2873
2906
  if (file3) form.set("file3", file3, "application/octet-stream", "hi..bin");
2874
- let req = await this.internal._createRequestMultiPart(SmuleUrls.getPerformanceUploadUrl(host), pop, form);
2907
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.getPerformanceUploadUrl(host), form, pop);
2875
2908
  this.internal._handleNon200(req);
2876
2909
  },
2877
2910
  _logreccomplete: async (arrKey) => {
2878
- let req = await this.internal._createRequest(SmuleUrls.PerformanceLogRecCompletedArr, { arrKey });
2911
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceLogRecCompletedArr, { arrKey });
2879
2912
  this.internal._handleNon200(req);
2880
2913
  },
2881
2914
  _storeStreamLog: async (arrKey) => {
2882
- let req = await this.internal._createRequest(SmuleUrls.StoreStreamLog, {
2915
+ const req = await this.internal._createRequest(SmuleUrls.StoreStreamLog, {
2883
2916
  productId: arrKey,
2884
2917
  productType: "ARR",
2885
2918
  type: "own"
@@ -2916,7 +2949,7 @@ var Smule = class {
2916
2949
  * @returns The user's data
2917
2950
  */
2918
2951
  byEmail: async (email) => {
2919
- let req = await this.internal._createRequest(SmuleUrls.UserLookup, { email }, false, false);
2952
+ const req = await this.internal._createRequest(SmuleUrls.UserLookup, { email }, false, false);
2920
2953
  if (!this.internal._handleNon200(req)) return;
2921
2954
  return this.internal._getResponseData(req);
2922
2955
  },
@@ -2926,7 +2959,7 @@ var Smule = class {
2926
2959
  * @returns The accounts' details
2927
2960
  */
2928
2961
  byIds: async (accountIds) => {
2929
- let req = await this.internal._createRequest(SmuleUrls.AccountLookup, { accountIds });
2962
+ const req = await this.internal._createRequest(SmuleUrls.AccountLookup, { accountIds });
2930
2963
  if (!this.internal._handleNon200(req)) return;
2931
2964
  return this.internal._getResponseData(req);
2932
2965
  },
@@ -2938,6 +2971,11 @@ var Smule = class {
2938
2971
  byId: async (accountId) => {
2939
2972
  let data = await this.account.lookup.byIds([accountId]);
2940
2973
  return data.accountIcons[0];
2974
+ },
2975
+ byContacts: async (contacts) => {
2976
+ const req = await this.internal._createRequest(SmuleUrls.ContactFind, { contacts, simCountryCode: "" });
2977
+ if (!this.internal._handleNon200(req)) return;
2978
+ return this.internal._getResponseData(req);
2941
2979
  }
2942
2980
  },
2943
2981
  /**
@@ -2945,7 +2983,7 @@ var Smule = class {
2945
2983
  * @returns Whether or not the login was successful
2946
2984
  */
2947
2985
  loginAsGuest: async () => {
2948
- let req = await this.internal._createRequest(SmuleUrls.LoginGuest, new LoginAsGuestRequest(), false, false);
2986
+ const req = await this.internal._createRequest(SmuleUrls.LoginGuest, new LoginAsGuestRequest(), false, false);
2949
2987
  if (!this.internal._handleNon200(req)) return false;
2950
2988
  let res = this.internal._getResponseData(req);
2951
2989
  this.session.sessionToken = res.loginResult.sessionToken;
@@ -2962,7 +3000,7 @@ var Smule = class {
2962
3000
  * @returns Whether the log in was successful
2963
3001
  */
2964
3002
  login: async (email, password) => {
2965
- let req = await this.internal._createRequest(SmuleUrls.UserLogin, new LoginRequest(email, password), false, false);
3003
+ const req = await this.internal._createRequest(SmuleUrls.UserLogin, new LoginRequest(email, password, new LoginCommonData(this.session.device)), false, false);
2966
3004
  if (!this.internal._handleNon200(req)) return false;
2967
3005
  let res = this.internal._getResponseData(req);
2968
3006
  this.session.sessionToken = res.sessionToken;
@@ -2989,7 +3027,7 @@ var Smule = class {
2989
3027
  _warn("Refreshing login although session isnt expired?");
2990
3028
  this.session.expired = true;
2991
3029
  }
2992
- let req = await this.internal._createRequest(SmuleUrls.LoginRefresh, { common: new LoginCommonData(this.session.device), refreshToken: this.session.refreshToken }, false, false);
3030
+ const req = await this.internal._createRequest(SmuleUrls.LoginRefresh, { common: new LoginCommonData(this.session.device), refreshToken: this.session.refreshToken }, false, false);
2993
3031
  if (!this.internal._handleNon200(req)) return false;
2994
3032
  let res = this.internal._getResponseData(req);
2995
3033
  this.session.sessionToken = res.loginResult.sessionToken;
@@ -3010,7 +3048,7 @@ var Smule = class {
3010
3048
  * @returns Your profile
3011
3049
  */
3012
3050
  fetchSelf: async () => {
3013
- let req = await this.internal._createRequest(SmuleUrls.SingUserProfileMe, { includeActiveState: false });
3051
+ const req = await this.internal._createRequest(SmuleUrls.SingUserProfileMe, { includeActiveState: false });
3014
3052
  if (!this.internal._handleNon200(req)) return;
3015
3053
  return this.internal._getResponseData(req);
3016
3054
  },
@@ -3020,9 +3058,166 @@ var Smule = class {
3020
3058
  * @returns The user's details
3021
3059
  */
3022
3060
  fetchOne: async (accountId) => {
3023
- let req = await this.internal._createRequest(SmuleUrls.SingUserProfile, new SingUserProfileRequest(accountId));
3061
+ const req = await this.internal._createRequest(SmuleUrls.SingUserProfile, new SingUserProfileRequest(accountId));
3062
+ if (!this.internal._handleNon200(req)) return;
3063
+ return this.internal._getResponseData(req);
3064
+ },
3065
+ /**
3066
+ * Registers a new account on smule
3067
+ * @param email Your email address
3068
+ * @param password Your password
3069
+ * @returns The server response
3070
+ */
3071
+ createWithEmail: async (email, password) => {
3072
+ const req = await this.internal._createRequest(SmuleUrls.UserEmailRegister, {
3073
+ ...new LoginCommonData(this.session.device),
3074
+ ageParams: {
3075
+ enteredBirthMonth: null,
3076
+ enteredBirthYear: null,
3077
+ birthDateRequired: false
3078
+ },
3079
+ email,
3080
+ password,
3081
+ emailVerificationRequired: null,
3082
+ preferredLang: "en",
3083
+ tzOffset: (/* @__PURE__ */ new Date()).getTimezoneOffset() * -60
3084
+ }, false, false);
3085
+ if (!this.internal._handleNon200(req)) {
3086
+ if ("reason" in req.data) {
3087
+ throw new Error("Registration error: " + SmuleRegisterErrorCode[req.data.reason] || req.data.reason);
3088
+ }
3089
+ }
3090
+ const data = this.internal._getResponseData(req);
3091
+ this.session.sessionToken = data.sessionToken;
3092
+ this.session.refreshToken = data.refreshToken;
3093
+ this.session.expired = false;
3094
+ this.session.isGuest = false;
3095
+ return data;
3096
+ },
3097
+ /**
3098
+ * Uploads a profile picture
3099
+ * @param imageData The image data (jpeg)
3100
+ * @returns The server response
3101
+ */
3102
+ uploadProfilePicture: async (imageData) => {
3103
+ const form = new CustomFormData();
3104
+ form.set("picture", imageData, "image/jpeg", "profile.jpg");
3105
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.UserUploadPicture, form);
3024
3106
  if (!this.internal._handleNon200(req)) return;
3025
3107
  return this.internal._getResponseData(req);
3108
+ },
3109
+ /**
3110
+ * Deletes your profile picture
3111
+ */
3112
+ deleteProfilePicture: async () => {
3113
+ const req = await this.internal._createRequest(SmuleUrls.UserPictureDelete, {});
3114
+ if (!this.internal._handleNon200(req)) return;
3115
+ },
3116
+ /**
3117
+ * Uploads a cover picture
3118
+ * @param imageData The image data
3119
+ * @remarks Requires VIP
3120
+ */
3121
+ uploadCoverPicture: async (imageData) => {
3122
+ const form = new CustomFormData();
3123
+ form.set("coverPhoto", imageData, "image/jpeg", "coverPhoto.jpg");
3124
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.SingCoverPhotoUpload, form);
3125
+ if (!this.internal._handleNon200(req)) return;
3126
+ },
3127
+ /**
3128
+ * Deletes your cover picture
3129
+ * @remarks Requires VIP
3130
+ */
3131
+ deleteCoverPicture: async () => {
3132
+ const req = await this.internal._createRequest(SmuleUrls.SingCoverPhotoDelete, {});
3133
+ if (!this.internal._handleNon200(req)) return;
3134
+ },
3135
+ /**
3136
+ * Changes your username
3137
+ * @param username The new username
3138
+ */
3139
+ changeUsername: async (username) => {
3140
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, {
3141
+ handle: username
3142
+ });
3143
+ this.internal._handleNon200(req);
3144
+ },
3145
+ /**
3146
+ * Changes your email
3147
+ * @param email The new email
3148
+ */
3149
+ changeEmail: async (email) => {
3150
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, {
3151
+ email
3152
+ });
3153
+ this.internal._handleNon200(req);
3154
+ },
3155
+ /**
3156
+ * Changes your bio
3157
+ * @param text The new bio
3158
+ */
3159
+ changeBio: async (text) => {
3160
+ const req = await this.internal._createRequest(SmuleUrls.UserBlurbUpdate, { blurb: text });
3161
+ this.internal._handleNon200(req);
3162
+ },
3163
+ /**
3164
+ * Customize your VIP profile
3165
+ * @param colorTheme The background and foreground colors (RRGGBB hex), and whether the text should be white or black
3166
+ * @param displayMentions Whether to display mentions
3167
+ * @param displayName Your new display name
3168
+ * @remarks Requires VIP
3169
+ */
3170
+ changeVIPProfileStuff: async (colorTheme, displayMentions, displayName) => {
3171
+ const req = await this.internal._createRequest(SmuleUrls.SingProfileUpdate, { colorTheme, displayName, displayMentions });
3172
+ this.internal._handleNon200(req);
3173
+ },
3174
+ /**
3175
+ * Changes your full name
3176
+ * @param firstName Your first name
3177
+ * @param lastName Your last name
3178
+ */
3179
+ changeFullName: async (firstName, lastName) => {
3180
+ const req = await this.internal._createRequest(SmuleUrls.UserPersonalUpdate, { firstName, lastName });
3181
+ this.internal._handleNon200(req);
3182
+ },
3183
+ /**
3184
+ * Changes your password
3185
+ * @param newPassword The new password
3186
+ */
3187
+ changePassword: async (newPassword) => {
3188
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, { password: newPassword });
3189
+ this.internal._handleNon200(req);
3190
+ },
3191
+ /**
3192
+ * @returns Your preferences
3193
+ */
3194
+ fetchPreferences: async () => {
3195
+ const req = await this.internal._createRequest(SmuleUrls.Pref, { names: [
3196
+ "TRACK_ACTIVENESS_DISABLE",
3197
+ // reverse "Show Chat Activity Status"
3198
+ "PROFILE_PRIVACY_MODE",
3199
+ // reverse "Show My Online Status"
3200
+ "STUDIO_TRACK_VIEW_DISABLE"
3201
+ // "Visible In Style Studio Editor"
3202
+ ] });
3203
+ if (!this.internal._handleNon200(req)) return;
3204
+ return this.internal._getResponseData(req);
3205
+ },
3206
+ /**
3207
+ * Changes your preferences
3208
+ * @param preferences The modified preferences
3209
+ */
3210
+ changePreferences: async (preferences) => {
3211
+ const req = await this.internal._createRequest(SmuleUrls.PrefUpdate, { prefs: preferences });
3212
+ this.internal._handleNon200(req);
3213
+ },
3214
+ /**
3215
+ * Changes whether you wish to receive newsletter emails
3216
+ * @param consent Whether to consent
3217
+ */
3218
+ changeNewsletterConsent: async (consent) => {
3219
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, { newsletter: consent ? 1 : 0 });
3220
+ this.internal._handleNon200(req);
3026
3221
  }
3027
3222
  };
3028
3223
  /**
@@ -3045,7 +3240,7 @@ var Smule = class {
3045
3240
  * @returns idk
3046
3241
  */
3047
3242
  create: async (address, type = "ACCT") => {
3048
- let req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { add: [{ name: address, type }], remove: [] });
3243
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { add: [{ name: address, type }], remove: [] });
3049
3244
  if (!this.internal._handleNon200(req)) return;
3050
3245
  return this.internal._getResponseData(req);
3051
3246
  },
@@ -3198,7 +3393,7 @@ var Smule = class {
3198
3393
  * @returns The users you're following, and the one's you aren't
3199
3394
  */
3200
3395
  isFollowingUsers: async (accountIds) => {
3201
- let req = await this.internal._createRequest(SmuleUrls.SocialIsFollowing, new IsFollowingRequest(accountIds));
3396
+ const req = await this.internal._createRequest(SmuleUrls.SocialIsFollowing, new IsFollowingRequest(accountIds));
3202
3397
  if (!this.internal._handleNon200(req)) return;
3203
3398
  return this.internal._getResponseData(req);
3204
3399
  },
@@ -3215,7 +3410,7 @@ var Smule = class {
3215
3410
  * @param accountIds The ids of the accounts to follow.
3216
3411
  */
3217
3412
  followUsers: async (accountIds) => {
3218
- let req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest(accountIds, []));
3413
+ const req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest(accountIds, []));
3219
3414
  this.internal._handleNon200(req);
3220
3415
  },
3221
3416
  /**
@@ -3230,7 +3425,7 @@ var Smule = class {
3230
3425
  * @param accountIds The ids of the accounts to unfollow.
3231
3426
  */
3232
3427
  unfollowUsers: async (accountIds) => {
3233
- let req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest([], accountIds));
3428
+ const req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest([], accountIds));
3234
3429
  this.internal._handleNon200(req);
3235
3430
  },
3236
3431
  /**
@@ -3248,7 +3443,7 @@ var Smule = class {
3248
3443
  * @remarks Followee = Following
3249
3444
  */
3250
3445
  fetchFollowings: async (accountId) => {
3251
- let req = await this.internal._createRequest(SmuleUrls.SocialFollowee, { accountId });
3446
+ const req = await this.internal._createRequest(SmuleUrls.SocialFollowee, { accountId });
3252
3447
  if (!this.internal._handleNon200(req)) return;
3253
3448
  return this.internal._getResponseData(req);
3254
3449
  },
@@ -3259,7 +3454,7 @@ var Smule = class {
3259
3454
  * @remarks Smule returns the ENTIRE list of followers, nonpaginated, so make sure you use it wisely
3260
3455
  */
3261
3456
  fetchFollowers: async (accountId) => {
3262
- let req = await this.internal._createRequest(SmuleUrls.SocialFollower, { accountId });
3457
+ const req = await this.internal._createRequest(SmuleUrls.SocialFollower, { accountId });
3263
3458
  if (!this.internal._handleNon200(req)) return;
3264
3459
  return this.internal._getResponseData(req);
3265
3460
  },
@@ -3275,7 +3470,7 @@ var Smule = class {
3275
3470
  _error("Offset must be positive");
3276
3471
  return;
3277
3472
  }
3278
- let req = await this.internal._createRequest(SmuleUrls.PerformanceGetComments, {
3473
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceGetComments, {
3279
3474
  limit,
3280
3475
  offset,
3281
3476
  performanceKey,
@@ -3290,7 +3485,7 @@ var Smule = class {
3290
3485
  * @param commentKey The comment's key.
3291
3486
  */
3292
3487
  likeComment: async (performanceKey, commentKey) => {
3293
- let req = await this.internal._createRequest(SmuleUrls.CommentLike, {
3488
+ const req = await this.internal._createRequest(SmuleUrls.CommentLike, {
3294
3489
  postKey: commentKey,
3295
3490
  performanceKey
3296
3491
  });
@@ -3302,7 +3497,7 @@ var Smule = class {
3302
3497
  * @param commentKey The comment's key.
3303
3498
  */
3304
3499
  unlikeComment: async (performanceKey, commentKey) => {
3305
- let req = await this.internal._createRequest(SmuleUrls.CommentUnlike, {
3500
+ const req = await this.internal._createRequest(SmuleUrls.CommentUnlike, {
3306
3501
  postKey: commentKey,
3307
3502
  performanceKey
3308
3503
  });
@@ -3316,7 +3511,7 @@ var Smule = class {
3316
3511
  * @returns The likes on the specified comment.
3317
3512
  */
3318
3513
  fetchCommentLikes: async (performanceKey, commentKey) => {
3319
- let req = await this.internal._createRequest(SmuleUrls.CommentLikes, {
3514
+ const req = await this.internal._createRequest(SmuleUrls.CommentLikes, {
3320
3515
  postKey: commentKey,
3321
3516
  performanceKey
3322
3517
  });
@@ -3332,7 +3527,7 @@ var Smule = class {
3332
3527
  * @returns The created comment's details.
3333
3528
  */
3334
3529
  createComment: async (performanceKey, comment, latitude = 37, longitude = -120) => {
3335
- let req = await this.internal._createRequest(SmuleUrls.PerformanceComment, {
3530
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceComment, {
3336
3531
  comment,
3337
3532
  latitude,
3338
3533
  longitude,
@@ -3347,7 +3542,7 @@ var Smule = class {
3347
3542
  * @param postKeys The keys of the comments to delete.
3348
3543
  */
3349
3544
  deleteComments: async (performanceKey, postKeys) => {
3350
- let req = await this.internal._createRequest(SmuleUrls.PerformanceDeleteComment, {
3545
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceDeleteComment, {
3351
3546
  postKeys,
3352
3547
  performanceKey
3353
3548
  });
@@ -3367,7 +3562,7 @@ var Smule = class {
3367
3562
  * @param performanceKey The performance's key
3368
3563
  */
3369
3564
  likePerformance: async (performanceKey) => {
3370
- let req = await this.internal._createRequest(SmuleUrls.PerformanceLove, {
3565
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceLove, {
3371
3566
  performanceKey,
3372
3567
  latitude: this.session.latitude,
3373
3568
  longitude: this.session.longitude
@@ -3379,7 +3574,7 @@ var Smule = class {
3379
3574
  * @returns The blocked users.
3380
3575
  */
3381
3576
  fetchBlocked: async () => {
3382
- let req = await this.internal._createRequest(SmuleUrls.SocialBlockList, {});
3577
+ const req = await this.internal._createRequest(SmuleUrls.SocialBlockList, {});
3383
3578
  if (!this.internal._handleNon200(req)) return;
3384
3579
  return this.internal._getResponseData(req) || { accountIds: [] };
3385
3580
  },
@@ -3388,7 +3583,7 @@ var Smule = class {
3388
3583
  * @param accountIds The ids of the accounts to block.
3389
3584
  */
3390
3585
  blockUsers: async (accountIds) => {
3391
- let req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: accountIds, remove: [] });
3586
+ const req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: accountIds, remove: [] });
3392
3587
  this.internal._handleNon200(req);
3393
3588
  },
3394
3589
  /**
@@ -3403,7 +3598,7 @@ var Smule = class {
3403
3598
  * @param accountIds The ids of the accounts to unblock.
3404
3599
  */
3405
3600
  unblockUsers: async (accountIds) => {
3406
- let req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: [], remove: accountIds });
3601
+ const req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: [], remove: accountIds });
3407
3602
  this.internal._handleNon200(req);
3408
3603
  },
3409
3604
  /**
@@ -3422,7 +3617,7 @@ var Smule = class {
3422
3617
  * @returns An object containing the profile views of the current user.
3423
3618
  */
3424
3619
  fetchProfileViews: async (period = "WEEK", cursor = "start", limit = 10) => {
3425
- let req = await this.internal._createRequest(SmuleUrls.AccountProfileStatsViews, { period, cursor, limit });
3620
+ const req = await this.internal._createRequest(SmuleUrls.AccountProfileStatsViews, { period, cursor, limit });
3426
3621
  if (!this.internal._handleNon200(req)) return;
3427
3622
  return this.internal._getResponseData(req);
3428
3623
  },
@@ -3433,7 +3628,7 @@ var Smule = class {
3433
3628
  * @returns Some invites.
3434
3629
  */
3435
3630
  fetchPersonalInvites: async (cursor = "start", limit = 20) => {
3436
- let req = await this.internal._createRequest(SmuleUrls.InviteMe, { cursor, limit });
3631
+ const req = await this.internal._createRequest(SmuleUrls.InviteMe, { cursor, limit });
3437
3632
  if (!this.internal._handleNon200(req)) return;
3438
3633
  return this.internal._getResponseData(req);
3439
3634
  },
@@ -3444,7 +3639,7 @@ var Smule = class {
3444
3639
  * @returns Some invites.
3445
3640
  */
3446
3641
  fetchInvites: async (cursor = "start", limit = 20) => {
3447
- let req = await this.internal._createRequest(SmuleUrls.InviteList, { cursor, limit });
3642
+ const req = await this.internal._createRequest(SmuleUrls.InviteList, { cursor, limit });
3448
3643
  if (!this.internal._handleNon200(req)) return;
3449
3644
  return this.internal._getResponseData(req);
3450
3645
  }
@@ -3460,7 +3655,7 @@ var Smule = class {
3460
3655
  * @returns The "song book"
3461
3656
  */
3462
3657
  fetchSongbook: async (cursor = "start", limit = 10) => {
3463
- let req = await this.internal._createRequest(this.session.isGuest ? SmuleUrls.SongbookGuest : SmuleUrls.Songbook, new SongbookRequest(cursor, limit));
3658
+ const req = await this.internal._createRequest(this.session.isGuest ? SmuleUrls.SongbookGuest : SmuleUrls.Songbook, new SongbookRequest(cursor, limit));
3464
3659
  if (!this.internal._handleNon200(req)) return;
3465
3660
  return this.internal._getResponseData(req);
3466
3661
  },
@@ -3470,7 +3665,7 @@ var Smule = class {
3470
3665
  * @returns The updated songbook.
3471
3666
  */
3472
3667
  updateSongbook: async (categoryIds) => {
3473
- let req = await this.internal._createRequest(SmuleUrls.SongbookUpdate, { categoryIds });
3668
+ const req = await this.internal._createRequest(SmuleUrls.SongbookUpdate, { categoryIds });
3474
3669
  if (!this.internal._handleNon200(req)) return;
3475
3670
  return this.internal._getResponseData(req);
3476
3671
  },
@@ -3482,7 +3677,7 @@ var Smule = class {
3482
3677
  * @returns The songs
3483
3678
  */
3484
3679
  fetchFromCategory: async (cursor = "start", categoryId = 9998, limit = 10, duetAccountId) => {
3485
- let req = await this.internal._createRequest(SmuleUrls.Category, new CategoryRequest(cursor, limit, categoryId));
3680
+ const req = await this.internal._createRequest(SmuleUrls.Category, new CategoryRequest(cursor, limit, categoryId));
3486
3681
  if (!this.internal._handleNon200(req)) return;
3487
3682
  return this.internal._getResponseData(req);
3488
3683
  },
@@ -3492,7 +3687,7 @@ var Smule = class {
3492
3687
  * @returns The list of categories sorted by the specified type.
3493
3688
  */
3494
3689
  fetchCategoryList: async (sortType = "POPULAR") => {
3495
- let req = await this.internal._createRequest(SmuleUrls.CategoryList, { sort: sortType });
3690
+ const req = await this.internal._createRequest(SmuleUrls.CategoryList, { sort: sortType });
3496
3691
  if (!this.internal._handleNon200(req)) return;
3497
3692
  return this.internal._getResponseData(req);
3498
3693
  },
@@ -3503,14 +3698,14 @@ var Smule = class {
3503
3698
  * @returns The details of the song
3504
3699
  */
3505
3700
  fetchOne: async (key) => {
3506
- let req = await this.internal._createRequest(SmuleUrls.Arr, { arrKey: key });
3701
+ const req = await this.internal._createRequest(SmuleUrls.Arr, { arrKey: key });
3507
3702
  if (!this.internal._handleNon200(req)) return;
3508
3703
  return this.internal._getResponseData(req);
3509
3704
  },
3510
3705
  //TODO: raven is also sth ive seen in those official songs too
3511
3706
  //TODO: maybe they have another specialised id?
3512
3707
  fetchOneFromRaven: async (ravenSongId) => {
3513
- let req = await this.internal._createRequest(SmuleUrls.ArrFromRSong, { rsongId: ravenSongId });
3708
+ const req = await this.internal._createRequest(SmuleUrls.ArrFromRSong, { rsongId: ravenSongId });
3514
3709
  if (!this.internal._handleNon200(req)) return;
3515
3710
  return this.internal._getResponseData(req);
3516
3711
  },
@@ -3520,13 +3715,26 @@ var Smule = class {
3520
3715
  * @returns The details of the songs.
3521
3716
  */
3522
3717
  fetch: async (keys) => {
3523
- let req = await this.internal._createRequest(SmuleUrls.ArrByKeys, { arrKeys: keys });
3718
+ const req = await this.internal._createRequest(SmuleUrls.ArrByKeys, { arrKeys: keys });
3524
3719
  if (!this.internal._handleNon200(req)) return;
3525
3720
  return this.internal._getResponseData(req);
3526
3721
  },
3527
3722
  // TODO: test and doc
3528
3723
  fetchOwnedBy: async (ownerId, offset = 0, limit = 10) => {
3529
- let req = await this.internal._createRequest(SmuleUrls.ArrOwned, { ownerAccountId: ownerId, offset, limit });
3724
+ const req = await this.internal._createRequest(SmuleUrls.ArrOwned, { ownerAccountId: ownerId, offset, limit });
3725
+ if (!this.internal._handleNon200(req)) return;
3726
+ return this.internal._getResponseData(req);
3727
+ },
3728
+ /**
3729
+ * Fetches free songs from a list of genres
3730
+ *
3731
+ * This endpoint is usually used at register, to recommend
3732
+ * some songs to the new user.
3733
+ * @param genreIds The ids of the genres
3734
+ * @returns A stupid nested list with free "compositions"
3735
+ */
3736
+ fetchFromGenres: async (genreIds) => {
3737
+ const req = await this.internal._createRequest(SmuleUrls.TopicChoose, { compositionChoices: true, topicIds: genreIds });
3530
3738
  if (!this.internal._handleNon200(req)) return;
3531
3739
  return this.internal._getResponseData(req);
3532
3740
  },
@@ -3566,22 +3774,18 @@ var Smule = class {
3566
3774
  /**
3567
3775
  * Bookmarks a song.
3568
3776
  * @param key The song / arr key.
3569
- * @returns idk
3570
3777
  */
3571
3778
  bookmark: async (key) => {
3572
- let req = await this.internal._createRequest(SmuleUrls.ArrBookmark, { arrKey: key });
3573
- if (!this.internal._handleNon200(req)) return;
3574
- return this.internal._getResponseData(req);
3779
+ const req = await this.internal._createRequest(SmuleUrls.ArrBookmark, { arrKey: key });
3780
+ this.internal._handleNon200(req);
3575
3781
  },
3576
3782
  /**
3577
3783
  * Unbookmarks a song.
3578
3784
  * @param key The song / arr key.
3579
- * @returns idk
3580
3785
  */
3581
3786
  unbookmark: async (key) => {
3582
- let req = await this.internal._createRequest(SmuleUrls.ArrBookmarkRemove, { arrKey: key });
3583
- if (!this.internal._handleNon200(req)) return;
3584
- return this.internal._getResponseData(req);
3787
+ const req = await this.internal._createRequest(SmuleUrls.ArrBookmarkRemove, { arrKey: key });
3788
+ this.internal._handleNon200(req);
3585
3789
  },
3586
3790
  /**
3587
3791
  * Fetches bookmarked songs.
@@ -3590,25 +3794,25 @@ var Smule = class {
3590
3794
  * @returns idk prolly bookmarks
3591
3795
  */
3592
3796
  fetchBookmarks: async (cursor = "start", limit = 10) => {
3593
- let req = await this.internal._createRequest(SmuleUrls.ArrBookmarkList, { cursor, limit });
3797
+ const req = await this.internal._createRequest(SmuleUrls.ArrBookmarkList, { cursor, limit });
3594
3798
  if (!this.internal._handleNon200(req)) return;
3595
3799
  return this.internal._getResponseData(req);
3596
3800
  },
3597
3801
  //TODO:
3598
3802
  update: async (key, artist, name, tags) => {
3599
- let req = await this.internal._createRequest(SmuleUrls.ArrUpdate, { arrKey: key, artist, name, tags });
3803
+ const req = await this.internal._createRequest(SmuleUrls.ArrUpdate, { arrKey: key, artist, name, tags });
3600
3804
  if (!this.internal._handleNon200(req)) return;
3601
3805
  return this.internal._getResponseData(req);
3602
3806
  },
3603
3807
  //TODO:
3604
3808
  vote: async (key, arrVersion, reason, vote) => {
3605
- let req = await this.internal._createRequest(SmuleUrls.ArrVote, { arrKey: key, ver: arrVersion, reason, vote });
3809
+ const req = await this.internal._createRequest(SmuleUrls.ArrVote, { arrKey: key, ver: arrVersion, reason, vote });
3606
3810
  if (!this.internal._handleNon200(req)) return;
3607
3811
  return this.internal._getResponseData(req);
3608
3812
  },
3609
3813
  //TODO:
3610
3814
  delete: async (key, deletePerformances = true) => {
3611
- let req = await this.internal._createRequest(SmuleUrls.ArrDelete, { arrKey: key, deletePerfs: deletePerformances });
3815
+ const req = await this.internal._createRequest(SmuleUrls.ArrDelete, { arrKey: key, deletePerfs: deletePerformances });
3612
3816
  if (!this.internal._handleNon200(req)) return;
3613
3817
  return this.internal._getResponseData(req);
3614
3818
  }
@@ -3627,7 +3831,7 @@ var Smule = class {
3627
3831
  * @returns The performances' details
3628
3832
  */
3629
3833
  byKeys: async (performanceKeys) => {
3630
- let req = await this.internal._createRequest(SmuleUrls.PerformanceByKeys, { performanceKeys });
3834
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceByKeys, { performanceKeys });
3631
3835
  if (!this.internal._handleNon200(req)) return;
3632
3836
  return this.internal._getResponseData(req);
3633
3837
  },
@@ -3648,7 +3852,7 @@ var Smule = class {
3648
3852
  * @returns The performances
3649
3853
  */
3650
3854
  byUser: async (accountId, fillStatus = "FILLED", sortMethod = "NEWEST_FIRST", limit = 20, offset = 0) => {
3651
- let req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3855
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3652
3856
  if (!this.internal._handleNon200(req)) return;
3653
3857
  return this.internal._getResponseData(req);
3654
3858
  },
@@ -3662,7 +3866,21 @@ var Smule = class {
3662
3866
  * @returns The performances associated with the given AV template.
3663
3867
  */
3664
3868
  byAvTemplate: async (templateId, cursor = "start", limit = 10, performanceKey) => {
3665
- let req = await this.internal._createRequest(SmuleUrls.DiscoveryPerfByAvTemplateList, { avTemplateId: templateId, cursor, limit, performanceKey });
3869
+ const req = await this.internal._createRequest(SmuleUrls.DiscoveryPerfByAvTemplateList, { avTemplateId: templateId, cursor, limit, performanceKey });
3870
+ if (!this.internal._handleNon200(req)) return;
3871
+ return this.internal._getResponseData(req);
3872
+ },
3873
+ /**
3874
+ * Fetches performances based on the specified genre.
3875
+ * @param genreId The id of the genre
3876
+ * @param offset The starting point
3877
+ * @param limit The maximum number of performances
3878
+ * @param fillStatus Type of performances
3879
+ * @param sort The order
3880
+ * @returns The performances
3881
+ */
3882
+ byGenre: async (genreId, offset = 0, limit = 10, fillStatus = "FILLED", sort = "SUGGESTED") => {
3883
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceList, { fillStatus, limit, offset, sort, topicId: genreId });
3666
3884
  if (!this.internal._handleNon200(req)) return;
3667
3885
  return this.internal._getResponseData(req);
3668
3886
  }
@@ -3704,7 +3922,7 @@ var Smule = class {
3704
3922
  * @returns The performance lists.
3705
3923
  */
3706
3924
  fetchLists: async (requests) => {
3707
- let req = await this.internal._createRequest(SmuleUrls.PerformanceLists, { perfRequests: requests });
3925
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceLists, { perfRequests: requests });
3708
3926
  if (!this.internal._handleNon200(req)) return;
3709
3927
  return this.internal._getResponseData(req);
3710
3928
  },
@@ -3714,7 +3932,7 @@ var Smule = class {
3714
3932
  * @returns The performance's details
3715
3933
  */
3716
3934
  fetchOne: async (performanceKey) => {
3717
- let req = await this.internal._createRequest(SmuleUrls.PerformanceUrl, { performanceKey });
3935
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceUrl, { performanceKey });
3718
3936
  if (!this.internal._handleNon200(req)) return;
3719
3937
  return this.internal._getResponseData(req);
3720
3938
  },
@@ -3728,7 +3946,12 @@ var Smule = class {
3728
3946
  * @returns The performances of the user
3729
3947
  */
3730
3948
  fetchFromAccount: async (accountId, fillStatus = "FILLED", sortMethod = "NEWEST_FIRST", limit = 20, offset = 0) => {
3731
- let req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3949
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3950
+ if (!this.internal._handleNon200(req)) return;
3951
+ return this.internal._getResponseData(req);
3952
+ },
3953
+ fetchBookmarkedInvites: async (offset = 0, limit = 10) => {
3954
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceBookmarkSeed, { offset, limit, forApps: ["sing_google"] });
3732
3955
  if (!this.internal._handleNon200(req)) return;
3733
3956
  return this.internal._getResponseData(req);
3734
3957
  },
@@ -3740,7 +3963,7 @@ var Smule = class {
3740
3963
  * @returns The children performances of the given performance.
3741
3964
  */
3742
3965
  fetchChildren: async (performanceKey, limit = 25, offset = 0) => {
3743
- let req = await this.internal._createRequest(SmuleUrls.PerformanceChildren, { performanceKey, limit, offset });
3966
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceChildren, { performanceKey, limit, offset });
3744
3967
  if (!this.internal._handleNon200(req)) {
3745
3968
  return {
3746
3969
  performanceIcons: [],
@@ -3755,7 +3978,7 @@ var Smule = class {
3755
3978
  * @returns The details of the performances.
3756
3979
  */
3757
3980
  fetchDetails: async (performanceKeys) => {
3758
- let req = await this.internal._createRequest(SmuleUrls.PerformanceListDetails, { keys: performanceKeys, returnAvTemplateDetails: true, returnBookmarked: true, returnLoved: true, returnRestricted: true, returnTopComment: true });
3981
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceListDetails, { keys: performanceKeys, returnAvTemplateDetails: true, returnBookmarked: true, returnLoved: true, returnRestricted: true, returnTopComment: true });
3759
3982
  if (!this.internal._handleNon200(req)) return;
3760
3983
  return this.internal._getResponseData(req);
3761
3984
  },
@@ -3892,7 +4115,15 @@ var Smule = class {
3892
4115
  * @param performanceKey The key of the performance to be deleted.
3893
4116
  */
3894
4117
  deleteOne: async (performanceKey) => {
3895
- let req = await this.internal._createRequest(SmuleUrls.PerformanceDelete, { performanceKey });
4118
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceDelete, { performanceKey });
4119
+ this.internal._handleNon200(req);
4120
+ },
4121
+ bookmarkInvites: async (performanceKeys) => {
4122
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceBookmarkSeedUpdate, { add: performanceKeys, remove: [] });
4123
+ this.internal._handleNon200(req);
4124
+ },
4125
+ unbookmarkInvites: async (performanceKeys) => {
4126
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceBookmarkSeedUpdate, { add: [], remove: performanceKeys });
3896
4127
  this.internal._handleNon200(req);
3897
4128
  }
3898
4129
  };
@@ -3905,7 +4136,7 @@ var Smule = class {
3905
4136
  * @returns The trending searches currently available
3906
4137
  */
3907
4138
  fetchTrending: async () => {
3908
- let req = await this.internal._createRequest(SmuleUrls.RecTsrch, {});
4139
+ const req = await this.internal._createRequest(SmuleUrls.RecTsrch, {});
3909
4140
  if (!this.internal._handleNon200(req)) return;
3910
4141
  return this.internal._getResponseData(req);
3911
4142
  },
@@ -3915,7 +4146,7 @@ var Smule = class {
3915
4146
  * @returns The search result
3916
4147
  */
3917
4148
  perform: async (query) => {
3918
- let req = await this.internal._createRequest(SmuleUrls.SearchGlobal, { includeRecording: 0, term: query });
4149
+ const req = await this.internal._createRequest(SmuleUrls.SearchGlobal, { includeRecording: 0, term: query });
3919
4150
  if (!this.internal._handleNon200(req)) return;
3920
4151
  return this.internal._getResponseData(req);
3921
4152
  },
@@ -3929,7 +4160,7 @@ var Smule = class {
3929
4160
  * @returns The search results matching the specified criteria.
3930
4161
  */
3931
4162
  performSpecific: async (query, type, sort = "POPULAR", cursor = "start", limit = 25) => {
3932
- let req = await this.internal._createRequest(SmuleUrls.Search, new SearchRequest(cursor, limit, type, sort, query));
4163
+ const req = await this.internal._createRequest(SmuleUrls.Search, new SearchRequest(cursor, limit, type, sort, query));
3933
4164
  if (!this.internal._handleNon200(req)) return;
3934
4165
  return this.internal._getResponseData(req);
3935
4166
  },
@@ -3940,7 +4171,7 @@ var Smule = class {
3940
4171
  * @returns The autocomplete suggestions
3941
4172
  */
3942
4173
  fetchAutocomplete: async (query, limit = 5) => {
3943
- let req = await this.internal._createRequest(SmuleUrls.SearchAutocomplete, new SearchAutocompleteRequest(query, limit));
4174
+ const req = await this.internal._createRequest(SmuleUrls.SearchAutocomplete, new SearchAutocompleteRequest(query, limit));
3944
4175
  if (!this.internal._handleNon200(req)) return;
3945
4176
  return this.internal._getResponseData(req);
3946
4177
  }
@@ -3956,7 +4187,7 @@ var Smule = class {
3956
4187
  * @returns The fetched AV templates.
3957
4188
  */
3958
4189
  fetch: async (limit = 25) => {
3959
- let req = await this.internal._createRequest(SmuleUrls.AvtemplateCategoryList, new AvTemplateCategoryListRequest("AUDIO", "start", limit, "STANDARD"));
4190
+ const req = await this.internal._createRequest(SmuleUrls.AvtemplateCategoryList, new AvTemplateCategoryListRequest("AUDIO", "start", limit, "STANDARD"));
3960
4191
  if (!this.internal._handleNon200(req)) return;
3961
4192
  return this.internal._getResponseData(req);
3962
4193
  }
@@ -3971,7 +4202,7 @@ var Smule = class {
3971
4202
  * @param arrKey The key associated with the song to be marked as played.
3972
4203
  */
3973
4204
  markSongAsPlayed: async (arrKey) => {
3974
- let req = await this.internal._createRequest(SmuleUrls.ArrPlay, { arrKey });
4205
+ const req = await this.internal._createRequest(SmuleUrls.ArrPlay, { arrKey });
3975
4206
  this.internal._handleNon200(req);
3976
4207
  },
3977
4208
  /**
@@ -3980,7 +4211,7 @@ var Smule = class {
3980
4211
  * @param performanceKey The key associated with the performance to be marked as played.
3981
4212
  */
3982
4213
  markPerformanceAsPlayed: async (performanceKey) => {
3983
- let req = await this.internal._createRequest(SmuleUrls.PerformancePlay, { performanceKey });
4214
+ const req = await this.internal._createRequest(SmuleUrls.PerformancePlay, { performanceKey });
3984
4215
  this.internal._handleNon200(req);
3985
4216
  },
3986
4217
  /**
@@ -3989,7 +4220,7 @@ var Smule = class {
3989
4220
  * @param performanceKey The key associated with the performance to be marked as listened to.
3990
4221
  */
3991
4222
  markPerformanceListenStart: async (performanceKey) => {
3992
- let req = await this.internal._createRequest(SmuleUrls.PerformanceListenStart, { performanceKey });
4223
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceListenStart, { performanceKey });
3993
4224
  this.internal._handleNon200(req);
3994
4225
  }
3995
4226
  };
@@ -4002,7 +4233,7 @@ var Smule = class {
4002
4233
  * @returns The playlists that match the specified criteria.
4003
4234
  */
4004
4235
  fetchPlaylists: async () => {
4005
- let req = await this.internal._createRequest(SmuleUrls.PlaylistExplore, {});
4236
+ const req = await this.internal._createRequest(SmuleUrls.PlaylistExplore, {});
4006
4237
  if (!this.internal._handleNon200(req)) return;
4007
4238
  return this.internal._getResponseData(req);
4008
4239
  },
@@ -4014,7 +4245,7 @@ var Smule = class {
4014
4245
  * @returns The playlist with the specified details.
4015
4246
  */
4016
4247
  fetchPlaylist: async (playlistId, offset = 0, limit = 10) => {
4017
- let req = await this.internal._createRequest(SmuleUrls.PlaylistGet, { playlistId, offset, limit });
4248
+ const req = await this.internal._createRequest(SmuleUrls.PlaylistGet, { playlistId, offset, limit });
4018
4249
  if (!this.internal._handleNon200(req)) return;
4019
4250
  return this.internal._getResponseData(req);
4020
4251
  },
@@ -4025,7 +4256,14 @@ var Smule = class {
4025
4256
  * @returns The users that match the specified criteria.
4026
4257
  */
4027
4258
  fetchAccounts: async (cursor = "start", limit = 20) => {
4028
- let req = await this.internal._createRequest(SmuleUrls.AccountExplore, { cursor, limit });
4259
+ const req = await this.internal._createRequest(SmuleUrls.AccountExplore, { cursor, limit });
4260
+ if (!this.internal._handleNon200(req)) return;
4261
+ return this.internal._getResponseData(req);
4262
+ },
4263
+ // TODO: find out if this is the same as #fetchAccounts
4264
+ // TODO: this one is used in the find friends tab, but it might be the same exact thing
4265
+ fetchRecommendedAccounts: async (cursor = "start", limit = 20) => {
4266
+ const req = await this.internal._createRequest(SmuleUrls.RecAcct, { cursor, limit });
4029
4267
  if (!this.internal._handleNon200(req)) return;
4030
4268
  return this.internal._getResponseData(req);
4031
4269
  },
@@ -4037,7 +4275,7 @@ var Smule = class {
4037
4275
  * @returns The groups matching the specified criteria.
4038
4276
  */
4039
4277
  fetchGroups: async (cursor = "start", limit = 10, sortBy = "RECOMMENDED") => {
4040
- let req = await this.internal._createRequest(SmuleUrls.SfamList, { cursor, limit, sortBy });
4278
+ const req = await this.internal._createRequest(SmuleUrls.SfamList, { cursor, limit, sortBy });
4041
4279
  if (!this.internal._handleNon200(req)) return;
4042
4280
  return this.internal._getResponseData(req);
4043
4281
  },
@@ -4051,7 +4289,7 @@ var Smule = class {
4051
4289
  */
4052
4290
  fetchLivestreams: async (cursor = "start", limit = 20, sort = "POPULAR") => {
4053
4291
  let self = await this.account.fetchSelf();
4054
- let req = await this.internal._createRequest(SmuleUrls.CfireList, { accountId: self.profile.accountIcon.accountId, cursor, limit, sort });
4292
+ const req = await this.internal._createRequest(SmuleUrls.CfireList, { accountId: self.profile.accountIcon.accountId, cursor, limit, sort });
4055
4293
  if (!this.internal._handleNon200(req)) return;
4056
4294
  return this.internal._getResponseData(req);
4057
4295
  },
@@ -4063,7 +4301,27 @@ var Smule = class {
4063
4301
  * @remarks You must be logged in in order to fetch your feed.
4064
4302
  */
4065
4303
  fetchFeed: async (cursor = "start", limit = 20) => {
4066
- let req = await this.internal._createRequest(SmuleUrls.SocialFeedList, { cursor, limit });
4304
+ const req = await this.internal._createRequest(SmuleUrls.SocialFeedList, { cursor, limit });
4305
+ if (!this.internal._handleNon200(req)) return;
4306
+ return this.internal._getResponseData(req);
4307
+ },
4308
+ /**
4309
+ * Fetches a list of genres
4310
+ * @param cursor The offset to start from
4311
+ * @param limit The number of genres to fetch
4312
+ * @returns A list of genres
4313
+ */
4314
+ fetchGenres: async (cursor = 0, limit = 10) => {
4315
+ const req = await this.internal._createRequest(SmuleUrls.TopicOption, { limit, offset: cursor, singleCoverUrl: false });
4316
+ if (!this.internal._handleNon200(req)) return;
4317
+ return this.internal._getResponseData(req);
4318
+ },
4319
+ /**
4320
+ * Fetches your selected genres
4321
+ * @returns A list of genres
4322
+ */
4323
+ fetchYourGenres: async () => {
4324
+ const req = await this.internal._createRequest(SmuleUrls.Topic, {});
4067
4325
  if (!this.internal._handleNon200(req)) return;
4068
4326
  return this.internal._getResponseData(req);
4069
4327
  }
@@ -4071,7 +4329,7 @@ var Smule = class {
4071
4329
  // utterly useless but it's here if needed
4072
4330
  settings = {
4073
4331
  fetch: async () => {
4074
- let req = await this.internal._createRequest(SmuleUrls.Settings, new SettingsRequest(this.session.device));
4332
+ const req = await this.internal._createRequest(SmuleUrls.Settings, new SettingsRequest(this.session.device));
4075
4333
  if (!this.internal._handleNon200(req)) return;
4076
4334
  return this.internal._getResponseData(req);
4077
4335
  }
@@ -4183,9 +4441,132 @@ var Smule = class {
4183
4441
  }
4184
4442
  },
4185
4443
  fetch: async (campfireId) => {
4186
- let req = await this.internal._createRequest(SmuleUrls.CfireSync, { campfireId });
4444
+ const req = await this.internal._createRequest(SmuleUrls.CfireSync, { campfireId });
4445
+ if (!this.internal._handleNon200(req)) return;
4446
+ return this.internal._getResponseData(req);
4447
+ }
4448
+ };
4449
+ groups = {
4450
+ /**
4451
+ * Fetches a group's details
4452
+ * @param groupId The ID of the group
4453
+ * @returns The group
4454
+ */
4455
+ fetchOne: async (groupId) => {
4456
+ const req = await this.internal._createRequest(SmuleUrls.SfamInfo, { sfamId: groupId });
4457
+ if (!this.internal._handleNon200(req)) return;
4458
+ return this.internal._getResponseData(req);
4459
+ },
4460
+ /**
4461
+ * Fetches a group's posts
4462
+ * @param groupId The ID of the group
4463
+ * @param cursor The starting point
4464
+ * @param limit How many to fetch
4465
+ * @returns The posts
4466
+ */
4467
+ fetchPosts: async (groupId, cursor = "start", limit = 10) => {
4468
+ const req = await this.internal._createRequest(SmuleUrls.SfamPostFeed, { sfamId: groupId, cursor, limit });
4469
+ if (!this.internal._handleNon200(req)) return;
4470
+ return this.internal._getResponseData(req);
4471
+ },
4472
+ /**
4473
+ * Fetches a group's members
4474
+ * @param groupId The ID of the group
4475
+ * @param cursor Starting point
4476
+ * @param limit How many
4477
+ * @param roles Member roles (0 - owner, 1 - admin, 2 - member)
4478
+ * @returns The members
4479
+ */
4480
+ fetchMembers: async (groupId, cursor = "start", limit = 10, roles = [2]) => {
4481
+ const req = await this.internal._createRequest(SmuleUrls.SfamMemberList, { sfamId: groupId, cursor, limit, roles, memberGroup: 0, vipStatus: "ALL" });
4482
+ if (!this.internal._handleNon200(req)) return;
4483
+ return this.internal._getResponseData(req);
4484
+ },
4485
+ /**
4486
+ * Sends a request to join a group
4487
+ * @param groupId The ID of the group
4488
+ * @returns The membership status
4489
+ */
4490
+ join: async (groupId) => {
4491
+ const req = await this.internal._createRequest(SmuleUrls.SfamMembershipRequestSend, { sfamId: groupId });
4492
+ if (!this.internal._handleNon200(req)) return;
4493
+ return SmuleUtil.getGroupMembershipType(this.internal._getResponseData(req).mbrshipStatus);
4494
+ },
4495
+ /**
4496
+ * Uploads a cover picture for a group
4497
+ * @param imageData The image data
4498
+ * @returns The resource ID of the uploaded image, to be used in `create`
4499
+ */
4500
+ uploadCoverPicture: async (imageData) => {
4501
+ const form = new CustomFormData();
4502
+ form.set("coverPhoto", imageData, "image/jpeg", "family_cover_photo.jpg");
4503
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.SfamCoverPhotoUpload, form);
4504
+ if (!this.internal._handleNon200(req)) return;
4505
+ return this.internal._getResponseData(req).resource_id;
4506
+ },
4507
+ /**
4508
+ * Creates a group
4509
+ * @param name The name of the group
4510
+ * @param desc The description of the group
4511
+ * @param lang The language
4512
+ * @param loc The location (XX - global)
4513
+ * @param picId The resource id of the cover picture
4514
+ * @param sfamTag The global group tag
4515
+ * @returns The group
4516
+ */
4517
+ create: async (name, desc, lang, loc, picId, sfamTag) => {
4518
+ const req = await this.internal._createRequest(SmuleUrls.SfamCreate, { name, desc, lang, loc, picId, sfamTag });
4519
+ if (!this.internal._handleNon200(req)) return;
4520
+ return this.internal._getResponseData(req).sfam;
4521
+ },
4522
+ /**
4523
+ * Posts multiple performances to a group's feed
4524
+ * @param performanceKeys The performances to post
4525
+ * @param groupId The ID of the group
4526
+ */
4527
+ postPerformances: async (performanceKeys, groupId) => {
4528
+ const req = await this.internal._createRequest(SmuleUrls.SfamPostAdd, { objects: performanceKeys, sfamId: groupId });
4529
+ this.internal._handleNon200(req);
4530
+ },
4531
+ /**
4532
+ * Removes a post from a group
4533
+ * @param groupId The ID of the group
4534
+ * @param postId The ID of the post
4535
+ * @param postType The type of the post
4536
+ */
4537
+ removePost: async (groupId, postId, postType = "FEED") => {
4538
+ const req = await this.internal._createRequest(SmuleUrls.SfamPostRemove, { sfamId: groupId, postId, postType });
4539
+ this.internal._handleNon200(req);
4540
+ }
4541
+ };
4542
+ playlists = {
4543
+ create: async (name, visibility = "PUB") => {
4544
+ const req = await this.internal._createRequest(SmuleUrls.AplistCreate, { name, visibility });
4545
+ if (!this.internal._handleNon200(req)) return;
4546
+ return this.internal._getResponseData(req).playlistIcon;
4547
+ },
4548
+ addPerformance: async (playlistKey, performanceKey) => {
4549
+ const req = await this.internal._createRequest(SmuleUrls.AplistPerfAdd, { playlistKey, perfKey: performanceKey });
4550
+ this.internal._handleNon200(req);
4551
+ },
4552
+ changeVisibility: async (playlistKey, visibility) => {
4553
+ const req = await this.internal._createRequest(SmuleUrls.AplistUpdate, { playlistKey, visibility });
4554
+ if (!this.internal._handleNon200(req)) return;
4555
+ return this.internal._getResponseData(req).playlistIcon;
4556
+ },
4557
+ changeName: async (playlistKey, name) => {
4558
+ const req = await this.internal._createRequest(SmuleUrls.AplistUpdate, { playlistKey, name });
4559
+ if (!this.internal._handleNon200(req)) return;
4560
+ return this.internal._getResponseData(req).playlistIcon;
4561
+ },
4562
+ fetchOne: async (playlistKey, sortMethod, cursor = "start", limit = 10) => {
4563
+ const req = await this.internal._createRequest(SmuleUrls.AplistView, { playlistKey, playlistSortMethod: sortMethod, cursor, limit });
4187
4564
  if (!this.internal._handleNon200(req)) return;
4188
4565
  return this.internal._getResponseData(req);
4566
+ },
4567
+ deleteOne: async (playlistKey) => {
4568
+ const req = await this.internal._createRequest(SmuleUrls.AplistDelete, { playlistKey });
4569
+ this.internal._handleNon200(req);
4189
4570
  }
4190
4571
  };
4191
4572
  // shit i try to test
@@ -4506,6 +4887,116 @@ var SmuleDotCom = class {
4506
4887
  return req.data;
4507
4888
  }
4508
4889
  };
4890
+
4891
+ // src/smule-effects.ts
4892
+ var yauzl = __toESM(require("yauzl"), 1);
4893
+ var SmuleEffects;
4894
+ ((SmuleEffects2) => {
4895
+ function processZipFile(filePath) {
4896
+ return new Promise((resolve, reject) => {
4897
+ yauzl.open(filePath, { lazyEntries: true, decodeStrings: false }, (err, zipfile) => {
4898
+ let filesRead = 0;
4899
+ if (err) throw err;
4900
+ zipfile.readEntry();
4901
+ let data = {
4902
+ component_library: {},
4903
+ template: {},
4904
+ copyright: "my ass",
4905
+ files: {}
4906
+ };
4907
+ zipfile.on("entry", (entry) => {
4908
+ let fileName = entry.fileName.toString("utf-8");
4909
+ if (fileName.endsWith(".alyc")) {
4910
+ if (Object.keys(data.component_library).length > 1) {
4911
+ console.warn("[SmuleEffects] Double component_library file? that shouldnt happen i think? Overwriting...");
4912
+ }
4913
+ zipfile.openReadStream(entry, (err2, stream) => {
4914
+ if (err2) throw err2;
4915
+ let rawData = [];
4916
+ stream.on("data", (chunk) => {
4917
+ rawData.push(chunk);
4918
+ });
4919
+ stream.on("end", () => {
4920
+ let componentLibrary = JSON.parse(Buffer.concat(rawData).toString("utf-8"));
4921
+ data.component_library = componentLibrary;
4922
+ filesRead++;
4923
+ });
4924
+ });
4925
+ } else if (fileName.endsWith(".alyt")) {
4926
+ if (Object.keys(data.template).length > 1) {
4927
+ console.warn("[SmuleEffects] Double template file? that shouldnt happen i think? Overwriting...");
4928
+ }
4929
+ zipfile.openReadStream(entry, (err2, stream) => {
4930
+ if (err2) throw err2;
4931
+ let rawData = [];
4932
+ stream.on("data", (chunk) => {
4933
+ rawData.push(chunk);
4934
+ });
4935
+ stream.on("end", () => {
4936
+ let template = JSON.parse(Buffer.concat(rawData).toString("utf-8"));
4937
+ data.template = template;
4938
+ filesRead++;
4939
+ });
4940
+ });
4941
+ } else if (fileName.endsWith(".alyg") || fileName.endsWith(".json")) {
4942
+ zipfile.openReadStream(entry, (err2, stream) => {
4943
+ if (err2) throw err2;
4944
+ let rawData = [];
4945
+ stream.on("data", (chunk) => {
4946
+ rawData.push(chunk);
4947
+ });
4948
+ stream.on("end", () => {
4949
+ data.files[fileName] = JSON.parse(Buffer.concat(rawData).toString("utf-8"));
4950
+ filesRead++;
4951
+ });
4952
+ });
4953
+ } else if (fileName == "copyright.txt") {
4954
+ zipfile.openReadStream(entry, (err2, stream) => {
4955
+ if (err2) throw err2;
4956
+ let rawData = [];
4957
+ stream.on("data", (chunk) => {
4958
+ rawData.push(chunk);
4959
+ });
4960
+ stream.on("end", () => {
4961
+ data.copyright = Buffer.concat(rawData).toString("utf-8");
4962
+ filesRead++;
4963
+ });
4964
+ });
4965
+ } else if (fileName.endsWith(".txt")) {
4966
+ zipfile.openReadStream(entry, (err2, stream) => {
4967
+ if (err2) throw err2;
4968
+ let rawData = [];
4969
+ stream.on("data", (chunk) => {
4970
+ rawData.push(chunk);
4971
+ });
4972
+ stream.on("end", () => {
4973
+ data.files[fileName] = Buffer.concat(rawData).toString("utf-8");
4974
+ filesRead++;
4975
+ });
4976
+ });
4977
+ } else {
4978
+ data.files[fileName] = fileName;
4979
+ filesRead++;
4980
+ }
4981
+ zipfile.readEntry();
4982
+ });
4983
+ zipfile.on("end", () => {
4984
+ let entries = zipfile.entriesRead;
4985
+ zipfile.close();
4986
+ let interval = setInterval(() => {
4987
+ if (entries > filesRead) return;
4988
+ clearInterval(interval);
4989
+ resolve(data);
4990
+ }, 1);
4991
+ });
4992
+ });
4993
+ });
4994
+ }
4995
+ SmuleEffects2.processZipFile = processZipFile;
4996
+ function processRawEffects(data) {
4997
+ }
4998
+ SmuleEffects2.processRawEffects = processRawEffects;
4999
+ })(SmuleEffects || (SmuleEffects = {}));
4509
5000
  // Annotate the CommonJS export names for ESM import in node:
4510
5001
  0 && (module.exports = {
4511
5002
  AvTemplateCategoryListRequest,
@@ -4528,7 +5019,9 @@ var SmuleDotCom = class {
4528
5019
  SingUserProfileRequest,
4529
5020
  Smule,
4530
5021
  SmuleDotCom,
5022
+ SmuleEffects,
4531
5023
  SmuleErrorCode,
5024
+ SmuleRegisterErrorCode,
4532
5025
  SmuleSession,
4533
5026
  SmuleUrls,
4534
5027
  SmuleUserSinging,