smule.js 1.1.1 → 1.2.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.
package/dist/index.js CHANGED
@@ -128,8 +128,8 @@ var LoginAsGuestRequest = class {
128
128
  }
129
129
  };
130
130
  var LoginRequest = class {
131
+ loginCommon = new LoginCommonData();
131
132
  data = {
132
- ...new LoginCommonData(),
133
133
  email: "",
134
134
  password: ""
135
135
  };
@@ -137,10 +137,13 @@ var LoginRequest = class {
137
137
  this.data.email = email;
138
138
  this.data.password = password;
139
139
  if (loginCommon)
140
- this.data = { ...this.data, ...loginCommon };
140
+ this.loginCommon = loginCommon;
141
141
  }
142
142
  toJSON() {
143
- return this.data;
143
+ return {
144
+ ...this.loginCommon,
145
+ ...this.data
146
+ };
144
147
  }
145
148
  };
146
149
  var SearchRequest = class {
@@ -515,7 +518,14 @@ var SmuleErrorCode = {
515
518
  1012: "VIP required",
516
519
  1013: "Subscription error / VIP required",
517
520
  10: "No result?",
518
- 1052: "Not enough coins"
521
+ 1052: "Not enough coins",
522
+ 2017: "Group waiting period not expired",
523
+ // unsure what this actually means
524
+ 2013: "Banned from group",
525
+ 1044: "Group join limit reached"
526
+ };
527
+ var SmuleRegisterErrorCode = {
528
+ 13: "Account already exists"
519
529
  };
520
530
 
521
531
  // src/util.ts
@@ -611,6 +621,23 @@ var SmuleUtil;
611
621
  return subApps.filter((s) => ["sing_google", "sing"].includes(s)).length > 0;
612
622
  }
613
623
  SmuleUtil2.isVIP = isVIP;
624
+ function getGroupMembershipType(membership) {
625
+ switch (membership) {
626
+ case 1:
627
+ return "ADMIN";
628
+ case 2:
629
+ return "MEMBER";
630
+ case 3:
631
+ return "PENDING_INVTN";
632
+ case 4:
633
+ return "PENDING_RQST";
634
+ case 5:
635
+ return "GUEST";
636
+ default:
637
+ return "UNKNOWN";
638
+ }
639
+ }
640
+ SmuleUtil2.getGroupMembershipType = getGroupMembershipType;
614
641
  function getFilesFromArr(arr) {
615
642
  return {
616
643
  preview: arr.normResources.find((r) => r.role == "preview")?.url,
@@ -951,6 +978,7 @@ var SmuleUrls;
951
978
  SmuleUrls2.SfamMembershipInvitationReject = SmuleUrls2.baseUrl + "/sfam/mbrship/invtn/reject";
952
979
  SmuleUrls2.SfamMembershipInvitationSend = SmuleUrls2.baseUrl + "/sfam/mbrship/invtn/send";
953
980
  SmuleUrls2.SfamMembershipRequestRoles = SmuleUrls2.baseUrl + "/sfam/mbrship/rqst/roles";
981
+ SmuleUrls2.SfamMembershipRequestSend = SmuleUrls2.baseUrl + "/sfam/mbrship/rqst/send";
954
982
  SmuleUrls2.SfamPostAdd = SmuleUrls2.baseUrl + "/sfam/post/add";
955
983
  SmuleUrls2.SfamPostFeed = SmuleUrls2.baseUrl + "/sfam/post/feed";
956
984
  SmuleUrls2.SfamPostRemove = SmuleUrls2.baseUrl + "/sfam/post/remove";
@@ -997,6 +1025,7 @@ var SmuleUrls;
997
1025
  SmuleUrls2.UserLogin = SmuleUrls2.baseUrl + "/user/login";
998
1026
  SmuleUrls2.UserLookup = SmuleUrls2.baseUrl + "/user/lookup";
999
1027
  SmuleUrls2.UserPasswordReset = SmuleUrls2.baseUrl + "/user/password/reset";
1028
+ SmuleUrls2.UserPersonalUpdate = SmuleUrls2.baseUrl + "/user/personal/update";
1000
1029
  SmuleUrls2.UserProfileUpdate = SmuleUrls2.baseUrl + "/user/personal/update";
1001
1030
  SmuleUrls2.UserPhoneConnect = SmuleUrls2.baseUrl + "/user/phone/connect";
1002
1031
  SmuleUrls2.UserPictureDelete = SmuleUrls2.baseUrl + "/user/picture/delete";
@@ -1233,6 +1262,7 @@ var SmuleUrls;
1233
1262
  SmuleUrls2.UserEmailUpdateConfirm,
1234
1263
  SmuleUrls2.UserEmailUpdateResend,
1235
1264
  SmuleUrls2.UserPasswordReset,
1265
+ SmuleUrls2.UserPersonalUpdate,
1236
1266
  SmuleUrls2.UserProfileUpdate,
1237
1267
  SmuleUrls2.UserPhoneConnect,
1238
1268
  SmuleUrls2.UserPictureDelete,
@@ -2612,7 +2642,7 @@ var SmuleDigest;
2612
2642
  SmuleDigest2._calculateDigest = _calculateDigest;
2613
2643
  function _getDigestParameters(parameters, needsSession = false, isGetRequest = false, multiPartBody = null) {
2614
2644
  let neededParameters = {};
2615
- let required = ["appVersion", "app", "appVariant", "msgId"];
2645
+ const required = ["appVersion", "app", "appVariant", "msgId"];
2616
2646
  if (needsSession) required.push("session");
2617
2647
  for (let param of required) {
2618
2648
  if (!parameters[param])
@@ -2696,7 +2726,7 @@ var Smule = class {
2696
2726
  }
2697
2727
  }
2698
2728
  if (response.request && response.request.path) {
2699
- _warn(`[${response.request.path}] Got ${response.status} - ${response.statusText}`);
2729
+ _warn(`[${response.request.path}] Got ${response.status} - ${response.status == 418 ? "Unauthorized" : response.statusText}`);
2700
2730
  _warn(response.data);
2701
2731
  } else {
2702
2732
  _warn(`[NO REQUEST?] Got ${response.status} - ${response.statusText}`);
@@ -2704,9 +2734,10 @@ var Smule = class {
2704
2734
  }
2705
2735
  return false;
2706
2736
  },
2707
- _createRequestMultiPart: async (url, pop, body, checkSession = true) => {
2737
+ _createRequestMultiPart: async (url, body, pop, checkSession = true) => {
2708
2738
  let params = new URLSearchParams();
2709
- params.append("pop", pop);
2739
+ if (pop)
2740
+ params.append("pop", pop);
2710
2741
  if (checkSession && this.session && this.session.sessionToken && !this.session.expired) {
2711
2742
  params.append("session", decodeURIComponent(this.session.sessionToken));
2712
2743
  }
@@ -2765,7 +2796,7 @@ var Smule = class {
2765
2796
  _error("You cannot create a new performance as a guest");
2766
2797
  return;
2767
2798
  }
2768
- let req = await this.internal._createRequest(SmuleUrls.PerfPreupload, new PreuploadRequest(arrKey, compType, ensembleType, uploadType, false, seedKey));
2799
+ const req = await this.internal._createRequest(SmuleUrls.PerfPreupload, new PreuploadRequest(arrKey, compType, ensembleType, uploadType, false, seedKey));
2769
2800
  if (!this.internal._handleNon200(req)) return;
2770
2801
  return this.internal._getResponseData(req);
2771
2802
  },
@@ -2778,7 +2809,7 @@ var Smule = class {
2778
2809
  _error("You cannot create a new performance as a guest");
2779
2810
  return;
2780
2811
  }
2781
- let req = await this.internal._createRequest(SmuleUrls.PerfCreate, perfReq);
2812
+ const req = await this.internal._createRequest(SmuleUrls.PerfCreate, perfReq);
2782
2813
  if (!this.internal._handleNon200(req)) return;
2783
2814
  return this.internal._getResponseData(req);
2784
2815
  },
@@ -2791,7 +2822,7 @@ var Smule = class {
2791
2822
  _error("You cannot join a new performance as a guest");
2792
2823
  return;
2793
2824
  }
2794
- let req = await this.internal._createRequest(SmuleUrls.PerfJoin, perfReq);
2825
+ const req = await this.internal._createRequest(SmuleUrls.PerfJoin, perfReq);
2795
2826
  if (!this.internal._handleNon200(req)) return;
2796
2827
  return this.internal._getResponseData(req);
2797
2828
  },
@@ -2809,15 +2840,15 @@ var Smule = class {
2809
2840
  form.set("file1", file1, "application/octet-stream", "hi..m4a");
2810
2841
  form.set("file2", file2, "application/octet-stream", "hi.." + (file3 ? ".jpg" : ".bin"));
2811
2842
  if (file3) form.set("file3", file3, "application/octet-stream", "hi..bin");
2812
- let req = await this.internal._createRequestMultiPart(SmuleUrls.getPerformanceUploadUrl(host), pop, form);
2843
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.getPerformanceUploadUrl(host), form, pop);
2813
2844
  this.internal._handleNon200(req);
2814
2845
  },
2815
2846
  _logreccomplete: async (arrKey) => {
2816
- let req = await this.internal._createRequest(SmuleUrls.PerformanceLogRecCompletedArr, { arrKey });
2847
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceLogRecCompletedArr, { arrKey });
2817
2848
  this.internal._handleNon200(req);
2818
2849
  },
2819
2850
  _storeStreamLog: async (arrKey) => {
2820
- let req = await this.internal._createRequest(SmuleUrls.StoreStreamLog, {
2851
+ const req = await this.internal._createRequest(SmuleUrls.StoreStreamLog, {
2821
2852
  productId: arrKey,
2822
2853
  productType: "ARR",
2823
2854
  type: "own"
@@ -2854,7 +2885,7 @@ var Smule = class {
2854
2885
  * @returns The user's data
2855
2886
  */
2856
2887
  byEmail: async (email) => {
2857
- let req = await this.internal._createRequest(SmuleUrls.UserLookup, { email }, false, false);
2888
+ const req = await this.internal._createRequest(SmuleUrls.UserLookup, { email }, false, false);
2858
2889
  if (!this.internal._handleNon200(req)) return;
2859
2890
  return this.internal._getResponseData(req);
2860
2891
  },
@@ -2864,7 +2895,7 @@ var Smule = class {
2864
2895
  * @returns The accounts' details
2865
2896
  */
2866
2897
  byIds: async (accountIds) => {
2867
- let req = await this.internal._createRequest(SmuleUrls.AccountLookup, { accountIds });
2898
+ const req = await this.internal._createRequest(SmuleUrls.AccountLookup, { accountIds });
2868
2899
  if (!this.internal._handleNon200(req)) return;
2869
2900
  return this.internal._getResponseData(req);
2870
2901
  },
@@ -2876,6 +2907,11 @@ var Smule = class {
2876
2907
  byId: async (accountId) => {
2877
2908
  let data = await this.account.lookup.byIds([accountId]);
2878
2909
  return data.accountIcons[0];
2910
+ },
2911
+ byContacts: async (contacts) => {
2912
+ const req = await this.internal._createRequest(SmuleUrls.ContactFind, { contacts, simCountryCode: "" });
2913
+ if (!this.internal._handleNon200(req)) return;
2914
+ return this.internal._getResponseData(req);
2879
2915
  }
2880
2916
  },
2881
2917
  /**
@@ -2883,7 +2919,7 @@ var Smule = class {
2883
2919
  * @returns Whether or not the login was successful
2884
2920
  */
2885
2921
  loginAsGuest: async () => {
2886
- let req = await this.internal._createRequest(SmuleUrls.LoginGuest, new LoginAsGuestRequest(), false, false);
2922
+ const req = await this.internal._createRequest(SmuleUrls.LoginGuest, new LoginAsGuestRequest(), false, false);
2887
2923
  if (!this.internal._handleNon200(req)) return false;
2888
2924
  let res = this.internal._getResponseData(req);
2889
2925
  this.session.sessionToken = res.loginResult.sessionToken;
@@ -2900,7 +2936,7 @@ var Smule = class {
2900
2936
  * @returns Whether the log in was successful
2901
2937
  */
2902
2938
  login: async (email, password) => {
2903
- let req = await this.internal._createRequest(SmuleUrls.UserLogin, new LoginRequest(email, password), false, false);
2939
+ const req = await this.internal._createRequest(SmuleUrls.UserLogin, new LoginRequest(email, password, new LoginCommonData(this.session.device)), false, false);
2904
2940
  if (!this.internal._handleNon200(req)) return false;
2905
2941
  let res = this.internal._getResponseData(req);
2906
2942
  this.session.sessionToken = res.sessionToken;
@@ -2927,7 +2963,7 @@ var Smule = class {
2927
2963
  _warn("Refreshing login although session isnt expired?");
2928
2964
  this.session.expired = true;
2929
2965
  }
2930
- let req = await this.internal._createRequest(SmuleUrls.LoginRefresh, { common: new LoginCommonData(this.session.device), refreshToken: this.session.refreshToken }, false, false);
2966
+ const req = await this.internal._createRequest(SmuleUrls.LoginRefresh, { common: new LoginCommonData(this.session.device), refreshToken: this.session.refreshToken }, false, false);
2931
2967
  if (!this.internal._handleNon200(req)) return false;
2932
2968
  let res = this.internal._getResponseData(req);
2933
2969
  this.session.sessionToken = res.loginResult.sessionToken;
@@ -2948,7 +2984,7 @@ var Smule = class {
2948
2984
  * @returns Your profile
2949
2985
  */
2950
2986
  fetchSelf: async () => {
2951
- let req = await this.internal._createRequest(SmuleUrls.SingUserProfileMe, { includeActiveState: false });
2987
+ const req = await this.internal._createRequest(SmuleUrls.SingUserProfileMe, { includeActiveState: false });
2952
2988
  if (!this.internal._handleNon200(req)) return;
2953
2989
  return this.internal._getResponseData(req);
2954
2990
  },
@@ -2958,9 +2994,166 @@ var Smule = class {
2958
2994
  * @returns The user's details
2959
2995
  */
2960
2996
  fetchOne: async (accountId) => {
2961
- let req = await this.internal._createRequest(SmuleUrls.SingUserProfile, new SingUserProfileRequest(accountId));
2997
+ const req = await this.internal._createRequest(SmuleUrls.SingUserProfile, new SingUserProfileRequest(accountId));
2998
+ if (!this.internal._handleNon200(req)) return;
2999
+ return this.internal._getResponseData(req);
3000
+ },
3001
+ /**
3002
+ * Registers a new account on smule
3003
+ * @param email Your email address
3004
+ * @param password Your password
3005
+ * @returns The server response
3006
+ */
3007
+ createWithEmail: async (email, password) => {
3008
+ const req = await this.internal._createRequest(SmuleUrls.UserEmailRegister, {
3009
+ ...new LoginCommonData(this.session.device),
3010
+ ageParams: {
3011
+ enteredBirthMonth: null,
3012
+ enteredBirthYear: null,
3013
+ birthDateRequired: false
3014
+ },
3015
+ email,
3016
+ password,
3017
+ emailVerificationRequired: null,
3018
+ preferredLang: "en",
3019
+ tzOffset: (/* @__PURE__ */ new Date()).getTimezoneOffset() * -60
3020
+ }, false, false);
3021
+ if (!this.internal._handleNon200(req)) {
3022
+ if ("reason" in req.data) {
3023
+ throw new Error("Registration error: " + SmuleRegisterErrorCode[req.data.reason] || req.data.reason);
3024
+ }
3025
+ }
3026
+ const data = this.internal._getResponseData(req);
3027
+ this.session.sessionToken = data.sessionToken;
3028
+ this.session.refreshToken = data.refreshToken;
3029
+ this.session.expired = false;
3030
+ this.session.isGuest = false;
3031
+ return data;
3032
+ },
3033
+ /**
3034
+ * Uploads a profile picture
3035
+ * @param imageData The image data (jpeg)
3036
+ * @returns The server response
3037
+ */
3038
+ uploadProfilePicture: async (imageData) => {
3039
+ const form = new CustomFormData();
3040
+ form.set("picture", imageData, "image/jpeg", "profile.jpg");
3041
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.UserUploadPicture, form);
2962
3042
  if (!this.internal._handleNon200(req)) return;
2963
3043
  return this.internal._getResponseData(req);
3044
+ },
3045
+ /**
3046
+ * Deletes your profile picture
3047
+ */
3048
+ deleteProfilePicture: async () => {
3049
+ const req = await this.internal._createRequest(SmuleUrls.UserPictureDelete, {});
3050
+ if (!this.internal._handleNon200(req)) return;
3051
+ },
3052
+ /**
3053
+ * Uploads a cover picture
3054
+ * @param imageData The image data
3055
+ * @remarks Requires VIP
3056
+ */
3057
+ uploadCoverPicture: async (imageData) => {
3058
+ const form = new CustomFormData();
3059
+ form.set("coverPhoto", imageData, "image/jpeg", "coverPhoto.jpg");
3060
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.SingCoverPhotoUpload, form);
3061
+ if (!this.internal._handleNon200(req)) return;
3062
+ },
3063
+ /**
3064
+ * Deletes your cover picture
3065
+ * @remarks Requires VIP
3066
+ */
3067
+ deleteCoverPicture: async () => {
3068
+ const req = await this.internal._createRequest(SmuleUrls.SingCoverPhotoDelete, {});
3069
+ if (!this.internal._handleNon200(req)) return;
3070
+ },
3071
+ /**
3072
+ * Changes your username
3073
+ * @param username The new username
3074
+ */
3075
+ changeUsername: async (username) => {
3076
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, {
3077
+ handle: username
3078
+ });
3079
+ this.internal._handleNon200(req);
3080
+ },
3081
+ /**
3082
+ * Changes your email
3083
+ * @param email The new email
3084
+ */
3085
+ changeEmail: async (email) => {
3086
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, {
3087
+ email
3088
+ });
3089
+ this.internal._handleNon200(req);
3090
+ },
3091
+ /**
3092
+ * Changes your bio
3093
+ * @param text The new bio
3094
+ */
3095
+ changeBio: async (text) => {
3096
+ const req = await this.internal._createRequest(SmuleUrls.UserBlurbUpdate, { blurb: text });
3097
+ this.internal._handleNon200(req);
3098
+ },
3099
+ /**
3100
+ * Customize your VIP profile
3101
+ * @param colorTheme The background and foreground colors (RRGGBB hex), and whether the text should be white or black
3102
+ * @param displayMentions Whether to display mentions
3103
+ * @param displayName Your new display name
3104
+ * @remarks Requires VIP
3105
+ */
3106
+ changeVIPProfileStuff: async (colorTheme, displayMentions, displayName) => {
3107
+ const req = await this.internal._createRequest(SmuleUrls.SingProfileUpdate, { colorTheme, displayName, displayMentions });
3108
+ this.internal._handleNon200(req);
3109
+ },
3110
+ /**
3111
+ * Changes your full name
3112
+ * @param firstName Your first name
3113
+ * @param lastName Your last name
3114
+ */
3115
+ changeFullName: async (firstName, lastName) => {
3116
+ const req = await this.internal._createRequest(SmuleUrls.UserPersonalUpdate, { firstName, lastName });
3117
+ this.internal._handleNon200(req);
3118
+ },
3119
+ /**
3120
+ * Changes your password
3121
+ * @param newPassword The new password
3122
+ */
3123
+ changePassword: async (newPassword) => {
3124
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, { password: newPassword });
3125
+ this.internal._handleNon200(req);
3126
+ },
3127
+ /**
3128
+ * @returns Your preferences
3129
+ */
3130
+ fetchPreferences: async () => {
3131
+ const req = await this.internal._createRequest(SmuleUrls.Pref, { names: [
3132
+ "TRACK_ACTIVENESS_DISABLE",
3133
+ // reverse "Show Chat Activity Status"
3134
+ "PROFILE_PRIVACY_MODE",
3135
+ // reverse "Show My Online Status"
3136
+ "STUDIO_TRACK_VIEW_DISABLE"
3137
+ // "Visible In Style Studio Editor"
3138
+ ] });
3139
+ if (!this.internal._handleNon200(req)) return;
3140
+ return this.internal._getResponseData(req);
3141
+ },
3142
+ /**
3143
+ * Changes your preferences
3144
+ * @param preferences The modified preferences
3145
+ */
3146
+ changePreferences: async (preferences) => {
3147
+ const req = await this.internal._createRequest(SmuleUrls.PrefUpdate, { prefs: preferences });
3148
+ this.internal._handleNon200(req);
3149
+ },
3150
+ /**
3151
+ * Changes whether you wish to receive newsletter emails
3152
+ * @param consent Whether to consent
3153
+ */
3154
+ changeNewsletterConsent: async (consent) => {
3155
+ const req = await this.internal._createRequest(SmuleUrls.UserUpdate, { newsletter: consent ? 1 : 0 });
3156
+ this.internal._handleNon200(req);
2964
3157
  }
2965
3158
  };
2966
3159
  /**
@@ -2983,7 +3176,7 @@ var Smule = class {
2983
3176
  * @returns idk
2984
3177
  */
2985
3178
  create: async (address, type = "ACCT") => {
2986
- let req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { add: [{ name: address, type }], remove: [] });
3179
+ const req = await this.internal._createRequest(SmuleUrls.SparkChatUpdate, { add: [{ name: address, type }], remove: [] });
2987
3180
  if (!this.internal._handleNon200(req)) return;
2988
3181
  return this.internal._getResponseData(req);
2989
3182
  },
@@ -3136,7 +3329,7 @@ var Smule = class {
3136
3329
  * @returns The users you're following, and the one's you aren't
3137
3330
  */
3138
3331
  isFollowingUsers: async (accountIds) => {
3139
- let req = await this.internal._createRequest(SmuleUrls.SocialIsFollowing, new IsFollowingRequest(accountIds));
3332
+ const req = await this.internal._createRequest(SmuleUrls.SocialIsFollowing, new IsFollowingRequest(accountIds));
3140
3333
  if (!this.internal._handleNon200(req)) return;
3141
3334
  return this.internal._getResponseData(req);
3142
3335
  },
@@ -3153,7 +3346,7 @@ var Smule = class {
3153
3346
  * @param accountIds The ids of the accounts to follow.
3154
3347
  */
3155
3348
  followUsers: async (accountIds) => {
3156
- let req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest(accountIds, []));
3349
+ const req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest(accountIds, []));
3157
3350
  this.internal._handleNon200(req);
3158
3351
  },
3159
3352
  /**
@@ -3168,7 +3361,7 @@ var Smule = class {
3168
3361
  * @param accountIds The ids of the accounts to unfollow.
3169
3362
  */
3170
3363
  unfollowUsers: async (accountIds) => {
3171
- let req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest([], accountIds));
3364
+ const req = await this.internal._createRequest(SmuleUrls.SocialFolloweeUpdate, new UpdateFollowingRequest([], accountIds));
3172
3365
  this.internal._handleNon200(req);
3173
3366
  },
3174
3367
  /**
@@ -3186,7 +3379,7 @@ var Smule = class {
3186
3379
  * @remarks Followee = Following
3187
3380
  */
3188
3381
  fetchFollowings: async (accountId) => {
3189
- let req = await this.internal._createRequest(SmuleUrls.SocialFollowee, { accountId });
3382
+ const req = await this.internal._createRequest(SmuleUrls.SocialFollowee, { accountId });
3190
3383
  if (!this.internal._handleNon200(req)) return;
3191
3384
  return this.internal._getResponseData(req);
3192
3385
  },
@@ -3197,7 +3390,7 @@ var Smule = class {
3197
3390
  * @remarks Smule returns the ENTIRE list of followers, nonpaginated, so make sure you use it wisely
3198
3391
  */
3199
3392
  fetchFollowers: async (accountId) => {
3200
- let req = await this.internal._createRequest(SmuleUrls.SocialFollower, { accountId });
3393
+ const req = await this.internal._createRequest(SmuleUrls.SocialFollower, { accountId });
3201
3394
  if (!this.internal._handleNon200(req)) return;
3202
3395
  return this.internal._getResponseData(req);
3203
3396
  },
@@ -3213,7 +3406,7 @@ var Smule = class {
3213
3406
  _error("Offset must be positive");
3214
3407
  return;
3215
3408
  }
3216
- let req = await this.internal._createRequest(SmuleUrls.PerformanceGetComments, {
3409
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceGetComments, {
3217
3410
  limit,
3218
3411
  offset,
3219
3412
  performanceKey,
@@ -3228,7 +3421,7 @@ var Smule = class {
3228
3421
  * @param commentKey The comment's key.
3229
3422
  */
3230
3423
  likeComment: async (performanceKey, commentKey) => {
3231
- let req = await this.internal._createRequest(SmuleUrls.CommentLike, {
3424
+ const req = await this.internal._createRequest(SmuleUrls.CommentLike, {
3232
3425
  postKey: commentKey,
3233
3426
  performanceKey
3234
3427
  });
@@ -3240,7 +3433,7 @@ var Smule = class {
3240
3433
  * @param commentKey The comment's key.
3241
3434
  */
3242
3435
  unlikeComment: async (performanceKey, commentKey) => {
3243
- let req = await this.internal._createRequest(SmuleUrls.CommentUnlike, {
3436
+ const req = await this.internal._createRequest(SmuleUrls.CommentUnlike, {
3244
3437
  postKey: commentKey,
3245
3438
  performanceKey
3246
3439
  });
@@ -3254,7 +3447,7 @@ var Smule = class {
3254
3447
  * @returns The likes on the specified comment.
3255
3448
  */
3256
3449
  fetchCommentLikes: async (performanceKey, commentKey) => {
3257
- let req = await this.internal._createRequest(SmuleUrls.CommentLikes, {
3450
+ const req = await this.internal._createRequest(SmuleUrls.CommentLikes, {
3258
3451
  postKey: commentKey,
3259
3452
  performanceKey
3260
3453
  });
@@ -3270,7 +3463,7 @@ var Smule = class {
3270
3463
  * @returns The created comment's details.
3271
3464
  */
3272
3465
  createComment: async (performanceKey, comment, latitude = 37, longitude = -120) => {
3273
- let req = await this.internal._createRequest(SmuleUrls.PerformanceComment, {
3466
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceComment, {
3274
3467
  comment,
3275
3468
  latitude,
3276
3469
  longitude,
@@ -3285,7 +3478,7 @@ var Smule = class {
3285
3478
  * @param postKeys The keys of the comments to delete.
3286
3479
  */
3287
3480
  deleteComments: async (performanceKey, postKeys) => {
3288
- let req = await this.internal._createRequest(SmuleUrls.PerformanceDeleteComment, {
3481
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceDeleteComment, {
3289
3482
  postKeys,
3290
3483
  performanceKey
3291
3484
  });
@@ -3305,7 +3498,7 @@ var Smule = class {
3305
3498
  * @param performanceKey The performance's key
3306
3499
  */
3307
3500
  likePerformance: async (performanceKey) => {
3308
- let req = await this.internal._createRequest(SmuleUrls.PerformanceLove, {
3501
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceLove, {
3309
3502
  performanceKey,
3310
3503
  latitude: this.session.latitude,
3311
3504
  longitude: this.session.longitude
@@ -3317,7 +3510,7 @@ var Smule = class {
3317
3510
  * @returns The blocked users.
3318
3511
  */
3319
3512
  fetchBlocked: async () => {
3320
- let req = await this.internal._createRequest(SmuleUrls.SocialBlockList, {});
3513
+ const req = await this.internal._createRequest(SmuleUrls.SocialBlockList, {});
3321
3514
  if (!this.internal._handleNon200(req)) return;
3322
3515
  return this.internal._getResponseData(req) || { accountIds: [] };
3323
3516
  },
@@ -3326,7 +3519,7 @@ var Smule = class {
3326
3519
  * @param accountIds The ids of the accounts to block.
3327
3520
  */
3328
3521
  blockUsers: async (accountIds) => {
3329
- let req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: accountIds, remove: [] });
3522
+ const req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: accountIds, remove: [] });
3330
3523
  this.internal._handleNon200(req);
3331
3524
  },
3332
3525
  /**
@@ -3341,7 +3534,7 @@ var Smule = class {
3341
3534
  * @param accountIds The ids of the accounts to unblock.
3342
3535
  */
3343
3536
  unblockUsers: async (accountIds) => {
3344
- let req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: [], remove: accountIds });
3537
+ const req = await this.internal._createRequest(SmuleUrls.SocialBlockUpdate, { add: [], remove: accountIds });
3345
3538
  this.internal._handleNon200(req);
3346
3539
  },
3347
3540
  /**
@@ -3360,7 +3553,7 @@ var Smule = class {
3360
3553
  * @returns An object containing the profile views of the current user.
3361
3554
  */
3362
3555
  fetchProfileViews: async (period = "WEEK", cursor = "start", limit = 10) => {
3363
- let req = await this.internal._createRequest(SmuleUrls.AccountProfileStatsViews, { period, cursor, limit });
3556
+ const req = await this.internal._createRequest(SmuleUrls.AccountProfileStatsViews, { period, cursor, limit });
3364
3557
  if (!this.internal._handleNon200(req)) return;
3365
3558
  return this.internal._getResponseData(req);
3366
3559
  },
@@ -3371,7 +3564,7 @@ var Smule = class {
3371
3564
  * @returns Some invites.
3372
3565
  */
3373
3566
  fetchPersonalInvites: async (cursor = "start", limit = 20) => {
3374
- let req = await this.internal._createRequest(SmuleUrls.InviteMe, { cursor, limit });
3567
+ const req = await this.internal._createRequest(SmuleUrls.InviteMe, { cursor, limit });
3375
3568
  if (!this.internal._handleNon200(req)) return;
3376
3569
  return this.internal._getResponseData(req);
3377
3570
  },
@@ -3382,7 +3575,7 @@ var Smule = class {
3382
3575
  * @returns Some invites.
3383
3576
  */
3384
3577
  fetchInvites: async (cursor = "start", limit = 20) => {
3385
- let req = await this.internal._createRequest(SmuleUrls.InviteList, { cursor, limit });
3578
+ const req = await this.internal._createRequest(SmuleUrls.InviteList, { cursor, limit });
3386
3579
  if (!this.internal._handleNon200(req)) return;
3387
3580
  return this.internal._getResponseData(req);
3388
3581
  }
@@ -3398,7 +3591,7 @@ var Smule = class {
3398
3591
  * @returns The "song book"
3399
3592
  */
3400
3593
  fetchSongbook: async (cursor = "start", limit = 10) => {
3401
- let req = await this.internal._createRequest(this.session.isGuest ? SmuleUrls.SongbookGuest : SmuleUrls.Songbook, new SongbookRequest(cursor, limit));
3594
+ const req = await this.internal._createRequest(this.session.isGuest ? SmuleUrls.SongbookGuest : SmuleUrls.Songbook, new SongbookRequest(cursor, limit));
3402
3595
  if (!this.internal._handleNon200(req)) return;
3403
3596
  return this.internal._getResponseData(req);
3404
3597
  },
@@ -3408,7 +3601,7 @@ var Smule = class {
3408
3601
  * @returns The updated songbook.
3409
3602
  */
3410
3603
  updateSongbook: async (categoryIds) => {
3411
- let req = await this.internal._createRequest(SmuleUrls.SongbookUpdate, { categoryIds });
3604
+ const req = await this.internal._createRequest(SmuleUrls.SongbookUpdate, { categoryIds });
3412
3605
  if (!this.internal._handleNon200(req)) return;
3413
3606
  return this.internal._getResponseData(req);
3414
3607
  },
@@ -3420,7 +3613,7 @@ var Smule = class {
3420
3613
  * @returns The songs
3421
3614
  */
3422
3615
  fetchFromCategory: async (cursor = "start", categoryId = 9998, limit = 10, duetAccountId) => {
3423
- let req = await this.internal._createRequest(SmuleUrls.Category, new CategoryRequest(cursor, limit, categoryId));
3616
+ const req = await this.internal._createRequest(SmuleUrls.Category, new CategoryRequest(cursor, limit, categoryId));
3424
3617
  if (!this.internal._handleNon200(req)) return;
3425
3618
  return this.internal._getResponseData(req);
3426
3619
  },
@@ -3430,7 +3623,7 @@ var Smule = class {
3430
3623
  * @returns The list of categories sorted by the specified type.
3431
3624
  */
3432
3625
  fetchCategoryList: async (sortType = "POPULAR") => {
3433
- let req = await this.internal._createRequest(SmuleUrls.CategoryList, { sort: sortType });
3626
+ const req = await this.internal._createRequest(SmuleUrls.CategoryList, { sort: sortType });
3434
3627
  if (!this.internal._handleNon200(req)) return;
3435
3628
  return this.internal._getResponseData(req);
3436
3629
  },
@@ -3441,14 +3634,14 @@ var Smule = class {
3441
3634
  * @returns The details of the song
3442
3635
  */
3443
3636
  fetchOne: async (key) => {
3444
- let req = await this.internal._createRequest(SmuleUrls.Arr, { arrKey: key });
3637
+ const req = await this.internal._createRequest(SmuleUrls.Arr, { arrKey: key });
3445
3638
  if (!this.internal._handleNon200(req)) return;
3446
3639
  return this.internal._getResponseData(req);
3447
3640
  },
3448
3641
  //TODO: raven is also sth ive seen in those official songs too
3449
3642
  //TODO: maybe they have another specialised id?
3450
3643
  fetchOneFromRaven: async (ravenSongId) => {
3451
- let req = await this.internal._createRequest(SmuleUrls.ArrFromRSong, { rsongId: ravenSongId });
3644
+ const req = await this.internal._createRequest(SmuleUrls.ArrFromRSong, { rsongId: ravenSongId });
3452
3645
  if (!this.internal._handleNon200(req)) return;
3453
3646
  return this.internal._getResponseData(req);
3454
3647
  },
@@ -3458,13 +3651,26 @@ var Smule = class {
3458
3651
  * @returns The details of the songs.
3459
3652
  */
3460
3653
  fetch: async (keys) => {
3461
- let req = await this.internal._createRequest(SmuleUrls.ArrByKeys, { arrKeys: keys });
3654
+ const req = await this.internal._createRequest(SmuleUrls.ArrByKeys, { arrKeys: keys });
3462
3655
  if (!this.internal._handleNon200(req)) return;
3463
3656
  return this.internal._getResponseData(req);
3464
3657
  },
3465
3658
  // TODO: test and doc
3466
3659
  fetchOwnedBy: async (ownerId, offset = 0, limit = 10) => {
3467
- let req = await this.internal._createRequest(SmuleUrls.ArrOwned, { ownerAccountId: ownerId, offset, limit });
3660
+ const req = await this.internal._createRequest(SmuleUrls.ArrOwned, { ownerAccountId: ownerId, offset, limit });
3661
+ if (!this.internal._handleNon200(req)) return;
3662
+ return this.internal._getResponseData(req);
3663
+ },
3664
+ /**
3665
+ * Fetches free songs from a list of genres
3666
+ *
3667
+ * This endpoint is usually used at register, to recommend
3668
+ * some songs to the new user.
3669
+ * @param genreIds The ids of the genres
3670
+ * @returns A stupid nested list with free "compositions"
3671
+ */
3672
+ fetchFromGenres: async (genreIds) => {
3673
+ const req = await this.internal._createRequest(SmuleUrls.TopicChoose, { compositionChoices: true, topicIds: genreIds });
3468
3674
  if (!this.internal._handleNon200(req)) return;
3469
3675
  return this.internal._getResponseData(req);
3470
3676
  },
@@ -3504,22 +3710,18 @@ var Smule = class {
3504
3710
  /**
3505
3711
  * Bookmarks a song.
3506
3712
  * @param key The song / arr key.
3507
- * @returns idk
3508
3713
  */
3509
3714
  bookmark: async (key) => {
3510
- let req = await this.internal._createRequest(SmuleUrls.ArrBookmark, { arrKey: key });
3511
- if (!this.internal._handleNon200(req)) return;
3512
- return this.internal._getResponseData(req);
3715
+ const req = await this.internal._createRequest(SmuleUrls.ArrBookmark, { arrKey: key });
3716
+ this.internal._handleNon200(req);
3513
3717
  },
3514
3718
  /**
3515
3719
  * Unbookmarks a song.
3516
3720
  * @param key The song / arr key.
3517
- * @returns idk
3518
3721
  */
3519
3722
  unbookmark: async (key) => {
3520
- let req = await this.internal._createRequest(SmuleUrls.ArrBookmarkRemove, { arrKey: key });
3521
- if (!this.internal._handleNon200(req)) return;
3522
- return this.internal._getResponseData(req);
3723
+ const req = await this.internal._createRequest(SmuleUrls.ArrBookmarkRemove, { arrKey: key });
3724
+ this.internal._handleNon200(req);
3523
3725
  },
3524
3726
  /**
3525
3727
  * Fetches bookmarked songs.
@@ -3528,25 +3730,25 @@ var Smule = class {
3528
3730
  * @returns idk prolly bookmarks
3529
3731
  */
3530
3732
  fetchBookmarks: async (cursor = "start", limit = 10) => {
3531
- let req = await this.internal._createRequest(SmuleUrls.ArrBookmarkList, { cursor, limit });
3733
+ const req = await this.internal._createRequest(SmuleUrls.ArrBookmarkList, { cursor, limit });
3532
3734
  if (!this.internal._handleNon200(req)) return;
3533
3735
  return this.internal._getResponseData(req);
3534
3736
  },
3535
3737
  //TODO:
3536
3738
  update: async (key, artist, name, tags) => {
3537
- let req = await this.internal._createRequest(SmuleUrls.ArrUpdate, { arrKey: key, artist, name, tags });
3739
+ const req = await this.internal._createRequest(SmuleUrls.ArrUpdate, { arrKey: key, artist, name, tags });
3538
3740
  if (!this.internal._handleNon200(req)) return;
3539
3741
  return this.internal._getResponseData(req);
3540
3742
  },
3541
3743
  //TODO:
3542
3744
  vote: async (key, arrVersion, reason, vote) => {
3543
- let req = await this.internal._createRequest(SmuleUrls.ArrVote, { arrKey: key, ver: arrVersion, reason, vote });
3745
+ const req = await this.internal._createRequest(SmuleUrls.ArrVote, { arrKey: key, ver: arrVersion, reason, vote });
3544
3746
  if (!this.internal._handleNon200(req)) return;
3545
3747
  return this.internal._getResponseData(req);
3546
3748
  },
3547
3749
  //TODO:
3548
3750
  delete: async (key, deletePerformances = true) => {
3549
- let req = await this.internal._createRequest(SmuleUrls.ArrDelete, { arrKey: key, deletePerfs: deletePerformances });
3751
+ const req = await this.internal._createRequest(SmuleUrls.ArrDelete, { arrKey: key, deletePerfs: deletePerformances });
3550
3752
  if (!this.internal._handleNon200(req)) return;
3551
3753
  return this.internal._getResponseData(req);
3552
3754
  }
@@ -3565,7 +3767,7 @@ var Smule = class {
3565
3767
  * @returns The performances' details
3566
3768
  */
3567
3769
  byKeys: async (performanceKeys) => {
3568
- let req = await this.internal._createRequest(SmuleUrls.PerformanceByKeys, { performanceKeys });
3770
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceByKeys, { performanceKeys });
3569
3771
  if (!this.internal._handleNon200(req)) return;
3570
3772
  return this.internal._getResponseData(req);
3571
3773
  },
@@ -3586,7 +3788,7 @@ var Smule = class {
3586
3788
  * @returns The performances
3587
3789
  */
3588
3790
  byUser: async (accountId, fillStatus = "FILLED", sortMethod = "NEWEST_FIRST", limit = 20, offset = 0) => {
3589
- let req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3791
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3590
3792
  if (!this.internal._handleNon200(req)) return;
3591
3793
  return this.internal._getResponseData(req);
3592
3794
  },
@@ -3600,7 +3802,21 @@ var Smule = class {
3600
3802
  * @returns The performances associated with the given AV template.
3601
3803
  */
3602
3804
  byAvTemplate: async (templateId, cursor = "start", limit = 10, performanceKey) => {
3603
- let req = await this.internal._createRequest(SmuleUrls.DiscoveryPerfByAvTemplateList, { avTemplateId: templateId, cursor, limit, performanceKey });
3805
+ const req = await this.internal._createRequest(SmuleUrls.DiscoveryPerfByAvTemplateList, { avTemplateId: templateId, cursor, limit, performanceKey });
3806
+ if (!this.internal._handleNon200(req)) return;
3807
+ return this.internal._getResponseData(req);
3808
+ },
3809
+ /**
3810
+ * Fetches performances based on the specified genre.
3811
+ * @param genreId The id of the genre
3812
+ * @param offset The starting point
3813
+ * @param limit The maximum number of performances
3814
+ * @param fillStatus Type of performances
3815
+ * @param sort The order
3816
+ * @returns The performances
3817
+ */
3818
+ byGenre: async (genreId, offset = 0, limit = 10, fillStatus = "FILLED", sort = "SUGGESTED") => {
3819
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceList, { fillStatus, limit, offset, sort, topicId: genreId });
3604
3820
  if (!this.internal._handleNon200(req)) return;
3605
3821
  return this.internal._getResponseData(req);
3606
3822
  }
@@ -3642,7 +3858,7 @@ var Smule = class {
3642
3858
  * @returns The performance lists.
3643
3859
  */
3644
3860
  fetchLists: async (requests) => {
3645
- let req = await this.internal._createRequest(SmuleUrls.PerformanceLists, { perfRequests: requests });
3861
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceLists, { perfRequests: requests });
3646
3862
  if (!this.internal._handleNon200(req)) return;
3647
3863
  return this.internal._getResponseData(req);
3648
3864
  },
@@ -3652,7 +3868,7 @@ var Smule = class {
3652
3868
  * @returns The performance's details
3653
3869
  */
3654
3870
  fetchOne: async (performanceKey) => {
3655
- let req = await this.internal._createRequest(SmuleUrls.PerformanceUrl, { performanceKey });
3871
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceUrl, { performanceKey });
3656
3872
  if (!this.internal._handleNon200(req)) return;
3657
3873
  return this.internal._getResponseData(req);
3658
3874
  },
@@ -3666,7 +3882,12 @@ var Smule = class {
3666
3882
  * @returns The performances of the user
3667
3883
  */
3668
3884
  fetchFromAccount: async (accountId, fillStatus = "FILLED", sortMethod = "NEWEST_FIRST", limit = 20, offset = 0) => {
3669
- let req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3885
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceParts, new PerformancePartsRequest(accountId, fillStatus, sortMethod, limit, offset));
3886
+ if (!this.internal._handleNon200(req)) return;
3887
+ return this.internal._getResponseData(req);
3888
+ },
3889
+ fetchBookmarkedInvites: async (offset = 0, limit = 10) => {
3890
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceBookmarkSeed, { offset, limit, forApps: ["sing_google"] });
3670
3891
  if (!this.internal._handleNon200(req)) return;
3671
3892
  return this.internal._getResponseData(req);
3672
3893
  },
@@ -3678,7 +3899,7 @@ var Smule = class {
3678
3899
  * @returns The children performances of the given performance.
3679
3900
  */
3680
3901
  fetchChildren: async (performanceKey, limit = 25, offset = 0) => {
3681
- let req = await this.internal._createRequest(SmuleUrls.PerformanceChildren, { performanceKey, limit, offset });
3902
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceChildren, { performanceKey, limit, offset });
3682
3903
  if (!this.internal._handleNon200(req)) {
3683
3904
  return {
3684
3905
  performanceIcons: [],
@@ -3693,7 +3914,7 @@ var Smule = class {
3693
3914
  * @returns The details of the performances.
3694
3915
  */
3695
3916
  fetchDetails: async (performanceKeys) => {
3696
- let req = await this.internal._createRequest(SmuleUrls.PerformanceListDetails, { keys: performanceKeys, returnAvTemplateDetails: true, returnBookmarked: true, returnLoved: true, returnRestricted: true, returnTopComment: true });
3917
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceListDetails, { keys: performanceKeys, returnAvTemplateDetails: true, returnBookmarked: true, returnLoved: true, returnRestricted: true, returnTopComment: true });
3697
3918
  if (!this.internal._handleNon200(req)) return;
3698
3919
  return this.internal._getResponseData(req);
3699
3920
  },
@@ -3830,7 +4051,15 @@ var Smule = class {
3830
4051
  * @param performanceKey The key of the performance to be deleted.
3831
4052
  */
3832
4053
  deleteOne: async (performanceKey) => {
3833
- let req = await this.internal._createRequest(SmuleUrls.PerformanceDelete, { performanceKey });
4054
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceDelete, { performanceKey });
4055
+ this.internal._handleNon200(req);
4056
+ },
4057
+ bookmarkInvites: async (performanceKeys) => {
4058
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceBookmarkSeedUpdate, { add: performanceKeys, remove: [] });
4059
+ this.internal._handleNon200(req);
4060
+ },
4061
+ unbookmarkInvites: async (performanceKeys) => {
4062
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceBookmarkSeedUpdate, { add: [], remove: performanceKeys });
3834
4063
  this.internal._handleNon200(req);
3835
4064
  }
3836
4065
  };
@@ -3843,7 +4072,7 @@ var Smule = class {
3843
4072
  * @returns The trending searches currently available
3844
4073
  */
3845
4074
  fetchTrending: async () => {
3846
- let req = await this.internal._createRequest(SmuleUrls.RecTsrch, {});
4075
+ const req = await this.internal._createRequest(SmuleUrls.RecTsrch, {});
3847
4076
  if (!this.internal._handleNon200(req)) return;
3848
4077
  return this.internal._getResponseData(req);
3849
4078
  },
@@ -3853,7 +4082,7 @@ var Smule = class {
3853
4082
  * @returns The search result
3854
4083
  */
3855
4084
  perform: async (query) => {
3856
- let req = await this.internal._createRequest(SmuleUrls.SearchGlobal, { includeRecording: 0, term: query });
4085
+ const req = await this.internal._createRequest(SmuleUrls.SearchGlobal, { includeRecording: 0, term: query });
3857
4086
  if (!this.internal._handleNon200(req)) return;
3858
4087
  return this.internal._getResponseData(req);
3859
4088
  },
@@ -3867,7 +4096,7 @@ var Smule = class {
3867
4096
  * @returns The search results matching the specified criteria.
3868
4097
  */
3869
4098
  performSpecific: async (query, type, sort = "POPULAR", cursor = "start", limit = 25) => {
3870
- let req = await this.internal._createRequest(SmuleUrls.Search, new SearchRequest(cursor, limit, type, sort, query));
4099
+ const req = await this.internal._createRequest(SmuleUrls.Search, new SearchRequest(cursor, limit, type, sort, query));
3871
4100
  if (!this.internal._handleNon200(req)) return;
3872
4101
  return this.internal._getResponseData(req);
3873
4102
  },
@@ -3878,7 +4107,7 @@ var Smule = class {
3878
4107
  * @returns The autocomplete suggestions
3879
4108
  */
3880
4109
  fetchAutocomplete: async (query, limit = 5) => {
3881
- let req = await this.internal._createRequest(SmuleUrls.SearchAutocomplete, new SearchAutocompleteRequest(query, limit));
4110
+ const req = await this.internal._createRequest(SmuleUrls.SearchAutocomplete, new SearchAutocompleteRequest(query, limit));
3882
4111
  if (!this.internal._handleNon200(req)) return;
3883
4112
  return this.internal._getResponseData(req);
3884
4113
  }
@@ -3894,7 +4123,7 @@ var Smule = class {
3894
4123
  * @returns The fetched AV templates.
3895
4124
  */
3896
4125
  fetch: async (limit = 25) => {
3897
- let req = await this.internal._createRequest(SmuleUrls.AvtemplateCategoryList, new AvTemplateCategoryListRequest("AUDIO", "start", limit, "STANDARD"));
4126
+ const req = await this.internal._createRequest(SmuleUrls.AvtemplateCategoryList, new AvTemplateCategoryListRequest("AUDIO", "start", limit, "STANDARD"));
3898
4127
  if (!this.internal._handleNon200(req)) return;
3899
4128
  return this.internal._getResponseData(req);
3900
4129
  }
@@ -3909,7 +4138,7 @@ var Smule = class {
3909
4138
  * @param arrKey The key associated with the song to be marked as played.
3910
4139
  */
3911
4140
  markSongAsPlayed: async (arrKey) => {
3912
- let req = await this.internal._createRequest(SmuleUrls.ArrPlay, { arrKey });
4141
+ const req = await this.internal._createRequest(SmuleUrls.ArrPlay, { arrKey });
3913
4142
  this.internal._handleNon200(req);
3914
4143
  },
3915
4144
  /**
@@ -3918,7 +4147,7 @@ var Smule = class {
3918
4147
  * @param performanceKey The key associated with the performance to be marked as played.
3919
4148
  */
3920
4149
  markPerformanceAsPlayed: async (performanceKey) => {
3921
- let req = await this.internal._createRequest(SmuleUrls.PerformancePlay, { performanceKey });
4150
+ const req = await this.internal._createRequest(SmuleUrls.PerformancePlay, { performanceKey });
3922
4151
  this.internal._handleNon200(req);
3923
4152
  },
3924
4153
  /**
@@ -3927,7 +4156,7 @@ var Smule = class {
3927
4156
  * @param performanceKey The key associated with the performance to be marked as listened to.
3928
4157
  */
3929
4158
  markPerformanceListenStart: async (performanceKey) => {
3930
- let req = await this.internal._createRequest(SmuleUrls.PerformanceListenStart, { performanceKey });
4159
+ const req = await this.internal._createRequest(SmuleUrls.PerformanceListenStart, { performanceKey });
3931
4160
  this.internal._handleNon200(req);
3932
4161
  }
3933
4162
  };
@@ -3940,7 +4169,7 @@ var Smule = class {
3940
4169
  * @returns The playlists that match the specified criteria.
3941
4170
  */
3942
4171
  fetchPlaylists: async () => {
3943
- let req = await this.internal._createRequest(SmuleUrls.PlaylistExplore, {});
4172
+ const req = await this.internal._createRequest(SmuleUrls.PlaylistExplore, {});
3944
4173
  if (!this.internal._handleNon200(req)) return;
3945
4174
  return this.internal._getResponseData(req);
3946
4175
  },
@@ -3952,7 +4181,7 @@ var Smule = class {
3952
4181
  * @returns The playlist with the specified details.
3953
4182
  */
3954
4183
  fetchPlaylist: async (playlistId, offset = 0, limit = 10) => {
3955
- let req = await this.internal._createRequest(SmuleUrls.PlaylistGet, { playlistId, offset, limit });
4184
+ const req = await this.internal._createRequest(SmuleUrls.PlaylistGet, { playlistId, offset, limit });
3956
4185
  if (!this.internal._handleNon200(req)) return;
3957
4186
  return this.internal._getResponseData(req);
3958
4187
  },
@@ -3963,7 +4192,14 @@ var Smule = class {
3963
4192
  * @returns The users that match the specified criteria.
3964
4193
  */
3965
4194
  fetchAccounts: async (cursor = "start", limit = 20) => {
3966
- let req = await this.internal._createRequest(SmuleUrls.AccountExplore, { cursor, limit });
4195
+ const req = await this.internal._createRequest(SmuleUrls.AccountExplore, { cursor, limit });
4196
+ if (!this.internal._handleNon200(req)) return;
4197
+ return this.internal._getResponseData(req);
4198
+ },
4199
+ // TODO: find out if this is the same as #fetchAccounts
4200
+ // TODO: this one is used in the find friends tab, but it might be the same exact thing
4201
+ fetchRecommendedAccounts: async (cursor = "start", limit = 20) => {
4202
+ const req = await this.internal._createRequest(SmuleUrls.RecAcct, { cursor, limit });
3967
4203
  if (!this.internal._handleNon200(req)) return;
3968
4204
  return this.internal._getResponseData(req);
3969
4205
  },
@@ -3975,7 +4211,7 @@ var Smule = class {
3975
4211
  * @returns The groups matching the specified criteria.
3976
4212
  */
3977
4213
  fetchGroups: async (cursor = "start", limit = 10, sortBy = "RECOMMENDED") => {
3978
- let req = await this.internal._createRequest(SmuleUrls.SfamList, { cursor, limit, sortBy });
4214
+ const req = await this.internal._createRequest(SmuleUrls.SfamList, { cursor, limit, sortBy });
3979
4215
  if (!this.internal._handleNon200(req)) return;
3980
4216
  return this.internal._getResponseData(req);
3981
4217
  },
@@ -3989,7 +4225,7 @@ var Smule = class {
3989
4225
  */
3990
4226
  fetchLivestreams: async (cursor = "start", limit = 20, sort = "POPULAR") => {
3991
4227
  let self = await this.account.fetchSelf();
3992
- let req = await this.internal._createRequest(SmuleUrls.CfireList, { accountId: self.profile.accountIcon.accountId, cursor, limit, sort });
4228
+ const req = await this.internal._createRequest(SmuleUrls.CfireList, { accountId: self.profile.accountIcon.accountId, cursor, limit, sort });
3993
4229
  if (!this.internal._handleNon200(req)) return;
3994
4230
  return this.internal._getResponseData(req);
3995
4231
  },
@@ -4001,7 +4237,27 @@ var Smule = class {
4001
4237
  * @remarks You must be logged in in order to fetch your feed.
4002
4238
  */
4003
4239
  fetchFeed: async (cursor = "start", limit = 20) => {
4004
- let req = await this.internal._createRequest(SmuleUrls.SocialFeedList, { cursor, limit });
4240
+ const req = await this.internal._createRequest(SmuleUrls.SocialFeedList, { cursor, limit });
4241
+ if (!this.internal._handleNon200(req)) return;
4242
+ return this.internal._getResponseData(req);
4243
+ },
4244
+ /**
4245
+ * Fetches a list of genres
4246
+ * @param cursor The offset to start from
4247
+ * @param limit The number of genres to fetch
4248
+ * @returns A list of genres
4249
+ */
4250
+ fetchGenres: async (cursor = 0, limit = 10) => {
4251
+ const req = await this.internal._createRequest(SmuleUrls.TopicOption, { limit, offset: cursor, singleCoverUrl: false });
4252
+ if (!this.internal._handleNon200(req)) return;
4253
+ return this.internal._getResponseData(req);
4254
+ },
4255
+ /**
4256
+ * Fetches your selected genres
4257
+ * @returns A list of genres
4258
+ */
4259
+ fetchYourGenres: async () => {
4260
+ const req = await this.internal._createRequest(SmuleUrls.Topic, {});
4005
4261
  if (!this.internal._handleNon200(req)) return;
4006
4262
  return this.internal._getResponseData(req);
4007
4263
  }
@@ -4009,7 +4265,7 @@ var Smule = class {
4009
4265
  // utterly useless but it's here if needed
4010
4266
  settings = {
4011
4267
  fetch: async () => {
4012
- let req = await this.internal._createRequest(SmuleUrls.Settings, new SettingsRequest(this.session.device));
4268
+ const req = await this.internal._createRequest(SmuleUrls.Settings, new SettingsRequest(this.session.device));
4013
4269
  if (!this.internal._handleNon200(req)) return;
4014
4270
  return this.internal._getResponseData(req);
4015
4271
  }
@@ -4121,9 +4377,132 @@ var Smule = class {
4121
4377
  }
4122
4378
  },
4123
4379
  fetch: async (campfireId) => {
4124
- let req = await this.internal._createRequest(SmuleUrls.CfireSync, { campfireId });
4380
+ const req = await this.internal._createRequest(SmuleUrls.CfireSync, { campfireId });
4381
+ if (!this.internal._handleNon200(req)) return;
4382
+ return this.internal._getResponseData(req);
4383
+ }
4384
+ };
4385
+ groups = {
4386
+ /**
4387
+ * Fetches a group's details
4388
+ * @param groupId The ID of the group
4389
+ * @returns The group
4390
+ */
4391
+ fetchOne: async (groupId) => {
4392
+ const req = await this.internal._createRequest(SmuleUrls.SfamInfo, { sfamId: groupId });
4393
+ if (!this.internal._handleNon200(req)) return;
4394
+ return this.internal._getResponseData(req);
4395
+ },
4396
+ /**
4397
+ * Fetches a group's posts
4398
+ * @param groupId The ID of the group
4399
+ * @param cursor The starting point
4400
+ * @param limit How many to fetch
4401
+ * @returns The posts
4402
+ */
4403
+ fetchPosts: async (groupId, cursor = "start", limit = 10) => {
4404
+ const req = await this.internal._createRequest(SmuleUrls.SfamPostFeed, { sfamId: groupId, cursor, limit });
4405
+ if (!this.internal._handleNon200(req)) return;
4406
+ return this.internal._getResponseData(req);
4407
+ },
4408
+ /**
4409
+ * Fetches a group's members
4410
+ * @param groupId The ID of the group
4411
+ * @param cursor Starting point
4412
+ * @param limit How many
4413
+ * @param roles Member roles (0 - owner, 1 - admin, 2 - member)
4414
+ * @returns The members
4415
+ */
4416
+ fetchMembers: async (groupId, cursor = "start", limit = 10, roles = [2]) => {
4417
+ const req = await this.internal._createRequest(SmuleUrls.SfamMemberList, { sfamId: groupId, cursor, limit, roles, memberGroup: 0, vipStatus: "ALL" });
4418
+ if (!this.internal._handleNon200(req)) return;
4419
+ return this.internal._getResponseData(req);
4420
+ },
4421
+ /**
4422
+ * Sends a request to join a group
4423
+ * @param groupId The ID of the group
4424
+ * @returns The membership status
4425
+ */
4426
+ join: async (groupId) => {
4427
+ const req = await this.internal._createRequest(SmuleUrls.SfamMembershipRequestSend, { sfamId: groupId });
4428
+ if (!this.internal._handleNon200(req)) return;
4429
+ return SmuleUtil.getGroupMembershipType(this.internal._getResponseData(req).mbrshipStatus);
4430
+ },
4431
+ /**
4432
+ * Uploads a cover picture for a group
4433
+ * @param imageData The image data
4434
+ * @returns The resource ID of the uploaded image, to be used in `create`
4435
+ */
4436
+ uploadCoverPicture: async (imageData) => {
4437
+ const form = new CustomFormData();
4438
+ form.set("coverPhoto", imageData, "image/jpeg", "family_cover_photo.jpg");
4439
+ const req = await this.internal._createRequestMultiPart(SmuleUrls.SfamCoverPhotoUpload, form);
4440
+ if (!this.internal._handleNon200(req)) return;
4441
+ return this.internal._getResponseData(req).resource_id;
4442
+ },
4443
+ /**
4444
+ * Creates a group
4445
+ * @param name The name of the group
4446
+ * @param desc The description of the group
4447
+ * @param lang The language
4448
+ * @param loc The location (XX - global)
4449
+ * @param picId The resource id of the cover picture
4450
+ * @param sfamTag The global group tag
4451
+ * @returns The group
4452
+ */
4453
+ create: async (name, desc, lang, loc, picId, sfamTag) => {
4454
+ const req = await this.internal._createRequest(SmuleUrls.SfamCreate, { name, desc, lang, loc, picId, sfamTag });
4455
+ if (!this.internal._handleNon200(req)) return;
4456
+ return this.internal._getResponseData(req).sfam;
4457
+ },
4458
+ /**
4459
+ * Posts multiple performances to a group's feed
4460
+ * @param performanceKeys The performances to post
4461
+ * @param groupId The ID of the group
4462
+ */
4463
+ postPerformances: async (performanceKeys, groupId) => {
4464
+ const req = await this.internal._createRequest(SmuleUrls.SfamPostAdd, { objects: performanceKeys, sfamId: groupId });
4465
+ this.internal._handleNon200(req);
4466
+ },
4467
+ /**
4468
+ * Removes a post from a group
4469
+ * @param groupId The ID of the group
4470
+ * @param postId The ID of the post
4471
+ * @param postType The type of the post
4472
+ */
4473
+ removePost: async (groupId, postId, postType = "FEED") => {
4474
+ const req = await this.internal._createRequest(SmuleUrls.SfamPostRemove, { sfamId: groupId, postId, postType });
4475
+ this.internal._handleNon200(req);
4476
+ }
4477
+ };
4478
+ playlists = {
4479
+ create: async (name, visibility = "PUB") => {
4480
+ const req = await this.internal._createRequest(SmuleUrls.AplistCreate, { name, visibility });
4481
+ if (!this.internal._handleNon200(req)) return;
4482
+ return this.internal._getResponseData(req).playlistIcon;
4483
+ },
4484
+ addPerformance: async (playlistKey, performanceKey) => {
4485
+ const req = await this.internal._createRequest(SmuleUrls.AplistPerfAdd, { playlistKey, perfKey: performanceKey });
4486
+ this.internal._handleNon200(req);
4487
+ },
4488
+ changeVisibility: async (playlistKey, visibility) => {
4489
+ const req = await this.internal._createRequest(SmuleUrls.AplistUpdate, { playlistKey, visibility });
4490
+ if (!this.internal._handleNon200(req)) return;
4491
+ return this.internal._getResponseData(req).playlistIcon;
4492
+ },
4493
+ changeName: async (playlistKey, name) => {
4494
+ const req = await this.internal._createRequest(SmuleUrls.AplistUpdate, { playlistKey, name });
4495
+ if (!this.internal._handleNon200(req)) return;
4496
+ return this.internal._getResponseData(req).playlistIcon;
4497
+ },
4498
+ fetchOne: async (playlistKey, sortMethod, cursor = "start", limit = 10) => {
4499
+ const req = await this.internal._createRequest(SmuleUrls.AplistView, { playlistKey, playlistSortMethod: sortMethod, cursor, limit });
4125
4500
  if (!this.internal._handleNon200(req)) return;
4126
4501
  return this.internal._getResponseData(req);
4502
+ },
4503
+ deleteOne: async (playlistKey) => {
4504
+ const req = await this.internal._createRequest(SmuleUrls.AplistDelete, { playlistKey });
4505
+ this.internal._handleNon200(req);
4127
4506
  }
4128
4507
  };
4129
4508
  // shit i try to test
@@ -4444,6 +4823,116 @@ var SmuleDotCom = class {
4444
4823
  return req.data;
4445
4824
  }
4446
4825
  };
4826
+
4827
+ // src/smule-effects.ts
4828
+ import * as yauzl from "yauzl";
4829
+ var SmuleEffects;
4830
+ ((SmuleEffects2) => {
4831
+ function processZipFile(filePath) {
4832
+ return new Promise((resolve, reject) => {
4833
+ yauzl.open(filePath, { lazyEntries: true, decodeStrings: false }, (err, zipfile) => {
4834
+ let filesRead = 0;
4835
+ if (err) throw err;
4836
+ zipfile.readEntry();
4837
+ let data = {
4838
+ component_library: {},
4839
+ template: {},
4840
+ copyright: "my ass",
4841
+ files: {}
4842
+ };
4843
+ zipfile.on("entry", (entry) => {
4844
+ let fileName = entry.fileName.toString("utf-8");
4845
+ if (fileName.endsWith(".alyc")) {
4846
+ if (Object.keys(data.component_library).length > 1) {
4847
+ console.warn("[SmuleEffects] Double component_library file? that shouldnt happen i think? Overwriting...");
4848
+ }
4849
+ zipfile.openReadStream(entry, (err2, stream) => {
4850
+ if (err2) throw err2;
4851
+ let rawData = [];
4852
+ stream.on("data", (chunk) => {
4853
+ rawData.push(chunk);
4854
+ });
4855
+ stream.on("end", () => {
4856
+ let componentLibrary = JSON.parse(Buffer.concat(rawData).toString("utf-8"));
4857
+ data.component_library = componentLibrary;
4858
+ filesRead++;
4859
+ });
4860
+ });
4861
+ } else if (fileName.endsWith(".alyt")) {
4862
+ if (Object.keys(data.template).length > 1) {
4863
+ console.warn("[SmuleEffects] Double template file? that shouldnt happen i think? Overwriting...");
4864
+ }
4865
+ zipfile.openReadStream(entry, (err2, stream) => {
4866
+ if (err2) throw err2;
4867
+ let rawData = [];
4868
+ stream.on("data", (chunk) => {
4869
+ rawData.push(chunk);
4870
+ });
4871
+ stream.on("end", () => {
4872
+ let template = JSON.parse(Buffer.concat(rawData).toString("utf-8"));
4873
+ data.template = template;
4874
+ filesRead++;
4875
+ });
4876
+ });
4877
+ } else if (fileName.endsWith(".alyg") || fileName.endsWith(".json")) {
4878
+ zipfile.openReadStream(entry, (err2, stream) => {
4879
+ if (err2) throw err2;
4880
+ let rawData = [];
4881
+ stream.on("data", (chunk) => {
4882
+ rawData.push(chunk);
4883
+ });
4884
+ stream.on("end", () => {
4885
+ data.files[fileName] = JSON.parse(Buffer.concat(rawData).toString("utf-8"));
4886
+ filesRead++;
4887
+ });
4888
+ });
4889
+ } else if (fileName == "copyright.txt") {
4890
+ zipfile.openReadStream(entry, (err2, stream) => {
4891
+ if (err2) throw err2;
4892
+ let rawData = [];
4893
+ stream.on("data", (chunk) => {
4894
+ rawData.push(chunk);
4895
+ });
4896
+ stream.on("end", () => {
4897
+ data.copyright = Buffer.concat(rawData).toString("utf-8");
4898
+ filesRead++;
4899
+ });
4900
+ });
4901
+ } else if (fileName.endsWith(".txt")) {
4902
+ zipfile.openReadStream(entry, (err2, stream) => {
4903
+ if (err2) throw err2;
4904
+ let rawData = [];
4905
+ stream.on("data", (chunk) => {
4906
+ rawData.push(chunk);
4907
+ });
4908
+ stream.on("end", () => {
4909
+ data.files[fileName] = Buffer.concat(rawData).toString("utf-8");
4910
+ filesRead++;
4911
+ });
4912
+ });
4913
+ } else {
4914
+ data.files[fileName] = fileName;
4915
+ filesRead++;
4916
+ }
4917
+ zipfile.readEntry();
4918
+ });
4919
+ zipfile.on("end", () => {
4920
+ let entries = zipfile.entriesRead;
4921
+ zipfile.close();
4922
+ let interval = setInterval(() => {
4923
+ if (entries > filesRead) return;
4924
+ clearInterval(interval);
4925
+ resolve(data);
4926
+ }, 1);
4927
+ });
4928
+ });
4929
+ });
4930
+ }
4931
+ SmuleEffects2.processZipFile = processZipFile;
4932
+ function processRawEffects(data) {
4933
+ }
4934
+ SmuleEffects2.processRawEffects = processRawEffects;
4935
+ })(SmuleEffects || (SmuleEffects = {}));
4447
4936
  export {
4448
4937
  AvTemplateCategoryListRequest,
4449
4938
  CategoryRequest,
@@ -4465,7 +4954,9 @@ export {
4465
4954
  SingUserProfileRequest,
4466
4955
  Smule,
4467
4956
  SmuleDotCom,
4957
+ SmuleEffects,
4468
4958
  SmuleErrorCode,
4959
+ SmuleRegisterErrorCode,
4469
4960
  SmuleSession,
4470
4961
  SmuleUrls,
4471
4962
  SmuleUserSinging,