noblox.ts 4.10.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of noblox.ts might be problematic. Click here for more details.
- package/.eslintrc.js +21 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +29 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +22 -0
- package/.github/workflows/doc-publish.yml +33 -0
- package/.github/workflows/npmpublish.yml +70 -0
- package/.travis.yml +13 -0
- package/CODE_OF_CONDUCT.md +76 -0
- package/LICENSE +21 -0
- package/README.md +168 -0
- package/examples/cleanPlayers.js +130 -0
- package/examples/cleanWall.js +110 -0
- package/examples/revertRanks.js +100 -0
- package/examples/savePlayers.js +119 -0
- package/examples/saveWall.js +96 -0
- package/img/moderatedThumbnails/moderatedThumbnail_100x100.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_110x110.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_140x140.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_150x150.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_150x200.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_180x180.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_250x250.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_30x30.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_352x352.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_420x420.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_48x48.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_50x50.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_60x60.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_720x720.png +0 -0
- package/img/moderatedThumbnails/moderatedThumbnail_75x75.png +0 -0
- package/img/noblox-js-small.png +0 -0
- package/img/noblox-js.png +0 -0
- package/img/thumbnailSizes.png +0 -0
- package/jsDocsConfig.json +55 -0
- package/lib/accountinformation/getUserSocialLinks.js +42 -0
- package/lib/accountsettings/block.js +58 -0
- package/lib/accountsettings/unblock.js +58 -0
- package/lib/asset/deleteFromInventory.js +69 -0
- package/lib/asset/getGamePassProductInfo.js +51 -0
- package/lib/asset/getProductInfo.js +56 -0
- package/lib/asset/uploadAnimation.js +103 -0
- package/lib/asset/uploadItem.js +83 -0
- package/lib/asset/uploadModel.js +90 -0
- package/lib/avatar/avatarRules.js +38 -0
- package/lib/avatar/currentlyWearing.js +32 -0
- package/lib/avatar/getAvatar.js +35 -0
- package/lib/avatar/getCurrentAvatar.js +37 -0
- package/lib/avatar/getRecentItems.js +37 -0
- package/lib/avatar/outfitDetails.js +32 -0
- package/lib/avatar/outfits.js +37 -0
- package/lib/avatar/redrawAvatar.js +48 -0
- package/lib/avatar/removeAssetId.js +55 -0
- package/lib/avatar/setAvatarBodyColors.js +60 -0
- package/lib/avatar/setAvatarScales.js +60 -0
- package/lib/avatar/setPlayerAvatarType.js +50 -0
- package/lib/avatar/setWearingAssets.js +50 -0
- package/lib/avatar/wearAssetId.js +55 -0
- package/lib/badges/getAwardedTimestamps.js +52 -0
- package/lib/badges/getBadgeInfo.js +43 -0
- package/lib/badges/getGameBadges.js +62 -0
- package/lib/badges/getPlayerBadges.js +28 -0
- package/lib/badges/updateBadgeInfo.js +80 -0
- package/lib/cache/add.js +14 -0
- package/lib/cache/addIf.js +26 -0
- package/lib/cache/clear.js +8 -0
- package/lib/cache/get.js +28 -0
- package/lib/cache/index.js +17 -0
- package/lib/cache/new.js +12 -0
- package/lib/cache/wrap.js +25 -0
- package/lib/chat/addUsersToConversation.js +61 -0
- package/lib/chat/chatSettings.js +33 -0
- package/lib/chat/getChatMessages.js +40 -0
- package/lib/chat/getConversations.js +43 -0
- package/lib/chat/getRolloutSettings.js +35 -0
- package/lib/chat/getUnreadConversationCount.js +33 -0
- package/lib/chat/getUnreadMessages.js +38 -0
- package/lib/chat/getUserConversations.js +37 -0
- package/lib/chat/markChatAsRead.js +52 -0
- package/lib/chat/markChatAsSeen.js +50 -0
- package/lib/chat/multiGetLatestMessages.js +37 -0
- package/lib/chat/onNewConversation.js +50 -0
- package/lib/chat/onNewMessage.js +53 -0
- package/lib/chat/onNewMessageBySelf.js +50 -0
- package/lib/chat/onUserOnline.js +50 -0
- package/lib/chat/onUserTyping.js +54 -0
- package/lib/chat/removeFromGroupConversation.js +62 -0
- package/lib/chat/renameGroupConversation.js +57 -0
- package/lib/chat/sendChatMessage.js +57 -0
- package/lib/chat/setChatUserTyping.js +61 -0
- package/lib/chat/start121Conversation.js +50 -0
- package/lib/chat/startCloudEditConversation.js +50 -0
- package/lib/chat/startGroupConversation.js +62 -0
- package/lib/client/onNotification.js +70 -0
- package/lib/client/setAPIKey.js +18 -0
- package/lib/client/setCookie.js +38 -0
- package/lib/datastores/deleteDatastoreEntry.js +66 -0
- package/lib/datastores/getDatastoreEntry.js +98 -0
- package/lib/datastores/getDatastoreEntryVersions.js +83 -0
- package/lib/datastores/getDatastoreKeys.js +73 -0
- package/lib/datastores/getDatastores.js +72 -0
- package/lib/datastores/incrementDatastoreEntry.js +93 -0
- package/lib/datastores/setDatastoreEntry.js +90 -0
- package/lib/develop/canManage.js +44 -0
- package/lib/develop/configureItem.js +142 -0
- package/lib/develop/updateUniverse.js +53 -0
- package/lib/develop/updateUniverseAccess.js +55 -0
- package/lib/economy/buy.js +99 -0
- package/lib/economy/getGroupFunds.js +43 -0
- package/lib/economy/getGroupRevenueSummary.js +48 -0
- package/lib/economy/getGroupTransactions.js +32 -0
- package/lib/economy/getResaleData.js +54 -0
- package/lib/economy/getResellers.js +35 -0
- package/lib/economy/getUserTransactions.js +34 -0
- package/lib/economy/onGroupTransaction.js +74 -0
- package/lib/friends/acceptFriendRequest.js +59 -0
- package/lib/friends/declineAllFriendRequests.js +57 -0
- package/lib/friends/declineFriendRequest.js +59 -0
- package/lib/friends/getFollowers.js +61 -0
- package/lib/friends/getFollowings.js +61 -0
- package/lib/friends/getFriendRequests.js +56 -0
- package/lib/friends/getFriends.js +53 -0
- package/lib/friends/onFriendRequest.js +58 -0
- package/lib/friends/removeFriend.js +58 -0
- package/lib/friends/sendFriendRequest.js +59 -0
- package/lib/friends/unfollow.js +58 -0
- package/lib/games/addDeveloperProduct.js +65 -0
- package/lib/games/checkDeveloperProductName.js +39 -0
- package/lib/games/configureGamePass.js +146 -0
- package/lib/games/getDeveloperProducts.js +51 -0
- package/lib/games/getGameInstances.js +31 -0
- package/lib/games/getGamePasses.js +39 -0
- package/lib/games/getGameRevenue.js +49 -0
- package/lib/games/getGameSocialLinks.js +45 -0
- package/lib/games/getGroupGames.js +30 -0
- package/lib/games/getPlaceInfo.js +48 -0
- package/lib/games/getUniverseInfo.js +51 -0
- package/lib/games/updateDeveloperProduct.js +69 -0
- package/lib/groups/changeRank.js +59 -0
- package/lib/groups/deleteWallPost.js +64 -0
- package/lib/groups/deleteWallPostsByUser.js +59 -0
- package/lib/groups/demote.js +25 -0
- package/lib/groups/exile.js +59 -0
- package/lib/groups/getAuditLog.js +67 -0
- package/lib/groups/getGroup.js +57 -0
- package/lib/groups/getGroupSocialLinks.js +44 -0
- package/lib/groups/getGroups.js +88 -0
- package/lib/groups/getJoinRequest.js +52 -0
- package/lib/groups/getJoinRequests.js +58 -0
- package/lib/groups/getPlayers.js +108 -0
- package/lib/groups/getRankInGroup.js +52 -0
- package/lib/groups/getRankNameInGroup.js +52 -0
- package/lib/groups/getRole.js +64 -0
- package/lib/groups/getRolePermissions.js +51 -0
- package/lib/groups/getRoles.js +56 -0
- package/lib/groups/getShout.js +49 -0
- package/lib/groups/getWall.js +59 -0
- package/lib/groups/groupPayout.js +103 -0
- package/lib/groups/handleJoinRequest.js +60 -0
- package/lib/groups/leaveGroup.js +60 -0
- package/lib/groups/onAuditLog.js +62 -0
- package/lib/groups/onJoinRequest.js +63 -0
- package/lib/groups/onJoinRequestHandle.js +105 -0
- package/lib/groups/onShout.js +57 -0
- package/lib/groups/onWallPost.js +58 -0
- package/lib/groups/promote.js +25 -0
- package/lib/groups/searchGroups.js +32 -0
- package/lib/groups/setGroupDescription.js +65 -0
- package/lib/groups/setGroupName.js +66 -0
- package/lib/groups/setRank.js +79 -0
- package/lib/groups/shout.js +65 -0
- package/lib/index.js +30 -0
- package/lib/internal/levelOneCopy.js +16 -0
- package/lib/internal/queue.js +61 -0
- package/lib/internal/timeout.js +30 -0
- package/lib/internal/wrap.js +78 -0
- package/lib/inventory/getCollectibles.js +31 -0
- package/lib/inventory/getInventory.js +32 -0
- package/lib/inventory/getInventoryById.js +31 -0
- package/lib/inventory/getOwnership.js +54 -0
- package/lib/inventory/getUAIDs.js +47 -0
- package/lib/itemconfiguration/getGroupAssets.js +32 -0
- package/lib/options.js +26 -0
- package/lib/party/onPartyDeleted.js +53 -0
- package/lib/party/onPartyInvite.js +53 -0
- package/lib/party/onPartyJoinedGame.js +53 -0
- package/lib/party/onPartyLeftGame.js +53 -0
- package/lib/party/onPartySelfJoined.js +53 -0
- package/lib/party/onPartySelfLeft.js +53 -0
- package/lib/party/onPartyUserJoined.js +53 -0
- package/lib/party/onPartyUserLeft.js +53 -0
- package/lib/premiumfeatures/getPremium.js +51 -0
- package/lib/presence/getPresences.js +63 -0
- package/lib/privatemessages/getMessages.js +60 -0
- package/lib/privatemessages/message.js +80 -0
- package/lib/privatemessages/onMessage.js +88 -0
- package/lib/thumbnails/getLogo.js +60 -0
- package/lib/thumbnails/getPlayerThumbnail.js +121 -0
- package/lib/thumbnails/getThumbnails.js +93 -0
- package/lib/trades/acceptTrade.js +58 -0
- package/lib/trades/canTradeWith.js +48 -0
- package/lib/trades/counterTrade.js +84 -0
- package/lib/trades/declineTrade.js +58 -0
- package/lib/trades/getTradeInfo.js +52 -0
- package/lib/trades/getTrades.js +37 -0
- package/lib/trades/sendTrade.js +82 -0
- package/lib/users/getBlurb.js +36 -0
- package/lib/users/getIdFromUsername.js +53 -0
- package/lib/users/getPlayerInfo.js +100 -0
- package/lib/users/getUsernameFromId.js +44 -0
- package/lib/users/onBlurbChange.js +46 -0
- package/lib/util/clearSession.js +32 -0
- package/lib/util/generalRequest.js +61 -0
- package/lib/util/getAction.js +45 -0
- package/lib/util/getCurrentUser.js +44 -0
- package/lib/util/getGeneralToken.js +52 -0
- package/lib/util/getHash.js +29 -0
- package/lib/util/getInputs.js +37 -0
- package/lib/util/getPageResults.js +89 -0
- package/lib/util/getSenderUserId.js +30 -0
- package/lib/util/getSession.js +38 -0
- package/lib/util/getVerification.js +60 -0
- package/lib/util/getVerificationInputs.js +31 -0
- package/lib/util/http.js +110 -0
- package/lib/util/jar.js +24 -0
- package/lib/util/refreshCookie.js +52 -0
- package/lib/util/relog.js +81 -0
- package/lib/util/setOptions.js +54 -0
- package/lib/util/shortPoll.js +102 -0
- package/lib/util/threaded.js +80 -0
- package/package.json +94 -0
- package/postinstall.js +1 -0
- package/settings.json +107 -0
- package/test/accountinformation.test.js +27 -0
- package/test/accountsettings.test.js +27 -0
- package/test/asset.test.js +81 -0
- package/test/assets/Great-White-Shark-Fin.rbxm +0 -0
- package/test/assets/KeyframeSequence.rbxm +0 -0
- package/test/avatar.test.js +164 -0
- package/test/badges.test.js +96 -0
- package/test/chat.test.js +104 -0
- package/test/datastore.test.js +105 -0
- package/test/develop.test.js +53 -0
- package/test/economy.test.js +137 -0
- package/test/friends.test.js +128 -0
- package/test/games.test.js +212 -0
- package/test/groups.test.js +311 -0
- package/test/inventory.test.js +98 -0
- package/test/itemconfiguration.test.js +24 -0
- package/test/premiumfeatures.test.js +17 -0
- package/test/presence.test.js +25 -0
- package/test/privatemessages.test.js +33 -0
- package/test/thumbnails.test.js +53 -0
- package/test/users.test.js +68 -0
- package/tutorials/Authentication.md +75 -0
- package/tutorials/Event Emitters.md +26 -0
- package/tutorials/Promises.md +86 -0
- package/tutorials/VPS Authentication.md +72 -0
- package/typings/index.d.ts +2525 -0
- package/typings/jsDocs.ts +1927 -0
@@ -0,0 +1,18 @@
|
|
1
|
+
const options = require('../options.js')
|
2
|
+
|
3
|
+
exports.required = ['apiKey']
|
4
|
+
|
5
|
+
// Docs
|
6
|
+
/**
|
7
|
+
* 🔑 Sign in with an API key.
|
8
|
+
* @category Client
|
9
|
+
* @alias setAPIKey
|
10
|
+
* @param {string} apiKey - The api key to sign in with.
|
11
|
+
* @returns {Promise<boolean>}
|
12
|
+
* @example const noblox = require("noblox.js")
|
13
|
+
* noblox.setAPIKey("A3H+1rfQj0Kwz0CsSO2ciuT/e/ZHekahvehGG3PPmFOASZx1")
|
14
|
+
**/
|
15
|
+
|
16
|
+
exports.func = function (args) {
|
17
|
+
options.jar.apiKey = args.apiKey
|
18
|
+
}
|
@@ -0,0 +1,38 @@
|
|
1
|
+
const options = require('../options.js')
|
2
|
+
const getCurrentUser = require('../util/getCurrentUser.js').func
|
3
|
+
|
4
|
+
exports.required = ['cookie']
|
5
|
+
exports.optional = ['validate']
|
6
|
+
|
7
|
+
// Docs
|
8
|
+
/**
|
9
|
+
* 🔑 Sign in with a cookie.
|
10
|
+
* @category Client
|
11
|
+
* @alias setCookie
|
12
|
+
* @param {string} cookie - The cookie to sign in with.
|
13
|
+
* @param {boolean=} [validate=true] - Whether to validate the cookie or not.
|
14
|
+
* @returns {Promise<LoggedInUserData>}
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* noblox.setCookie("cookie").then(function() {
|
17
|
+
* //your code here
|
18
|
+
* })
|
19
|
+
**/
|
20
|
+
|
21
|
+
exports.func = async function (args) {
|
22
|
+
// verify it
|
23
|
+
if (!args.cookie.toLowerCase().includes('warning:-')) {
|
24
|
+
console.error('Warning: No Roblox warning detected in provided cookie. Ensure you include the entire .ROBLOSECURITY warning.')
|
25
|
+
}
|
26
|
+
if (args.validate === false) {
|
27
|
+
options.jar.session = args.cookie
|
28
|
+
return false
|
29
|
+
}
|
30
|
+
try {
|
31
|
+
const res = await getCurrentUser({ jar: { session: args.cookie } })
|
32
|
+
options.jar.session = args.cookie
|
33
|
+
return res
|
34
|
+
} catch (error) {
|
35
|
+
console.error('Failed to validate cookie: Are you sure the cookie is valid?\nEnsure you include the full cookie, including warning text.')
|
36
|
+
throw new Error(error)
|
37
|
+
}
|
38
|
+
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['universeId', 'datastoreName', 'entryKey']
|
6
|
+
exports.optional = ['scope', 'jar']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* <p> ☁️ Marks the entry as deleted by creating a tombstone version. Entries are deleted permanently after 30 days. </p>
|
11
|
+
* API Key Permissions:
|
12
|
+
* <ul>
|
13
|
+
* <li> Delete entry </li>
|
14
|
+
* </ul>
|
15
|
+
* @category Datastores
|
16
|
+
* @param {number} universeId - The ID of the universe
|
17
|
+
* @param {string} datastoreName - Name of the data store
|
18
|
+
* @param {string} entryKey - The key which identifies the entry.
|
19
|
+
* @param {string=} [scope=global] - Defaults to global, similar to Lua API.
|
20
|
+
* @returns {Promise<void>}
|
21
|
+
* @example const noblox = require("noblox.js")
|
22
|
+
* await noblox.deleteDatastoreEntry({ universeId: 127407415, datastoreName: 'LevelStore', entryKey: 'Level_User' })
|
23
|
+
**/
|
24
|
+
|
25
|
+
// Define
|
26
|
+
function deleteDatastoreEntry (universeId, datastoreName, entryKey, scope = 'global', jar) {
|
27
|
+
return new Promise((resolve, reject) => {
|
28
|
+
const httpOpt = {
|
29
|
+
url: `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries/entry`,
|
30
|
+
options: {
|
31
|
+
resolveWithFullResponse: true,
|
32
|
+
method: 'DELETE',
|
33
|
+
jar,
|
34
|
+
qs: {
|
35
|
+
datastoreName,
|
36
|
+
scope,
|
37
|
+
entryKey
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
return http(httpOpt)
|
42
|
+
.then(function (res) {
|
43
|
+
if (res.statusCode === 204) {
|
44
|
+
resolve()
|
45
|
+
} else {
|
46
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
47
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
48
|
+
|
49
|
+
let body
|
50
|
+
|
51
|
+
try {
|
52
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
53
|
+
} catch (error) {
|
54
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
55
|
+
}
|
56
|
+
|
57
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
58
|
+
}
|
59
|
+
})
|
60
|
+
.catch(error => reject(error))
|
61
|
+
})
|
62
|
+
}
|
63
|
+
|
64
|
+
exports.func = function (args) {
|
65
|
+
return deleteDatastoreEntry(args.universeId, args.datastoreName, args.entryKey, args.scope, args.jar)
|
66
|
+
}
|
@@ -0,0 +1,98 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['universeId', 'datastoreName', 'entryKey']
|
6
|
+
exports.optional = ['scope', 'versionId', 'jar']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* <p> ☁️ Returns the latest value and metadata associated with an entry, or a specific version if versionId is provided. </p>
|
11
|
+
* API Key Permissions:
|
12
|
+
* <ul>
|
13
|
+
* <li> Read entries </li>
|
14
|
+
* <li> Read version </li>
|
15
|
+
* </ul>
|
16
|
+
* @category Datastores
|
17
|
+
* @param {number} universeId - The ID of the universe
|
18
|
+
* @param {string} datastoreName - Name of the data store
|
19
|
+
* @param {string} entryKey - The key which identifies the entry.
|
20
|
+
* @param {string=} [scope=global] - Defaults to global, similar to Lua API.
|
21
|
+
* @param {string=} versionId - The version to inspect
|
22
|
+
* @returns {Promise<DatastoreEntry>}
|
23
|
+
* @example const noblox = require("noblox.js")
|
24
|
+
* const entry = await noblox.getDatastoreEntry({ universeId: 127407415, datastoreName: 'LevelStore', entryKey: 'Level_User' })
|
25
|
+
**/
|
26
|
+
|
27
|
+
// Define
|
28
|
+
function getDatastoreEntry (universeId, datastoreName, entryKey, scope = 'global', versionId, jar) {
|
29
|
+
return new Promise((resolve, reject) => {
|
30
|
+
const httpOpt = {
|
31
|
+
url: versionId ? `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries/entry/versions/version` : `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries/entry`,
|
32
|
+
options: {
|
33
|
+
resolveWithFullResponse: true,
|
34
|
+
method: 'GET',
|
35
|
+
jar,
|
36
|
+
qs: {
|
37
|
+
datastoreName,
|
38
|
+
scope,
|
39
|
+
entryKey,
|
40
|
+
versionId
|
41
|
+
}
|
42
|
+
}
|
43
|
+
}
|
44
|
+
return http(httpOpt)
|
45
|
+
.then(function (res) {
|
46
|
+
if (res.statusCode === 200) {
|
47
|
+
const response = JSON.parse(res.body)
|
48
|
+
const headers = res.headers
|
49
|
+
|
50
|
+
resolve({
|
51
|
+
data: response,
|
52
|
+
metadata: {
|
53
|
+
robloxEntryCreatedTime: new Date(headers['roblox-entry-created-time']),
|
54
|
+
lastModified: headers['last-modified'] ? new Date(headers['last-modified']) : new Date(headers['roblox-entry-created-time']),
|
55
|
+
robloxEntryVersion: headers['roblox-entry-version'],
|
56
|
+
robloxEntryAttributes: headers['roblox-entry-attributes'],
|
57
|
+
robloxEntryUserIDs: headers['roblox-entry-userids'],
|
58
|
+
contentMD5: headers['content-md5'],
|
59
|
+
contentLength: parseInt(headers['content-length'])
|
60
|
+
}
|
61
|
+
})
|
62
|
+
} else if (res.statusCode === 204) {
|
63
|
+
const headers = res.headers
|
64
|
+
|
65
|
+
resolve({
|
66
|
+
data: null,
|
67
|
+
metadata: {
|
68
|
+
robloxEntryCreatedTime: new Date(headers['roblox-entry-created-time']),
|
69
|
+
lastModified: headers['last-modified'] ? new Date(headers['last-modified']) : new Date(headers['roblox-entry-created-time']),
|
70
|
+
robloxEntryVersion: headers['roblox-entry-version'],
|
71
|
+
robloxEntryAttributes: headers['roblox-entry-attributes'],
|
72
|
+
robloxEntryUserIDs: headers['roblox-entry-userids'],
|
73
|
+
contentMD5: headers['content-md5'],
|
74
|
+
contentLength: headers['content-length']
|
75
|
+
}
|
76
|
+
})
|
77
|
+
} else {
|
78
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
79
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
80
|
+
|
81
|
+
let body
|
82
|
+
|
83
|
+
try {
|
84
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
85
|
+
} catch (error) {
|
86
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
87
|
+
}
|
88
|
+
|
89
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
90
|
+
}
|
91
|
+
})
|
92
|
+
.catch(error => reject(error))
|
93
|
+
})
|
94
|
+
}
|
95
|
+
|
96
|
+
exports.func = function (args) {
|
97
|
+
return getDatastoreEntry(args.universeId, args.datastoreName, args.entryKey, args.scope, args.versionId, args.jar)
|
98
|
+
}
|
@@ -0,0 +1,83 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['universeId', 'datastoreName', 'entryKey']
|
6
|
+
exports.optional = ['scope', 'startTime', 'endTime', 'sortOrder', 'limit', 'cursor', 'jar']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* <p> ☁️ Returns a list of entry versions of an entry. </p>
|
11
|
+
* API Key Permissions:
|
12
|
+
* <ul>
|
13
|
+
* <li> List versions </li>
|
14
|
+
* </ul>
|
15
|
+
* @category Datastores
|
16
|
+
* @param {number} universeId - The ID of the universe
|
17
|
+
* @param {string} datastoreName - Name of the data store
|
18
|
+
* @param {string} entryKey - The key which identifies the entry.
|
19
|
+
* @param {(string | boolean)=} [scope=global] - Defaults to global, similar to Lua API.
|
20
|
+
* @param {Date=} startTime - Don't consider versions older than this
|
21
|
+
* @param {Date=} endTime - Don't consider versions younger than this
|
22
|
+
* @param {("Ascending" | "Descending")=} [sortOrder=Ascending] - Older first (Ascending) or younger first (Descending)
|
23
|
+
* @param {number=} limit - Maximum number of items to return
|
24
|
+
* @param {string=} cursor - Provide to request the next set of data
|
25
|
+
* @returns {Promise<EntryVersionsResult>}
|
26
|
+
* @example const noblox = require("noblox.js")
|
27
|
+
* const versions = await noblox.getDatastoreEntryVersions({ universeId: 127407415, datastoreName: 'LevelStore', entryKey: 'Level_User' })
|
28
|
+
**/
|
29
|
+
|
30
|
+
// Define
|
31
|
+
function getDatastoreEntryVersions (universeId, datastoreName, entryKey, scope = 'global', startTime, endTime, sortOrder, limit, cursor, jar) {
|
32
|
+
return new Promise((resolve, reject) => {
|
33
|
+
const httpOpt = {
|
34
|
+
url: `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries/entry/versions`,
|
35
|
+
options: {
|
36
|
+
resolveWithFullResponse: true,
|
37
|
+
method: 'GET',
|
38
|
+
jar,
|
39
|
+
qs: {
|
40
|
+
datastoreName,
|
41
|
+
scope,
|
42
|
+
entryKey,
|
43
|
+
startTime,
|
44
|
+
endTime,
|
45
|
+
sortOrder,
|
46
|
+
limit,
|
47
|
+
cursor
|
48
|
+
}
|
49
|
+
}
|
50
|
+
}
|
51
|
+
return http(httpOpt)
|
52
|
+
.then(function (res) {
|
53
|
+
if (res.statusCode === 200) {
|
54
|
+
const response = JSON.parse(res.body)
|
55
|
+
response.versions = response.versions.map(version => {
|
56
|
+
version.createdTime = new Date(version.createdTime)
|
57
|
+
version.objectCreatedTime = new Date(version.objectCreatedTime)
|
58
|
+
return version
|
59
|
+
})
|
60
|
+
|
61
|
+
resolve(response)
|
62
|
+
} else {
|
63
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
64
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
65
|
+
|
66
|
+
let body
|
67
|
+
|
68
|
+
try {
|
69
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
70
|
+
} catch (error) {
|
71
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
72
|
+
}
|
73
|
+
|
74
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
75
|
+
}
|
76
|
+
})
|
77
|
+
.catch(error => reject(error))
|
78
|
+
})
|
79
|
+
}
|
80
|
+
|
81
|
+
exports.func = function (args) {
|
82
|
+
return getDatastoreEntryVersions(args.universeId, args.datastoreName, args.entryKey, args.scope, args.startTime, args.endTime, args.sortOrder, args.limit, args.cursor, args.jar)
|
83
|
+
}
|
@@ -0,0 +1,73 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['universeId', 'datastoreName']
|
6
|
+
exports.optional = ['scope', 'prefix', 'limit', 'cursor', 'jar']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* <p> ☁️ Returns a list of entry keys within a data store. </p>
|
11
|
+
* API Key Permissions:
|
12
|
+
* <ul>
|
13
|
+
* <li> List keys </li>
|
14
|
+
* </ul>
|
15
|
+
* @category Datastores
|
16
|
+
* @param {number} universeId - The ID of the universe
|
17
|
+
* @param {string} datastoreName - Name of the data store
|
18
|
+
* @param {(string | boolean)=} [scope=global] - Defaults to global, similar to Lua API. If set to true, returns keys from all scopes.
|
19
|
+
* @param {string=} prefix - Return only data stores with this prefix
|
20
|
+
* @param {number=} limit - Maximum number of items to return
|
21
|
+
* @param {string=} cursor - Provide to request the next set of data
|
22
|
+
* @returns {Promise<DatastoreKeysResult>}
|
23
|
+
* @example const noblox = require("noblox.js")
|
24
|
+
* const keys = await noblox.getDatastoreKeys({ universeId: 127407415, datastoreName: 'LevelStore' })
|
25
|
+
**/
|
26
|
+
|
27
|
+
// Define
|
28
|
+
function getDatastoreKeys (universeId, datastoreName, scope = 'global', prefix, limit, cursor, jar) {
|
29
|
+
return new Promise((resolve, reject) => {
|
30
|
+
const httpOpt = {
|
31
|
+
url: `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries`,
|
32
|
+
options: {
|
33
|
+
resolveWithFullResponse: true,
|
34
|
+
method: 'GET',
|
35
|
+
jar,
|
36
|
+
qs: {
|
37
|
+
datastoreName,
|
38
|
+
scope,
|
39
|
+
AllScopes: scope === true,
|
40
|
+
prefix,
|
41
|
+
limit,
|
42
|
+
cursor
|
43
|
+
}
|
44
|
+
}
|
45
|
+
}
|
46
|
+
return http(httpOpt)
|
47
|
+
.then(function (res) {
|
48
|
+
if (res.statusCode === 200) {
|
49
|
+
const response = JSON.parse(res.body)
|
50
|
+
|
51
|
+
resolve(response)
|
52
|
+
} else {
|
53
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
54
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
55
|
+
|
56
|
+
let body
|
57
|
+
|
58
|
+
try {
|
59
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
60
|
+
} catch (error) {
|
61
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
62
|
+
}
|
63
|
+
|
64
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
65
|
+
}
|
66
|
+
})
|
67
|
+
.catch(error => reject(error))
|
68
|
+
})
|
69
|
+
}
|
70
|
+
|
71
|
+
exports.func = function (args) {
|
72
|
+
return getDatastoreKeys(args.universeId, args.datastoreName, args.scope, args.prefix, args.limit, args.cursor, args.jar)
|
73
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['universeId']
|
6
|
+
exports.optional = ['prefix', 'limit', 'cursor', 'jar']
|
7
|
+
|
8
|
+
// Docs
|
9
|
+
/**
|
10
|
+
* <p> ☁️ Returns a list of data stores belonging to a universe. </p>
|
11
|
+
* API Key Permissions:
|
12
|
+
* <ul>
|
13
|
+
* <li> List DataStores </li>
|
14
|
+
* </ul>
|
15
|
+
* @category Datastores
|
16
|
+
* @param {number} universeId - The ID of the universe whose data stores are being retrieved.
|
17
|
+
* @param {string=} prefix - Return only data stores with this prefix
|
18
|
+
* @param {number=} limit - Maximum number of items to return
|
19
|
+
* @param {string=} cursor - Provide to request the next set of data
|
20
|
+
* @returns {Promise<DatastoresResult>}
|
21
|
+
* @example const noblox = require("noblox.js")
|
22
|
+
* const datastores = await noblox.getDatastores(1117747196)
|
23
|
+
**/
|
24
|
+
|
25
|
+
// Define
|
26
|
+
function getDatastores (universeId, prefix, limit, cursor, jar) {
|
27
|
+
return new Promise((resolve, reject) => {
|
28
|
+
const httpOpt = {
|
29
|
+
url: `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores`,
|
30
|
+
options: {
|
31
|
+
resolveWithFullResponse: true,
|
32
|
+
method: 'GET',
|
33
|
+
jar,
|
34
|
+
qs: {
|
35
|
+
prefix,
|
36
|
+
limit,
|
37
|
+
cursor
|
38
|
+
}
|
39
|
+
}
|
40
|
+
}
|
41
|
+
return http(httpOpt)
|
42
|
+
.then(function (res) {
|
43
|
+
if (res.statusCode === 200) {
|
44
|
+
const response = JSON.parse(res.body)
|
45
|
+
response.datastores = response.datastores.map(datastore => {
|
46
|
+
datastore.createdTime = new Date(datastore.createdTime)
|
47
|
+
return datastore
|
48
|
+
})
|
49
|
+
|
50
|
+
resolve(response)
|
51
|
+
} else {
|
52
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
53
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
54
|
+
|
55
|
+
let body
|
56
|
+
|
57
|
+
try {
|
58
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
59
|
+
} catch (error) {
|
60
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
61
|
+
}
|
62
|
+
|
63
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
64
|
+
}
|
65
|
+
})
|
66
|
+
.catch(error => reject(error))
|
67
|
+
})
|
68
|
+
}
|
69
|
+
|
70
|
+
exports.func = function (args) {
|
71
|
+
return getDatastores(args.universeId, args.prefix, args.limit, args.cursor, args.jar)
|
72
|
+
}
|
@@ -0,0 +1,93 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const crypto = require('crypto')
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['universeId', 'datastoreName', 'entryKey', 'incrementBy']
|
7
|
+
exports.optional = ['scope', 'robloxEntryUserIDs', 'robloxEntryAttributes', 'jar']
|
8
|
+
|
9
|
+
// Docs
|
10
|
+
/**
|
11
|
+
* <p> ☁️ Increments the value for an entry by a given amount, or create a new entry with that amount. </p>
|
12
|
+
* API Key Permissions:
|
13
|
+
* <ul>
|
14
|
+
* <li> Create entry </li>
|
15
|
+
* <li> Update entry </li>
|
16
|
+
* </ul>
|
17
|
+
* @category Datastores
|
18
|
+
* @param {number} universeId - The ID of the universe
|
19
|
+
* @param {string} datastoreName - Name of the data store
|
20
|
+
* @param {string} entryKey - The key which identifies the entry.
|
21
|
+
* @param {number} incrementBy - The amount by which the entry should be incremented, or the starting value if it does not exist
|
22
|
+
* @param {string=} [scope=global] - Defaults to global, similar to Lua API.
|
23
|
+
* @param {Array<number>=} robloxEntryUserIDs - Comma-separated list of Roblox user IDs the entry is tagged with. If not provided, existing user IDs are cleared.
|
24
|
+
* @param {object=} robloxEntryAttributes - If not provided, existing attributes are cleared.
|
25
|
+
* @returns {Promise<DatastoreEntry>}
|
26
|
+
* @example const noblox = require("noblox.js")
|
27
|
+
* const entry = await noblox.incrementDatastoreEntry({ universeId: 127407415, datastoreName: 'LevelStore', entryKey: 'Level_User', incrementBy: 2 })
|
28
|
+
**/
|
29
|
+
|
30
|
+
// Define
|
31
|
+
function incrementDatastoreEntry (universeId, datastoreName, entryKey, incrementBy, scope = 'global', robloxEntryUserIDs = [], robloxEntryAttributes, jar) {
|
32
|
+
return new Promise((resolve, reject) => {
|
33
|
+
const httpOpt = {
|
34
|
+
url: `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries/entry/increment`,
|
35
|
+
options: {
|
36
|
+
resolveWithFullResponse: true,
|
37
|
+
method: 'POST',
|
38
|
+
jar,
|
39
|
+
qs: {
|
40
|
+
datastoreName,
|
41
|
+
scope,
|
42
|
+
entryKey,
|
43
|
+
incrementBy
|
44
|
+
},
|
45
|
+
headers: {
|
46
|
+
'Content-Type': 'application/json',
|
47
|
+
'content-md5': crypto.createHash('md5').update(JSON.stringify(incrementBy)).digest('base64'),
|
48
|
+
'roblox-entry-userids': JSON.stringify(robloxEntryUserIDs),
|
49
|
+
'roblox-entry-attributes': JSON.stringify(robloxEntryAttributes),
|
50
|
+
'content-length': '0'
|
51
|
+
}
|
52
|
+
}
|
53
|
+
}
|
54
|
+
return http(httpOpt)
|
55
|
+
.then(function (res) {
|
56
|
+
if (res.statusCode === 200) {
|
57
|
+
const response = JSON.parse(res.body)
|
58
|
+
const headers = res.headers
|
59
|
+
|
60
|
+
resolve({
|
61
|
+
data: response,
|
62
|
+
metadata: {
|
63
|
+
robloxEntryCreatedTime: new Date(headers['roblox-entry-created-time']),
|
64
|
+
lastModified: headers['last-modified'] ? new Date(headers['last-modified']) : new Date(headers['roblox-entry-created-time']),
|
65
|
+
robloxEntryVersion: headers['roblox-entry-version'],
|
66
|
+
robloxEntryAttributes: headers['roblox-entry-attributes'],
|
67
|
+
robloxEntryUserIDs: headers['roblox-entry-userids'],
|
68
|
+
contentMD5: headers['content-md5'],
|
69
|
+
contentLength: parseInt(headers['content-length'])
|
70
|
+
}
|
71
|
+
})
|
72
|
+
} else {
|
73
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
74
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
75
|
+
|
76
|
+
let body
|
77
|
+
|
78
|
+
try {
|
79
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
80
|
+
} catch (error) {
|
81
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
82
|
+
}
|
83
|
+
|
84
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
85
|
+
}
|
86
|
+
})
|
87
|
+
.catch(error => reject(error))
|
88
|
+
})
|
89
|
+
}
|
90
|
+
|
91
|
+
exports.func = function (args) {
|
92
|
+
return incrementDatastoreEntry(args.universeId, args.datastoreName, args.entryKey, args.incrementBy, args.scope, args.robloxEntryUserIDs, args.robloxEntryAttributes, args.jar)
|
93
|
+
}
|
@@ -0,0 +1,90 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
const crypto = require('crypto')
|
4
|
+
|
5
|
+
// Args
|
6
|
+
exports.required = ['universeId', 'datastoreName', 'entryKey', 'body']
|
7
|
+
exports.optional = ['scope', 'matchVersion', 'exclusiveCreate', 'robloxEntryUserIDs', 'robloxEntryAttributes', 'jar']
|
8
|
+
|
9
|
+
// Docs
|
10
|
+
/**
|
11
|
+
* <p> ☁️ Sets the value, metadata and user IDs associated with an entry. </p>
|
12
|
+
* <p>
|
13
|
+
* Note: You cannot use both matchVersion and exclusiveCreate. MD5 checksum is automatically generated.
|
14
|
+
* </p>
|
15
|
+
* API Key Permissions:
|
16
|
+
* <ul>
|
17
|
+
* <li> Create entry </li>
|
18
|
+
* <li> Update entry </li>
|
19
|
+
* </ul>
|
20
|
+
* @category Datastores
|
21
|
+
* @param {number} universeId - The ID of the universe
|
22
|
+
* @param {string} datastoreName - Name of the data store
|
23
|
+
* @param {string} entryKey - The key which identifies the entry.
|
24
|
+
* @param {any} body - The value the key should be set to.
|
25
|
+
* @param {string=} [scope=global] - Defaults to global, similar to Lua API.
|
26
|
+
* @param {string=} matchVersion - Only update if current version matches this.
|
27
|
+
* @param {boolean} [exclusiveCreate=false] - Only create the entry if it does not exist.
|
28
|
+
* @param {Array<number>=} robloxEntryUserIDs - Comma-separated list of Roblox user IDs the entry is tagged with. If not provided, existing user IDs are cleared.
|
29
|
+
* @param {object=} robloxEntryAttributes - If not provided, existing attributes are cleared.
|
30
|
+
* @returns {Promise<EntryVersion>}
|
31
|
+
* @example const noblox = require("noblox.js")
|
32
|
+
* const response = await noblox.setDatastoreEntry({ universeId: 127407415, datastoreName: 'LevelStore', entryKey: 'Level_Random', body: 230, robloxEntryUserIDs: [55549140], robloxEntryAttributes: { node: true } }))
|
33
|
+
**/
|
34
|
+
|
35
|
+
// Define
|
36
|
+
function setDatastoreEntry (universeId, datastoreName, entryKey, body, scope = 'global', matchVersion, exclusiveCreate = false, robloxEntryUserIDs = [], robloxEntryAttributes, jar) {
|
37
|
+
return new Promise((resolve, reject) => {
|
38
|
+
const httpOpt = {
|
39
|
+
url: `//apis.roblox.com/datastores/v1/universes/${universeId}/standard-datastores/datastore/entries/entry`,
|
40
|
+
options: {
|
41
|
+
resolveWithFullResponse: true,
|
42
|
+
method: 'POST',
|
43
|
+
jar,
|
44
|
+
qs: {
|
45
|
+
datastoreName,
|
46
|
+
scope,
|
47
|
+
entryKey,
|
48
|
+
matchVersion,
|
49
|
+
exclusiveCreate
|
50
|
+
},
|
51
|
+
headers: {
|
52
|
+
'Content-Type': 'application/json',
|
53
|
+
'content-md5': crypto.createHash('md5').update(JSON.stringify(body)).digest('base64'),
|
54
|
+
'roblox-entry-userids': JSON.stringify(robloxEntryUserIDs),
|
55
|
+
'roblox-entry-attributes': JSON.stringify(robloxEntryAttributes)
|
56
|
+
},
|
57
|
+
body: JSON.stringify(body)
|
58
|
+
}
|
59
|
+
}
|
60
|
+
return http(httpOpt)
|
61
|
+
.then(function (res) {
|
62
|
+
if (res.statusCode === 200) {
|
63
|
+
const response = JSON.parse(res.body)
|
64
|
+
|
65
|
+
response.createdTime = new Date(response.createdTime)
|
66
|
+
response.objectCreatedTime = new Date(response.objectCreatedTime)
|
67
|
+
|
68
|
+
resolve(response)
|
69
|
+
} else {
|
70
|
+
// Sourced from: https://stackoverflow.com/a/32278428
|
71
|
+
const isAnObject = (val) => !!(val instanceof Array || val instanceof Object)
|
72
|
+
|
73
|
+
let body
|
74
|
+
|
75
|
+
try {
|
76
|
+
body = isAnObject(JSON.parse(res.body)) ? JSON.parse(res.body) : {}
|
77
|
+
} catch (error) {
|
78
|
+
reject(new Error(`${res.statusCode} ${res.statusMessage}`))
|
79
|
+
}
|
80
|
+
|
81
|
+
reject(new Error(`${res.statusCode} ${body.error} ${body.message}`))
|
82
|
+
}
|
83
|
+
})
|
84
|
+
.catch(error => reject(error))
|
85
|
+
})
|
86
|
+
}
|
87
|
+
|
88
|
+
exports.func = function (args) {
|
89
|
+
return setDatastoreEntry(args.universeId, args.datastoreName, args.entryKey, args.body, args.scope, args.matchVersion, args.exclusiveCreate, args.robloxEntryUserIDs, args.robloxEntryAttributes, args.jar)
|
90
|
+
}
|
@@ -0,0 +1,44 @@
|
|
1
|
+
// Includes
|
2
|
+
const http = require('../util/http.js').func
|
3
|
+
|
4
|
+
// Args
|
5
|
+
exports.required = ['userId', 'assetId']
|
6
|
+
|
7
|
+
// Docs
|
8
|
+
/**
|
9
|
+
* ✅ Returns whether the user can manage a given asset.
|
10
|
+
* @category Develop
|
11
|
+
* @alias canManage
|
12
|
+
* @param {number} userId - The id of the user.
|
13
|
+
* @param {number} assetId - The id of the asset.
|
14
|
+
* @returns {Promise<boolean>}
|
15
|
+
* @example const noblox = require("noblox.js")
|
16
|
+
* let canManage = await noblox.canManage(123456, 234567)
|
17
|
+
**/
|
18
|
+
|
19
|
+
// Define
|
20
|
+
function canManage (userId, assetId) {
|
21
|
+
return http({
|
22
|
+
url: `//develop.roblox.com/v1/user/${userId}/canmanage/${assetId}`,
|
23
|
+
options: {
|
24
|
+
method: 'GET',
|
25
|
+
resolveWithFullResponse: true
|
26
|
+
}
|
27
|
+
})
|
28
|
+
.then(function ({ statusCode, body }) {
|
29
|
+
const { Success: success, CanManage: canManage, ErrorMessage: error } = JSON.parse(body)
|
30
|
+
if (success) {
|
31
|
+
return canManage
|
32
|
+
} else {
|
33
|
+
if (error) {
|
34
|
+
throw new Error(`${error} | userId: ${userId}, assetId: ${assetId}`)
|
35
|
+
} else {
|
36
|
+
throw new Error(`An unknown error occurred with canManage() | [${statusCode}] userId: ${userId}, assetId: ${assetId}`)
|
37
|
+
}
|
38
|
+
}
|
39
|
+
})
|
40
|
+
}
|
41
|
+
|
42
|
+
exports.func = function ({ userId, assetId }) {
|
43
|
+
return canManage(userId, assetId)
|
44
|
+
}
|