Implemented search for games and mods
parent
f7dd2d8e4e
commit
20fea5c315
|
@ -0,0 +1,111 @@
|
|||
"use strict";
|
||||
|
||||
class GameInfo {
|
||||
constructor() {
|
||||
//#region Properties
|
||||
/**
|
||||
* Game name
|
||||
* @type String
|
||||
*/
|
||||
this.name = null;
|
||||
/**
|
||||
* Game author
|
||||
* @type String
|
||||
*/
|
||||
this.author = null;
|
||||
/**
|
||||
* URL to the game's official conversation on the F95Zone portal
|
||||
* @type String
|
||||
*/
|
||||
this.url = null;
|
||||
/**
|
||||
* Game description
|
||||
* @type String
|
||||
*/
|
||||
this.overview = null;
|
||||
/**
|
||||
* List of tags associated with the game
|
||||
* @type String[]
|
||||
*/
|
||||
this.tags = [];
|
||||
/**
|
||||
* Graphics engine used for game development
|
||||
* @type String
|
||||
*/
|
||||
this.engine = null;
|
||||
/**
|
||||
* Progress of the game
|
||||
* @type String
|
||||
*/
|
||||
this.status = null;
|
||||
/**
|
||||
* Game description image URL
|
||||
* @type String
|
||||
*/
|
||||
this.previewSrc = null;
|
||||
/**
|
||||
* Game version
|
||||
* @type String
|
||||
*/
|
||||
this.version = null;
|
||||
/**
|
||||
* Last time the game underwent updates
|
||||
* @type String
|
||||
*/
|
||||
this.lastUpdate = null;
|
||||
/**
|
||||
* Last time the local copy of the game was run
|
||||
* @type String
|
||||
*/
|
||||
this.lastPlayed = null;
|
||||
/**
|
||||
* Specifies if the game is original or a mod
|
||||
* @type Boolean
|
||||
*/
|
||||
this.isMod = false;
|
||||
/**
|
||||
* Changelog for the last version.
|
||||
* @type String
|
||||
*/
|
||||
this.changelog = null;
|
||||
/**
|
||||
* Directory containing the local copy of the game
|
||||
* @type String
|
||||
*/
|
||||
this.gameDir = null;
|
||||
//#endregion Properties
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the object to a dictionary used for JSON serialization.
|
||||
*/
|
||||
/* istanbul ignore next */
|
||||
toJSON() {
|
||||
return {
|
||||
name: this.name,
|
||||
author: this.author,
|
||||
url: this.url,
|
||||
overview: this.overview,
|
||||
engine: this.engine,
|
||||
status: this.status,
|
||||
previewSrc: this.previewSrc,
|
||||
version: this.version,
|
||||
lastUpdate: this.lastUpdate,
|
||||
lastPlayed: this.lastPlayed,
|
||||
isMod: this.isMod,
|
||||
changelog: this.changelog,
|
||||
gameDir: this.gameDir,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new GameInfo from a JSON string.
|
||||
* @param {String} json JSON string used to create the new object
|
||||
* @returns {GameInfo}
|
||||
*/
|
||||
/* istanbul ignore next */
|
||||
static fromJSON(json) {
|
||||
return Object.assign(new GameInfo(), json);
|
||||
}
|
||||
}
|
||||
module.exports = GameInfo;
|
|
@ -0,0 +1,20 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Object obtained in response to an attempt to login to the portal.
|
||||
*/
|
||||
class LoginResult {
|
||||
constructor(success, message) {
|
||||
/**
|
||||
* Result of the login operation
|
||||
* @type Boolean
|
||||
*/
|
||||
this.success = success;
|
||||
/**
|
||||
* Login response message
|
||||
* @type String
|
||||
*/
|
||||
this.message = message;
|
||||
}
|
||||
}
|
||||
module.exports = LoginResult;
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
|
||||
/**
|
||||
* Class containing the data of the user currently connected to the F95Zone platform.
|
||||
*/
|
||||
class UserData {
|
||||
constructor() {
|
||||
/**
|
||||
* User username.
|
||||
* @type String
|
||||
*/
|
||||
this.username = "";
|
||||
/**
|
||||
* Path to the user's profile picture.
|
||||
* @type String
|
||||
*/
|
||||
this.avatarSrc = null;
|
||||
/**
|
||||
* List of followed thread URLs.
|
||||
* @type URL[]
|
||||
*/
|
||||
this.watchedThreads = [];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserData;
|
|
@ -0,0 +1,31 @@
|
|||
module.exports = Object.freeze({
|
||||
AVATAR_INFO: "span.avatar",
|
||||
AVATAR_PIC: "a[href=\"/account/\"] > span.avatar > img[class^=\"avatar\"]",
|
||||
ENGINE_ID_SELECTOR: "div[id^=\"btn-prefix_1_\"]>span",
|
||||
FILTER_THREADS_BUTTON: "button[class=\"button--primary button\"]",
|
||||
GT_IMAGES: "img[src^=\"https://attachments.f95zone.to\"]",
|
||||
GT_TAGS: "a.tagItem",
|
||||
GT_TITLE: "h1.p-title-value",
|
||||
GT_TITLE_PREFIXES: "h1.p-title-value > a.labelLink > span[dir=\"auto\"]",
|
||||
LOGIN_BUTTON: "button.button--icon--login",
|
||||
LOGIN_MESSAGE_ERROR: "div.blockMessage.blockMessage--error.blockMessage--iconic",
|
||||
ONLY_GAMES_THREAD_OPTION: "select[name=\"nodes[]\"] > option[value=\"2\"]",
|
||||
PASSWORD_INPUT: "input[name=\"password\"]",
|
||||
SEARCH_BUTTON: "form.block > * button.button--icon--search",
|
||||
SEARCH_FORM_TEXTBOX: "input[name=\"keywords\"][type=\"search\"]",
|
||||
SEARCH_ONLY_GAMES_OPTION: "select[name=\"c[nodes][]\"] > option[value=\"1\"]",
|
||||
STATUS_ID_SELECTOR: "div[id^=\"btn-prefix_4_\"]>span",
|
||||
THREAD_POSTS: "article.message-body:first-child > div.bbWrapper:first-of-type",
|
||||
GS_RESULT_THREAD_TITLE: "h3.contentRow-title > a",
|
||||
TITLE_ONLY_CHECKBOX: "form.block > * input[name=\"c[title_only]\"]",
|
||||
WT_UNREAD_THREAD_CHECKBOX: "input[type=\"checkbox\"][name=\"unread\"]",
|
||||
USERNAME_ELEMENT: "a[href=\"/account/\"] > span.p-navgroup-linkText",
|
||||
USERNAME_INPUT: "input[name=\"login\"]",
|
||||
WT_FILTER_POPUP_BUTTON: "a.filterBar-menuTrigger",
|
||||
WT_NEXT_PAGE: "a.pageNav-jump--next",
|
||||
WT_URLS: "a[href^=\"/threads/\"][data-tp-primary]",
|
||||
DOWNLOAD_LINKS_CONTAINER: "span[style=\"font-size: 18px\"]",
|
||||
GS_RESULT_BODY: "div.contentRow-main",
|
||||
GS_MEMBERSHIP: "li > a:not(.username)",
|
||||
THREAD_LAST_CHANGELOG: "div.bbCodeBlock-content > div:first-of-type",
|
||||
});
|
|
@ -0,0 +1,7 @@
|
|||
module.exports = Object.freeze({
|
||||
F95_BASE_URL: "https://f95zone.to",
|
||||
F95_SEARCH_URL: "https://f95zone.to/search/?type=post",
|
||||
F95_LATEST_UPDATES: "https://f95zone.to/latest",
|
||||
F95_LOGIN_URL: "https://f95zone.to/login",
|
||||
F95_WATCHED_THREADS: "https://f95zone.to/watched/threads",
|
||||
});
|
|
@ -0,0 +1,35 @@
|
|||
"use strict";
|
||||
|
||||
// Public modules from npm
|
||||
const axios = require("axios").default;
|
||||
const _ = require("lodash");
|
||||
|
||||
// Modules from file
|
||||
const shared = require("./scripts/shared.js");
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* Gets the HTML code of a page.
|
||||
* @param {String} url URL to fetch
|
||||
* @returns {Promise<String>} HTML code or `null` if an error arise
|
||||
*/
|
||||
module.exports = async function fetchHTML(url) {
|
||||
try {
|
||||
const response = await axios.get(url);
|
||||
return response.data;
|
||||
} catch {
|
||||
shared.logger.error(`An error occurred while trying to fetch the URL: ${url}`);
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* Enforces the scheme of the URL is https and returns the new URL.
|
||||
* @param {String} url
|
||||
* @returns {String}
|
||||
*/
|
||||
module.exports = function enforceHttpsUrl(url) {
|
||||
const value = _.isString(url) ? url.replace(/^(https?:)?\/\//, "https://") : null;
|
||||
return value;
|
||||
};
|
|
@ -0,0 +1,88 @@
|
|||
"use strict";
|
||||
|
||||
// Public modules from npm
|
||||
const cheerio = require("cheerio");
|
||||
|
||||
// Modules from file
|
||||
const { fetchHTML } = require("./network-helper.js");
|
||||
const shared = require("./scripts/shared.js");
|
||||
const f95Selector = require("./constants/css-selector.js");
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* Search for a game on F95Zone and return a list of URLs, one for each search result.
|
||||
* @param {String} name Game name
|
||||
* @returns {Promise<String[]>} URLs of results
|
||||
*/
|
||||
module.exports = async function searchGame(name) {
|
||||
shared.logger.info(`Searching games with name ${name}`);
|
||||
|
||||
// Replace the whitespaces with +
|
||||
const searchName = name.replaceAll(" ", "+").toUpperCase();
|
||||
|
||||
// Prepare the URL (only title, search in the "Games" section, order by relevance)
|
||||
const url = `https://f95zone.to/search/83456043/?q=${searchName}&t=post&c[child_nodes]=1&c[nodes][0]=2&c[title_only]=1&o=relevance`;
|
||||
|
||||
// Fetch and parse the result URLs
|
||||
return await fetchResultURLs(url);
|
||||
};
|
||||
|
||||
/**
|
||||
* @protected
|
||||
* Search for a mod on F95Zone and return a list of URLs, one for each search result.
|
||||
* @param {String} name Mod name
|
||||
* @returns {Promise<String[]>} URLs of results
|
||||
*/
|
||||
module.exports = async function searchMod(name) {
|
||||
shared.logger.info(`Searching mods with name ${name}`);
|
||||
// Replace the whitespaces with +
|
||||
const searchName = name.replaceAll(" ", "+").toUpperCase();
|
||||
|
||||
// Prepare the URL (only title, search in the "Mods" section, order by relevance)
|
||||
const url = `https://f95zone.to/search/83459796/?q=${searchName}&t=post&c[child_nodes]=1&c[nodes][0]=41&c[title_only]=1&o=relevance`;
|
||||
|
||||
// Fetch and parse the result URLs
|
||||
return await fetchResultURLs(url);
|
||||
};
|
||||
|
||||
//#region Private methods
|
||||
/**
|
||||
* @private
|
||||
* Gets the URLs of the threads resulting from the F95Zone search.
|
||||
* @param {String} url Search URL
|
||||
* @return {Promise<String[]>} List of URLs
|
||||
*/
|
||||
async function fetchResultURLs(url) {
|
||||
shared.logger.info(`Fetching ${url}...`);
|
||||
|
||||
// Fetch HTML and prepare Cheerio
|
||||
const html = await fetchHTML(url);
|
||||
const $ = cheerio.load(html);
|
||||
|
||||
// Here we get all the DIV that are the body of the various query results
|
||||
const results = $("body").find(f95Selector.GS_RESULT_BODY);
|
||||
|
||||
// Than we extract the URLs
|
||||
const urls = results.map((idx, el) => {
|
||||
const elementSelector = $(el);
|
||||
return extractLinkFromResult(elementSelector);
|
||||
}).get();
|
||||
|
||||
return urls;
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
* Look for the URL to the thread referenced by the item.
|
||||
* @param {cheerio.Cheerio} selector Element to search
|
||||
* @returns {String} URL to thread
|
||||
*/
|
||||
function extractLinkFromResult(selector) {
|
||||
const link = selector
|
||||
.find(f95Selector.GS_RESULT_THREAD_TITLE)
|
||||
.attr("href")
|
||||
.trim();
|
||||
|
||||
return link;
|
||||
}
|
||||
//#endregion Private methods
|
|
@ -285,8 +285,7 @@
|
|||
"@types/node": {
|
||||
"version": "14.11.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.11.2.tgz",
|
||||
"integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA==",
|
||||
"optional": true
|
||||
"integrity": "sha512-jiE3QIxJ8JLNcb1Ps6rDbysDhN4xa8DJJvuC9prr6w+1tIh+QAbYyNF3tyiZNLDBIuBCf4KEcV2UvQm/V60xfA=="
|
||||
},
|
||||
"@types/yauzl": {
|
||||
"version": "2.9.1",
|
||||
|
@ -423,6 +422,14 @@
|
|||
"integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.0.tgz",
|
||||
"integrity": "sha512-fmkJBknJKoZwem3/IKSSLpkdNXZeBu5Q7GA/aRsr2btgrptmSCxi2oFjZHqGdK9DoTil9PIHlPIZw2EcRJXRvw==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"babel-eslint": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz",
|
||||
|
@ -471,6 +478,11 @@
|
|||
"readable-stream": "^3.4.0"
|
||||
}
|
||||
},
|
||||
"boolbase": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
|
||||
"integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
|
@ -564,6 +576,19 @@
|
|||
"integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
|
||||
"dev": true
|
||||
},
|
||||
"cheerio": {
|
||||
"version": "1.0.0-rc.3",
|
||||
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.3.tgz",
|
||||
"integrity": "sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==",
|
||||
"requires": {
|
||||
"css-select": "~1.2.0",
|
||||
"dom-serializer": "~0.1.1",
|
||||
"entities": "~1.1.1",
|
||||
"htmlparser2": "^3.9.1",
|
||||
"lodash": "^4.15.0",
|
||||
"parse5": "^3.0.1"
|
||||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.2.tgz",
|
||||
|
@ -648,6 +673,22 @@
|
|||
"which": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"css-select": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
|
||||
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
|
||||
"requires": {
|
||||
"boolbase": "~1.0.0",
|
||||
"css-what": "2.1",
|
||||
"domutils": "1.5.1",
|
||||
"nth-check": "~1.0.1"
|
||||
}
|
||||
},
|
||||
"css-what": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
|
||||
"integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg=="
|
||||
},
|
||||
"data-uri-to-buffer": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz",
|
||||
|
@ -725,6 +766,37 @@
|
|||
"esutils": "^2.0.2"
|
||||
}
|
||||
},
|
||||
"dom-serializer": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
|
||||
"integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.0",
|
||||
"entities": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"domelementtype": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
|
||||
"integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w=="
|
||||
},
|
||||
"domhandler": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
|
||||
"integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
|
||||
"requires": {
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"domutils": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
|
||||
"integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
|
||||
"requires": {
|
||||
"dom-serializer": "0",
|
||||
"domelementtype": "1"
|
||||
}
|
||||
},
|
||||
"dotenv": {
|
||||
"version": "8.2.0",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
||||
|
@ -754,6 +826,11 @@
|
|||
"ansi-colors": "^4.1.1"
|
||||
}
|
||||
},
|
||||
"entities": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||
},
|
||||
"es-abstract": {
|
||||
"version": "1.17.6",
|
||||
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz",
|
||||
|
@ -1159,6 +1236,11 @@
|
|||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
|
||||
"integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.13.0",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.13.0.tgz",
|
||||
"integrity": "sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA=="
|
||||
},
|
||||
"foreground-child": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
|
||||
|
@ -1327,6 +1409,19 @@
|
|||
"integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
|
||||
"dev": true
|
||||
},
|
||||
"htmlparser2": {
|
||||
"version": "3.10.1",
|
||||
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
|
||||
"integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
|
||||
"requires": {
|
||||
"domelementtype": "^1.3.1",
|
||||
"domhandler": "^2.3.0",
|
||||
"domutils": "^1.5.1",
|
||||
"entities": "^1.1.1",
|
||||
"inherits": "^2.0.1",
|
||||
"readable-stream": "^3.1.1"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz",
|
||||
|
@ -1724,8 +1819,7 @@
|
|||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"lodash.flattendeep": {
|
||||
"version": "4.4.0",
|
||||
|
@ -2127,6 +2221,14 @@
|
|||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
|
||||
"dev": true
|
||||
},
|
||||
"nth-check": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
|
||||
"integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
|
||||
"requires": {
|
||||
"boolbase": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"nyc": {
|
||||
"version": "15.1.0",
|
||||
"resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz",
|
||||
|
@ -2259,6 +2361,14 @@
|
|||
"callsites": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"parse5": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
|
||||
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
|
||||
"requires": {
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"path-exists": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
|
||||
|
|
|
@ -31,6 +31,8 @@
|
|||
"node": ">=10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.0",
|
||||
"cheerio": "^1.0.0-rc.3",
|
||||
"ky": "^0.24.0",
|
||||
"ky-universal": "^0.8.2",
|
||||
"log4js": "^6.3.0",
|
||||
|
|
Loading…
Reference in New Issue