UNPKG

serpapi

Version:

Scrape and parse search engine results using SerpApi.

107 lines (106 loc) 3.92 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.execute = exports.buildRequestOptions = exports.getSource = exports._internals = void 0; const version_js_1 = require("../version.js"); const https_1 = __importDefault(require("https")); const querystring_1 = __importDefault(require("querystring")); const process_1 = __importDefault(require("process")); const errors_js_1 = require("./errors.js"); const config_js_1 = require("./config.js"); /** * This `_internals` object is needed to support stubbing/spying of * certain functions in this file. * https://deno.land/manual@v1.28.3/basics/testing/mocking * * It's also useful to encapsulate functions that are polyfilled. */ exports._internals = { execute: execute, getHostnameAndPort: getHostnameAndPort, }; /** Facilitates stubbing in tests */ function getHostnameAndPort() { return { hostname: "serpapi.com", port: 443, }; } function getSource() { var _a, _b; const moduleSource = `serpapi@${version_js_1.version}`; if (typeof Deno == "object") { const denoVersion = (_a = Deno.version) === null || _a === void 0 ? void 0 : _a.deno; if (denoVersion) { return `deno@${denoVersion},${moduleSource}`; } } else if (typeof process_1.default == "object") { const nodeVersion = (_b = process_1.default.versions) === null || _b === void 0 ? void 0 : _b.node; if (nodeVersion) { return `nodejs@${nodeVersion},${moduleSource}`; } } return `nodejs,${moduleSource}`; } exports.getSource = getSource; function buildRequestOptions(path, parameters) { const clonedParams = Object.assign({}, parameters); for (const k in clonedParams) { if (k === "requestOptions" || k === "timeout" || clonedParams[k] === undefined) { delete clonedParams[k]; } } const basicOptions = Object.assign(Object.assign({}, exports._internals.getHostnameAndPort()), { path: `${path}?${querystring_1.default.stringify(clonedParams)}`, method: "GET" }); return Object.assign(Object.assign(Object.assign({}, config_js_1.config.requestOptions), parameters.requestOptions), basicOptions); } exports.buildRequestOptions = buildRequestOptions; function execute(path, parameters, timeout) { const options = buildRequestOptions(path, Object.assign(Object.assign({}, parameters), { source: getSource() })); return new Promise((resolve, reject) => { let timer; const handleResponse = (resp) => { resp.setEncoding("utf8"); let data = ""; // A chunk of data has been received resp.on("data", (chunk) => { data += chunk; }); // The whole response has been received resp.on("end", () => { try { if (resp.statusCode == 200) { resolve(data); } else { reject(data); } } catch (e) { reject(e); } finally { if (timer) clearTimeout(timer); } }); }; const handleError = (err) => { reject(err); if (timer) clearTimeout(timer); }; const req = https_1.default.get(options, handleResponse).on("error", handleError); if (timeout > 0) { timer = setTimeout(() => { reject(new errors_js_1.RequestTimeoutError()); req.destroy(); }, timeout); } }); } exports.execute = execute;