noblox-asset.js 7.4.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.
Files changed (272) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
  2. package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
  3. package/.github/workflows/doc-publish.yml +33 -0
  4. package/.github/workflows/npmpublish.yml +72 -0
  5. package/.github/workflows/run-tests.yml +49 -0
  6. package/CODE_OF_CONDUCT.md +76 -0
  7. package/LICENSE +21 -0
  8. package/README.md +182 -0
  9. package/eslint.config.mjs +34 -0
  10. package/examples/cleanPlayers.js +130 -0
  11. package/examples/cleanWall.js +110 -0
  12. package/examples/revertRanks.js +100 -0
  13. package/examples/savePlayers.js +119 -0
  14. package/examples/saveWall.js +96 -0
  15. package/img/moderatedThumbnails/moderatedThumbnail_100x100.png +0 -0
  16. package/img/moderatedThumbnails/moderatedThumbnail_110x110.png +0 -0
  17. package/img/moderatedThumbnails/moderatedThumbnail_140x140.png +0 -0
  18. package/img/moderatedThumbnails/moderatedThumbnail_150x150.png +0 -0
  19. package/img/moderatedThumbnails/moderatedThumbnail_150x200.png +0 -0
  20. package/img/moderatedThumbnails/moderatedThumbnail_180x180.png +0 -0
  21. package/img/moderatedThumbnails/moderatedThumbnail_250x250.png +0 -0
  22. package/img/moderatedThumbnails/moderatedThumbnail_30x30.png +0 -0
  23. package/img/moderatedThumbnails/moderatedThumbnail_352x352.png +0 -0
  24. package/img/moderatedThumbnails/moderatedThumbnail_420x420.png +0 -0
  25. package/img/moderatedThumbnails/moderatedThumbnail_48x48.png +0 -0
  26. package/img/moderatedThumbnails/moderatedThumbnail_50x50.png +0 -0
  27. package/img/moderatedThumbnails/moderatedThumbnail_60x60.png +0 -0
  28. package/img/moderatedThumbnails/moderatedThumbnail_720x720.png +0 -0
  29. package/img/moderatedThumbnails/moderatedThumbnail_75x75.png +0 -0
  30. package/img/noblox-js-small.png +0 -0
  31. package/img/noblox-js.png +0 -0
  32. package/img/thumbnailSizes.png +0 -0
  33. package/jsDocsConfig.json +55 -0
  34. package/lib/accountinformation/getUserSocialLinks.js +40 -0
  35. package/lib/accountsettings/block.js +53 -0
  36. package/lib/accountsettings/unblock.js +53 -0
  37. package/lib/asset/deleteFromInventory.js +56 -0
  38. package/lib/asset/getGamePassProductInfo.js +50 -0
  39. package/lib/asset/getProductInfo.js +46 -0
  40. package/lib/asset/uploadAnimation.js +103 -0
  41. package/lib/asset/uploadItem.js +83 -0
  42. package/lib/asset/uploadModel.js +90 -0
  43. package/lib/avatar/avatarRules.js +39 -0
  44. package/lib/avatar/currentlyWearing.js +33 -0
  45. package/lib/avatar/getAvatar.js +36 -0
  46. package/lib/avatar/getCurrentAvatar.js +38 -0
  47. package/lib/avatar/getRecentItems.js +36 -0
  48. package/lib/avatar/outfitDetails.js +33 -0
  49. package/lib/avatar/outfits.js +38 -0
  50. package/lib/avatar/redrawAvatar.js +47 -0
  51. package/lib/avatar/removeAssetId.js +51 -0
  52. package/lib/avatar/setAvatarBodyColors.js +61 -0
  53. package/lib/avatar/setAvatarScales.js +61 -0
  54. package/lib/avatar/setPlayerAvatarType.js +51 -0
  55. package/lib/avatar/setWearingAssets.js +51 -0
  56. package/lib/avatar/wearAssetId.js +51 -0
  57. package/lib/badges/getAwardedTimestamps.js +49 -0
  58. package/lib/badges/getBadgeInfo.js +44 -0
  59. package/lib/badges/getGameBadges.js +63 -0
  60. package/lib/badges/getPlayerBadges.js +28 -0
  61. package/lib/badges/updateBadgeInfo.js +75 -0
  62. package/lib/cache/add.js +14 -0
  63. package/lib/cache/addIf.js +26 -0
  64. package/lib/cache/clear.js +8 -0
  65. package/lib/cache/get.js +28 -0
  66. package/lib/cache/index.js +17 -0
  67. package/lib/cache/new.js +12 -0
  68. package/lib/cache/wrap.js +25 -0
  69. package/lib/chat/addUsersToConversation.js +58 -0
  70. package/lib/chat/chatSettings.js +34 -0
  71. package/lib/chat/getChatMessages.js +41 -0
  72. package/lib/chat/getConversations.js +44 -0
  73. package/lib/chat/getRolloutSettings.js +36 -0
  74. package/lib/chat/getUnreadConversationCount.js +34 -0
  75. package/lib/chat/getUnreadMessages.js +39 -0
  76. package/lib/chat/getUserConversations.js +38 -0
  77. package/lib/chat/markChatAsRead.js +53 -0
  78. package/lib/chat/markChatAsSeen.js +51 -0
  79. package/lib/chat/multiGetLatestMessages.js +38 -0
  80. package/lib/chat/onNewConversation.js +50 -0
  81. package/lib/chat/onNewMessage.js +53 -0
  82. package/lib/chat/onNewMessageBySelf.js +50 -0
  83. package/lib/chat/onUserOnline.js +50 -0
  84. package/lib/chat/onUserTyping.js +54 -0
  85. package/lib/chat/removeFromGroupConversation.js +59 -0
  86. package/lib/chat/renameGroupConversation.js +58 -0
  87. package/lib/chat/sendChatMessage.js +58 -0
  88. package/lib/chat/setChatUserTyping.js +58 -0
  89. package/lib/chat/start121Conversation.js +51 -0
  90. package/lib/chat/startCloudEditConversation.js +51 -0
  91. package/lib/chat/startGroupConversation.js +59 -0
  92. package/lib/client/onNotification.js +86 -0
  93. package/lib/client/setAPIKey.js +18 -0
  94. package/lib/client/setCookie.js +38 -0
  95. package/lib/datastores/deleteDatastoreEntry.js +56 -0
  96. package/lib/datastores/getDatastoreEntry.js +88 -0
  97. package/lib/datastores/getDatastoreEntryVersions.js +73 -0
  98. package/lib/datastores/getDatastoreKeys.js +63 -0
  99. package/lib/datastores/getDatastores.js +62 -0
  100. package/lib/datastores/incrementDatastoreEntry.js +83 -0
  101. package/lib/datastores/setDatastoreEntry.js +80 -0
  102. package/lib/develop/canManage.js +42 -0
  103. package/lib/develop/configureItem.js +210 -0
  104. package/lib/develop/updateUniverse.js +52 -0
  105. package/lib/develop/updateUniverseAccess.js +54 -0
  106. package/lib/economy/getGroupFunds.js +42 -0
  107. package/lib/economy/getGroupPayoutEligibility.js +55 -0
  108. package/lib/economy/getGroupRevenueSummary.js +42 -0
  109. package/lib/economy/getGroupTransactions.js +32 -0
  110. package/lib/economy/getResaleData.js +48 -0
  111. package/lib/economy/getResellers.js +35 -0
  112. package/lib/economy/getUserFunds.js +43 -0
  113. package/lib/economy/getUserTransactions.js +34 -0
  114. package/lib/economy/onGroupTransaction.js +74 -0
  115. package/lib/friends/acceptFriendRequest.js +54 -0
  116. package/lib/friends/declineAllFriendRequests.js +52 -0
  117. package/lib/friends/declineFriendRequest.js +54 -0
  118. package/lib/friends/getFollowerCount.js +35 -0
  119. package/lib/friends/getFollowers.js +56 -0
  120. package/lib/friends/getFollowingCount.js +35 -0
  121. package/lib/friends/getFollowings.js +56 -0
  122. package/lib/friends/getFriendCount.js +35 -0
  123. package/lib/friends/getFriendRequests.js +51 -0
  124. package/lib/friends/getFriends.js +48 -0
  125. package/lib/friends/onFriendRequest.js +58 -0
  126. package/lib/friends/removeFriend.js +53 -0
  127. package/lib/friends/sendFriendRequest.js +54 -0
  128. package/lib/friends/unfollow.js +53 -0
  129. package/lib/games/addDeveloperProduct.js +53 -0
  130. package/lib/games/configureGamePass.js +126 -0
  131. package/lib/games/getDeveloperProducts.js +44 -0
  132. package/lib/games/getGameInstances.js +31 -0
  133. package/lib/games/getGamePasses.js +39 -0
  134. package/lib/games/getGameRevenue.js +48 -0
  135. package/lib/games/getGameSocialLinks.js +42 -0
  136. package/lib/games/getGroupGames.js +30 -0
  137. package/lib/games/getPlaceInfo.js +47 -0
  138. package/lib/games/getUniverseInfo.js +50 -0
  139. package/lib/games/publishToTopic.js +52 -0
  140. package/lib/games/sendUserNotification.js +65 -0
  141. package/lib/games/updateDeveloperProduct.js +56 -0
  142. package/lib/groups/banFromGroup.js +47 -0
  143. package/lib/groups/changeRank.js +59 -0
  144. package/lib/groups/deleteWallPost.js +59 -0
  145. package/lib/groups/deleteWallPostsByUser.js +55 -0
  146. package/lib/groups/demote.js +25 -0
  147. package/lib/groups/exile.js +55 -0
  148. package/lib/groups/getAuditLog.js +64 -0
  149. package/lib/groups/getGroup.js +50 -0
  150. package/lib/groups/getGroupBans.js +37 -0
  151. package/lib/groups/getGroupSocialLinks.js +41 -0
  152. package/lib/groups/getGroups.js +82 -0
  153. package/lib/groups/getJoinRequest.js +47 -0
  154. package/lib/groups/getJoinRequests.js +53 -0
  155. package/lib/groups/getPlayers.js +103 -0
  156. package/lib/groups/getRankInGroup.js +45 -0
  157. package/lib/groups/getRankNameInGroup.js +44 -0
  158. package/lib/groups/getRole.js +64 -0
  159. package/lib/groups/getRolePermissions.js +48 -0
  160. package/lib/groups/getRoles.js +53 -0
  161. package/lib/groups/getShout.js +47 -0
  162. package/lib/groups/getWall.js +56 -0
  163. package/lib/groups/groupPayout.js +103 -0
  164. package/lib/groups/handleJoinRequest.js +57 -0
  165. package/lib/groups/handleJoinRequests.js +61 -0
  166. package/lib/groups/leaveGroup.js +56 -0
  167. package/lib/groups/onAuditLog.js +62 -0
  168. package/lib/groups/onJoinRequest.js +63 -0
  169. package/lib/groups/onJoinRequestHandle.js +105 -0
  170. package/lib/groups/onShout.js +57 -0
  171. package/lib/groups/onWallPost.js +58 -0
  172. package/lib/groups/promote.js +25 -0
  173. package/lib/groups/searchGroups.js +32 -0
  174. package/lib/groups/setGroupDescription.js +58 -0
  175. package/lib/groups/setGroupName.js +59 -0
  176. package/lib/groups/setRank.js +74 -0
  177. package/lib/groups/setRoleInfo.js +84 -0
  178. package/lib/groups/shout.js +58 -0
  179. package/lib/groups/unbanFromGroup.js +41 -0
  180. package/lib/index.js +212 -0
  181. package/lib/internal/levelOneCopy.js +16 -0
  182. package/lib/internal/queue.js +61 -0
  183. package/lib/internal/timeout.js +30 -0
  184. package/lib/internal/wrap.js +78 -0
  185. package/lib/inventory/getCollectibles.js +31 -0
  186. package/lib/inventory/getInventory.js +32 -0
  187. package/lib/inventory/getInventoryById.js +31 -0
  188. package/lib/inventory/getOwnership.js +47 -0
  189. package/lib/inventory/getUAIDs.js +47 -0
  190. package/lib/itemconfiguration/getGroupAssets.js +32 -0
  191. package/lib/options.js +26 -0
  192. package/lib/party/onPartyDeleted.js +53 -0
  193. package/lib/party/onPartyInvite.js +53 -0
  194. package/lib/party/onPartyJoinedGame.js +53 -0
  195. package/lib/party/onPartyLeftGame.js +53 -0
  196. package/lib/party/onPartySelfJoined.js +53 -0
  197. package/lib/party/onPartySelfLeft.js +53 -0
  198. package/lib/party/onPartyUserJoined.js +53 -0
  199. package/lib/party/onPartyUserLeft.js +53 -0
  200. package/lib/premiumfeatures/getPremium.js +46 -0
  201. package/lib/presence/getPresences.js +60 -0
  202. package/lib/privatemessages/getMessages.js +55 -0
  203. package/lib/privatemessages/message.js +75 -0
  204. package/lib/privatemessages/onMessage.js +89 -0
  205. package/lib/thumbnails/getLogo.js +56 -0
  206. package/lib/thumbnails/getPlayerThumbnail.js +120 -0
  207. package/lib/thumbnails/getThumbnails.js +92 -0
  208. package/lib/trades/acceptTrade.js +52 -0
  209. package/lib/trades/canTradeWith.js +43 -0
  210. package/lib/trades/counterTrade.js +78 -0
  211. package/lib/trades/declineTrade.js +52 -0
  212. package/lib/trades/getTradeInfo.js +47 -0
  213. package/lib/trades/getTrades.js +37 -0
  214. package/lib/trades/sendTrade.js +76 -0
  215. package/lib/users/getBlurb.js +37 -0
  216. package/lib/users/getIdFromUsername.js +56 -0
  217. package/lib/users/getPlayerInfo.js +128 -0
  218. package/lib/users/getUserInfo.js +35 -0
  219. package/lib/users/getUsernameFromId.js +45 -0
  220. package/lib/users/getUsernameHistory.js +42 -0
  221. package/lib/users/onBlurbChange.js +46 -0
  222. package/lib/users/searchUsers.js +41 -0
  223. package/lib/util/apiError.js +50 -0
  224. package/lib/util/clearSession.js +32 -0
  225. package/lib/util/generalRequest.js +61 -0
  226. package/lib/util/getAction.js +45 -0
  227. package/lib/util/getAuthenticatedUser.js +41 -0
  228. package/lib/util/getCurrentUser.js +58 -0
  229. package/lib/util/getGeneralToken.js +52 -0
  230. package/lib/util/getHash.js +29 -0
  231. package/lib/util/getInputs.js +37 -0
  232. package/lib/util/getPageResults.js +86 -0
  233. package/lib/util/getSenderUserId.js +30 -0
  234. package/lib/util/getSession.js +38 -0
  235. package/lib/util/getVerification.js +60 -0
  236. package/lib/util/getVerificationInputs.js +31 -0
  237. package/lib/util/http.js +138 -0
  238. package/lib/util/jar.js +25 -0
  239. package/lib/util/refreshCookie.js +52 -0
  240. package/lib/util/relog.js +81 -0
  241. package/lib/util/setOptions.js +54 -0
  242. package/lib/util/shortPoll.js +102 -0
  243. package/package.json +76 -0
  244. package/postinstall.mjs +1 -0
  245. package/settings.json +115 -0
  246. package/test/accountinformation.test.js +27 -0
  247. package/test/accountsettings.test.js +27 -0
  248. package/test/asset.test.js +81 -0
  249. package/test/assets/Great-White-Shark-Fin.rbxm +0 -0
  250. package/test/assets/KeyframeSequence.rbxm +0 -0
  251. package/test/avatar.test.js +164 -0
  252. package/test/badges.test.js +96 -0
  253. package/test/chat.test.js +104 -0
  254. package/test/datastore.test.js +105 -0
  255. package/test/develop.test.js +53 -0
  256. package/test/economy.test.js +143 -0
  257. package/test/friends.test.js +146 -0
  258. package/test/games.test.js +229 -0
  259. package/test/groups.test.js +405 -0
  260. package/test/inventory.test.js +98 -0
  261. package/test/itemconfiguration.test.js +24 -0
  262. package/test/premiumfeatures.test.js +17 -0
  263. package/test/presence.test.js +25 -0
  264. package/test/privatemessages.test.js +33 -0
  265. package/test/thumbnails.test.js +53 -0
  266. package/test/users.test.js +110 -0
  267. package/tutorials/Authentication.md +75 -0
  268. package/tutorials/Event Emitters.md +26 -0
  269. package/tutorials/Promises.md +86 -0
  270. package/tutorials/VPS Authentication.md +72 -0
  271. package/typings/index.d.ts +2639 -0
  272. package/typings/jsDocs.ts +1987 -0
@@ -0,0 +1,56 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getGeneralToken = require('../util/getGeneralToken.js').func
4
+ const RobloxAPIError = require('../util/apiError.js')
5
+
6
+ // Args
7
+ exports.required = ['assetId']
8
+ exports.optional = ['jar']
9
+
10
+ // Docs
11
+ /**
12
+ * 🔐 Removes an asset from the authenticated user's inventory; throws an error if the item is not owned.
13
+ * @category Asset
14
+ * @alias deleteFromInventory
15
+ * @param {number} assetId - The id of the asset.
16
+ * @returns {Promise<void>}
17
+ * @example const noblox = require("noblox.js")
18
+ * // Login using your cookie
19
+ * await noblox.deleteFromInventory(144075659)
20
+ **/
21
+
22
+ // Define
23
+ function deleteFromInventory (jar, assetId, xcsrf) {
24
+ return new Promise((resolve, reject) => {
25
+ const httpOpt = {
26
+ url: `https://inventory.roblox.com/v2/inventory/asset/${assetId}`,
27
+ options: {
28
+ method: 'DELETE',
29
+ resolveWithFullResponse: true,
30
+ jar,
31
+ headers: {
32
+ 'X-CSRF-TOKEN': xcsrf
33
+ }
34
+ }
35
+ }
36
+
37
+ return http(httpOpt)
38
+ .then(function (res) {
39
+ if (res.statusCode === 200) {
40
+ resolve()
41
+ } else {
42
+ reject(new RobloxAPIError(res))
43
+ }
44
+ })
45
+ .catch(error => reject(error))
46
+ })
47
+ }
48
+
49
+ // Define
50
+ exports.func = function (args) {
51
+ const jar = args.jar
52
+ return getGeneralToken({ jar })
53
+ .then(function (xcsrf) {
54
+ return deleteFromInventory(jar, args.assetId, xcsrf)
55
+ })
56
+ }
@@ -0,0 +1,50 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const cache = require('../cache')
4
+ const RobloxAPIError = require('../util/apiError.js')
5
+
6
+ // Args
7
+ exports.required = ['gamepass']
8
+
9
+ // Docs
10
+ /**
11
+ * ✅ Get the info of an gamepass.
12
+ * @category Asset
13
+ * @param {number} gamePassId - The id of the asset.
14
+ * @returns {Promise<GamePassProductInfo>}
15
+ * @example const noblox = require("noblox.js")
16
+ * const gamePassInfo = await noblox.getGamePassProductInfo(2919875)
17
+ **/
18
+
19
+ // Define
20
+ function getGamePassProductInfo (gamepass) {
21
+ return new Promise((resolve, reject) => {
22
+ const httpOpt = {
23
+ url: `//apis.roblox.com/game-passes/v1/game-passes/${gamepass}/product-info`,
24
+ options: {
25
+ resolveWithFullResponse: true,
26
+ method: 'GET'
27
+ }
28
+ }
29
+
30
+ return http(httpOpt)
31
+ .then(function (res) {
32
+ const data = JSON.parse(res.body)
33
+
34
+ if (res.statusCode === 200) {
35
+ resolve(data)
36
+ } else {
37
+ reject(new RobloxAPIError(res))
38
+ }
39
+ })
40
+ .catch(error => reject(error))
41
+ })
42
+ }
43
+
44
+ exports.func = function (args) {
45
+ const gamepass = args.gamepass
46
+
47
+ return cache.wrap('GamePassProduct', gamepass, function () {
48
+ return getGamePassProductInfo(gamepass)
49
+ })
50
+ }
@@ -0,0 +1,46 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const cache = require('../cache')
4
+ const RobloxAPIError = require('../util/apiError.js')
5
+
6
+ // Args
7
+ exports.required = ['asset']
8
+
9
+ // Docs
10
+ /**
11
+ * ✅ Get the info of an asset.
12
+ * @category Asset
13
+ * @param {number} assetId - The id of the asset.
14
+ * @returns {Promise<ProductInfo>}
15
+ * @example const noblox = require("noblox.js")
16
+ * const productInfo = await noblox.getProductInfo(1117747196)
17
+ **/
18
+
19
+ // Define
20
+ function getProductInfo (asset) {
21
+ return new Promise((resolve, reject) => {
22
+ const httpOpt = {
23
+ url: `//economy.roblox.com/v2/assets/${asset}/details`,
24
+ options: {
25
+ resolveWithFullResponse: true,
26
+ method: 'GET'
27
+ }
28
+ }
29
+ return http(httpOpt)
30
+ .then(function (res) {
31
+ if (res.statusCode === 200) {
32
+ resolve(JSON.parse(res.body))
33
+ } else {
34
+ reject(new RobloxAPIError(res))
35
+ }
36
+ })
37
+ .catch(error => reject(error))
38
+ })
39
+ }
40
+
41
+ exports.func = function (args) {
42
+ const asset = args.asset
43
+ return cache.wrap('Product', asset, function () {
44
+ return getProductInfo(asset)
45
+ })
46
+ }
@@ -0,0 +1,103 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getGeneralToken = require('../util/getGeneralToken').func
4
+ const configureItem = require('../develop/configureItem.js').func
5
+
6
+ // Args
7
+ exports.required = ['data']
8
+ exports.optional = ['itemOptions', 'assetId', 'jar']
9
+
10
+ // Docs
11
+ /**
12
+ * 🔐 Upload an animation, either as a new asset or by overwriting an existing animation.
13
+ * @category Asset
14
+ * @alias uploadAnimation
15
+ * @param {string | Stream} data - The rbxm file containing the KeyframeSequence.
16
+ * @param {object=} itemOptions - The options for the upload. Only optional if assetId is not provided.
17
+ * @param {string=} itemOptions.name - The name of the animation.
18
+ * @param {string=} itemOptions.description - The description for the animation.
19
+ * @param {boolean=} itemOptions.copyLocked - If the animation is copy-locked.
20
+ * @param {boolean=} itemOptions.allowComments - If comments are allowed.
21
+ * @param {number=} itemOptions.groupId - The group to upload the animation to. This is ignored if the assetId is provided.
22
+ * @param {number=} assetId - An existing assetId to overwrite.
23
+ * @returns {Promise<number>}
24
+ * @example const noblox = require("noblox.js")
25
+ * const fs = require("fs")
26
+ * // Login using your cookie
27
+ * const assetId = await noblox.uploadAnimation(fs.readFileSync("./KeyframeSequence.rbxm"), {
28
+ * name: "A cool animation",
29
+ * description: "This is a very cool animation",
30
+ * copyLocked: false, //The asset is allowed to be copied.
31
+ * allowComments: false
32
+ * }, 7132858975)
33
+ **/
34
+
35
+ // Define
36
+ function upload (data, itemOptions, assetId, jar, token) {
37
+ const httpOpt = {
38
+ url: assetId ? `//www.roblox.com/ide/publish/uploadexistinganimation?assetID=${assetId}&isGamesAsset=False` : '//www.roblox.com/ide/publish/uploadnewanimation?AllID=1',
39
+ options: {
40
+ resolveWithFullResponse: true,
41
+ method: 'POST',
42
+ jar,
43
+ body: data,
44
+ headers: {
45
+ 'X-CSRF-TOKEN': token,
46
+ 'Content-Type': 'application/xml',
47
+ 'User-Agent': 'RobloxStudio/WinInet RobloxApp/0.483.1.425021 (GlobalDist; RobloxDirectDownload)'
48
+ }
49
+ }
50
+ }
51
+
52
+ if (!assetId && itemOptions) {
53
+ const copyLocked = itemOptions.copyLocked
54
+ const allowComments = itemOptions.allowComments
55
+ httpOpt.url += '&assetTypeName=Animation&genreTypeId=1&name=' +
56
+ itemOptions.name +
57
+ '&description=' +
58
+ (itemOptions.description || '') +
59
+ '&ispublic=' +
60
+ (copyLocked != null ? !copyLocked : false) +
61
+ '&allowComments=' +
62
+ (allowComments != null ? allowComments : true) +
63
+ '&groupId=' +
64
+ (itemOptions.groupId || '')
65
+ } else if (!assetId) {
66
+ throw new Error('ItemOptions is required for new assets.')
67
+ }
68
+
69
+ return http(httpOpt)
70
+ .then(function (res) {
71
+ if (res.statusCode === 200) {
72
+ const resultId = assetId || Number(res.body)
73
+
74
+ if (assetId && itemOptions) {
75
+ const copyLocked = itemOptions.copyLocked
76
+ const allowComments = itemOptions.allowComments
77
+
78
+ return configureItem({
79
+ id: resultId,
80
+ name: itemOptions.name,
81
+ description: itemOptions.description,
82
+ enableComments: (allowComments != null ? allowComments : true),
83
+ sellForRobux: (copyLocked != null ? !copyLocked : false)
84
+ }).then(function () {
85
+ return resultId
86
+ })
87
+ } else {
88
+ return resultId
89
+ }
90
+ } else {
91
+ throw new Error('Animation upload failed, confirm that all item options, asset options, and upload data are valid.')
92
+ }
93
+ })
94
+ }
95
+
96
+ exports.func = function (args) {
97
+ const jar = args.jar
98
+ return getGeneralToken({
99
+ jar
100
+ }).then(function (token) {
101
+ return upload(args.data, args.itemOptions, args.assetId, args.jar, token)
102
+ })
103
+ }
@@ -0,0 +1,83 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getVerification = require('../util/getVerification.js').func
4
+
5
+ // Args
6
+ exports.required = ['name', 'assetType', 'file']
7
+ exports.optional = ['groupId', 'jar']
8
+
9
+ // Docs
10
+ /**
11
+ * 🔐 Upload an item.
12
+ * @category Asset
13
+ * @alias uploadItem
14
+ * @param {string} name - The name of the asset.
15
+ * @param {number} assetType - The [id for the asset type]{@link https://developer.roblox.com/en-us/api-reference/enum/AssetType}.
16
+ * @param {ReadStream} file - The read stream for the asset being uploaded.
17
+ * @param {number=} groupId - The group to upload the asset to.
18
+ * @returns {Promise<UploadItemResponse>}
19
+ * @example const noblox = require("noblox.js")
20
+ * const fs = require("fs")
21
+ * // Login using your cookie
22
+ * await noblox.uploadItem("A cool decal.", 13, fs.createReadStream("./Image.png"))
23
+ **/
24
+
25
+ // Define
26
+ function uploadItem (jar, file, name, assetType, groupId) {
27
+ return new Promise((resolve, reject) => {
28
+ return getVerification({
29
+ url: 'https://www.roblox.com/build/upload',
30
+ options: {
31
+ jar
32
+ }
33
+ }).then(function (ver) {
34
+ const data = {
35
+ name,
36
+ assetTypeId: assetType,
37
+ groupId: groupId || '',
38
+ __RequestVerificationToken: ver.inputs.__RequestVerificationToken,
39
+ file: {
40
+ value: file,
41
+ options: {
42
+ filename: 'Image.png',
43
+ contentType: 'image/png'
44
+ }
45
+ }
46
+ }
47
+ return http({
48
+ url: '//www.roblox.com/build/upload',
49
+ options: {
50
+ method: 'POST',
51
+ verification: ver.header,
52
+ formData: data,
53
+ resolveWithFullResponse: true,
54
+ jar
55
+ }
56
+ }).then(function (res) {
57
+ if (res.statusCode === 302) {
58
+ const location = res.headers.location
59
+ const errMsg = location.match('uploadedId=(.*)$')
60
+ const match = location.match(/\d+$/)
61
+ if (match) {
62
+ const id = parseInt(match[0], 10)
63
+ if (location.indexOf('/build/upload') === -1) {
64
+ reject(new Error('Unknown redirect: ' + location))
65
+ }
66
+ resolve(id)
67
+ } else if (errMsg) {
68
+ reject(new Error('Upload error: ' + decodeURI(errMsg[1])))
69
+ } else {
70
+ reject(new Error('Match error. Original: ' + location))
71
+ }
72
+ } else {
73
+ reject(new Error('Unknown upload error'))
74
+ }
75
+ })
76
+ })
77
+ .catch(error => reject(error))
78
+ })
79
+ }
80
+
81
+ exports.func = function (args) {
82
+ return uploadItem(args.jar, args.file, args.name, args.assetType, args.groupId)
83
+ }
@@ -0,0 +1,90 @@
1
+ // Includes
2
+ const http = require('../util/http.js').func
3
+ const getGeneralToken = require('../util/getGeneralToken').func
4
+
5
+ // Args
6
+ exports.required = ['data']
7
+ exports.optional = ['itemOptions', 'assetId', 'jar']
8
+
9
+ // Docs
10
+ /**
11
+ * 🔐 Upload a model.
12
+ * @category Asset
13
+ * @alias uploadModel
14
+ * @param {string | Stream} data - The model data.
15
+ * @param {object=} itemOptions - The options for the upload.
16
+ * @param {string=} itemOptions.name - The name of the model.
17
+ * @param {string=} itemOptions.description - The description for the model.
18
+ * @param {boolean=} itemOptions.copyLocked - If the model is copy-locked.
19
+ * @param {boolean=} itemOptions.allowComments - If comments are allowed.
20
+ * @param {number=} itemOptions.groupId - The group to upload the model to.
21
+ * @param {number=} assetId - An existing assetId to overwrite.
22
+ * @returns {Promise<UploadModelResponse>}
23
+ * @example const noblox = require("noblox.js")
24
+ * const fs = require("fs")
25
+ * // Login using your cookie
26
+ * noblox.uploadModel(fs.readFileSync("./model.rbxm"), {
27
+ * name: "A cool model",
28
+ * description: "This is a very cool model",
29
+ * copyLocked: false, //The asset is allowed to be copied.
30
+ * allowComments: false,
31
+ * groupId: 1
32
+ * }, 1117747196)
33
+ **/
34
+
35
+ // Define
36
+ function upload (data, itemOptions, assetId, jar, token) {
37
+ const httpOpt = {
38
+ url: '//data.roblox.com/Data/Upload.ashx?json=1&assetid=' + (assetId || 0),
39
+ options: {
40
+ resolveWithFullResponse: true,
41
+ method: 'POST',
42
+ jar,
43
+ body: data,
44
+ headers: {
45
+ 'X-CSRF-TOKEN': token,
46
+ 'Content-Type': 'application/xml'
47
+ }
48
+ }
49
+ }
50
+ if (itemOptions) {
51
+ const copyLocked = itemOptions.copyLocked
52
+ const allowComments = itemOptions.allowComments
53
+ httpOpt.url += '&type=Model&genreTypeId=1&name=' +
54
+ itemOptions.name +
55
+ '&description=' +
56
+ (itemOptions.description || '') +
57
+ '&ispublic=' +
58
+ (copyLocked != null ? !copyLocked : false) +
59
+ '&allowComments=' +
60
+ (allowComments != null ? allowComments : true) +
61
+ '&groupId=' +
62
+ (itemOptions.groupId || '')
63
+ } else if (!assetId) {
64
+ throw new Error('ItemOptions is required for new assets.')
65
+ }
66
+ return http(httpOpt)
67
+ .then(function (res) {
68
+ if (res.statusCode === 200) {
69
+ const body = res.body
70
+ let parsed
71
+ try {
72
+ parsed = JSON.parse(body)
73
+ } catch (e) {
74
+ throw new Error('Could not parse JSON, returned body:' + body)
75
+ }
76
+ return parsed
77
+ } else {
78
+ throw new Error('Upload failed, confirm that all item options, asset options, and upload data are valid.')
79
+ }
80
+ })
81
+ }
82
+
83
+ exports.func = function (args) {
84
+ const jar = args.jar
85
+ return getGeneralToken({
86
+ jar
87
+ }).then(function (token) {
88
+ return upload(args.data, args.itemOptions, args.assetId, args.jar, token)
89
+ })
90
+ }
@@ -0,0 +1,39 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.optional = ['option', 'jar']
5
+
6
+ // Docs
7
+ /**
8
+ * ✅ Get the avatar rules.
9
+ * @category Avatar
10
+ * @alias avatarRules
11
+ * @param {string=} option - A specific rule to filter for.
12
+ * @returns {Promise<AvatarRules>}
13
+ * @example const noblox = require("noblox.js")
14
+ * const avatarRules = await noblox.avatarRules()
15
+ **/
16
+
17
+ exports.func = (args) => {
18
+ const jar = args.jar
19
+ const option = args.option
20
+
21
+ return http({
22
+ url: '//avatar.roblox.com/v1/avatar-rules',
23
+ options: {
24
+ method: 'GET',
25
+ jar,
26
+ followRedirect: false,
27
+ resolveWithFullResponse: true
28
+ }
29
+ }).then((res) => {
30
+ if (res.statusCode === 200) {
31
+ const json = JSON.parse(res.body)
32
+ const result = (option ? json[option] : json)
33
+
34
+ return result
35
+ } else {
36
+ throw new RobloxAPIError(res)
37
+ }
38
+ })
39
+ }
@@ -0,0 +1,33 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.required = ['userId']
5
+
6
+ // Docs
7
+ /**
8
+ * ✅ Get the assets a given user is wearing.
9
+ * @category Avatar
10
+ * @alias currentlyWearing
11
+ * @param {number} userId - The user's userId.
12
+ * @returns {Promise<AssetIdList>}
13
+ * @example const noblox = require("noblox.js")
14
+ * const wearingAssets = await noblox.currentlyWearing(1)
15
+ **/
16
+
17
+ exports.func = (args) => {
18
+ const userId = args.userId
19
+
20
+ return http({
21
+ url: '//avatar.roblox.com/v1/users/' + userId + '/currently-wearing',
22
+ options: {
23
+ method: 'GET',
24
+ resolveWithFullResponse: true
25
+ }
26
+ }).then((res) => {
27
+ if (res.statusCode === 200) {
28
+ return JSON.parse(res.body)
29
+ } else {
30
+ throw new RobloxAPIError(res)
31
+ }
32
+ })
33
+ }
@@ -0,0 +1,36 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.required = ['userId']
5
+
6
+ // Docs
7
+ /**
8
+ * ✅ Get a user's avatar.
9
+ * @category Avatar
10
+ * @alias getAvatar
11
+ * @param {number} userId - The user's userId.
12
+ * @returns {Promise<AvatarInfo>}
13
+ * @example const noblox = require("noblox.js")
14
+ * const avatar = await noblox.getAvatar(1)
15
+ **/
16
+
17
+ const getAvatar = (userId) => {
18
+ return http({
19
+ url: '//avatar.roblox.com/v1/users/' + userId + '/avatar',
20
+ options: {
21
+ method: 'GET',
22
+ resolveWithFullResponse: true
23
+ }
24
+ }).then((res) => {
25
+ if (res.statusCode === 200) {
26
+ return JSON.parse(res.body)
27
+ } else {
28
+ throw new RobloxAPIError(res)
29
+ }
30
+ })
31
+ }
32
+
33
+ exports.func = (args) => {
34
+ const userId = args.userId
35
+ return getAvatar(userId)
36
+ }
@@ -0,0 +1,38 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.optional = ['option', 'jar']
5
+
6
+ // Docs
7
+ /**
8
+ * 🔐 Gets your current avatar.
9
+ * @category Avatar
10
+ * @alias getCurrentAvatar
11
+ * @param {number=} option - The name of a parameter on the avatar.
12
+ * @returns {Promise<AvatarInfo>}
13
+ * @example const noblox = require("noblox.js")
14
+ * // Login using your cookie
15
+ * const avatar = await noblox.getCurrentAvatar()
16
+ */
17
+
18
+ exports.func = (args) => {
19
+ const jar = args.jar
20
+ const option = args.option
21
+
22
+ return http({
23
+ url: '//avatar.roblox.com/v1/avatar',
24
+ options: {
25
+ method: 'GET',
26
+ jar,
27
+ followRedirect: false,
28
+ resolveWithFullResponse: true
29
+ }
30
+ }).then((res) => {
31
+ if (res.statusCode !== 200) {
32
+ throw new RobloxAPIError(res)
33
+ } else {
34
+ const json = JSON.parse(res.body)
35
+ return (option ? json[option] : json)
36
+ }
37
+ })
38
+ }
@@ -0,0 +1,36 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.optional = ['listType', 'jar']
5
+
6
+ // Docs
7
+ /**
8
+ * 🔐 Get assets you've recently worn.
9
+ * @category Avatar
10
+ * @alias getRecentItems
11
+ * @param {number=} listType - A type of item. Ex: Shirt, All
12
+ * @returns {Promise<AssetRecentItemsResult>}
13
+ * @example const noblox = require("noblox.js")
14
+ * // Login using your cookie
15
+ * const recentlyWorn = await noblox.getRecentItems("All")
16
+ **/
17
+
18
+ exports.func = (args) => {
19
+ const jar = args.jar
20
+ const listType = typeof (args.listType) === 'string' ? args.listType : 'All'
21
+
22
+ return http({
23
+ url: '//avatar.roblox.com/v1/recent-items/' + listType + '/list',
24
+ options: {
25
+ method: 'GET',
26
+ jar,
27
+ resolveWithFullResponse: true
28
+ }
29
+ }).then((res) => {
30
+ if (res.statusCode === 200) {
31
+ return JSON.parse(res.body)
32
+ } else {
33
+ throw new RobloxAPIError(res)
34
+ }
35
+ })
36
+ }
@@ -0,0 +1,33 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.required = ['outfitId']
5
+
6
+ // Docs
7
+ /**
8
+ * ✅ Get the details of an outfit.
9
+ * @category Avatar
10
+ * @alias outfitDetails
11
+ * @param {number} outfitId - The id of the outfit.
12
+ * @returns {Promise<AvatarOutfitDetails>}
13
+ * @example const noblox = require("noblox.js")
14
+ * const outfit = await noblox.outfitDetails(111)
15
+ **/
16
+
17
+ exports.func = (args) => {
18
+ const outfitId = args.outfitId
19
+
20
+ return http({
21
+ url: '//avatar.roblox.com/v1/outfits/' + outfitId + '/details',
22
+ options: {
23
+ method: 'GET',
24
+ resolveWithFullResponse: true
25
+ }
26
+ }).then((res) => {
27
+ if (res.statusCode === 200) {
28
+ return JSON.parse(res.body)
29
+ } else {
30
+ throw new RobloxAPIError(res)
31
+ }
32
+ })
33
+ }
@@ -0,0 +1,38 @@
1
+ const http = require('../util/http.js').func
2
+ const RobloxAPIError = require('../util/apiError.js')
3
+
4
+ exports.required = ['userId']
5
+ exports.optional = ['page', 'itemsPerPage']
6
+
7
+ // Docs
8
+ /**
9
+ * ✅ Get a user's outfits.
10
+ * @category Avatar
11
+ * @alias outfits
12
+ * @param {number} userId - The userId of the user.
13
+ * @param {number=} page - The page to index.
14
+ * @param {number=} itemsPerPage - The number of results on each page.
15
+ * @returns {Promise<GetOutfitsResult>}
16
+ * @example const noblox = require("noblox.js")
17
+ * const outfits = await noblox.outfits(1)
18
+ **/
19
+
20
+ exports.func = (args) => {
21
+ const userId = args.userId
22
+ const page = parseInt(args.page) ? parseInt(args.page) : '*'
23
+ const itemsPerPage = parseInt(args.itemsPerPage) ? parseInt(args.itemsPerPage) : '*'
24
+
25
+ return http({
26
+ url: '//avatar.roblox.com/v1/users/' + userId + '/outfits?page=' + page + '&itemsPerPage=' + itemsPerPage,
27
+ options: {
28
+ method: 'GET',
29
+ resolveWithFullResponse: true
30
+ }
31
+ }).then((res) => {
32
+ if (res.statusCode === 200) {
33
+ return JSON.parse(res.body)
34
+ } else {
35
+ throw new RobloxAPIError(res)
36
+ }
37
+ })
38
+ }