New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@apify/utilities

Package Overview
Dependencies
Maintainers
10
Versions
100
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@apify/utilities - npm Package Compare versions

Comparing version 1.2.14 to 2.0.0

index.js.map

1751

index.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
CHECK_TYPES: () => CHECK_TYPES,
HealthChecker: () => HealthChecker,
InvalidJsonError: () => InvalidJsonError,
InvalidVariableError: () => InvalidVariableError,
JsonVariable: () => JsonVariable,
ParseJsonlStream: () => ParseJsonlStream,
RetryableError: () => RetryableError,
WebhookPayloadTemplate: () => WebhookPayloadTemplate,
betterClearInterval: () => betterClearInterval,
betterSetInterval: () => betterSetInterval,
buildOrVersionNumberIntToStr: () => buildOrVersionNumberIntToStr,
checkParamPrototypeOrThrow: () => checkParamPrototypeOrThrow,
concatStreamToBuffer: () => concatStreamToBuffer,
configureLogger: () => configureLogger,
cryptoRandomObjectId: () => cryptoRandomObjectId,
dateToString: () => dateToString,
delayPromise: () => delayPromise,
deterministicUniqueId: () => deterministicUniqueId,
escapeForBson: () => escapeForBson,
escapePropertyName: () => escapePropertyName,
escapeRegExp: () => escapeRegExp,
expressErrorHandler: () => expressErrorHandler,
getOrdinalSuffix: () => getOrdinalSuffix,
getRandomInt: () => getRandomInt,
http404Route: () => http404Route,
isBadForMongo: () => isBadForMongo,
isBuffer: () => isBuffer,
isForbiddenUsername: () => isForbiddenUsername,
isNullOrUndefined: () => isNullOrUndefined,
isUrlRelative: () => isUrlRelative,
jsonStringifyExtended: () => jsonStringifyExtended,
leftpad: () => leftpad,
markedDecreaseHeadsLevel: () => markedDecreaseHeadsLevel,
markedSetNofollowLinks: () => markedSetNofollowLinks,
normalizeUrl: () => normalizeUrl,
parseDateFromJson: () => parseDateFromJson,
parseUrl: () => parseUrl,
promisifyServerListen: () => promisifyServerListen,
readStreamToString: () => readStreamToString,
removeFromArray: () => removeFromArray,
retryWithExpBackoff: () => retryWithExpBackoff,
sequentializePromises: () => sequentializePromises,
splitFullName: () => splitFullName,
timeoutPromise: () => timeoutPromise,
traverseObject: () => traverseObject,
truncate: () => truncate,
unescapeFromBson: () => unescapeFromBson,
unescapePropertyName: () => unescapePropertyName,
weightedAverage: () => weightedAverage
});
module.exports = __toCommonJS(src_exports);
// src/utilities.ts
var import_crypto = __toESM(require("crypto"));
var import_log = __toESM(require("@apify/log"));
var import_consts = require("@apify/consts");
function cryptoRandomObjectId(length = 17) {
const chars = "abcdefghijklmnopqrstuvwxyzABCEDFGHIJKLMNOPQRSTUVWXYZ0123456789";
const bytes = import_crypto.default.randomBytes(length);
let str = "";
for (let i = bytes.length - 1; i >= 0; i--) {
str += chars[(bytes[i] | 0) % chars.length];
}
return str;
}
__name(cryptoRandomObjectId, "cryptoRandomObjectId");
function deterministicUniqueId(key, length = 17) {
return import_crypto.default.createHash("sha256").update(key).digest("base64").replace(/(\+|\/|=)/g, "x").substr(0, length);
}
__name(deterministicUniqueId, "deterministicUniqueId");
function getRandomInt(maxExcluded) {
maxExcluded = Math.floor(maxExcluded);
return Math.floor(Math.random() * maxExcluded);
}
__name(getRandomInt, "getRandomInt");
function parseDateFromJson(date) {
if (typeof date === "string") {
return new Date(Date.parse(date));
}
return date;
}
__name(parseDateFromJson, "parseDateFromJson");
function delayPromise(millis) {
return new Promise((resolve) => {
if (millis > 0) {
setTimeout(() => resolve(), millis);
} else {
resolve();
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
});
}
__name(delayPromise, "delayPromise");
function removeFromArray(array, element) {
const index = array.indexOf(element);
if (index >= 0) {
array.splice(index, 1);
return true;
}
return false;
}
__name(removeFromArray, "removeFromArray");
function http404Route(req, res) {
res.status(404);
res.send("Page not found");
}
__name(http404Route, "http404Route");
function expressErrorHandler(err, req, res, next) {
import_log.default.warning("Client HTTP request failed", { url: req.url, errMsg: err.message });
if (res.headersSent) {
return next(err);
}
res.status(505);
res.send("Internal server error");
}
__name(expressErrorHandler, "expressErrorHandler");
function betterSetInterval(func, delay) {
let callback;
let timeoutId;
let isRunning = true;
const funcWrapper = /* @__PURE__ */ __name(function() {
func(callback);
}, "funcWrapper");
callback = /* @__PURE__ */ __name(function() {
if (isRunning)
timeoutId = setTimeout(funcWrapper, delay);
}, "callback");
funcWrapper();
return {
_betterClearInterval() {
isRunning = false;
clearTimeout(timeoutId);
}
};
}
__name(betterSetInterval, "betterSetInterval");
function betterClearInterval(intervalID) {
if (intervalID && intervalID._betterClearInterval) {
try {
intervalID._betterClearInterval();
} catch (e) {
import_log.default.exception(e, "_betterClearInterval() threw an exception!?");
}
}
}
__name(betterClearInterval, "betterClearInterval");
function escapeRegExp(str) {
return String(str).replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
__name(escapeRegExp, "escapeRegExp");
function leftpad(str, len, ch = " ") {
str = String(str);
let i = -1;
if (!ch && ch !== 0)
ch = " ";
len -= str.length;
while (++i < len) {
str = ch + str;
}
return str;
}
__name(leftpad, "leftpad");
function weightedAverage(val1, weight1, val2, weight2) {
return (val1 * weight1 + val2 * weight2) / (weight1 + weight2);
}
__name(weightedAverage, "weightedAverage");
var FORBIDDEN_USERNAMES_REGEXPS = [
"page-not-found",
"docs",
"terms-of-use",
"about",
"pricing",
"privacy-policy",
"customers",
"request-form",
"request-solution",
"release-notes",
"jobs",
"api-reference",
"video-tutorials",
"acts",
"key-value-stores",
"schedules",
"account",
"sign-up",
"sign-in-discourse",
"admin",
"documentation",
"change-password",
"enroll-account",
"forgot-password",
"reset-password",
"sign-in",
"verify-email",
"live-status",
"browser-info",
"webhooks",
"health-check",
"api",
"change-log",
"dashboard",
"community",
"crawlers",
"ext",
"admin",
"administration",
"crawler",
"act",
"library",
"lib",
"apifier",
"team",
"contact",
"doc",
"documentation",
"for-business",
"for-developers",
"developers",
"business",
"integrations",
"job",
"setting",
"settings",
"privacy",
"policy",
"assets",
"help",
"config",
"configuration",
"terms",
"hiring",
"hire",
"status",
"status-page",
"solutions",
"support",
"market",
"marketplace",
"download",
"downloads",
"username",
"users",
"user",
"login",
"logout",
"signin",
"sign",
"signup",
"sign-out",
"signout",
"plugins",
"plug-ins",
"reset",
"password",
"passwords",
"square",
"profile-photos",
"profiles",
"true",
"false",
"js",
"css",
"img",
"images",
"image",
"partials",
"fonts",
"font",
"dynamic_templates",
"app",
"schedules",
"community",
"storage",
"storages",
"account",
"node_modules",
"bower_components",
"video",
"knowledgebase",
"forum",
"customers",
"blog",
"health-check",
"health",
"anim",
"forum_topics.json",
"forum_categories.json",
"me",
"you",
"him",
"she",
"it",
"external",
"actor",
"crawler",
"scheduler",
"api",
"sdk",
"puppeteer",
"webdriver",
"selenium",
"(selenium.*webdriver)",
"undefined",
"page-analyzer",
"wp-login.php",
"welcome.action",
"echo",
"proxy",
"super-proxy",
"gdpr",
"case-studies",
"use-cases",
"how-to",
"kb",
"cookies",
"cookie-policy",
"cookies-policy",
"powered-by",
"run",
"runs",
"actor",
"actors",
"act",
"acts",
"success-stories",
"roadmap",
"join-marketplace",
"presskit",
"press-kit",
"covid-19",
"covid",
"covid19",
"matfyz",
"ideas",
"public-actors",
"resources",
"partners",
"affiliate",
"industries",
"web-scraping",
"custom-solutions",
"solution-provider",
"alternatives",
"platform",
"index",
"index\\.html",
"(favicon\\.[a-z]+)",
"BingSiteAuth.xml",
"(google.+\\.html)",
"robots\\.txt",
"(sitemap\\.[a-z]+)",
"(apple-touch-icon.*)",
"security-whitepaper\\.pdf",
"(\\..*)",
"(xxx-.*)",
"([^0-9a-z].*)",
"(.*[^0-9a-z])",
"(.*[_.\\-]{2}.*)",
"0",
"about",
"access",
"account",
"accounts",
"activate",
"activities",
"activity",
"ad",
"add",
"address",
"adm",
"admin",
"administration",
"administrator",
"ads",
"adult",
"advertising",
"affiliate",
"affiliates",
"ajax",
"all",
"alpha",
"analysis",
"analytics",
"android",
"anon",
"anonymous",
"api",
"app",
"apps",
"archive",
"archives",
"article",
"asct",
"asset",
"atom",
"auth",
"authentication",
"avatar",
"backup",
"balancer-manager",
"banner",
"banners",
"beta",
"billing",
"bin",
"blog",
"blogs",
"board",
"book",
"bookmark",
"bot",
"bots",
"bug",
"business",
"cache",
"cadastro",
"calendar",
"call",
"campaign",
"cancel",
"captcha",
"career",
"careers",
"cart",
"categories",
"category",
"cgi",
"cgi-bin",
"changelog",
"chat",
"check",
"checking",
"checkout",
"client",
"cliente",
"clients",
"code",
"codereview",
"comercial",
"comment",
"comments",
"communities",
"community",
"company",
"compare",
"compras",
"config",
"configuration",
"connect",
"contact",
"contact-us",
"contact_us",
"contactus",
"contest",
"contribute",
"corp",
"create",
"css",
"dashboard",
"data",
"db",
"default",
"delete",
"demo",
"design",
"designer",
"destroy",
"dev",
"devel",
"developer",
"developers",
"diagram",
"diary",
"dict",
"dictionary",
"die",
"dir",
"direct_messages",
"directory",
"dist",
"doc",
"docs",
"documentation",
"domain",
"download",
"downloads",
"ecommerce",
"edit",
"editor",
"edu",
"education",
"email",
"employment",
"empty",
"end",
"enterprise",
"entries",
"entry",
"error",
"errors",
"eval",
"event",
"exit",
"explore",
"facebook",
"faq",
"favorite",
"favorites",
"feature",
"features",
"feed",
"feedback",
"feeds",
"file",
"files",
"first",
"flash",
"fleet",
"fleets",
"flog",
"follow",
"followers",
"following",
"forgot",
"form",
"forum",
"forums",
"founder",
"free",
"friend",
"friends",
"ftp",
"gadget",
"gadgets",
"game",
"games",
"get",
"gift",
"gifts",
"gist",
"github",
"graph",
"group",
"groups",
"guest",
"guests",
"help",
"home",
"homepage",
"host",
"hosting",
"hostmaster",
"hostname",
"howto",
"hpg",
"html",
"http",
"httpd",
"https",
"i",
"iamges",
"icon",
"icons",
"id",
"idea",
"ideas",
"image",
"images",
"imap",
"img",
"index",
"indice",
"info",
"information",
"inquiry",
"instagram",
"intranet",
"invitations",
"invite",
"ipad",
"iphone",
"irc",
"is",
"issue",
"issues",
"it",
"item",
"items",
"java",
"javascript",
"job",
"jobs",
"join",
"js",
"json",
"jump",
"knowledgebase",
"language",
"languages",
"last",
"ldap-status",
"legal",
"license",
"link",
"links",
"linux",
"list",
"lists",
"log",
"log-in",
"log-out",
"log_in",
"log_out",
"login",
"logout",
"logs",
"m",
"mac",
"mail",
"mail1",
"mail2",
"mail3",
"mail4",
"mail5",
"mailer",
"mailing",
"maintenance",
"manager",
"manual",
"map",
"maps",
"marketing",
"master",
"me",
"media",
"member",
"members",
"message",
"messages",
"messenger",
"microblog",
"microblogs",
"mine",
"mis",
"mob",
"mobile",
"movie",
"movies",
"mp3",
"msg",
"msn",
"music",
"musicas",
"mx",
"my",
"mysql",
"name",
"named",
"nan",
"navi",
"navigation",
"net",
"network",
"new",
"news",
"newsletter",
"nick",
"nickname",
"notes",
"noticias",
"notification",
"notifications",
"notify",
"ns",
"ns1",
"ns10",
"ns2",
"ns3",
"ns4",
"ns5",
"ns6",
"ns7",
"ns8",
"ns9",
"null",
"oauth",
"oauth_clients",
"offer",
"offers",
"official",
"old",
"online",
"openid",
"operator",
"order",
"orders",
"organization",
"organizations",
"overview",
"owner",
"owners",
"page",
"pager",
"pages",
"panel",
"password",
"payment",
"perl",
"phone",
"photo",
"photoalbum",
"photos",
"php",
"phpmyadmin",
"phppgadmin",
"phpredisadmin",
"pic",
"pics",
"ping",
"plan",
"plans",
"plugin",
"plugins",
"policy",
"pop",
"pop3",
"popular",
"portal",
"post",
"postfix",
"postmaster",
"posts",
"pr",
"premium",
"press",
"price",
"pricing",
"privacy",
"privacy-policy",
"privacy_policy",
"privacypolicy",
"private",
"product",
"products",
"profile",
"project",
"projects",
"promo",
"pub",
"public",
"purpose",
"put",
"python",
"query",
"random",
"ranking",
"read",
"readme",
"recent",
"recruit",
"recruitment",
"register",
"registration",
"release",
"remove",
"replies",
"report",
"reports",
"repositories",
"repository",
"req",
"request",
"requests",
"reset",
"roc",
"root",
"rss",
"ruby",
"rule",
"sag",
"sale",
"sales",
"sample",
"samples",
"save",
"school",
"script",
"scripts",
"search",
"secure",
"security",
"self",
"send",
"server",
"server-info",
"server-status",
"service",
"services",
"session",
"sessions",
"setting",
"settings",
"setup",
"share",
"shop",
"show",
"sign-in",
"sign-up",
"sign_in",
"sign_up",
"signin",
"signout",
"signup",
"site",
"sitemap",
"sites",
"smartphone",
"smtp",
"soporte",
"source",
"spec",
"special",
"sql",
"src",
"ssh",
"ssl",
"ssladmin",
"ssladministrator",
"sslwebmaster",
"staff",
"stage",
"staging",
"start",
"stat",
"state",
"static",
"stats",
"status",
"store",
"stores",
"stories",
"style",
"styleguide",
"stylesheet",
"stylesheets",
"subdomain",
"subscribe",
"subscriptions",
"suporte",
"support",
"svn",
"swf",
"sys",
"sysadmin",
"sysadministrator",
"system",
"tablet",
"tablets",
"tag",
"talk",
"task",
"tasks",
"team",
"teams",
"tech",
"telnet",
"term",
"terms",
"terms-of-service",
"terms_of_service",
"termsofservice",
"test",
"test1",
"test2",
"test3",
"teste",
"testing",
"tests",
"theme",
"themes",
"thread",
"threads",
"tmp",
"todo",
"tool",
"tools",
"top",
"topic",
"topics",
"tos",
"tour",
"translations",
"trends",
"tutorial",
"tux",
"tv",
"twitter",
"undef",
"unfollow",
"unsubscribe",
"update",
"upload",
"uploads",
"url",
"usage",
"user",
"username",
"users",
"usuario",
"vendas",
"ver",
"version",
"video",
"videos",
"visitor",
"watch",
"weather",
"web",
"webhook",
"webhooks",
"webmail",
"webmaster",
"website",
"websites",
"welcome",
"widget",
"widgets",
"wiki",
"win",
"windows",
"word",
"work",
"works",
"workshop",
"ww",
"wws",
"www",
"www1",
"www2",
"www3",
"www4",
"www5",
"www6",
"www7",
"wwws",
"wwww",
"xfn",
"xml",
"xmpp",
"xpg",
"xxx",
"yaml",
"year",
"yml",
"you",
"yourdomain",
"yourname",
"yoursite",
"yourusername"
];
var FORBIDDEN_REGEXP = new RegExp(`^(${import_consts.ANONYMOUS_USERNAME}|${FORBIDDEN_USERNAMES_REGEXPS.join("|")})$`, "i");
function isForbiddenUsername(username) {
return !!username.match(FORBIDDEN_REGEXP);
}
__name(isForbiddenUsername, "isForbiddenUsername");
async function sequentializePromises(promises) {
if (!promises.length)
return [];
const results = [];
for (const promiseOrFunc of promises) {
const promise = promiseOrFunc instanceof Function ? promiseOrFunc() : promiseOrFunc;
results.push(await promise);
}
return results;
}
__name(sequentializePromises, "sequentializePromises");
function checkParamPrototypeOrThrow(paramVal, paramName, prototypes, prototypeName, isOptional = false) {
if (isOptional && (paramVal === void 0 || paramVal === null))
return;
const hasCorrectPrototype = prototypes instanceof Array ? prototypes.some((prototype) => paramVal instanceof prototype) : paramVal instanceof prototypes;
if (!hasCorrectPrototype)
throw new Error(`Parameter "${paramName}" must be an instance of ${prototypeName}`);
}
__name(checkParamPrototypeOrThrow, "checkParamPrototypeOrThrow");
function promisifyServerListen(server) {
return (port) => {
return new Promise((resolve, reject) => {
const onError = /* @__PURE__ */ __name((err) => {
removeListeners();
reject(err);
}, "onError");
const onListening = /* @__PURE__ */ __name(() => {
removeListeners();
resolve();
}, "onListening");
const removeListeners = /* @__PURE__ */ __name(() => {
server.removeListener("error", onError);
server.removeListener("listening", onListening);
}, "removeListeners");
server.on("error", onError);
server.on("listening", onListening);
server.listen(port);
});
};
}
__name(promisifyServerListen, "promisifyServerListen");
function configureLogger(givenLog, isProduction) {
if (isProduction) {
givenLog.setOptions({
level: import_log.LogLevel.INFO,
logger: new import_log.LoggerJson()
});
} else {
givenLog.setOptions({ level: import_log.LogLevel.DEBUG });
}
}
__name(configureLogger, "configureLogger");
function timeoutPromise(promise, timeoutMillis, errorMessage = "Promise has timed-out") {
return new Promise((resolve, reject) => {
let timeout;
let hasFulfilled = false;
const callback = /* @__PURE__ */ __name((err, result) => {
if (hasFulfilled)
return;
clearTimeout(timeout);
hasFulfilled = true;
if (err)
return reject(err);
resolve(result);
}, "callback");
promise.then((result) => callback(null, result), callback);
timeout = setTimeout(() => callback(new Error(errorMessage)), timeoutMillis);
});
}
__name(timeoutPromise, "timeoutPromise");
// src/utilities.client.ts
var import_consts2 = require("@apify/consts");
function isNullOrUndefined(obj) {
return obj == null;
}
__name(isNullOrUndefined, "isNullOrUndefined");
function isBuffer(obj) {
return obj != null && obj.constructor != null && typeof obj.constructor.isBuffer === "function" && obj.constructor.isBuffer(obj);
}
__name(isBuffer, "isBuffer");
function dateToString(date, middleT) {
if (!(date instanceof Date)) {
return "";
}
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const hours = date.getHours();
const minutes = date.getMinutes();
const seconds = date.getSeconds();
const millis = date.getMilliseconds();
const pad = /* @__PURE__ */ __name((num) => num < 10 ? `0${num}` : num, "pad");
const datePart = `${year}-${pad(month)}-${pad(day)}`;
const millisPart = millis < 10 ? `00${millis}` : millis < 100 ? `0${millis}` : millis;
const timePart = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}.${millisPart}`;
return `${datePart}${middleT ? "T" : " "}${timePart}`;
}
__name(dateToString, "dateToString");
function truncate(str, maxLength, suffix = "...[truncated]") {
maxLength = Math.floor(maxLength);
if (suffix.length > maxLength) {
throw new Error("suffix string cannot be longer than maxLength");
}
if (typeof str === "string" && str.length > maxLength) {
str = str.substr(0, maxLength - suffix.length) + suffix;
}
return str;
}
__name(truncate, "truncate");
function getOrdinalSuffix(num) {
const s = ["th", "st", "nd", "rd"];
const v = num % 100;
return s[(v - 20) % 10] || s[v] || s[0];
}
__name(getOrdinalSuffix, "getOrdinalSuffix");
function parseUrl(str) {
if (typeof str !== "string")
return {};
const o = {
strictMode: false,
key: [
"source",
"protocol",
"authority",
"userInfo",
"user",
"password",
"host",
"port",
"relative",
"path",
"directory",
"file",
"query",
"fragment"
],
q: {
name: "queryKey",
parser: /(?:^|&)([^&=]*)=?([^&]*)/g
},
parser: {
strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
loose: /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
}
};
const m = o.parser[o.strictMode ? "strict" : "loose"].exec(str);
const uri = {};
let i = o.key.length;
while (i--)
uri[o.key[i]] = m[i] || "";
uri[o.q.name] = {};
uri[o.key[12]].replace(o.q.parser, ($0, $1, $2) => {
if ($1)
uri[o.q.name][$1] = $2;
});
uri.fragmentKey = {};
if (uri.fragment) {
uri.fragment.replace(o.q.parser, ($0, $1, $2) => {
if ($1)
uri.fragmentKey[$1] = $2;
});
}
return uri;
}
__name(parseUrl, "parseUrl");
function normalizeUrl(url, keepFragment) {
if (typeof url !== "string" || !url.length) {
return null;
}
const urlObj = parseUrl(url.trim());
if (!urlObj.protocol || !urlObj.host) {
return null;
}
const path = urlObj.path.replace(/\/$/, "");
const params = urlObj.query ? urlObj.query.split("&").filter((param) => {
return !/^utm_/.test(param);
}).sort() : [];
return `${urlObj.protocol.trim().toLowerCase()}://${urlObj.host.trim().toLowerCase()}${path.trim()}${params.length ? `?${params.join("&").trim()}` : ""}${keepFragment && urlObj.fragment ? `#${urlObj.fragment.trim()}` : ""}`;
}
__name(normalizeUrl, "normalizeUrl");
function markedSetNofollowLinks(href, title, text) {
let urlParsed;
try {
urlParsed = new URL(href);
} catch (e) {
}
const isApifyLink = urlParsed && /(\.|^)apify\.com$/i.test(urlParsed.hostname);
return isApifyLink ? `<a href="${href}">${title || text}</a>` : `<a rel="noopener noreferrer nofollow" target="_blank" href="${href}">${title || text}</a>`;
}
__name(markedSetNofollowLinks, "markedSetNofollowLinks");
function markedDecreaseHeadsLevel(text, level) {
level += 1;
return `<h${level}>${text}</h${level}>`;
}
__name(markedDecreaseHeadsLevel, "markedDecreaseHeadsLevel");
function buildOrVersionNumberIntToStr(int) {
if (typeof int !== "number" || !(int >= 0))
return null;
const major = Math.floor(int / import_consts2.VERSION_INT_MAJOR_BASE);
const remainder = int % import_consts2.VERSION_INT_MAJOR_BASE;
const minor = Math.floor(remainder / import_consts2.VERSION_INT_MINOR_BASE);
const build = remainder % import_consts2.VERSION_INT_MINOR_BASE;
let str = `${major}.${minor}`;
if (build > 0)
str += `.${build}`;
return str;
}
__name(buildOrVersionNumberIntToStr, "buildOrVersionNumberIntToStr");
var ESCAPE_DOT = "\uFF0E";
var ESCAPE_DOLLAR = "\uFF04";
var ESCAPE_TO_BSON = "\uFF54\uFF4F\uFF22\uFF33\uFF2F\uFF2E";
var ESCAPE_TO_STRING = "\uFF54\uFF4F\uFF33\uFF54\uFF52\uFF49\uFF4E\uFF47";
var ESCAPE_BSON_TYPE = "\uFF3F\uFF42\uFF53\uFF4F\uFF4E\uFF54\uFF59\uFF50\uFF45";
var ESCAPE_NULL = "";
var REGEXP_IS_ESCAPED = new RegExp(`(${ESCAPE_DOT}|^${ESCAPE_DOLLAR}|^${ESCAPE_TO_BSON}$|^${ESCAPE_BSON_TYPE}|^${ESCAPE_TO_STRING}$)`);
var REGEXP_DOT = new RegExp(ESCAPE_DOT, "g");
var REGEXP_DOLLAR = new RegExp(`^${ESCAPE_DOLLAR}`);
var REGEXP_TO_BSON = new RegExp(`^${ESCAPE_TO_BSON}$`);
var REGEXP_TO_STRING = new RegExp(`^${ESCAPE_TO_STRING}$`);
var REGEXP_BSON_TYPE = new RegExp(`^${ESCAPE_BSON_TYPE}$`);
function escapePropertyName(name) {
if (/(\.|^\$|^toBSON$|^_bsontype$|^toString$|\0)/.test(name)) {
name = name.replace(/\./g, ESCAPE_DOT);
name = name.replace(/^\$/, ESCAPE_DOLLAR);
name = name.replace(/^toBSON$/, ESCAPE_TO_BSON);
name = name.replace(/^toString$/, ESCAPE_TO_STRING);
name = name.replace(/^_bsontype$/, ESCAPE_BSON_TYPE);
name = name.replace(/\0/g, ESCAPE_NULL);
}
return name;
}
__name(escapePropertyName, "escapePropertyName");
function unescapePropertyName(name) {
if (REGEXP_IS_ESCAPED.test(name)) {
name = name.replace(REGEXP_DOT, ".");
name = name.replace(REGEXP_DOLLAR, "$");
name = name.replace(REGEXP_TO_BSON, "toBSON");
name = name.replace(REGEXP_TO_STRING, "toString");
name = name.replace(REGEXP_BSON_TYPE, "_bsontype");
}
return name;
}
__name(unescapePropertyName, "unescapePropertyName");
function traverseObject(obj, clone, transformFunc) {
if (obj === null || typeof obj !== "object" || Object.prototype.toString.call(obj) === "[object Date]" || isBuffer(obj))
return obj;
let result;
if (Array.isArray(obj)) {
result = clone ? new Array(obj.length) : obj;
for (let i = 0; i < obj.length; i++) {
const val = traverseObject(obj[i], clone, transformFunc);
if (clone)
result[i] = val;
}
return result;
}
result = clone ? {} : obj;
for (const key in obj) {
const val = traverseObject(obj[key], clone, transformFunc);
const [transformedKey, transformedVal] = transformFunc(key, val);
if (key === transformedKey) {
if (clone || val !== transformedVal)
result[key] = transformedVal;
} else {
result[transformedKey] = transformedVal;
if (!clone)
delete obj[key];
}
}
return result;
}
__name(traverseObject, "traverseObject");
function escapeForBson(obj, clone = false) {
return traverseObject(obj, clone, (key, value) => [escapePropertyName(key), value]);
}
__name(escapeForBson, "escapeForBson");
function unescapeFromBson(obj, clone = false) {
return traverseObject(obj, clone, (key, value) => [unescapePropertyName(key), value]);
}
__name(unescapeFromBson, "unescapeFromBson");
function isBadForMongo(obj) {
let isBad = false;
try {
traverseObject(obj, false, (key, value) => {
const escapedKey = escapePropertyName(key);
if (key !== escapedKey) {
isBad = true;
throw new Error();
}
return [key, value];
});
} catch (e) {
if (!isBad)
throw e;
}
return isBad;
}
__name(isBadForMongo, "isBadForMongo");
var JsonVariable = class {
constructor(name) {
this.name = name;
}
getToken() {
return `{{${this.name}}}`;
}
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require("./utilities"), exports);
__exportStar(require("./utilities.client"), exports);
__exportStar(require("./exponential_backoff"), exports);
__exportStar(require("./health_checker"), exports);
__exportStar(require("./parse_jsonl_stream"), exports);
__exportStar(require("./streams_utilities"), exports);
__exportStar(require("./webhook_payload_template"), exports);
__name(JsonVariable, "JsonVariable");
function jsonStringifyExtended(value, replacer, space = 0) {
if (replacer && !(replacer instanceof Function))
throw new Error('Parameter "replacer" of jsonStringifyExtended() must be a function!');
const replacements = {};
const extendedReplacer = /* @__PURE__ */ __name((key, val) => {
val = replacer ? replacer(key, val) : val;
if (val instanceof Function)
return val.toString();
if (val instanceof JsonVariable) {
const randomToken = `<<<REPLACEMENT_TOKEN::${Math.random()}>>>`;
replacements[randomToken] = val.getToken();
return randomToken;
}
return val;
}, "extendedReplacer");
let stringifiedValue = JSON.stringify(value, extendedReplacer, space);
Object.entries(replacements).forEach(([replacementToken, replacementValue]) => {
stringifiedValue = stringifiedValue.replace(`"${replacementToken}"`, replacementValue);
});
return stringifiedValue;
}
__name(jsonStringifyExtended, "jsonStringifyExtended");
function splitFullName(fullName) {
if (typeof fullName !== "string")
return [null, null];
const names = (fullName || "").trim().split(" ");
const nonEmptyNames = names.filter((val) => val);
if (nonEmptyNames.length === 0) {
return [null, null];
}
if (nonEmptyNames.length === 1) {
return [null, nonEmptyNames[0]];
}
return [names[0], nonEmptyNames.slice(1).join(" ")];
}
__name(splitFullName, "splitFullName");
function isUrlRelative(url) {
return import_consts2.RELATIVE_URL_REGEX.test(url);
}
__name(isUrlRelative, "isUrlRelative");
// src/exponential_backoff.ts
var import_log2 = __toESM(require("@apify/log"));
var RetryableError = class extends Error {
constructor(error, ...args) {
super(...args);
this.error = error;
}
};
__name(RetryableError, "RetryableError");
async function retryWithExpBackoff(params = {}) {
const { func, expBackoffMillis, expBackoffMaxRepeats } = params;
if (typeof func !== "function") {
throw new Error('Parameter "func" should be a function.');
}
if (typeof expBackoffMillis !== "number") {
throw new Error('Parameter "expBackoffMillis" should be a number.');
}
if (typeof expBackoffMaxRepeats !== "number") {
throw new Error('Parameter "expBackoffMaxRepeats" should be a number.');
}
for (let i = 0; ; i++) {
let error;
try {
return await func();
} catch (e) {
error = e;
}
if (!(error instanceof RetryableError)) {
throw error;
}
if (i >= expBackoffMaxRepeats - 1) {
throw error.error;
}
const waitMillis = expBackoffMillis * 2 ** i;
const rand = /* @__PURE__ */ __name((from, to) => from + Math.floor(Math.random() * (to - from + 1)), "rand");
const randomizedWaitMillis = rand(waitMillis, waitMillis * 2);
if (i === Math.round(expBackoffMaxRepeats / 2)) {
import_log2.default.warning(`Retry failed ${i} times and will be repeated in ${randomizedWaitMillis}ms`, {
originalError: error.error.message,
errorDetails: error.error.details
});
}
await delayPromise(randomizedWaitMillis);
}
}
__name(retryWithExpBackoff, "retryWithExpBackoff");
// src/health_checker.ts
var CHECK_TYPES = /* @__PURE__ */ ((CHECK_TYPES2) => {
CHECK_TYPES2["MONGODB_READ"] = "MONGODB_READ";
CHECK_TYPES2["MONGODB_WRITE"] = "MONGODB_WRITE";
CHECK_TYPES2["REDIS"] = "REDIS";
return CHECK_TYPES2;
})(CHECK_TYPES || {});
var HealthChecker = class {
constructor(options) {
this.options = options;
const {
checks,
redisPrefix = "health-check",
redisTtlSecs = 15,
checkTimeoutMillis = 15e3,
mongoDbWriteTestCollection = "healthCheckPlayground",
mongoDbWriteTestRemoveOlderThanSecs = 15
} = options;
if (!Array.isArray(checks))
throw new Error('Parameter "check" must be an array');
checks.map((check) => this._validateCheck(check));
this.checks = checks;
this.redisPrefix = redisPrefix;
this.redisTtlSecs = redisTtlSecs;
this.checkTimeoutMillis = checkTimeoutMillis;
this.mongoDbWriteTestCollection = mongoDbWriteTestCollection;
this.mongoDbWriteTestRemoveOlderThanSecs = mongoDbWriteTestRemoveOlderThanSecs;
}
async ensureIsHealthy() {
for (const check of this.checks) {
try {
const checkPromise = this._performCheck(check);
await timeoutPromise(checkPromise, this.checkTimeoutMillis, "Check has timed-out");
} catch (_err) {
const err = _err;
throw new Error(`Health check test "${check.type}" failed with an error: ${err.message}"`);
}
}
}
_validateCheck(check) {
if (!(check.type in CHECK_TYPES))
throw new Error(`Check type "${check.type}" is invalid`);
if (typeof check.client !== "object")
throw new Error(`Check client must be an object got "${typeof check.client}" instead`);
}
_performCheck(check) {
switch (check.type) {
case "MONGODB_READ" /* MONGODB_READ */:
return this._testMongoDbRead(check);
case "MONGODB_WRITE" /* MONGODB_WRITE */:
return this._testMongoDbWrite(check);
case "REDIS" /* REDIS */:
return this._testRedisWrite(check);
default:
throw new Error("Unknown check type");
}
}
async _testMongoDbRead({ client }) {
const response = await client.listCollections().toArray();
if (!Array.isArray(response))
throw new Error(`Got ${typeof response} instead of an array!`);
}
async _testMongoDbWrite({ client }) {
const id = cryptoRandomObjectId();
const collection = client.collection(this.mongoDbWriteTestCollection);
await collection.deleteMany({
createdAt: {
$lt: new Date(Date.now() - this.mongoDbWriteTestRemoveOlderThanSecs * 1e3)
}
});
await collection.insertOne({
_id: id,
createdAt: new Date()
});
const retrieved = await collection.findOne({ _id: id });
if (!retrieved)
throw new Error(`Item with ID "${id}" not found!`);
}
async _testRedisWrite({ client }) {
const key = `${this.redisPrefix}:${cryptoRandomObjectId()}`;
const expected = "OK";
await client.set(key, expected, "EX", this.redisTtlSecs);
const given = await client.get(key);
if (given !== expected)
throw new Error(`Returned value "${given}" is not equal to "${expected}"!`);
}
};
__name(HealthChecker, "HealthChecker");
HealthChecker.CHECK_TYPES = CHECK_TYPES;
// src/parse_jsonl_stream.ts
var import_stream = require("stream");
var ParseJsonlStream = class extends import_stream.Transform {
constructor() {
super(...arguments);
this.pendingChunk = null;
}
parseLineAndEmitObject(line) {
line = line.trim();
if (!line) {
return;
}
try {
const obj = JSON.parse(line);
this.emit("object", obj);
} catch (e) {
throw new Error(`Cannot parse JSON stream data ('${String(line)}'): ${String(e)}`);
}
}
_transform(chunk, encoding, callback) {
let allData;
if (this.pendingChunk) {
allData = this.pendingChunk + chunk;
this.pendingChunk = null;
} else {
allData = chunk;
}
const lines = allData.toString().split("\n");
if (lines[lines.length - 1] !== "") {
this.pendingChunk = lines.pop();
}
try {
for (let i = 0; i < lines.length; i++) {
this.parseLineAndEmitObject(lines[i]);
}
} catch (err) {
callback(err, null);
return;
}
callback(null, chunk);
}
_flush(callback) {
if (this.pendingChunk) {
try {
this.parseLineAndEmitObject(this.pendingChunk);
this.pendingChunk = null;
} catch (err) {
callback(err, null);
return;
}
}
callback();
}
};
__name(ParseJsonlStream, "ParseJsonlStream");
// src/streams_utilities.ts
async function concatStreamToBuffer(stream) {
return new Promise((resolve, reject) => {
const chunks = [];
stream.on("data", (chunk) => {
chunks.push(chunk);
}).on("error", (e) => reject(e)).on("end", () => {
const buffer = Buffer.concat(chunks);
return resolve(buffer);
});
});
}
__name(concatStreamToBuffer, "concatStreamToBuffer");
async function readStreamToString(stream, encoding) {
const buffer = await concatStreamToBuffer(stream);
return buffer.toString(encoding);
}
__name(readStreamToString, "readStreamToString");
// src/webhook_payload_template.ts
var WebhookPayloadTemplateError = class extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
if (typeof Error.captureStackTrace === "function") {
Error.captureStackTrace(this, this.constructor);
}
}
};
__name(WebhookPayloadTemplateError, "WebhookPayloadTemplateError");
var InvalidJsonError = class extends WebhookPayloadTemplateError {
constructor(originalError) {
super(originalError.message);
}
};
__name(InvalidJsonError, "InvalidJsonError");
var InvalidVariableError = class extends Error {
constructor(variable) {
super(`Invalid payload template variable: ${variable}`);
}
};
__name(InvalidVariableError, "InvalidVariableError");
var WebhookPayloadTemplate = class {
constructor(template, allowedVariables = null, context = {}) {
this.template = template;
this.allowedVariables = allowedVariables;
this.context = context;
this.payload = this.template;
this.replacedVariables = [];
}
static parse(payloadTemplate, allowedVariables = null, context = {}) {
const type = typeof payloadTemplate;
if (type !== "string")
throw new Error(`Cannot parse a ${type} payload template.`);
const template = new WebhookPayloadTemplate(payloadTemplate, allowedVariables, context);
return template._parse();
}
static stringify(objectTemplate, replacer, indent = 2) {
const type = typeof objectTemplate;
if (!objectTemplate || type !== "object")
throw new Error(`Cannot stringify a ${type} payload template.`);
return jsonStringifyExtended(objectTemplate, replacer, indent);
}
static getVariable(variableName) {
return new JsonVariable(variableName);
}
_parse() {
while (true) {
try {
return JSON.parse(this.payload);
} catch (err) {
const position = this._findPositionOfNextVariable();
if (position) {
this._replaceVariable(position);
} else {
throw new InvalidJsonError(err);
}
}
}
}
_findPositionOfNextVariable(startIndex = 0) {
const openBraceIndex = this.payload.indexOf("{{", startIndex);
const closeBraceIndex = this.payload.indexOf("}}", openBraceIndex) + 1;
const someVariableMaybeExists = openBraceIndex > -1 && closeBraceIndex > -1;
if (!someVariableMaybeExists)
return null;
const isInsideString = this._isVariableInsideString(openBraceIndex);
if (!isInsideString)
return { openBraceIndex, closeBraceIndex };
return this._findPositionOfNextVariable(openBraceIndex + 1);
}
_isVariableInsideString(openBraceIndex) {
const unescapedQuoteCount = this._countUnescapedDoubleQuotesUpToIndex(openBraceIndex);
return unescapedQuoteCount % 2 === 1;
}
_countUnescapedDoubleQuotesUpToIndex(index) {
const payloadSection = this.payload.substring(0, index);
let unescapedQuoteCount = 0;
for (let i = 0; i < payloadSection.length; i++) {
const char = payloadSection[i];
const prevChar = payloadSection[i - 1];
if (char === '"' && prevChar !== "\\") {
unescapedQuoteCount++;
}
}
return unescapedQuoteCount;
}
_replaceVariable({ openBraceIndex, closeBraceIndex }) {
const variableName = this.payload.substring(openBraceIndex + 2, closeBraceIndex - 1);
this._validateVariableName(variableName);
const replacement = this._getVariableReplacement(variableName);
this.replacedVariables.push({ variableName, replacement });
this.payload = this.payload.replace(`{{${variableName}}}`, replacement);
}
_validateVariableName(variableName) {
if (this.allowedVariables === null)
return;
const [variable] = variableName.split(".");
const isVariableValid = this.allowedVariables.has(variable);
if (!isVariableValid)
throw new InvalidVariableError(variableName);
}
_getVariableReplacement(variableName) {
const [variable, ...properties] = variableName.split(".");
const context = this.context[variable];
const replacement = properties.reduce((ctx, prop) => {
if (!ctx || typeof ctx !== "object")
return null;
return ctx[prop];
}, context);
return replacement ? JSON.stringify(replacement) : null;
}
};
__name(WebhookPayloadTemplate, "WebhookPayloadTemplate");
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CHECK_TYPES,
HealthChecker,
InvalidJsonError,
InvalidVariableError,
JsonVariable,
ParseJsonlStream,
RetryableError,
WebhookPayloadTemplate,
betterClearInterval,
betterSetInterval,
buildOrVersionNumberIntToStr,
checkParamPrototypeOrThrow,
concatStreamToBuffer,
configureLogger,
cryptoRandomObjectId,
dateToString,
delayPromise,
deterministicUniqueId,
escapeForBson,
escapePropertyName,
escapeRegExp,
expressErrorHandler,
getOrdinalSuffix,
getRandomInt,
http404Route,
isBadForMongo,
isBuffer,
isForbiddenUsername,
isNullOrUndefined,
isUrlRelative,
jsonStringifyExtended,
leftpad,
markedDecreaseHeadsLevel,
markedSetNofollowLinks,
normalizeUrl,
parseDateFromJson,
parseUrl,
promisifyServerListen,
readStreamToString,
removeFromArray,
retryWithExpBackoff,
sequentializePromises,
splitFullName,
timeoutPromise,
traverseObject,
truncate,
unescapeFromBson,
unescapePropertyName,
weightedAverage
});
/*!
* This module contains various client-side utility and helper functions.
*
* Author: Jan Curn (jan@apify.com)
* Copyright(c) 2016 Apify. All rights reserved.
*
*/
/*!
* This module contains various server utility and helper functions.
* Note that it automatically exports functions from utilities.client.js
*
* Author: Jan Curn (jan@apify.com)
* Copyright(c) 2015 Apify. All rights reserved.
*
*/
//# sourceMappingURL=index.js.map

22

package.json
{
"name": "@apify/utilities",
"version": "1.2.14",
"version": "2.0.0",
"description": "Tools and constants shared across Apify projects.",
"main": "index.js",
"typings": "index.d.ts",
"main": "./index.js",
"module": "./index.mjs",
"typings": "./index.d.ts",
"exports": {
".": {
"import": "./index.mjs",
"require": "./index.js",
"types": "./index.d.ts"
}
},
"keywords": [

@@ -31,3 +39,3 @@ "apify"

"clean": "rimraf ./dist",
"compile": "tsc -p tsconfig.build.json",
"compile": "tsup && tsc -p tsconfig.build.json",
"copy": "ts-node -T ../../scripts/copy.ts"

@@ -39,4 +47,4 @@ },

"dependencies": {
"@apify/consts": "^1.11.0",
"@apify/log": "^1.2.5"
"@apify/consts": "^2.0.0",
"@apify/log": "^2.0.0"
},

@@ -46,3 +54,3 @@ "devDependencies": {

},
"gitHead": "e12348baa263a86c0de15cc3faab521b59ca0284"
"gitHead": "9e31c174fe30c8c5b517b0d26874d123e233d807"
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc