@crawlee/utils 4.0.0-beta.10 → 4.0.0-beta.101

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.
Files changed (69) hide show
  1. package/README.md +17 -13
  2. package/index.d.ts +1 -7
  3. package/index.js +1 -6
  4. package/internals/blocked.d.ts +0 -1
  5. package/internals/blocked.js +0 -1
  6. package/internals/cheerio.d.ts +3 -2
  7. package/internals/cheerio.js +4 -5
  8. package/internals/extract-urls.d.ts +5 -1
  9. package/internals/extract-urls.js +8 -5
  10. package/internals/general.d.ts +0 -25
  11. package/internals/general.js +2 -110
  12. package/internals/iterables.d.ts +47 -0
  13. package/internals/iterables.js +96 -0
  14. package/internals/open_graph_parser.d.ts +2 -3
  15. package/internals/open_graph_parser.js +8 -9
  16. package/internals/robots.d.ts +14 -5
  17. package/internals/robots.js +31 -35
  18. package/internals/sitemap.d.ts +65 -8
  19. package/internals/sitemap.js +174 -34
  20. package/internals/social.d.ts +1 -2
  21. package/internals/social.js +7 -5
  22. package/internals/url.d.ts +1 -2
  23. package/internals/url.js +1 -2
  24. package/package.json +6 -6
  25. package/index.d.ts.map +0 -1
  26. package/index.js.map +0 -1
  27. package/internals/blocked.d.ts.map +0 -1
  28. package/internals/blocked.js.map +0 -1
  29. package/internals/cheerio.d.ts.map +0 -1
  30. package/internals/cheerio.js.map +0 -1
  31. package/internals/chunk.d.ts +0 -2
  32. package/internals/chunk.d.ts.map +0 -1
  33. package/internals/chunk.js +0 -40
  34. package/internals/chunk.js.map +0 -1
  35. package/internals/debug.d.ts +0 -31
  36. package/internals/debug.d.ts.map +0 -1
  37. package/internals/debug.js +0 -29
  38. package/internals/debug.js.map +0 -1
  39. package/internals/extract-urls.d.ts.map +0 -1
  40. package/internals/extract-urls.js.map +0 -1
  41. package/internals/general.d.ts.map +0 -1
  42. package/internals/general.js.map +0 -1
  43. package/internals/open_graph_parser.d.ts.map +0 -1
  44. package/internals/open_graph_parser.js.map +0 -1
  45. package/internals/robots.d.ts.map +0 -1
  46. package/internals/robots.js.map +0 -1
  47. package/internals/sitemap.d.ts.map +0 -1
  48. package/internals/sitemap.js.map +0 -1
  49. package/internals/social.d.ts.map +0 -1
  50. package/internals/social.js.map +0 -1
  51. package/internals/system-info/cpu-info.d.ts +0 -64
  52. package/internals/system-info/cpu-info.d.ts.map +0 -1
  53. package/internals/system-info/cpu-info.js +0 -211
  54. package/internals/system-info/cpu-info.js.map +0 -1
  55. package/internals/system-info/memory-info.d.ts +0 -28
  56. package/internals/system-info/memory-info.d.ts.map +0 -1
  57. package/internals/system-info/memory-info.js +0 -118
  58. package/internals/system-info/memory-info.js.map +0 -1
  59. package/internals/system-info/ps-tree.d.ts +0 -18
  60. package/internals/system-info/ps-tree.d.ts.map +0 -1
  61. package/internals/system-info/ps-tree.js +0 -145
  62. package/internals/system-info/ps-tree.js.map +0 -1
  63. package/internals/typedefs.d.ts +0 -5
  64. package/internals/typedefs.d.ts.map +0 -1
  65. package/internals/typedefs.js +0 -9
  66. package/internals/typedefs.js.map +0 -1
  67. package/internals/url.d.ts.map +0 -1
  68. package/internals/url.js.map +0 -1
  69. package/tsconfig.build.tsbuildinfo +0 -1
package/README.md CHANGED
@@ -1,19 +1,23 @@
1
1
  <h1 align="center">
2
2
  <a href="https://crawlee.dev">
3
3
  <picture>
4
- <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-dark.svg?sanitize=true">
5
- <img alt="Crawlee" src="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-light.svg?sanitize=true" width="500">
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-dark.svg?sanitize=true" />
5
+ <img alt="Crawlee" src="https://raw.githubusercontent.com/apify/crawlee/master/website/static/img/crawlee-light.svg?sanitize=true" width="500" />
6
6
  </picture>
7
7
  </a>
8
- <br>
8
+ <br />
9
9
  <small>A web scraping and browser automation library</small>
10
10
  </h1>
11
11
 
12
- <p align=center>
13
- <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/v/@crawlee/core.svg" alt="NPM latest version" data-canonical-src="https://img.shields.io/npm/v/@crawlee/core/next.svg" style="max-width: 100%;"></a>
14
- <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/dm/@crawlee/core.svg" alt="Downloads" data-canonical-src="https://img.shields.io/npm/dm/@crawlee/core.svg" style="max-width: 100%;"></a>
15
- <a href="https://discord.gg/jyEM2PRvMU" rel="nofollow"><img src="https://img.shields.io/discord/801163717915574323?label=discord" alt="Chat on discord" data-canonical-src="https://img.shields.io/discord/801163717915574323?label=discord" style="max-width: 100%;"></a>
16
- <a href="https://github.com/apify/crawlee/actions/workflows/test-ci.yml"><img src="https://github.com/apify/crawlee/actions/workflows/test-ci.yml/badge.svg?branch=master" alt="Build Status" style="max-width: 100%;"></a>
12
+ <p align="center">
13
+ <a href="https://trendshift.io/repositories/5179" target="_blank"><img src="https://trendshift.io/api/badge/repositories/5179" alt="apify%2Fcrawlee | Trendshift" width="250" height="55"/></a>
14
+ </p>
15
+
16
+ <p align="center">
17
+ <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/v/@crawlee/core.svg" alt="NPM latest version" data-canonical-src="https://img.shields.io/npm/v/@crawlee/core/next.svg" /></a>
18
+ <a href="https://www.npmjs.com/package/@crawlee/core" rel="nofollow"><img src="https://img.shields.io/npm/dm/@crawlee/core.svg" alt="Downloads" data-canonical-src="https://img.shields.io/npm/dm/@crawlee/core.svg" /></a>
19
+ <a href="https://discord.gg/jyEM2PRvMU" rel="nofollow"><img src="https://img.shields.io/discord/801163717915574323?label=discord" alt="Chat on discord" data-canonical-src="https://img.shields.io/discord/801163717915574323?label=discord" /></a>
20
+ <a href="https://github.com/apify/crawlee/actions/workflows/test-ci.yml"><img src="https://github.com/apify/crawlee/actions/workflows/test-ci.yml/badge.svg?branch=master" alt="Build Status" /></a>
17
21
  </p>
18
22
 
19
23
  Crawlee covers your crawling and scraping end-to-end and **helps you build reliable scrapers. Fast.**
@@ -24,7 +28,7 @@ Crawlee is available as the [`crawlee`](https://www.npmjs.com/package/crawlee) N
24
28
 
25
29
  > 👉 **View full documentation, guides and examples on the [Crawlee project website](https://crawlee.dev)** 👈
26
30
 
27
- > Crawlee for Python is open for early adopters. 🐍 [👉 Checkout the source code 👈](https://github.com/apify/crawlee-python).
31
+ > Do you prefer 🐍 Python instead of JavaScript? [👉 Checkout Crawlee for Python 👈](https://github.com/apify/crawlee-python).
28
32
 
29
33
  ## Installation
30
34
 
@@ -85,7 +89,7 @@ By default, Crawlee stores data to `./storage` in the current working directory.
85
89
  We provide automated beta builds for every merged code change in Crawlee. You can find them in the npm [list of releases](https://www.npmjs.com/package/crawlee?activeTab=versions). If you want to test new features or bug fixes before we release them, feel free to install a beta build like this:
86
90
 
87
91
  ```bash
88
- npm install crawlee@3.12.3-beta.13
92
+ npm install crawlee@next
89
93
  ```
90
94
 
91
95
  If you also use the [Apify SDK](https://github.com/apify/apify-sdk-js), you need to specify dependency overrides in your `package.json` file so that you don't end up with multiple versions of Crawlee installed:
@@ -94,9 +98,9 @@ If you also use the [Apify SDK](https://github.com/apify/apify-sdk-js), you need
94
98
  {
95
99
  "overrides": {
96
100
  "apify": {
97
- "@crawlee/core": "3.12.3-beta.13",
98
- "@crawlee/types": "3.12.3-beta.13",
99
- "@crawlee/utils": "3.12.3-beta.13"
101
+ "@crawlee/core": "$crawlee",
102
+ "@crawlee/types": "$crawlee",
103
+ "@crawlee/utils": "$crawlee"
100
104
  }
101
105
  }
102
106
  }
package/index.d.ts CHANGED
@@ -1,16 +1,10 @@
1
1
  export * from './internals/blocked.js';
2
2
  export * from './internals/cheerio.js';
3
- export * from './internals/chunk.js';
4
3
  export * from './internals/extract-urls.js';
5
4
  export * from './internals/general.js';
6
- export * from './internals/debug.js';
7
5
  export * as social from './internals/social.js';
8
- export * from './internals/typedefs.js';
9
6
  export * from './internals/open_graph_parser.js';
10
7
  export * from './internals/robots.js';
11
8
  export * from './internals/sitemap.js';
9
+ export * from './internals/iterables.js';
12
10
  export * from './internals/url.js';
13
- export { getCurrentCpuTicksV2, CpuSample } from './internals/system-info/cpu-info.js';
14
- export { getMemoryInfo, MemoryInfo } from './internals/system-info/memory-info.js';
15
- export { Dictionary, Awaitable, Constructor } from '@crawlee/types';
16
- //# sourceMappingURL=index.d.ts.map
package/index.js CHANGED
@@ -1,15 +1,10 @@
1
1
  export * from './internals/blocked.js';
2
2
  export * from './internals/cheerio.js';
3
- export * from './internals/chunk.js';
4
3
  export * from './internals/extract-urls.js';
5
4
  export * from './internals/general.js';
6
- export * from './internals/debug.js';
7
5
  export * as social from './internals/social.js';
8
- export * from './internals/typedefs.js';
9
6
  export * from './internals/open_graph_parser.js';
10
7
  export * from './internals/robots.js';
11
8
  export * from './internals/sitemap.js';
9
+ export * from './internals/iterables.js';
12
10
  export * from './internals/url.js';
13
- export { getCurrentCpuTicksV2 } from './internals/system-info/cpu-info.js';
14
- export { getMemoryInfo } from './internals/system-info/memory-info.js';
15
- //# sourceMappingURL=index.js.map
@@ -7,4 +7,3 @@ export declare const RETRY_CSS_SELECTORS: string[];
7
7
  * Content of proxy errors that should trigger a retry, as the proxy is likely getting blocked / is malfunctioning.
8
8
  */
9
9
  export declare const ROTATE_PROXY_ERRORS: string[];
10
- //# sourceMappingURL=blocked.d.ts.map
@@ -17,4 +17,3 @@ export const ROTATE_PROXY_ERRORS = [
17
17
  'ERR_TUNNEL_CONNECTION_FAILED',
18
18
  'Proxy responded with',
19
19
  ];
20
- //# sourceMappingURL=blocked.js.map
@@ -1,5 +1,7 @@
1
1
  import type { CheerioAPI } from 'cheerio';
2
2
  export type CheerioRoot = CheerioAPI;
3
+ export type { CheerioAPI, Cheerio } from 'cheerio';
4
+ export type { Element } from 'domhandler';
3
5
  /**
4
6
  * The function converts a HTML document to a plain text.
5
7
  *
@@ -27,7 +29,7 @@ export type CheerioRoot = CheerioAPI;
27
29
  * @param htmlOrCheerioElement HTML text or parsed HTML represented using a [cheerio](https://www.npmjs.com/package/cheerio) function.
28
30
  * @return Plain text
29
31
  */
30
- export declare function htmlToText(htmlOrCheerioElement: string | CheerioRoot): string;
32
+ export declare function htmlToText(htmlOrCheerioElement: string | CheerioRoot): Promise<string>;
31
33
  /**
32
34
  * Extracts URLs from a given Cheerio object.
33
35
  *
@@ -38,4 +40,3 @@ export declare function htmlToText(htmlOrCheerioElement: string | CheerioRoot):
38
40
  * @return An array of absolute URLs
39
41
  */
40
42
  export declare function extractUrlsFromCheerio($: CheerioAPI, selector?: string, baseUrl?: string): string[];
41
- //# sourceMappingURL=cheerio.d.ts.map
@@ -1,4 +1,3 @@
1
- import * as cheerio from 'cheerio';
2
1
  import { tryAbsoluteURL } from './extract-urls.js';
3
2
  // NOTE: We are skipping 'noscript' since it's content is evaluated as text, instead of HTML elements. That damages the results.
4
3
  const SKIP_TAGS_REGEX = /^(script|style|canvas|svg|noscript)$/i;
@@ -30,10 +29,11 @@ const BLOCK_TAGS_REGEX = /^(p|h1|h2|h3|h4|h5|h6|ol|ul|li|pre|address|blockquote|
30
29
  * @param htmlOrCheerioElement HTML text or parsed HTML represented using a [cheerio](https://www.npmjs.com/package/cheerio) function.
31
30
  * @return Plain text
32
31
  */
33
- export function htmlToText(htmlOrCheerioElement) {
32
+ export async function htmlToText(htmlOrCheerioElement) {
33
+ const { load } = await import('cheerio');
34
34
  if (!htmlOrCheerioElement)
35
35
  return '';
36
- const $ = typeof htmlOrCheerioElement === 'function' ? htmlOrCheerioElement : cheerio.load(htmlOrCheerioElement);
36
+ const $ = typeof htmlOrCheerioElement === 'function' ? htmlOrCheerioElement : load(htmlOrCheerioElement);
37
37
  let text = '';
38
38
  const process = (elems) => {
39
39
  const len = elems ? elems.length : 0;
@@ -42,7 +42,7 @@ export function htmlToText(htmlOrCheerioElement) {
42
42
  if (elem.type === 'text') {
43
43
  // Compress spaces, unless we're inside <pre> element
44
44
  let compr;
45
- if (elem.parent && elem.parent.tagName === 'pre')
45
+ if (elem.parent?.tagName === 'pre')
46
46
  compr = elem.data;
47
47
  else
48
48
  compr = elem.data.replace(/\s+/g, ' ');
@@ -107,4 +107,3 @@ export function extractUrlsFromCheerio($, selector = 'a', baseUrl = '') {
107
107
  })
108
108
  .filter(Boolean);
109
109
  }
110
- //# sourceMappingURL=cheerio.js.map
@@ -1,3 +1,4 @@
1
+ import type { BaseHttpClient } from '@crawlee/types';
1
2
  export interface DownloadListOfUrlsOptions {
2
3
  /**
3
4
  * URL to the file
@@ -16,6 +17,10 @@ export interface DownloadListOfUrlsOptions {
16
17
  urlRegExp?: RegExp;
17
18
  /** Allows to use a proxy for the download request. */
18
19
  proxyUrl?: string;
20
+ /**
21
+ * Custom HTTP client to use for downloading the file.
22
+ */
23
+ httpClient?: BaseHttpClient;
19
24
  }
20
25
  /**
21
26
  * Returns a promise that resolves to an array of urls parsed from the resource available at the provided url.
@@ -41,4 +46,3 @@ export declare function extractUrls(options: ExtractUrlsOptions): string[];
41
46
  * Helper function used to validate URLs used when extracting URLs from a page
42
47
  */
43
48
  export declare function tryAbsoluteURL(href: string, baseUrl: string): string | undefined;
44
- //# sourceMappingURL=extract-urls.d.ts.map
@@ -1,4 +1,4 @@
1
- import { gotScraping } from 'got-scraping';
1
+ import { FetchHttpClient } from '@crawlee/http-client';
2
2
  import ow from 'ow';
3
3
  import { URL_NO_COMMAS_REGEX } from './general.js';
4
4
  /**
@@ -11,15 +11,19 @@ export async function downloadListOfUrls(options) {
11
11
  encoding: ow.optional.string,
12
12
  urlRegExp: ow.optional.regExp,
13
13
  proxyUrl: ow.optional.string,
14
+ httpClient: ow.optional.object,
14
15
  }));
15
- const { url, encoding = 'utf8', urlRegExp = URL_NO_COMMAS_REGEX, proxyUrl } = options;
16
+ const { url, encoding = 'utf8', urlRegExp = URL_NO_COMMAS_REGEX, proxyUrl, httpClient = new FetchHttpClient(), } = options;
16
17
  // Try to detect wrong urls and fix them. Currently, detects only sharing url instead of csv download one.
17
- const match = url.match(/^(https:\/\/docs\.google\.com\/spreadsheets\/d\/(?:\w|-)+)\/?/);
18
+ const match = /^(https:\/\/docs\.google\.com\/spreadsheets\/d\/(?:\w|-)+)\/?/.exec(url);
18
19
  let fixedUrl = url;
19
20
  if (match) {
20
21
  fixedUrl = `${match[1]}/gviz/tq?tqx=out:csv`;
21
22
  }
22
- const { body: string } = await gotScraping({ url: fixedUrl, encoding, proxyUrl });
23
+ const response = await httpClient.sendRequest(new Request(fixedUrl, { method: 'GET' }), {
24
+ proxyUrl,
25
+ });
26
+ const string = new TextDecoder(encoding).decode(new Uint8Array(await response.arrayBuffer()));
23
27
  return extractUrls({ string, urlRegExp });
24
28
  }
25
29
  /**
@@ -49,4 +53,3 @@ export function tryAbsoluteURL(href, baseUrl) {
49
53
  return undefined;
50
54
  }
51
55
  }
52
- //# sourceMappingURL=extract-urls.js.map
@@ -8,25 +8,6 @@ export declare const URL_NO_COMMAS_REGEX: RegExp;
8
8
  * Note, however, that this may prevent parsing URLs from comma delimited lists, or the URLs may become malformed.
9
9
  */
10
10
  export declare const URL_WITH_COMMAS_REGEX: RegExp;
11
- /**
12
- * Returns a `Promise` that resolves to true if the code is running in a Docker container.
13
- */
14
- export declare function isDocker(forceReset?: boolean): Promise<boolean>;
15
- /**
16
- * Detects if crawlee is running in a containerized environment.
17
- */
18
- export declare function isContainerized(): Promise<boolean>;
19
- export declare function isLambda(): boolean;
20
- /**
21
- * gets the cgroup version by checking for a file at /sys/fs/cgroup/memory
22
- * @returns "V1" or "V2" for the version of cgroup or null if cgroup is not found.
23
- */
24
- export declare function getCgroupsVersion(forceReset?: boolean): Promise<"V1" | "V2" | null>;
25
- /**
26
- * Computes a weighted average of an array of numbers, complemented by an array of weights.
27
- * @ignore
28
- */
29
- export declare function weightedAvg(arrValues: number[], arrWeights: number[]): number;
30
11
  /**
31
12
  * Returns a `Promise` that resolves after a specific period of time. This is useful to implement waiting
32
13
  * in your code, e.g. to prevent overloading of target website or to avoid bot detection.
@@ -44,14 +25,8 @@ export declare function weightedAvg(arrValues: number[], arrWeights: number[]):
44
25
  * @param millis Period of time to sleep, in milliseconds. If not a positive number, the returned promise resolves immediately.
45
26
  */
46
27
  export declare function sleep(millis?: number): Promise<void>;
47
- /**
48
- * Converts SNAKE_CASE to camelCase.
49
- * @ignore
50
- */
51
- export declare function snakeCaseToCamelCase(snakeCaseStr: string): string;
52
28
  /**
53
29
  * Traverses DOM and expands shadow-root elements (created by custom components).
54
30
  * @ignore
55
31
  */
56
32
  export declare function expandShadowRoots(document: Document): string;
57
- //# sourceMappingURL=general.d.ts.map
@@ -1,108 +1,14 @@
1
- import fs from 'node:fs/promises';
2
1
  import { setTimeout } from 'node:timers/promises';
3
2
  /**
4
3
  * Default regular expression to match URLs in a string that may be plain text, JSON, CSV or other. It supports common URL characters
5
4
  * and does not support URLs containing commas or spaces. The URLs also may contain Unicode letters (not symbols).
6
5
  */
7
- export const URL_NO_COMMAS_REGEX = /https?:\/\/(www\.)?([\p{L}0-9]|[\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;
6
+ export const URL_NO_COMMAS_REGEX = /https?:\/\/(www\.)?([\p{L}0-9]|[\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;
8
7
  /**
9
8
  * Regular expression that, in addition to the default regular expression `URL_NO_COMMAS_REGEX`, supports matching commas in URL path and query.
10
9
  * Note, however, that this may prevent parsing URLs from comma delimited lists, or the URLs may become malformed.
11
10
  */
12
- export const URL_WITH_COMMAS_REGEX = /https?:\/\/(www\.)?([\p{L}0-9]|[\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;
13
- let isDockerPromiseCache;
14
- async function createIsDockerPromise() {
15
- const promise1 = fs
16
- .stat('/.dockerenv')
17
- .then(() => true)
18
- .catch(() => false);
19
- const promise2 = fs
20
- .readFile('/proc/self/cgroup', 'utf8')
21
- .then((content) => content.includes('docker'))
22
- .catch(() => false);
23
- const [result1, result2] = await Promise.all([promise1, promise2]);
24
- return result1 || result2;
25
- }
26
- /**
27
- * Returns a `Promise` that resolves to true if the code is running in a Docker container.
28
- */
29
- export async function isDocker(forceReset) {
30
- // Parameter forceReset is just internal for unit tests.
31
- if (!isDockerPromiseCache || forceReset)
32
- isDockerPromiseCache = createIsDockerPromise();
33
- return isDockerPromiseCache;
34
- }
35
- let isContainerizedResult;
36
- /**
37
- * Detects if crawlee is running in a containerized environment.
38
- */
39
- export async function isContainerized() {
40
- // Value is very unlikley to change. Cache the result after the first execution.
41
- if (isContainerizedResult !== undefined) {
42
- return isContainerizedResult;
43
- }
44
- // return false if running in aws lambda
45
- if (isLambda()) {
46
- isContainerizedResult = false;
47
- return isContainerizedResult;
48
- }
49
- const dockerenvCheck = fs
50
- .stat('/.dockerenv')
51
- .then(() => true)
52
- .catch(() => false);
53
- const cgroupCheck = fs
54
- .readFile('/proc/self/cgroup', 'utf8')
55
- .then((content) => content.includes('docker'))
56
- .catch(() => false);
57
- const [dockerenvResult, cgroupResult] = await Promise.all([dockerenvCheck, cgroupCheck]);
58
- isContainerizedResult = dockerenvResult || cgroupResult || !!process.env.KUBERNETES_SERVICE_HOST;
59
- return isContainerizedResult;
60
- }
61
- export function isLambda() {
62
- return !!process.env.AWS_LAMBDA_FUNCTION_MEMORY_SIZE;
63
- }
64
- let _cgroupsVersion;
65
- /**
66
- * gets the cgroup version by checking for a file at /sys/fs/cgroup/memory
67
- * @returns "V1" or "V2" for the version of cgroup or null if cgroup is not found.
68
- */
69
- export async function getCgroupsVersion(forceReset) {
70
- // Parameter forceReset is just internal for unit tests.
71
- if (_cgroupsVersion !== undefined && !forceReset) {
72
- return _cgroupsVersion;
73
- }
74
- try {
75
- // If this directory does not exists, cgroups are not available
76
- await fs.access('/sys/fs/cgroup/');
77
- }
78
- catch (e) {
79
- _cgroupsVersion = null;
80
- return null;
81
- }
82
- _cgroupsVersion = 'V1';
83
- try {
84
- // If this directory does not exists, assume the container is using cgroups V2
85
- await fs.access('/sys/fs/cgroup/memory/');
86
- }
87
- catch (e) {
88
- _cgroupsVersion = 'V2';
89
- }
90
- return _cgroupsVersion;
91
- }
92
- /**
93
- * Computes a weighted average of an array of numbers, complemented by an array of weights.
94
- * @ignore
95
- */
96
- export function weightedAvg(arrValues, arrWeights) {
97
- const result = arrValues
98
- .map((value, i) => {
99
- const weight = arrWeights[i];
100
- const sum = value * weight;
101
- return [sum, weight];
102
- })
103
- .reduce((p, c) => [p[0] + c[0], p[1] + c[1]], [0, 0]);
104
- return result[0] / result[1];
105
- }
11
+ export const URL_WITH_COMMAS_REGEX = /https?:\/\/(www\.)?([\p{L}0-9]|[\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;
106
12
  /**
107
13
  * Returns a `Promise` that resolves after a specific period of time. This is useful to implement waiting
108
14
  * in your code, e.g. to prevent overloading of target website or to avoid bot detection.
@@ -122,19 +28,6 @@ export function weightedAvg(arrValues, arrWeights) {
122
28
  export async function sleep(millis) {
123
29
  return setTimeout(millis ?? undefined);
124
30
  }
125
- /**
126
- * Converts SNAKE_CASE to camelCase.
127
- * @ignore
128
- */
129
- export function snakeCaseToCamelCase(snakeCaseStr) {
130
- return snakeCaseStr
131
- .toLowerCase()
132
- .split('_')
133
- .map((part, index) => {
134
- return index > 0 ? part.charAt(0).toUpperCase() + part.slice(1) : part;
135
- })
136
- .join('');
137
- }
138
31
  /**
139
32
  * Traverses DOM and expands shadow-root elements (created by custom components).
140
33
  * @ignore
@@ -164,4 +57,3 @@ export function expandShadowRoots(document) {
164
57
  replaceShadowDomsWithHtml(document.body);
165
58
  return document.documentElement.outerHTML;
166
59
  }
167
- //# sourceMappingURL=general.js.map
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Type guard that checks if a value is iterable (has Symbol.iterator).
3
+ * @internal
4
+ *
5
+ * **Example usage:**
6
+ * ```ts
7
+ * if (isIterable(someValue)) {
8
+ * for (const item of someValue) {
9
+ * console.log(item);
10
+ * }
11
+ * }
12
+ * ```
13
+ */
14
+ export declare function isIterable<T>(value: unknown): value is Iterable<T>;
15
+ /**
16
+ * Type guard that checks if a value is async iterable (has Symbol.asyncIterator).
17
+ * @internal
18
+ *
19
+ * **Example usage:**
20
+ * ```ts
21
+ * if (isAsyncIterable(someValue)) {
22
+ * for await (const item of someValue) {
23
+ * console.log(item);
24
+ * }
25
+ * }
26
+ * ```
27
+ */
28
+ export declare function isAsyncIterable<T>(value: unknown): value is AsyncIterable<T>;
29
+ /**
30
+ * Merges multiple async iterables into a single async iterable, yielding values concurrently.
31
+ *
32
+ * **Example usage:**
33
+ * ```ts
34
+ * const asyncIterable1 = async function* () {
35
+ * yield 1; yield 3; yield 5;
36
+ * };
37
+ *
38
+ * const asyncIterable2 = async function* () {
39
+ * yield 2; yield 4; yield 6;
40
+ * };
41
+ *
42
+ * for await (const value of mergeAsyncIterables(asyncIterable1(), asyncIterable2())) {
43
+ * console.log(value);
44
+ * }
45
+ * ```
46
+ */
47
+ export declare function mergeAsyncIterables<T>(...iterables: AsyncIterable<T>[]): AsyncIterable<T>;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Type guard that checks if a value is iterable (has Symbol.iterator).
3
+ * @internal
4
+ *
5
+ * **Example usage:**
6
+ * ```ts
7
+ * if (isIterable(someValue)) {
8
+ * for (const item of someValue) {
9
+ * console.log(item);
10
+ * }
11
+ * }
12
+ * ```
13
+ */
14
+ export function isIterable(value) {
15
+ if (value == null || typeof value === 'string' || ArrayBuffer.isView(value)) {
16
+ return false;
17
+ }
18
+ if (Array.isArray(value)) {
19
+ return true;
20
+ }
21
+ return typeof Object(value)[Symbol.iterator] === 'function';
22
+ }
23
+ /**
24
+ * Type guard that checks if a value is async iterable (has Symbol.asyncIterator).
25
+ * @internal
26
+ *
27
+ * **Example usage:**
28
+ * ```ts
29
+ * if (isAsyncIterable(someValue)) {
30
+ * for await (const item of someValue) {
31
+ * console.log(item);
32
+ * }
33
+ * }
34
+ * ```
35
+ */
36
+ export function isAsyncIterable(value) {
37
+ if (value == null || typeof value === 'string' || ArrayBuffer.isView(value)) {
38
+ return false;
39
+ }
40
+ return typeof Object(value)[Symbol.asyncIterator] === 'function';
41
+ }
42
+ // Source - https://stackoverflow.com/a/71288323
43
+ /**
44
+ * Merges multiple async iterables into a single async iterable, yielding values concurrently.
45
+ *
46
+ * **Example usage:**
47
+ * ```ts
48
+ * const asyncIterable1 = async function* () {
49
+ * yield 1; yield 3; yield 5;
50
+ * };
51
+ *
52
+ * const asyncIterable2 = async function* () {
53
+ * yield 2; yield 4; yield 6;
54
+ * };
55
+ *
56
+ * for await (const value of mergeAsyncIterables(asyncIterable1(), asyncIterable2())) {
57
+ * console.log(value);
58
+ * }
59
+ * ```
60
+ */
61
+ export async function* mergeAsyncIterables(...iterables) {
62
+ const asyncIterators = iterables.map((iterable) => iterable[Symbol.asyncIterator]());
63
+ const results = [];
64
+ let count = asyncIterators.length;
65
+ const never = new Promise(() => { });
66
+ async function getNext(asyncIterator, index) {
67
+ const result = await asyncIterator.next();
68
+ return {
69
+ index,
70
+ result,
71
+ };
72
+ }
73
+ const nextPromises = asyncIterators.map(getNext);
74
+ try {
75
+ while (count) {
76
+ const { index, result } = await Promise.race(nextPromises);
77
+ if (result.done) {
78
+ nextPromises[index] = never;
79
+ results[index] = result.value;
80
+ count--;
81
+ }
82
+ else {
83
+ nextPromises[index] = getNext(asyncIterators[index], index);
84
+ yield result.value;
85
+ }
86
+ }
87
+ }
88
+ finally {
89
+ for (const [index, iterator] of asyncIterators.entries()) {
90
+ // no await here - see https://github.com/tc39/proposal-async-iteration/issues/126
91
+ if (nextPromises[index] !== never && iterator.return != null)
92
+ void iterator.return();
93
+ }
94
+ }
95
+ return results;
96
+ }
@@ -14,7 +14,6 @@ type OpenGraphResult = string | string[] | Dictionary<string | Dictionary>;
14
14
  * Currently existing properties are kept up to date.
15
15
  * @returns Scraped OpenGraph properties as an object.
16
16
  */
17
- export declare function parseOpenGraph(raw: string, additionalProperties?: OpenGraphProperty[]): Dictionary<OpenGraphResult>;
18
- export declare function parseOpenGraph($: CheerioAPI, additionalProperties?: OpenGraphProperty[]): Dictionary<OpenGraphResult>;
17
+ export declare function parseOpenGraph(raw: string, additionalProperties?: OpenGraphProperty[]): Promise<Dictionary<OpenGraphResult>>;
18
+ export declare function parseOpenGraph($: CheerioAPI, additionalProperties?: OpenGraphProperty[]): Promise<Dictionary<OpenGraphResult>>;
19
19
  export {};
20
- //# sourceMappingURL=open_graph_parser.d.ts.map
@@ -1,4 +1,3 @@
1
- import { load } from 'cheerio';
2
1
  /**
3
2
  * To be used with the spread operator. Ensures that the item is defined, and is not empty.
4
3
  *
@@ -255,32 +254,32 @@ const OPEN_GRAPH_PROPERTIES = [
255
254
  outputName: 'articleInfo',
256
255
  children: [
257
256
  {
258
- name: 'music:published_time',
257
+ name: 'article:published_time',
259
258
  outputName: 'publishedTime',
260
259
  children: [],
261
260
  },
262
261
  {
263
- name: 'music:modified_time',
262
+ name: 'article:modified_time',
264
263
  outputName: 'modifiedTime',
265
264
  children: [],
266
265
  },
267
266
  {
268
- name: 'music:expiration_time',
267
+ name: 'article:expiration_time',
269
268
  outputName: 'expirationTime',
270
269
  children: [],
271
270
  },
272
271
  {
273
- name: 'music:author',
272
+ name: 'article:author',
274
273
  outputName: 'author',
275
274
  children: [],
276
275
  },
277
276
  {
278
- name: 'music:section',
277
+ name: 'article:section',
279
278
  outputName: 'section',
280
279
  children: [],
281
280
  },
282
281
  {
283
- name: 'music:tag',
282
+ name: 'article:tag',
284
283
  outputName: 'tag',
285
284
  children: [],
286
285
  },
@@ -366,7 +365,8 @@ const parseOpenGraphProperty = (property, $) => {
366
365
  }, {}),
367
366
  };
368
367
  };
369
- export function parseOpenGraph(item, additionalProperties) {
368
+ export async function parseOpenGraph(item, additionalProperties) {
369
+ const { load } = await import('cheerio');
370
370
  const $ = typeof item === 'string' ? load(item) : item;
371
371
  return [...(additionalProperties || []), ...OPEN_GRAPH_PROPERTIES].reduce((acc, curr) => {
372
372
  return {
@@ -375,4 +375,3 @@ export function parseOpenGraph(item, additionalProperties) {
375
375
  };
376
376
  }, {});
377
377
  }
378
- //# sourceMappingURL=open_graph_parser.js.map
@@ -1,3 +1,4 @@
1
+ import type { BaseHttpClient, CrawleeLogger } from '@crawlee/types';
1
2
  import { Sitemap } from './sitemap.js';
2
3
  /**
3
4
  * Loads and queries information from a [robots.txt file](https://en.wikipedia.org/wiki/Robots.txt).
@@ -20,13 +21,23 @@ import { Sitemap } from './sitemap.js';
20
21
  export declare class RobotsTxtFile {
21
22
  private robots;
22
23
  private proxyUrl?;
24
+ private logger?;
23
25
  private constructor();
24
26
  /**
25
27
  * Determine the location of a robots.txt file for a URL and fetch it.
26
28
  * @param url the URL to fetch robots.txt for
27
- * @param [proxyUrl] a proxy to be used for fetching the robots.txt file
29
+ * @param [options] additional options
30
+ * @param [options.signal] an AbortSignal to cancel the request
31
+ * @param [options.timeoutMillis] timeout in milliseconds for the request
32
+ * @param [options.proxyUrl] a proxy to be used for fetching the robots.txt file
28
33
  */
29
- static find(url: string, proxyUrl?: string): Promise<RobotsTxtFile>;
34
+ static find(url: string, options?: {
35
+ signal?: AbortSignal;
36
+ timeoutMillis?: number;
37
+ proxyUrl?: string;
38
+ httpClient?: BaseHttpClient;
39
+ logger?: CrawleeLogger;
40
+ }): Promise<RobotsTxtFile>;
30
41
  /**
31
42
  * Allows providing the URL and robots.txt content explicitly instead of loading it from the target site.
32
43
  * @param url the URL for robots.txt file
@@ -34,7 +45,7 @@ export declare class RobotsTxtFile {
34
45
  * @param [proxyUrl] a proxy to be used for fetching the robots.txt file
35
46
  */
36
47
  static from(url: string, content: string, proxyUrl?: string): RobotsTxtFile;
37
- protected static load(url: string, proxyUrl?: string): Promise<RobotsTxtFile>;
48
+ private static load;
38
49
  /**
39
50
  * Check if a URL should be crawled by robots.
40
51
  * @param url the URL to check against the rules in robots.txt
@@ -54,5 +65,3 @@ export declare class RobotsTxtFile {
54
65
  */
55
66
  parseUrlsFromSitemaps(): Promise<string[]>;
56
67
  }
57
- export { RobotsTxtFile as RobotsFile };
58
- //# sourceMappingURL=robots.d.ts.map