#!/usr/bin/env -S node --experimental-fetch --no-warnings --tls-max-v1.3 import path from 'node:path'; import process from 'node:process'; import url from 'node:url'; const __filename = path.resolve(url.fileURLToPath(import.meta.url)); /** * @typedef {Object} RankingQuery * @property {string} ctg * @property {number} page * @property {string} keyword * @property {number?} amount * * @typedef {Object} PlayerLadderInfo * @property {number} rank * @property {string} name * @property {number} score * @property {number} wins * @property {number} losses * @property {string} tierUrl */ /** * @param {string!} name * @returns {Promise} */ async function showPlayerLadderInfo(name) { /** @type {RankingQuery} */ const body = { ctg: 'ladder', keyword: name, page: 0, // required - '0' fetches results from every page }; try { const response = await fetch( 'https://www.fxpgunz.com/api/app/rankings', { method: 'POST', mode: 'cors', redirect: 'follow', referrerPolicy: 'strict-origin-when-cross-origin', headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify(body), } ) /** @type {PlayerLadderInfo[]} */ const data = await response.json(); const player = data.find( entry => entry?.name.toLowerCase() === name.toLowerCase(), ) ?? 'Not found.'; console.dir(player); } catch (error) { console.error(error); return 1; } return 0; } /** * @returns {never} */ function usage() { console.log(`Usage: ${process.argv.slice(-2).join(" ")} `); process.exit(2); } /** * @param {readonly string[]} args * @returns {Promise} */ async function main(args) { if (args.length != 1) usage(); const name = args[0]; return await showPlayerLadderInfo(name); } if (process.argv[1] === __filename) { // Temporary workaround - we cannot pass a custom agent to fetch() yet process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0; process.exitCode = await main(process.argv.slice(2)); }