@crawlee/utils 3.0.0-alpha.2 → 3.0.0-alpha.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from './internals/cheerio';
2
+ export * from './internals/extract-urls';
3
+ export * from './internals/general';
4
+ export * from './internals/memory-info';
5
+ export * as social from './internals/social';
6
+ export * from './internals/typedefs';
7
+ //# sourceMappingURL=index.d.ts.map
package/index.d.ts.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC;AACpC,cAAc,0BAA0B,CAAC;AACzC,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,cAAc,sBAAsB,CAAC"}
package/index.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;AAAA,8DAAoC;AACpC,mEAAyC;AACzC,8DAAoC;AACpC,kEAAwC;AACxC,qEAA6C;AAC7C,+DAAqC"}
package/index.mjs ADDED
@@ -0,0 +1,18 @@
1
+ import mod from "./index.js";
2
+
3
+ export default mod;
4
+ export const URL_NO_COMMAS_REGEX = mod.URL_NO_COMMAS_REGEX;
5
+ export const URL_WITH_COMMAS_REGEX = mod.URL_WITH_COMMAS_REGEX;
6
+ export const downloadListOfUrls = mod.downloadListOfUrls;
7
+ export const entries = mod.entries;
8
+ export const extractUrls = mod.extractUrls;
9
+ export const getMemoryInfo = mod.getMemoryInfo;
10
+ export const htmlToText = mod.htmlToText;
11
+ export const isDocker = mod.isDocker;
12
+ export const keys = mod.keys;
13
+ export const parseContentTypeFromResponse = mod.parseContentTypeFromResponse;
14
+ export const purgeLocalStorage = mod.purgeLocalStorage;
15
+ export const sleep = mod.sleep;
16
+ export const snakeCaseToCamelCase = mod.snakeCaseToCamelCase;
17
+ export const social = mod.social;
18
+ export const weightedAvg = mod.weightedAvg;
@@ -0,0 +1,32 @@
1
+ import { load } from 'cheerio';
2
+ export declare type CheerioRoot = ReturnType<typeof load>;
3
+ /**
4
+ * The function converts a HTML document to a plain text.
5
+ *
6
+ * The plain text generated by the function is similar to a text captured
7
+ * by pressing Ctrl+A and Ctrl+C on a page when loaded in a web browser.
8
+ * The function doesn't aspire to preserve the formatting or to be perfectly correct with respect to HTML specifications.
9
+ * However, it attempts to generate newlines and whitespaces in and around HTML elements
10
+ * to avoid merging distinct parts of text and thus enable extraction of data from the text (e.g. phone numbers).
11
+ *
12
+ * **Example usage**
13
+ * ```javascript
14
+ * const text = htmlToText('<html><body>Some text</body></html>');
15
+ * console.log(text);
16
+ * ```
17
+ *
18
+ * Note that the function uses [cheerio](https://www.npmjs.com/package/cheerio) to parse the HTML.
19
+ * Optionally, to avoid duplicate parsing of HTML and thus improve performance, you can pass
20
+ * an existing Cheerio object to the function instead of the HTML text. The HTML should be parsed
21
+ * with the `decodeEntities` option set to `true`. For example:
22
+ *
23
+ * ```javascript
24
+ * const cheerio = require('cheerio');
25
+ * const html = '<html><body>Some text</body></html>';
26
+ * const text = htmlToText(cheerio.load(html, { decodeEntities: true }));
27
+ * ```
28
+ * @param htmlOrCheerioElement HTML text or parsed HTML represented using a [cheerio](https://www.npmjs.com/package/cheerio) function.
29
+ * @return Plain text
30
+ */
31
+ export declare function htmlToText(htmlOrCheerioElement: string | CheerioRoot): string;
32
+ //# sourceMappingURL=cheerio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cheerio.d.ts","sourceRoot":"","sources":["../../src/internals/cheerio.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAExC,oBAAY,WAAW,GAAG,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC;AAMlD;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,UAAU,CAAC,oBAAoB,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAiD7E"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.htmlToText = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const cheerio_1 = tslib_1.__importDefault(require("cheerio"));
6
+ // NOTE: We are skipping 'noscript' since it's content is evaluated as text, instead of HTML elements. That damages the results.
7
+ const SKIP_TAGS_REGEX = /^(script|style|canvas|svg|noscript)$/i;
8
+ const BLOCK_TAGS_REGEX = /^(p|h1|h2|h3|h4|h5|h6|ol|ul|li|pre|address|blockquote|dl|div|fieldset|form|table|tr|select|option)$/i;
9
+ /**
10
+ * The function converts a HTML document to a plain text.
11
+ *
12
+ * The plain text generated by the function is similar to a text captured
13
+ * by pressing Ctrl+A and Ctrl+C on a page when loaded in a web browser.
14
+ * The function doesn't aspire to preserve the formatting or to be perfectly correct with respect to HTML specifications.
15
+ * However, it attempts to generate newlines and whitespaces in and around HTML elements
16
+ * to avoid merging distinct parts of text and thus enable extraction of data from the text (e.g. phone numbers).
17
+ *
18
+ * **Example usage**
19
+ * ```javascript
20
+ * const text = htmlToText('<html><body>Some text</body></html>');
21
+ * console.log(text);
22
+ * ```
23
+ *
24
+ * Note that the function uses [cheerio](https://www.npmjs.com/package/cheerio) to parse the HTML.
25
+ * Optionally, to avoid duplicate parsing of HTML and thus improve performance, you can pass
26
+ * an existing Cheerio object to the function instead of the HTML text. The HTML should be parsed
27
+ * with the `decodeEntities` option set to `true`. For example:
28
+ *
29
+ * ```javascript
30
+ * const cheerio = require('cheerio');
31
+ * const html = '<html><body>Some text</body></html>';
32
+ * const text = htmlToText(cheerio.load(html, { decodeEntities: true }));
33
+ * ```
34
+ * @param htmlOrCheerioElement HTML text or parsed HTML represented using a [cheerio](https://www.npmjs.com/package/cheerio) function.
35
+ * @return Plain text
36
+ */
37
+ function htmlToText(htmlOrCheerioElement) {
38
+ if (!htmlOrCheerioElement)
39
+ return '';
40
+ // TODO: Add support for "html" being a Cheerio element, otherwise the only way
41
+ // to use it is e.g. htmlToText($('p').html())) which is inefficient
42
+ // Also, it seems this doesn't work well in CheerioScraper, e.g. htmlToText($)
43
+ // produces really text with a lot of HTML elements in it. Let's just deprecate this sort of usage,
44
+ // and make the parameter "htmlOrCheerioElement"
45
+ const $ = typeof htmlOrCheerioElement === 'function' ? htmlOrCheerioElement : cheerio_1.default.load(htmlOrCheerioElement, { decodeEntities: true });
46
+ let text = '';
47
+ // TODO: the type for elems is very annoying to work with.
48
+ // The correct type is Node[] from cheerio but it needs a lot more casting in each branch, or alternatively,
49
+ // use the is* methods from domhandler (isText, isTag, isComment, etc.)
50
+ // @ts-expect-error
51
+ const process = (elems) => {
52
+ const len = elems ? elems.length : 0;
53
+ for (let i = 0; i < len; i++) {
54
+ const elem = elems[i];
55
+ if (elem.type === 'text') {
56
+ // Compress spaces, unless we're inside <pre> element
57
+ let compr;
58
+ if (elem.parent && elem.parent.tagName === 'pre')
59
+ compr = elem.data;
60
+ else
61
+ compr = elem.data.replace(/\s+/g, ' ');
62
+ // If text is empty or ends with a whitespace, don't add the leading whitepsace
63
+ if (compr.startsWith(' ') && /(^|\s)$/.test(text))
64
+ compr = compr.substr(1);
65
+ text += compr;
66
+ }
67
+ else if (elem.type === 'comment' || SKIP_TAGS_REGEX.test(elem.tagName)) {
68
+ // Skip comments and special elements
69
+ }
70
+ else if (elem.tagName === 'br') {
71
+ text += '\n';
72
+ }
73
+ else if (elem.tagName === 'td') {
74
+ process(elem.children);
75
+ text += '\t';
76
+ }
77
+ else {
78
+ // Block elements must be surrounded by newlines (unless beginning of text)
79
+ const isBlockTag = BLOCK_TAGS_REGEX.test(elem.tagName);
80
+ if (isBlockTag && !/(^|\n)$/.test(text))
81
+ text += '\n';
82
+ process(elem.children);
83
+ if (isBlockTag && !text.endsWith('\n'))
84
+ text += '\n';
85
+ }
86
+ }
87
+ };
88
+ // If HTML document has body, only convert that, otherwise convert the entire HTML
89
+ const $body = $('body');
90
+ process($body.length > 0 ? $body : $.root());
91
+ return text.trim();
92
+ }
93
+ exports.htmlToText = htmlToText;
94
+ //# sourceMappingURL=cheerio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cheerio.js","sourceRoot":"","sources":["../../src/internals/cheerio.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ /// <reference types="node" />
2
+ export interface DownloadListOfUrlsOptions {
3
+ /**
4
+ * URL to the file
5
+ */
6
+ url: string;
7
+ /**
8
+ * The encoding of the file.
9
+ * @default 'utf8'
10
+ */
11
+ encoding?: BufferEncoding;
12
+ /**
13
+ * Custom regular expression to identify the URLs in the file to extract.
14
+ * The regular expression should be case-insensitive and have global flag set (i.e. `/something/gi`).
15
+ * @default Actor.utils.URL_NO_COMMAS_REGEX
16
+ */
17
+ urlRegExp?: RegExp;
18
+ }
19
+ /**
20
+ * Returns a promise that resolves to an array of urls parsed from the resource available at the provided url.
21
+ * Optionally, custom regular expression and encoding may be provided.
22
+ */
23
+ export declare function downloadListOfUrls(options: DownloadListOfUrlsOptions): Promise<string[]>;
24
+ export interface ExtractUrlsOptions {
25
+ /**
26
+ * The string to extract URLs from.
27
+ */
28
+ string: string;
29
+ /**
30
+ * Custom regular expression
31
+ * @default URL_NO_COMMAS_REGEX
32
+ */
33
+ urlRegExp?: RegExp;
34
+ }
35
+ /**
36
+ * Collects all URLs in an arbitrary string to an array, optionally using a custom regular expression.
37
+ */
38
+ export declare function extractUrls(options: ExtractUrlsOptions): string[];
39
+ //# sourceMappingURL=extract-urls.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-urls.d.ts","sourceRoot":"","sources":["../../src/internals/extract-urls.ts"],"names":[],"mappings":";AAIA,MAAM,WAAW,yBAAyB;IACtC;;OAEG;IACH,GAAG,EAAE,MAAM,CAAC;IAEZ;;;OAGG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;IAE1B;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqB9F;AAED,MAAM,WAAW,kBAAkB;IAC/B;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,EAAE,CAOjE"}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractUrls = exports.downloadListOfUrls = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const ow_1 = tslib_1.__importDefault(require("ow"));
6
+ const got_scraping_1 = require("got-scraping");
7
+ const general_1 = require("./general");
8
+ /**
9
+ * Returns a promise that resolves to an array of urls parsed from the resource available at the provided url.
10
+ * Optionally, custom regular expression and encoding may be provided.
11
+ */
12
+ async function downloadListOfUrls(options) {
13
+ (0, ow_1.default)(options, ow_1.default.object.exactShape({
14
+ url: ow_1.default.string.url,
15
+ encoding: ow_1.default.optional.string,
16
+ urlRegExp: ow_1.default.optional.regExp,
17
+ proxyUrl: ow_1.default.optional.string,
18
+ }));
19
+ const { url, encoding = 'utf8', urlRegExp = general_1.URL_NO_COMMAS_REGEX, proxyUrl } = options;
20
+ // Try to detect wrong urls and fix them. Currently, detects only sharing url instead of csv download one.
21
+ const match = url.match(/^(https:\/\/docs\.google\.com\/spreadsheets\/d\/(?:\w|-)+)\/?/);
22
+ let fixedUrl = url;
23
+ if (match) {
24
+ fixedUrl = `${match[1]}/gviz/tq?tqx=out:csv`;
25
+ }
26
+ // @ts-expect-error https://github.com/apify/got-scraping/issues/66
27
+ const { body: string } = await (0, got_scraping_1.gotScraping)({ url: fixedUrl, encoding, proxyUrl });
28
+ return extractUrls({ string, urlRegExp });
29
+ }
30
+ exports.downloadListOfUrls = downloadListOfUrls;
31
+ /**
32
+ * Collects all URLs in an arbitrary string to an array, optionally using a custom regular expression.
33
+ */
34
+ function extractUrls(options) {
35
+ (0, ow_1.default)(options, ow_1.default.object.exactShape({
36
+ string: ow_1.default.string,
37
+ urlRegExp: ow_1.default.optional.regExp,
38
+ }));
39
+ const { string, urlRegExp = general_1.URL_NO_COMMAS_REGEX } = options;
40
+ return string.match(urlRegExp) || [];
41
+ }
42
+ exports.extractUrls = extractUrls;
43
+ //# sourceMappingURL=extract-urls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract-urls.js","sourceRoot":"","sources":["../../src/internals/extract-urls.ts"],"names":[],"mappings":";;;;AAAA,oDAAoB;AACpB,+CAA2C;AAC3C,uCAAgD;AAsBhD;;;GAGG;AACI,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACvE,IAAA,YAAE,EAAC,OAAO,EAAE,YAAE,CAAC,MAAM,CAAC,UAAU,CAAC;QAC7B,GAAG,EAAE,YAAE,CAAC,MAAM,CAAC,GAAG;QAClB,QAAQ,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;QAC5B,SAAS,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;QAC7B,QAAQ,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;KAC/B,CAAC,CAAC,CAAC;IACJ,MAAM,EAAE,GAAG,EAAE,QAAQ,GAAG,MAAM,EAAE,SAAS,GAAG,6BAAmB,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;IAEtF,0GAA0G;IAC1G,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;IACzF,IAAI,QAAQ,GAAG,GAAG,CAAC;IAEnB,IAAI,KAAK,EAAE;QACP,QAAQ,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,sBAAsB,CAAC;KAChD;IAED,mEAAmE;IACnE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,IAAA,0BAAW,EAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAElF,OAAO,WAAW,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;AAC9C,CAAC;AArBD,gDAqBC;AAeD;;GAEG;AACH,SAAgB,WAAW,CAAC,OAA2B;IACnD,IAAA,YAAE,EAAC,OAAO,EAAE,YAAE,CAAC,MAAM,CAAC,UAAU,CAAC;QAC7B,MAAM,EAAE,YAAE,CAAC,MAAM;QACjB,SAAS,EAAE,YAAE,CAAC,QAAQ,CAAC,MAAM;KAChC,CAAC,CAAC,CAAC;IACJ,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,6BAAmB,EAAE,GAAG,OAAO,CAAC;IAC5D,OAAO,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACzC,CAAC;AAPD,kCAOC"}
@@ -0,0 +1,62 @@
1
+ /// <reference types="node" />
2
+ import type { IncomingMessage } from 'node:http';
3
+ /**
4
+ * Default regular expression to match URLs in a string that may be plain text, JSON, CSV or other. It supports common URL characters
5
+ * and does not support URLs containing commas or spaces. The URLs also may contain Unicode letters (not symbols).
6
+ */
7
+ export declare const URL_NO_COMMAS_REGEX: RegExp;
8
+ /**
9
+ * Regular expression that, in addition to the default regular expression `URL_NO_COMMAS_REGEX`, supports matching commas in URL path and query.
10
+ * Note, however, that this may prevent parsing URLs from comma delimited lists, or the URLs may become malformed.
11
+ */
12
+ export declare const URL_WITH_COMMAS_REGEX: RegExp;
13
+ /**
14
+ * Returns a `Promise` that resolves to true if the code is running in a Docker container.
15
+ */
16
+ export declare function isDocker(forceReset?: boolean): Promise<boolean>;
17
+ /**
18
+ * Computes a weighted average of an array of numbers, complemented by an array of weights.
19
+ * @ignore
20
+ */
21
+ export declare function weightedAvg(arrValues: number[], arrWeights: number[]): number;
22
+ /**
23
+ * Returns a `Promise` that resolves after a specific period of time. This is useful to implement waiting
24
+ * in your code, e.g. to prevent overloading of target website or to avoid bot detection.
25
+ *
26
+ * **Example usage:**
27
+ *
28
+ * ```
29
+ * const { sleep } = require('@crawlee/utils');
30
+ *
31
+ * ...
32
+ *
33
+ * // Sleep 1.5 seconds
34
+ * await sleep(1500);
35
+ * ```
36
+ * @param millis Period of time to sleep, in milliseconds. If not a positive number, the returned promise resolves immediately.
37
+ */
38
+ export declare function sleep(millis?: number): Promise<void>;
39
+ /**
40
+ * Converts SNAKE_CASE to camelCase.
41
+ * @ignore
42
+ */
43
+ export declare function snakeCaseToCamelCase(snakeCaseStr: string): string;
44
+ /**
45
+ * Cleans up the local storage folder created when testing locally.
46
+ * This is useful in the event you are debugging your code locally.
47
+ *
48
+ * Be careful as this will remove the folder you provide and everything in it!
49
+ *
50
+ * @param [folder] The folder to clean up
51
+ */
52
+ export declare function purgeLocalStorage(folder?: string): Promise<void>;
53
+ /**
54
+ * Gets parsed content type from response object
55
+ * @param response HTTP response object
56
+ * @ignore
57
+ */
58
+ export declare function parseContentTypeFromResponse(response: IncomingMessage): {
59
+ type: string;
60
+ charset: BufferEncoding;
61
+ };
62
+ //# sourceMappingURL=general.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"general.d.ts","sourceRoot":"","sources":["../../src/internals/general.ts"],"names":[],"mappings":";AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAMjD;;;GAGG;AACH,eAAO,MAAM,mBAAmB,QAA0J,CAAC;AAE3L;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAA2J,CAAC;AAkB9L;;GAEG;AACH,wBAAgB,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAK/D;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAS7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAUjE;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQtE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,cAAc,CAAA;CAAE,CA6BjH"}
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseContentTypeFromResponse = exports.purgeLocalStorage = exports.snakeCaseToCamelCase = exports.sleep = exports.weightedAvg = exports.isDocker = exports.URL_WITH_COMMAS_REGEX = exports.URL_NO_COMMAS_REGEX = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const consts_1 = require("@apify/consts");
6
+ const content_type_1 = tslib_1.__importDefault(require("content-type"));
7
+ const mime_types_1 = tslib_1.__importDefault(require("mime-types"));
8
+ const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
9
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
10
+ const promises_2 = require("node:timers/promises");
11
+ const node_url_1 = require("node:url");
12
+ const ow_1 = tslib_1.__importDefault(require("ow"));
13
+ /**
14
+ * Default regular expression to match URLs in a string that may be plain text, JSON, CSV or other. It supports common URL characters
15
+ * and does not support URLs containing commas or spaces. The URLs also may contain Unicode letters (not symbols).
16
+ */
17
+ exports.URL_NO_COMMAS_REGEX = RegExp('https?://(www\\.)?[\\p{L}0-9][-\\p{L}0-9@:%._\\+~#=]{0,254}[\\p{L}0-9]\\.[a-z]{2,63}(:\\d{1,5})?(/[-\\p{L}0-9@:%_\\+.~#?&//=\\(\\)]*)?', 'giu'); // eslint-disable-line
18
+ /**
19
+ * Regular expression that, in addition to the default regular expression `URL_NO_COMMAS_REGEX`, supports matching commas in URL path and query.
20
+ * Note, however, that this may prevent parsing URLs from comma delimited lists, or the URLs may become malformed.
21
+ */
22
+ exports.URL_WITH_COMMAS_REGEX = RegExp('https?://(www\\.)?[\\p{L}0-9][-\\p{L}0-9@:%._\\+~#=]{0,254}[\\p{L}0-9]\\.[a-z]{2,63}(:\\d{1,5})?(/[-\\p{L}0-9@:%_\\+,.~#?&//=\\(\\)]*)?', 'giu'); // eslint-disable-line
23
+ let isDockerPromiseCache;
24
+ async function createIsDockerPromise() {
25
+ const promise1 = promises_1.default.stat('/.dockerenv')
26
+ .then(() => true)
27
+ .catch(() => false);
28
+ const promise2 = promises_1.default.readFile('/proc/self/cgroup', 'utf8')
29
+ .then((content) => content.includes('docker'))
30
+ .catch(() => false);
31
+ const [result1, result2] = await Promise.all([promise1, promise2]);
32
+ return result1 || result2;
33
+ }
34
+ /**
35
+ * Returns a `Promise` that resolves to true if the code is running in a Docker container.
36
+ */
37
+ function isDocker(forceReset) {
38
+ // Parameter forceReset is just internal for unit tests.
39
+ if (!isDockerPromiseCache || forceReset)
40
+ isDockerPromiseCache = createIsDockerPromise();
41
+ return isDockerPromiseCache;
42
+ }
43
+ exports.isDocker = isDocker;
44
+ /**
45
+ * Computes a weighted average of an array of numbers, complemented by an array of weights.
46
+ * @ignore
47
+ */
48
+ function weightedAvg(arrValues, arrWeights) {
49
+ const result = arrValues.map((value, i) => {
50
+ const weight = arrWeights[i];
51
+ const sum = value * weight;
52
+ return [sum, weight];
53
+ }).reduce((p, c) => [p[0] + c[0], p[1] + c[1]], [0, 0]);
54
+ return result[0] / result[1];
55
+ }
56
+ exports.weightedAvg = weightedAvg;
57
+ /**
58
+ * Returns a `Promise` that resolves after a specific period of time. This is useful to implement waiting
59
+ * in your code, e.g. to prevent overloading of target website or to avoid bot detection.
60
+ *
61
+ * **Example usage:**
62
+ *
63
+ * ```
64
+ * const { sleep } = require('@crawlee/utils');
65
+ *
66
+ * ...
67
+ *
68
+ * // Sleep 1.5 seconds
69
+ * await sleep(1500);
70
+ * ```
71
+ * @param millis Period of time to sleep, in milliseconds. If not a positive number, the returned promise resolves immediately.
72
+ */
73
+ function sleep(millis) {
74
+ return (0, promises_2.setTimeout)(millis);
75
+ }
76
+ exports.sleep = sleep;
77
+ /**
78
+ * Converts SNAKE_CASE to camelCase.
79
+ * @ignore
80
+ */
81
+ function snakeCaseToCamelCase(snakeCaseStr) {
82
+ return snakeCaseStr
83
+ .toLowerCase()
84
+ .split('_')
85
+ .map((part, index) => {
86
+ return index > 0
87
+ ? part.charAt(0).toUpperCase() + part.slice(1)
88
+ : part;
89
+ })
90
+ .join('');
91
+ }
92
+ exports.snakeCaseToCamelCase = snakeCaseToCamelCase;
93
+ /**
94
+ * Cleans up the local storage folder created when testing locally.
95
+ * This is useful in the event you are debugging your code locally.
96
+ *
97
+ * Be careful as this will remove the folder you provide and everything in it!
98
+ *
99
+ * @param [folder] The folder to clean up
100
+ */
101
+ async function purgeLocalStorage(folder) {
102
+ // If the user did not provide a folder, try to get it from the env variables, or the default one
103
+ if (!folder) {
104
+ folder = process.env[consts_1.ENV_VARS.LOCAL_STORAGE_DIR] || 'apify_storage';
105
+ }
106
+ // Clear the folder
107
+ await promises_1.default.rm(folder, { recursive: true, force: true });
108
+ }
109
+ exports.purgeLocalStorage = purgeLocalStorage;
110
+ /**
111
+ * Gets parsed content type from response object
112
+ * @param response HTTP response object
113
+ * @ignore
114
+ */
115
+ function parseContentTypeFromResponse(response) {
116
+ (0, ow_1.default)(response, ow_1.default.object.partialShape({
117
+ url: ow_1.default.string.url,
118
+ headers: ow_1.default.object,
119
+ }));
120
+ const { url, headers } = response;
121
+ let parsedContentType;
122
+ if (headers['content-type']) {
123
+ try {
124
+ parsedContentType = content_type_1.default.parse(headers['content-type']);
125
+ }
126
+ catch {
127
+ // Can not parse content type from Content-Type header. Try to parse it from file extension.
128
+ }
129
+ }
130
+ // Parse content type from file extension as fallback
131
+ if (!parsedContentType) {
132
+ const parsedUrl = new node_url_1.URL(url);
133
+ const contentTypeFromExtname = mime_types_1.default.contentType(node_path_1.default.extname(parsedUrl.pathname))
134
+ || 'application/octet-stream; charset=utf-8'; // Fallback content type, specified in https://tools.ietf.org/html/rfc7231#section-3.1.1.5
135
+ parsedContentType = content_type_1.default.parse(contentTypeFromExtname);
136
+ }
137
+ return {
138
+ type: parsedContentType.type,
139
+ charset: parsedContentType.parameters.charset,
140
+ };
141
+ }
142
+ exports.parseContentTypeFromResponse = parseContentTypeFromResponse;
143
+ //# sourceMappingURL=general.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"general.js","sourceRoot":"","sources":["../../src/internals/general.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Describes memory usage of the process.
3
+ */
4
+ export interface MemoryInfo {
5
+ /** Total memory available in the system or container */
6
+ totalBytes: number;
7
+ /** Amount of free memory in the system or container */
8
+ freeBytes: number;
9
+ /** Amount of memory used (= totalBytes - freeBytes) */
10
+ usedBytes: number;
11
+ /** Amount of memory used the current Node.js process */
12
+ mainProcessBytes: number;
13
+ /** Amount of memory used by child processes of the current Node.js process */
14
+ childProcessesBytes: number;
15
+ }
16
+ /**
17
+ * Returns memory statistics of the process and the system, see {@link MemoryInfo}.
18
+ *
19
+ * If the process runs inside of Docker, the `getMemoryInfo` gets container memory limits,
20
+ * otherwise it gets system memory limits.
21
+ *
22
+ * Beware that the function is quite inefficient because it spawns a new process.
23
+ * Therefore you shouldn't call it too often, like more than once per second.
24
+ */
25
+ export declare function getMemoryInfo(): Promise<MemoryInfo>;
26
+ //# sourceMappingURL=memory-info.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-info.d.ts","sourceRoot":"","sources":["../../src/internals/memory-info.ts"],"names":[],"mappings":"AAqBA;;GAEG;AACH,MAAM,WAAW,UAAU;IACvB,wDAAwD;IACxD,UAAU,EAAE,MAAM,CAAC;IAEnB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAElB,uDAAuD;IACvD,SAAS,EAAE,MAAM,CAAC;IAElB,wDAAwD;IACxD,gBAAgB,EAAE,MAAM,CAAC;IAEzB,8EAA8E;IAC9E,mBAAmB,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAmHzD"}
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getMemoryInfo = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const log_1 = tslib_1.__importDefault(require("@apify/log"));
6
+ // @ts-expect-error We need to add typings for @apify/ps-tree
7
+ const ps_tree_1 = tslib_1.__importDefault(require("@apify/ps-tree"));
8
+ const node_child_process_1 = require("node:child_process");
9
+ const promises_1 = tslib_1.__importDefault(require("node:fs/promises"));
10
+ const node_os_1 = tslib_1.__importDefault(require("node:os"));
11
+ const node_util_1 = tslib_1.__importDefault(require("node:util"));
12
+ const general_1 = require("./general");
13
+ const MEMORY_FILE_PATHS = {
14
+ TOTAL: {
15
+ V1: '/sys/fs/cgroup/memory/memory.limit_in_bytes',
16
+ V2: '/sys/fs/cgroup/memory.max',
17
+ },
18
+ USED: {
19
+ V1: '/sys/fs/cgroup/memory/memory.usage_in_bytes',
20
+ V2: '/sys/fs/cgroup/memory.current',
21
+ },
22
+ };
23
+ /**
24
+ * Returns memory statistics of the process and the system, see {@link MemoryInfo}.
25
+ *
26
+ * If the process runs inside of Docker, the `getMemoryInfo` gets container memory limits,
27
+ * otherwise it gets system memory limits.
28
+ *
29
+ * Beware that the function is quite inefficient because it spawns a new process.
30
+ * Therefore you shouldn't call it too often, like more than once per second.
31
+ */
32
+ async function getMemoryInfo() {
33
+ const psTreePromised = node_util_1.default.promisify(ps_tree_1.default);
34
+ // lambda does *not* have `ps` and other command line tools
35
+ // required to extract memory usage.
36
+ const isLambdaEnvironment = process.platform === 'linux'
37
+ && !!process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE;
38
+ const isDockerVar = !isLambdaEnvironment && await (0, general_1.isDocker)();
39
+ let mainProcessBytes = -1;
40
+ let childProcessesBytes = 0;
41
+ if (isLambdaEnvironment) {
42
+ // reported in bytes
43
+ mainProcessBytes = process.memoryUsage().rss;
44
+ // TODO this is quite ugly, let's introduce some local variables
45
+ // https://stackoverflow.com/a/55914335/129415
46
+ childProcessesBytes = +(0, node_child_process_1.execSync)('cat /proc/meminfo')
47
+ .toString()
48
+ .split(/[\n: ]/)
49
+ .filter((val) => val.trim())[19]
50
+ * 1000 // meminfo reports in kb, not bytes
51
+ // the total used memory is reported by meminfo
52
+ // subtract memory used by the main node process
53
+ // in order to infer memory used by any child processes
54
+ - mainProcessBytes;
55
+ }
56
+ else {
57
+ // Query both root and child processes
58
+ const processes = await psTreePromised(process.pid, true);
59
+ processes.forEach((rec) => {
60
+ // Skip the 'ps' or 'wmic' commands used by ps-tree to query the processes
61
+ if (rec.COMMAND === 'ps' || rec.COMMAND === 'WMIC.exe') {
62
+ return;
63
+ }
64
+ const bytes = parseInt(rec.RSS, 10);
65
+ // Obtain main process' memory separately
66
+ if (rec.PID === `${process.pid}`) {
67
+ mainProcessBytes = bytes;
68
+ return;
69
+ }
70
+ childProcessesBytes += bytes;
71
+ });
72
+ }
73
+ let totalBytes;
74
+ let usedBytes;
75
+ let freeBytes;
76
+ if (isLambdaEnvironment) {
77
+ // memory size is defined in megabytes
78
+ totalBytes = parseInt(process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE, 10) * 1000000;
79
+ usedBytes = mainProcessBytes + childProcessesBytes;
80
+ freeBytes = totalBytes - usedBytes;
81
+ log_1.default.debug(`lambda size of ${totalBytes} with ${freeBytes} free bytes`);
82
+ }
83
+ else if (isDockerVar) {
84
+ // When running inside Docker container, use container memory limits
85
+ // Check whether cgroups V1 or V2 is used
86
+ let cgroupsVersion = 'V1';
87
+ try {
88
+ // If this directory does not exists, assume docker is using cgroups V2
89
+ await promises_1.default.access('/sys/fs/cgroup/memory/');
90
+ }
91
+ catch {
92
+ cgroupsVersion = 'V2';
93
+ }
94
+ try {
95
+ let [totalBytesStr, usedBytesStr] = await Promise.all([
96
+ promises_1.default.readFile(MEMORY_FILE_PATHS.TOTAL[cgroupsVersion], 'utf8'),
97
+ promises_1.default.readFile(MEMORY_FILE_PATHS.USED[cgroupsVersion], 'utf8'),
98
+ ]);
99
+ // Cgroups V2 files contains newline character. Getting rid of it for better handling in later part of the code.
100
+ totalBytesStr = totalBytesStr.replace(/[^a-zA-Z0-9 ]/g, '');
101
+ usedBytesStr = usedBytesStr.replace(/[^a-zA-Z0-9 ]/g, '');
102
+ // Cgroups V2 contains 'max' string if memory is not limited
103
+ // See https://git.kernel.org/pub/scm/linux/kernel/git/tj/cgroup.git/tree/Documentation/admin-guide/cgroup-v2.rst (see "memory.max")
104
+ if (totalBytesStr === 'max') {
105
+ totalBytes = node_os_1.default.totalmem();
106
+ // Cgroups V1 is set to number related to platform and page size if memory is not limited
107
+ // See https://unix.stackexchange.com/q/420906
108
+ }
109
+ else {
110
+ totalBytes = parseInt(totalBytesStr, 10);
111
+ const containerRunsWithUnlimitedMemory = totalBytes > Number.MAX_SAFE_INTEGER;
112
+ if (containerRunsWithUnlimitedMemory)
113
+ totalBytes = node_os_1.default.totalmem();
114
+ }
115
+ usedBytes = parseInt(usedBytesStr, 10);
116
+ freeBytes = totalBytes - usedBytes;
117
+ }
118
+ catch (err) {
119
+ // log.deprecated logs a warning only once
120
+ log_1.default.deprecated('Your environment is Docker, but your system does not support memory cgroups. '
121
+ + 'If you\'re running containers with limited memory, memory auto-scaling will not work properly.\n\n'
122
+ + `Cause: ${err.message}`);
123
+ totalBytes = node_os_1.default.totalmem();
124
+ freeBytes = node_os_1.default.freemem();
125
+ usedBytes = totalBytes - freeBytes;
126
+ }
127
+ }
128
+ else {
129
+ totalBytes = node_os_1.default.totalmem();
130
+ freeBytes = node_os_1.default.freemem();
131
+ usedBytes = totalBytes - freeBytes;
132
+ }
133
+ return {
134
+ totalBytes,
135
+ freeBytes,
136
+ usedBytes,
137
+ mainProcessBytes,
138
+ childProcessesBytes,
139
+ };
140
+ }
141
+ exports.getMemoryInfo = getMemoryInfo;
142
+ //# sourceMappingURL=memory-info.js.map