UNPKG

osu-api-extended

Version:

Advanced osu! api wrapper cover all V2 and V1 endpoints, and provide useful tools

562 lines 24.7 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; System.register("types/index", [], function (exports_1, context_1) { "use strict"; var __moduleName = context_1 && context_1.id; return { setters: [], execute: function () { ; } }; }); System.register("utility/request", ["querystring", "https", "utility/auth"], function (exports_2, context_2) { "use strict"; var querystring_1, https_1, auth, total_retries, sanitize_query, request; var __moduleName = context_2 && context_2.id; return { setters: [ function (querystring_1_1) { querystring_1 = querystring_1_1; }, function (https_1_1) { https_1 = https_1_1; }, function (auth_1) { auth = auth_1; } ], execute: function () { ; // VALUES total_retries = 0; sanitize_query = (obj) => { const object = Object.assign({}, obj); const array = Object.keys(object); for (let i = 0; i < array.length; i++) { const key = array[i]; const value = object[key]; if (value != null) continue; delete object[key]; } ; return querystring_1.default.encode(object); }; exports_2("request", request = (url, { method, headers, data, params = {}, addons = {} }) => new Promise((resolve, reject) => { // check required args if (url == null) { return resolve({ error: 'URL not specified', }); } ; if (method == null) { return resolve({ error: 'Method not specified', }); } ; // V1 add credentials if (url.includes('https://osu.ppy.sh/api/') && !url.includes('https://osu.ppy.sh/api/v2')) { params.k = addons.authKey || auth.cache.v1; if (params.k == null) { return resolve({ error: 'v1 api key not specified', }); } ; } ; // V2 add credentials if (url.includes('https://osu.ppy.sh/api/v2')) { if (!headers) headers = {}; headers.Authorization = `Bearer ${addons.authKey || auth.cache.v2}`; if (!headers.Accept) headers.Accept = `application/json`; if (!headers['Content-Type']) headers['Content-Type'] = `application/json`; if (addons.apiVersion != '') headers['x-api-version'] = addons.apiVersion || '20240130'; if ((addons.authKey || auth.cache.v2) == null) { return resolve({ error: 'v2 not authorized' }); } ; } ; if (addons.legacy_only != null) params.legacy_only = addons.legacy_only == true ? 1 : 0; const generate_query = sanitize_query(params); const build_url = url + (generate_query ? `?${generate_query}` : ''); // console.log({ url: build_url, method, headers, data, generate_query, params }); // debug const req = https_1.default.request(build_url, { method, headers }, (response) => { const { location } = response.headers; if (response.headers['x-ratelimit-limit']) auth.cache['ratelimit-limit'] = parseInt(response.headers['x-ratelimit-limit'].toString() || '60'); if (response.headers['x-ratelimit-remaining']) auth.cache['ratelimit-remaining'] = parseInt(response.headers['x-ratelimit-remaining'].toString() || '60'); if (location) { request(location, { method, headers, data, params, addons }) .then(resolve) .catch(reject); return; } ; // console.log(response.statusCode, response.statusMessage, response.headers.accept, { // 'ratelimit-limit': auth.cache['ratelimit-limit'], // 'ratelimit-remaining': auth.cache['ratelimit-remaining'], // }, { // url: build_url, method, headers, data, generate_query, params, // }); // debug const chunks = []; // handle response events response.on('data', (chunk) => chunks.push(chunk)); response.on('end', () => __awaiter(void 0, void 0, void 0, function* () { const data = Buffer.concat(chunks).toString(); if (/^application\/json/.test(response.headers['content-type'] || '')) { try { const parse = JSON.parse(data); if (parse.authentication === 'basic' && total_retries < 3 && addons.ignoreSessionRefresh != true) { total_retries++; const refresh = yield auth.refresh_token(); if (refresh == null) { return resolve({ error: 'Cannot refresh session, double check your credentials (or report to package author)' }); } ; const retry_request = yield request(url, { method, headers, data, params }); return resolve(retry_request); } ; if ('error' in parse && Object.keys(parse).length == 1) { if (parse.error === null) { return resolve({ error: `osu returned empty error, double check your parameters (request)` }); } ; return resolve({ error: parse.error }); } ; if (parse.authentication === 'basic') { return resolve({ error: 'Unauthorized (double check credentials)' }); } ; total_retries = 0; return resolve(parse); } catch (error) { return resolve({ error: error.name }); } ; } ; resolve(data); })); }); // send error req.on('error', (error) => { resolve({ error: error.name }); }); // timeout req.setTimeout(addons.timeout_ms || auth.settings.timeout, () => { req.destroy(); resolve({ error: `Request to ${build_url} time out after ${addons.timeout_ms || auth.settings.timeout}ms` }); }); // write body to request, if specified if (data) req.write(data); req.end(); })); } }; }); System.register("types/v2/users_details", [], function (exports_3, context_3) { "use strict"; var __moduleName = context_3 && context_3.id; return { setters: [], execute: function () { } }; }); System.register("utility/handleErrors", ["utility/auth"], function (exports_4, context_4) { "use strict"; var auth_2, handleErrors; var __moduleName = context_4 && context_4.id; return { setters: [ function (auth_2_1) { auth_2 = auth_2_1; } ], execute: function () { exports_4("handleErrors", handleErrors = (error) => { if (auth_2.settings.throwErrors) { throw error; } ; return { error }; }); } }; }); System.register("utility/auth", ["utility/request", "utility/handleErrors"], function (exports_5, context_5) { "use strict"; var request_1, handleErrors_1, settings, credentials, cache, login, set_v2, refresh_token, client_login; var __moduleName = context_5 && context_5.id; return { setters: [ function (request_1_1) { request_1 = request_1_1; }, function (handleErrors_1_1) { handleErrors_1 = handleErrors_1_1; } ], execute: function () { exports_5("settings", settings = { timeout: 60000, throwErrors: true, }); exports_5("credentials", credentials = { type: '', api_key: '', client_id: '', client_secret: '', login: '', password: '', redirect_url: '', state: '', cachedTokenPath: '', scopes: ['public'], }); exports_5("cache", cache = { v1: '', v2: '', 'ratelimit-remaining': 1200, 'ratelimit-limit': 1200, }); exports_5("login", login = (params) => { credentials.type = 'v2'; if (params.timeout) settings.timeout = params.timeout; credentials.client_id = params.client_id; credentials.client_secret = params.client_secret; if (params.scopes) credentials.scopes = params.scopes; return client_login(params.client_id, params.client_secret, params.scopes || ['public']); }); exports_5("set_v2", set_v2 = (token) => cache.v2 = token); exports_5("refresh_token", refresh_token = () => __awaiter(void 0, void 0, void 0, function* () { const refresh = yield login(credentials); return refresh; })); client_login = (client_id, client_secret, scopes) => __awaiter(void 0, void 0, void 0, function* () { const response = yield request_1.request('https://osu.ppy.sh/oauth/token', { method: 'POST', headers: { "Accept": "application/json", "Content-Type": "application/json", }, data: JSON.stringify({ grant_type: 'client_credentials', client_id: client_id, client_secret: client_secret, scope: scopes.join(' '), code: 'code', }) }); if (response.error) return handleErrors_1.handleErrors(new Error(response.error)); cache.v2 = response.access_token; return response; }); } }; }); System.register("types/v2/beatmaps_lookup_difficulty", [], function (exports_6, context_6) { "use strict"; var __moduleName = context_6 && context_6.id; return { setters: [], execute: function () { } }; }); System.register("api/v2/beatmaps_lookup", ["utility/request", "utility/handleErrors"], function (exports_7, context_7) { "use strict"; var request_2, handleErrors_2, beatmaps_lookup; var __moduleName = context_7 && context_7.id; return { setters: [ function (request_2_1) { request_2 = request_2_1; }, function (handleErrors_2_1) { handleErrors_2 = handleErrors_2_1; } ], execute: function () { exports_7("beatmaps_lookup", beatmaps_lookup = (params, addons) => __awaiter(void 0, void 0, void 0, function* () { const object = {}; let url = 'https://osu.ppy.sh/api/v2'; let method = 'GET'; switch (params.type) { case 'difficulty': url += '/beatmaps/lookup'; if (params.id == null && params.checksum == null && params.filename == null) { return handleErrors_2.handleErrors(new Error(`Specify at least one parameter`)); } ; object.id = params.id; object.checksum = params.checksum; object.filename = params.filename; break; default: return handleErrors_2.handleErrors(new Error(`Unsupported type: ${params.type}`)); } ; const data = yield request_2.request(url, { method: method, params: object, addons, }); if (data.error) return handleErrors_2.handleErrors(new Error(data.error)); return data; })); } }; }); System.register("api/v2/users_details", ["utility/handleErrors", "utility/request"], function (exports_8, context_8) { "use strict"; var handleErrors_3, request_3, users_details; var __moduleName = context_8 && context_8.id; return { setters: [ function (handleErrors_3_1) { handleErrors_3 = handleErrors_3_1; }, function (request_3_1) { request_3 = request_3_1; } ], execute: function () { exports_8("users_details", users_details = (params, addons) => __awaiter(void 0, void 0, void 0, function* () { if ((params === null || params === void 0 ? void 0 : params.user) == null) { return handleErrors_3.handleErrors(new Error('Specify user id or name')); } ; let key = params === null || params === void 0 ? void 0 : params.key; if (key == 'username') key = '@'; const data = yield request_3.request(`https://osu.ppy.sh/api/v2/users/${params.user}${params.mode ? `/${params.mode}` : ''}`, { method: 'GET', params: { key: key }, addons, }); if (data.error) return handleErrors_3.handleErrors(new Error(data.error)); return data; })); } }; }); System.register("routes/v2", ["api/v2/beatmaps_lookup", "api/v2/users_details"], function (exports_9, context_9) { "use strict"; var beatmaps_lookup_1, beatmaps, users_details_1, users; var __moduleName = context_9 && context_9.id; return { setters: [ function (beatmaps_lookup_1_1) { beatmaps_lookup_1 = beatmaps_lookup_1_1; }, function (users_details_1_1) { users_details_1 = users_details_1_1; } ], execute: function () { /** * ##### Description * Object containing methods for retrieving beatmaps data. */ exports_9("beatmaps", beatmaps = { /** * ### `GET` [/v2/beatmaps/lookup](https://osu.ppy.sh/docs/index.html#lookup-beatmap) * ### `GET` [/v2/beatmapsets/lookup](https://osu.ppy.sh/docs/index.html#get-apiv2beatmapsetslookup) * ### `POST` [/v2/beatmaps/{beatmap}/attributes](https://osu.ppy.sh/docs/index.html#get-beatmap-attributes) * ### `GET` [/v2/beatmaps](https://osu.ppy.sh/docs/index.html#get-beatmaps) * `async` Lookup for a beatmap by given parameters. * * &nbsp; * * ### Global Parameters * - `params.type` - Type of lookup. * * & &nbsp; * * ### Parameters for `params.type:'difficulty'` * - `params.id` - ID of the difficulty to lookup for. * - `params.checksum` - Checksum of the difficulty to lookup. * - `params.filename` - Filename of the difficulty to lookup. * * &nbsp; * * ### Parameters for `params.type:'set'` * - `params.id` - ID of the beatmap set to lookup for. * * &nbsp; * * ### Parameters for `params.type:'attribute'` * - `params.id` - ID of the beatmap to lookup for. * - `params.mods` - Mod combination of the beatmap to lookup for. * - `params.mode` - Mode of the beatmap to lookup for. * * &nbsp; * * ### Parameters for `params.type:'difficulties'` * - `params.ids` - IDs of the difficulties to lookup for. * * &nbsp; * * ### Usage Example * ```js * const { auth, v2 } = require('osu-api-extended'); * * async function main() { * try { * await auth.login({ * type: 'v2', * client_id: CLIENT_ID, * client_secret: CLIENT_SECRET, * cachedTokenPath: './test.json' // path to the file your auth token will be saved (to prevent osu!api spam) * }); * * const result = await v2.beatmaps.lookup({ * type: 'attributes', * id: 3798013, * }); * // or * const result = await v2.beatmaps.lookup({ * type: 'difficulties', * ids: [4233769, 3798013] * }); * // or * const result = await v2.beatmaps.lookup({ * type: 'difficulty', * id: 4233769, * }); * // or * const result = await v2.beatmaps.lookup({ * type: 'set', * id: 2246377, * }); * if (result.error != null) { * console.log(result.error); * return; * }; * * * console.log(result); * } catch (error) { * console.log(error); * }; * }; * * main(); * ``` * * &nbsp; * * [See documentation](https://github.com/cyperdark/osu-api-extended/wiki/v2.beatmaps.lookup_v3) | [Check return types](../types/v2/beatmaps_lookup.ts) */ lookup: beatmaps_lookup_1.beatmaps_lookup, }); /** * ##### Description * Covers API Endpoints regarding users. */ exports_9("users", users = { /** * ### `GET` [/v2/users/{user}/{mode?}](https://osu.ppy.sh/docs/index.html#get-user) * `async` Retrieves a user by given parameters. * * &nbsp; * * ### Parameters * - `params.id` - ID or username of the user to retrieve. * - `params.mode?` - Retrieve data for a specific gamemode. * - `params.key?` - Type of the `params.id` parameter. * - `addons?` - Additional parameters to include in the request. * * &nbsp; * * ### Usage Example * ```js * const { auth, v2 } = require('osu-api-extended'); * * async function main() { * try { * await auth.login({ * type: 'v2', * client_id: CLIENT_ID, * client_secret: CLIENT_SECRET, * cachedTokenPath: './test.json' // path to the file your auth token will be saved (to prevent osu!api spam) * }); * * const result = await v2.users.details({ user: 9893708, mode: 'osu', key: 'id' }); * if (result.error != null) { * console.log(result.error); * return; * }; * * console.log(result); * } catch (error) { * console.log(error); * }; * }; * * main(); * ``` * * &nbsp; * * [See documentation](https://github.com/cyperdark/osu-api-extended/wiki/v2.users.details_v3) | [Check return types](../types/v2/users_details.ts) */ details: users_details_1.users_details, }); } }; }); System.register("index", ["utility/auth", "routes/v2", "types/v2/beatmaps_lookup_difficulty", "types/v2/users_details"], function (exports_10, context_10) { "use strict"; var __moduleName = context_10 && context_10.id; return { setters: [ function (auth_3) { exports_10("auth", auth_3); }, function (v2_1) { exports_10("v2", v2_1); }, function (v2_beatmaps_lookup_difficulty_1) { exports_10("v2_beatmaps_lookup_difficulty", v2_beatmaps_lookup_difficulty_1); }, function (v2_users_details_1) { exports_10("v2_users_details", v2_users_details_1); } ], execute: function () { } }; }); System.register("types/mods", [], function (exports_11, context_11) { "use strict"; var __moduleName = context_11 && context_11.id; return { setters: [], execute: function () { } }; }); //# sourceMappingURL=bundle.js.map