UNPKG

nationstates.js

Version:

A wrapper to interact with the NationStates API.

154 lines 6.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.NSMethods = void 0; const request_builder_1 = require("../request_builder/request_builder"); const fs = require("fs"); const zlib = require("zlib"); // Node-fetch v.2.6.5. Still supported by developers. const node_fetch_1 = require("node-fetch"); const xml_parser_1 = require("../xml_parser"); /** * As opposed to building requests manually, this class has built-in methods for easily accessing and handling * common information one looks for. You do not build, send, or parse requests manually. * @example const methods = new NSMethods(api); * @param { API } client The client object to enforce rate limiting and user agents. */ class NSMethods extends request_builder_1.RequestBuilder { constructor(api) { super(api); } /** * Returns a boolean response, if nation1 is endorsing nation2. * Does not modify the URL of the request. * @example console.log(await methods.isEndorsing('Testlandia', 'Testlandia')); // false * @param nation1 - The endorser. * @param nation2 - The endorsee. */ async isEndorsing(nation1, nation2) { // Reset the object's URL. this.resetURL(); // Get endorsements of nation2. const r = await (await this .addNation(nation2.replace(/ /g, '_')) .addShards('endorsements') .execute()) .toJS(); // Uses RegExp to verify if nation1 is in commma-seperated list of endorsements and returns the boolean. return new RegExp('(?:^|,)' + nation1.replace(/ /g, '_') + '(?:,|$)').test(r.js['endorsements']); } /** * Use the NS Verification client to verify the validity of a verification code. * Returns either a 0 or 1 as a number, as described in the NS client documentation. * @example console.log(await methods.verify('Testlandia', '12345')); // 0 * @param nation * @param checksum * @param siteSpecificToken */ async verify(nation, checksum, siteSpecificToken) { // Reset the object's URL. this.resetURL(); // Add nation this.addNation(nation.toLowerCase().replace(/ /g, '_')); // Adds "a=verify" to the URL parameters. this._urlObj.searchParams.append('a', 'verify'); // Adds checksum this._urlObj.searchParams.append('checksum', checksum); // Adds site specific token if it is set. if (siteSpecificToken) { this._urlObj.searchParams.append('token', siteSpecificToken); } // Get response await this.execute(); // Return response as number. return parseInt(this.response.body); } /** * Download the nation data dump from the client. * Note that it can take a while to download the dump, especially for nations or when converting to JSON. * Future feature: Decode utf-8 within the dump. * @example methods.downloadDump('Testlandia', {extract: true, deleteXMLGz: true, deleteXML: true, convertToJson: true}); // Returns just a .json file * @param type - Either 'nation' or 'region' * @param directoryToSave - The directory to save the dump to. Should be ended by a slash. Ex: "./downloads/" * @param options - If left blank, just downloads the {type}.xml.gz file. */ async downloadDumpAsync(type, directoryToSave, options) { // TODO: Implement decoding utf-8 within the dump. // Verify if type is correct if (type !== 'nations' && type !== 'regions') throw new Error('Type must be either "nation" or "region"'); // Get current date as YYYY-MM-DD const currentDate = new Date().toISOString().slice(0, 10); // Set fileName with directory const fileName = directoryToSave + type + '.' + currentDate; // If the dump is already present, do not download it. if (!fs.existsSync(fileName + '.xml.gz')) { // Check rate limit. await this.execRateLimit(); // Request the file from the NationStates client. const res = await (0, node_fetch_1.default)(`https://www.nationstates.net/pages/${type}.xml.gz`, { headers: { 'User-Agent': this.client.userAgent } }); // Create a file stream to save the file. const fileStream = fs.createWriteStream(fileName + '.xml.gz'); // Synchronously write the file to the file stream. await new Promise((resolve, reject) => { res.body.pipe(fileStream); res.body.on("error", reject); fileStream.on("finish", resolve); }); } if (options?.extract) await this.gunzip(fileName + '.xml.gz', fileName + '.xml'); if (options?.convertToJson) { // Verify the XML file has been unzipped. If not, do so. if (!fs.existsSync(fileName + '.xml')) await this.gunzip(fileName + '.xml.gz', fileName + '.xml'); // Convert the XML file to JSON. await this.xmlToJson(fileName + '.xml', fileName + '.json'); } if (options?.deleteXMLGz) fs.unlinkSync(fileName + '.xml.gz'); if (options?.deleteXML) fs.unlinkSync(fileName + '.xml'); // Method chaining return this; } /** * Extracts a gzipped file. * @param file * @param savePath * @private */ async gunzip(file, savePath) { // Decompress the gzip file. await new Promise((resolve) => { zlib.gunzip(fs.readFileSync(file), (err, buffer) => { fs.writeFileSync(savePath, buffer); resolve('Finished unzipping.'); }); }); // Method chaining return this; } /** * Converts an XML file to JSON and saves it to the specified path. * Uses the XML2Js library. * @param file * @param savePath * @private */ async xmlToJson(file, savePath) { // Convert the XML file to JSON. let xml = fs.readFileSync(file, 'utf8'); // Create JSON file const json = fs.createWriteStream(savePath); // Write JSON to file json.write(JSON.stringify(await (0, xml_parser_1.parseXml)(xml))); // Method Chaining return this; } } exports.NSMethods = NSMethods; //# sourceMappingURL=ns_methods.js.map