@crawlee/utils 4.0.0-beta.121 → 4.0.0-beta.123

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 CHANGED
@@ -6,3 +6,4 @@ export * as social from './internals/social.js';
6
6
  export * from './internals/open_graph_parser.js';
7
7
  export * from './internals/robots.js';
8
8
  export * from './internals/sitemap.js';
9
+ export * from './internals/validation.js';
package/index.js CHANGED
@@ -5,3 +5,4 @@ export * as social from './internals/social.js';
5
5
  export * from './internals/open_graph_parser.js';
6
6
  export * from './internals/robots.js';
7
7
  export * from './internals/sitemap.js';
8
+ export * from './internals/validation.js';
package/internal.d.ts CHANGED
@@ -5,3 +5,5 @@ export { tryAbsoluteURL } from './internals/extract-urls.js';
5
5
  export { URL_NO_COMMAS_REGEX, URL_WITH_COMMAS_REGEX } from './internals/general.js';
6
6
  export * from './internals/iterables.js';
7
7
  export * from './internals/url.js';
8
+ export * from './internals/validation.js';
9
+ export * as schemas from './internals/schemas.js';
package/internal.js CHANGED
@@ -4,3 +4,5 @@ export { tryAbsoluteURL } from './internals/extract-urls.js';
4
4
  export { URL_NO_COMMAS_REGEX, URL_WITH_COMMAS_REGEX } from './internals/general.js';
5
5
  export * from './internals/iterables.js';
6
6
  export * from './internals/url.js';
7
+ export * from './internals/validation.js';
8
+ export * as schemas from './internals/schemas.js';
@@ -1,4 +1,4 @@
1
- import type { BaseHttpClient } from '@crawlee/types';
1
+ import type { BaseHttpClient } from '@crawlee/http-client';
2
2
  export interface DownloadListOfUrlsOptions {
3
3
  /**
4
4
  * URL to the file
@@ -1,19 +1,25 @@
1
1
  import { FetchHttpClient } from '@crawlee/http-client';
2
- import ow from 'ow';
2
+ import { z } from 'zod';
3
3
  import { URL_NO_COMMAS_REGEX } from './general.js';
4
+ import { httpClient as httpClientSchema } from './schemas.js';
5
+ import { parseArgument } from './validation.js';
6
+ const downloadListOfUrlsOptionsSchema = z.strictObject({
7
+ url: z.url(),
8
+ encoding: z.string().default('utf8'),
9
+ urlRegExp: z.instanceof(RegExp).default(URL_NO_COMMAS_REGEX),
10
+ proxyUrl: z.string().optional(),
11
+ httpClient: httpClientSchema.default(() => new FetchHttpClient()),
12
+ });
13
+ const extractUrlsOptionsSchema = z.strictObject({
14
+ string: z.string(),
15
+ urlRegExp: z.instanceof(RegExp).default(URL_NO_COMMAS_REGEX),
16
+ });
4
17
  /**
5
18
  * Returns a promise that resolves to an array of urls parsed from the resource available at the provided url.
6
19
  * Optionally, custom regular expression and encoding may be provided.
7
20
  */
8
21
  export async function downloadListOfUrls(options) {
9
- ow(options, ow.object.exactShape({
10
- url: ow.string.url,
11
- encoding: ow.optional.string,
12
- urlRegExp: ow.optional.regExp,
13
- proxyUrl: ow.optional.string,
14
- httpClient: ow.optional.object,
15
- }));
16
- const { url, encoding = 'utf8', urlRegExp = URL_NO_COMMAS_REGEX, proxyUrl, httpClient = new FetchHttpClient(), } = options;
22
+ const { url, encoding, urlRegExp, proxyUrl, httpClient } = parseArgument(options, downloadListOfUrlsOptionsSchema);
17
23
  // Try to detect wrong urls and fix them. Currently, detects only sharing url instead of csv download one.
18
24
  const match = /^(https:\/\/docs\.google\.com\/spreadsheets\/d\/(?:\w|-)+)\/?/.exec(url);
19
25
  let fixedUrl = url;
@@ -30,13 +36,9 @@ export async function downloadListOfUrls(options) {
30
36
  * Collects all URLs in an arbitrary string to an array, optionally using a custom regular expression.
31
37
  */
32
38
  export function extractUrls(options) {
33
- ow(options, ow.object.exactShape({
34
- string: ow.string,
35
- urlRegExp: ow.optional.regExp,
36
- }));
37
- const lines = options.string.split('\n');
39
+ const { string, urlRegExp } = parseArgument(options, extractUrlsOptionsSchema);
40
+ const lines = string.split('\n');
38
41
  const result = [];
39
- const urlRegExp = options.urlRegExp ?? URL_NO_COMMAS_REGEX;
40
42
  for (const line of lines) {
41
43
  result.push(...(line.match(urlRegExp) ?? []));
42
44
  }
@@ -1,4 +1,5 @@
1
- import type { BaseHttpClient, CrawleeLogger } from '@crawlee/types';
1
+ import type { BaseHttpClient } from '@crawlee/http-client';
2
+ import type { CrawleeLogger } from '@crawlee/types';
2
3
  import { Sitemap } from './sitemap.js';
3
4
  /**
4
5
  * Loads and queries information from a [robots.txt file](https://en.wikipedia.org/wiki/Robots.txt).
@@ -0,0 +1,114 @@
1
+ import { BaseHttpClient } from '@crawlee/http-client';
2
+ import type { Dictionary } from '@crawlee/types';
3
+ import { z } from 'zod';
4
+ /**
5
+ * Accepts any object (including arrays and functions).
6
+ * @internal
7
+ */
8
+ export declare const anyObject: z.ZodCustom<Dictionary, Dictionary>;
9
+ /**
10
+ * Accepts any array without validating its items (cheap for huge arrays).
11
+ * @internal
12
+ */
13
+ export declare const anyArray: z.ZodCustom<unknown[], unknown[]>;
14
+ /**
15
+ * Accepts any function.
16
+ * @internal
17
+ */
18
+ export declare const anyFunction: z.ZodCustom<(...args: any[]) => unknown, (...args: any[]) => unknown>;
19
+ /**
20
+ * Mirrors `ow.number`: `Infinity` is a valid number, `NaN` is not.
21
+ * @internal
22
+ */
23
+ export declare const anyNumber: z.ZodCustom<number, number>;
24
+ /**
25
+ * Accepts any object (including functions) that has all the given keys, own or inherited.
26
+ * @internal
27
+ */
28
+ export declare function objectWithKeys(keys: string[], message?: string): z.ZodType<Dictionary>;
29
+ /**
30
+ * Accepts only instances of {@link BaseHttpClient} (all Crawlee HTTP clients extend it).
31
+ * @internal
32
+ */
33
+ export declare const httpClient: z.ZodCustom<BaseHttpClient, BaseHttpClient>;
34
+ /**
35
+ * Accepts any object implementing the CrawleeLogger interface.
36
+ * @internal
37
+ */
38
+ export declare const logger: z.ZodType<Dictionary, unknown, z.core.$ZodTypeInternals<Dictionary, unknown>>;
39
+ /**
40
+ * Accepts any typed array (`Uint8Array`, `Float64Array`, ...), but not a `DataView`.
41
+ * @internal
42
+ */
43
+ export declare const typedArray: z.ZodCustom<NodeJS.TypedArray<ArrayBufferLike>, NodeJS.TypedArray<ArrayBufferLike>>;
44
+ /**
45
+ * Accepts any non-null, non-array object.
46
+ * @internal
47
+ */
48
+ export declare const plainObject: z.ZodCustom<Record<string, unknown>, Record<string, unknown>>;
49
+ /**
50
+ * Shape of a request stored in a request queue.
51
+ * @internal
52
+ */
53
+ export declare const storageRequest: z.ZodObject<{
54
+ id: z.ZodString;
55
+ url: z.ZodURL;
56
+ uniqueKey: z.ZodString;
57
+ method: z.ZodOptional<z.ZodString>;
58
+ retryCount: z.ZodOptional<z.ZodNumber>;
59
+ handledAt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodDate]>>;
60
+ }, z.core.$loose>;
61
+ /**
62
+ * {@link storageRequest} before an id is assigned.
63
+ * @internal
64
+ */
65
+ export declare const storageRequestWithoutId: z.ZodObject<{
66
+ url: z.ZodURL;
67
+ uniqueKey: z.ZodString;
68
+ method: z.ZodOptional<z.ZodString>;
69
+ retryCount: z.ZodOptional<z.ZodNumber>;
70
+ handledAt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodDate]>>;
71
+ }, z.core.$loose>;
72
+ /**
73
+ * `z.array(item)` whose top-level type error names the element type — ``expected an array of numbers`` —
74
+ * instead of zod's bare `expected array`. Element failures keep zod's per-index messages, and `elements`
75
+ * is a human-readable plural (`'numbers'`, `'URL patterns'`), since element types cannot be introspected.
76
+ * @internal
77
+ */
78
+ export declare function arrayOf<TItem extends z.ZodType>(item: TItem, elements: string): z.ZodArray<TItem>;
79
+ /**
80
+ * Batch of {@link storageRequestWithoutId}.
81
+ * @internal
82
+ */
83
+ export declare const storageRequestBatch: z.ZodArray<z.ZodObject<{
84
+ url: z.ZodURL;
85
+ uniqueKey: z.ZodString;
86
+ method: z.ZodOptional<z.ZodString>;
87
+ retryCount: z.ZodOptional<z.ZodNumber>;
88
+ handledAt: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodDate]>>;
89
+ }, z.core.$loose>>;
90
+ /**
91
+ * Options of request queue add/update operations.
92
+ * @internal
93
+ */
94
+ export declare const requestQueueOperationOptions: z.ZodObject<{
95
+ forefront: z.ZodOptional<z.ZodBoolean>;
96
+ }, z.core.$strip>;
97
+ /**
98
+ * Options of key-value store `listKeys`.
99
+ * @internal
100
+ */
101
+ export declare const keyValueStoreListKeysOptions: z.ZodObject<{
102
+ prefix: z.ZodOptional<z.ZodString>;
103
+ exclusiveStartKey: z.ZodOptional<z.ZodString>;
104
+ limit: z.ZodOptional<z.ZodNumber>;
105
+ }, z.core.$strip>;
106
+ /**
107
+ * Options of dataset item listing.
108
+ * @internal
109
+ */
110
+ export declare const datasetListItemsOptions: z.ZodObject<{
111
+ desc: z.ZodOptional<z.ZodBoolean>;
112
+ limit: z.ZodOptional<z.ZodNumber>;
113
+ offset: z.ZodOptional<z.ZodNumber>;
114
+ }, z.core.$strip>;
@@ -0,0 +1,114 @@
1
+ import { BaseHttpClient } from '@crawlee/http-client';
2
+ import { z } from 'zod';
3
+ /**
4
+ * Accepts any object (including arrays and functions).
5
+ * @internal
6
+ */
7
+ export const anyObject = z.custom((value) => (typeof value === 'object' && value !== null) || typeof value === 'function', { message: 'Invalid input: expected object' });
8
+ /**
9
+ * Accepts any array without validating its items (cheap for huge arrays).
10
+ * @internal
11
+ */
12
+ export const anyArray = z.custom(Array.isArray, { message: 'Invalid input: expected array' });
13
+ /**
14
+ * Accepts any function.
15
+ * @internal
16
+ */
17
+ export const anyFunction = z.custom((value) => typeof value === 'function', {
18
+ message: 'Invalid input: expected function',
19
+ });
20
+ /**
21
+ * Mirrors `ow.number`: `Infinity` is a valid number, `NaN` is not.
22
+ * @internal
23
+ */
24
+ export const anyNumber = z.custom((value) => typeof value === 'number' && !Number.isNaN(value), {
25
+ message: 'Invalid input: expected number',
26
+ });
27
+ /**
28
+ * Accepts any object (including functions) that has all the given keys, own or inherited.
29
+ * @internal
30
+ */
31
+ export function objectWithKeys(keys, message) {
32
+ return z.custom((value) => ((typeof value === 'object' && value !== null) || typeof value === 'function') &&
33
+ keys.every((key) => key in value), {
34
+ message: message ?? `Invalid input: expected an object with keys ${keys.map((key) => `'${key}'`).join(', ')}`,
35
+ });
36
+ }
37
+ /**
38
+ * Accepts only instances of {@link BaseHttpClient} (all Crawlee HTTP clients extend it).
39
+ * @internal
40
+ */
41
+ export const httpClient = z.instanceof(BaseHttpClient);
42
+ /**
43
+ * Accepts any object implementing the CrawleeLogger interface.
44
+ * @internal
45
+ */
46
+ export const logger = objectWithKeys(['child', 'info', 'error', 'warning'], "Expected an object implementing the CrawleeLogger interface (missing one of 'child', 'info', 'error', 'warning'), got something else.");
47
+ /**
48
+ * Accepts any typed array (`Uint8Array`, `Float64Array`, ...), but not a `DataView`.
49
+ * @internal
50
+ */
51
+ export const typedArray = z.custom((value) => ArrayBuffer.isView(value) && !(value instanceof DataView), { message: 'Invalid input: expected a typed array' });
52
+ /**
53
+ * Accepts any non-null, non-array object.
54
+ * @internal
55
+ */
56
+ export const plainObject = z.custom((value) => typeof value === 'object' && value !== null && !Array.isArray(value), { message: 'Invalid input: expected an object' });
57
+ /**
58
+ * Shape of a request stored in a request queue.
59
+ * @internal
60
+ */
61
+ export const storageRequest = z.looseObject({
62
+ id: z.string(),
63
+ url: z.url({ protocol: /^https?$/ }),
64
+ uniqueKey: z.string(),
65
+ method: z.string().optional(),
66
+ retryCount: z.number().int().optional(),
67
+ handledAt: z.union([z.string(), z.date()]).optional(),
68
+ });
69
+ /**
70
+ * {@link storageRequest} before an id is assigned.
71
+ * @internal
72
+ */
73
+ export const storageRequestWithoutId = storageRequest.omit({ id: true });
74
+ /**
75
+ * `z.array(item)` whose top-level type error names the element type — ``expected an array of numbers`` —
76
+ * instead of zod's bare `expected array`. Element failures keep zod's per-index messages, and `elements`
77
+ * is a human-readable plural (`'numbers'`, `'URL patterns'`), since element types cannot be introspected.
78
+ * @internal
79
+ */
80
+ export function arrayOf(item, elements) {
81
+ return z.array(item, {
82
+ error: (issue) => issue.code === 'invalid_type' ? `Invalid input: expected an array of ${elements}` : undefined,
83
+ });
84
+ }
85
+ /**
86
+ * Batch of {@link storageRequestWithoutId}.
87
+ * @internal
88
+ */
89
+ export const storageRequestBatch = arrayOf(storageRequestWithoutId, 'requests');
90
+ /**
91
+ * Options of request queue add/update operations.
92
+ * @internal
93
+ */
94
+ export const requestQueueOperationOptions = z.object({
95
+ forefront: z.boolean().optional(),
96
+ });
97
+ /**
98
+ * Options of key-value store `listKeys`.
99
+ * @internal
100
+ */
101
+ export const keyValueStoreListKeysOptions = z.object({
102
+ prefix: z.string().optional(),
103
+ exclusiveStartKey: z.string().optional(),
104
+ limit: z.number().int().gt(0).optional(),
105
+ });
106
+ /**
107
+ * Options of dataset item listing.
108
+ * @internal
109
+ */
110
+ export const datasetListItemsOptions = z.object({
111
+ desc: z.boolean().optional(),
112
+ limit: z.number().int().optional(),
113
+ offset: z.number().int().optional(),
114
+ });
@@ -1,4 +1,5 @@
1
- import type { BaseHttpClient, CrawleeLogger } from '@crawlee/types';
1
+ import type { BaseHttpClient } from '@crawlee/http-client';
2
+ import type { CrawleeLogger } from '@crawlee/types';
2
3
  interface SitemapUrlData {
3
4
  loc: string;
4
5
  lastmod?: Date;
@@ -0,0 +1,25 @@
1
+ import type { z } from 'zod';
2
+ /**
3
+ * Thrown when an argument fails schema validation.
4
+ *
5
+ * Its `message` is a human-readable sentence naming the offending field and the
6
+ * value it received (rather than a raw JSON dump). The structured
7
+ * {@link https://zod.dev | zod} issues are available on `issues`, and the
8
+ * original `ZodError` on `cause`, for programmatic inspection.
9
+ */
10
+ export declare class ArgumentValidationError extends Error {
11
+ /** Structured issues from the underlying schema check. */
12
+ readonly issues: z.ZodError['issues'];
13
+ /** The raw zod error that triggered this. */
14
+ readonly cause: z.ZodError;
15
+ constructor(error: z.ZodError, value: unknown, label?: string);
16
+ }
17
+ /**
18
+ * Parses `value` with `schema`, returning the typed result (with schema defaults applied).
19
+ * Throws {@link ArgumentValidationError} on failure.
20
+ *
21
+ * The optional `label` names the interface being validated and is appended to every error line
22
+ * (e.g. ``… at `maxRequestRetries` in `BasicCrawlerOptions` ``).
23
+ * @internal
24
+ */
25
+ export declare function parseArgument<TValue, TSchema extends z.ZodType>(value: TValue, schema: TSchema, label?: string): TValue & z.output<TSchema>;
@@ -0,0 +1,140 @@
1
+ /** Formats a zod issue path like `groups[0]` or `countryCode`. */
2
+ function formatIssuePath(path) {
3
+ let out = '';
4
+ for (const key of path) {
5
+ if (typeof key === 'number')
6
+ out += `[${key}]`;
7
+ else
8
+ out += out ? `.${String(key)}` : String(key);
9
+ }
10
+ return out;
11
+ }
12
+ /** Reads the value at `path` from the validated input, to include in the error. */
13
+ function valueAtPath(root, path) {
14
+ let current = root;
15
+ for (const key of path) {
16
+ if (current === null || typeof current !== 'object')
17
+ return undefined;
18
+ current = current[key];
19
+ }
20
+ return current;
21
+ }
22
+ /** Names the runtime type of `value` the way zod's own messages do (`null`, `array`, `string`, …). */
23
+ function describeType(value) {
24
+ if (value === null)
25
+ return 'null';
26
+ if (Array.isArray(value))
27
+ return 'array';
28
+ return typeof value;
29
+ }
30
+ /** The bare custom-schema messages that stop at the expected type, e.g. `Invalid input: expected number`. */
31
+ const BARE_EXPECTED_TYPE_MESSAGE = /^Invalid input: expected (an array of .+|a typed array|an object|object|array|function|number|string|boolean)$/;
32
+ /** Longest received string rendered in an error; the rest is elided. */
33
+ const MAX_RENDERED_STRING_LENGTH = 200;
34
+ /** Renders a primitive received value for an error; skips objects/Dates (noisy). */
35
+ function describeReceived(value) {
36
+ switch (typeof value) {
37
+ case 'string':
38
+ // An empty string would render as bare backticks — make it visible.
39
+ if (value === '')
40
+ return "''";
41
+ return value.length > MAX_RENDERED_STRING_LENGTH
42
+ ? `${value.slice(0, MAX_RENDERED_STRING_LENGTH)}… (${value.length - MAX_RENDERED_STRING_LENGTH} more characters)`
43
+ : value;
44
+ case 'number':
45
+ case 'boolean':
46
+ case 'bigint':
47
+ return String(value);
48
+ default:
49
+ return undefined;
50
+ }
51
+ }
52
+ /** Renders the received side of a sentence: ``received the string `abc` ``, `received NaN`, `received array`. */
53
+ function describeReceivedClause(value) {
54
+ if (typeof value === 'number' && Number.isNaN(value))
55
+ return 'received NaN';
56
+ if (value === '')
57
+ return 'received an empty string';
58
+ const rendered = describeReceived(value);
59
+ return rendered === undefined
60
+ ? `received ${describeType(value)}`
61
+ : `received the ${describeType(value)} \`${rendered}\``;
62
+ }
63
+ /** Renders one issue as a line each; a union expands into a line per failed arm. */
64
+ function formatIssue(issue, root, basePath) {
65
+ const path = [...basePath, ...issue.path];
66
+ // A union's own message is a bare "Invalid input" — the useful part is in `errors`,
67
+ // whose paths are relative to the union, hence passing `path` down as the base.
68
+ if (issue.code === 'invalid_union') {
69
+ return issue.errors.flatMap((arm) => arm.flatMap((nested) => formatIssue(nested, root, path)));
70
+ }
71
+ const location = path.length ? ` at \`${formatIssuePath(path)}\`` : '';
72
+ const value = valueAtPath(root, path);
73
+ const rendered = describeReceived(value);
74
+ // ow named the received type ("expected `number` but received type `string`"). The received value is
75
+ // folded into that clause (``received the string `3` ``) rather than dangling after the location: our
76
+ // custom schemas stop at the expected type, so the clause is appended; zod's built-in messages already
77
+ // end with `, received <type>`, so that tail is replaced with the enriched one.
78
+ let { message } = issue;
79
+ let got = '';
80
+ const bareExpected = BARE_EXPECTED_TYPE_MESSAGE.exec(message);
81
+ const zodReceived = /, received (\S+)$/.exec(message);
82
+ // `arrayOf` messages name the element type — their expected runtime type is `array`.
83
+ const expectedType = bareExpected?.[1].startsWith('an array of') ? 'array' : bareExpected?.[1];
84
+ if (bareExpected && expectedType !== (Number.isNaN(value) ? 'NaN' : describeType(value))) {
85
+ message += `, ${describeReceivedClause(value)}`;
86
+ }
87
+ else if (zodReceived && zodReceived[1] === describeType(value) && rendered !== undefined) {
88
+ message = `${message.slice(0, zodReceived.index)}, ${describeReceivedClause(value)}`;
89
+ }
90
+ else if (rendered !== undefined && !message.endsWith(`received ${rendered}`)) {
91
+ // Messages that never name a received type (regex, min/max, enums) keep the plain value suffix.
92
+ got = `, got \`${rendered}\``;
93
+ }
94
+ return [`${message}${location}${got}`];
95
+ }
96
+ /**
97
+ * Formats a `ZodError` as a plain, human-readable message that names the
98
+ * offending field *and* the value it received (e.g. ``must match pattern
99
+ * /^[A-Z]{2}$/ at `countryCode`, got `CZE` ``) — closer to the old `ow` errors
100
+ * than zod's default, which omits the received value.
101
+ */
102
+ function formatZodError(error, root, label) {
103
+ const lines = error.issues.flatMap((issue) => formatIssue(issue, root, []));
104
+ // The label names the validated interface, the way ow's errors ended with "in object `X`".
105
+ return (label ? lines.map((line) => `${line} in \`${label}\``) : lines).join('\n');
106
+ }
107
+ /**
108
+ * Thrown when an argument fails schema validation.
109
+ *
110
+ * Its `message` is a human-readable sentence naming the offending field and the
111
+ * value it received (rather than a raw JSON dump). The structured
112
+ * {@link https://zod.dev | zod} issues are available on `issues`, and the
113
+ * original `ZodError` on `cause`, for programmatic inspection.
114
+ */
115
+ export class ArgumentValidationError extends Error {
116
+ /** Structured issues from the underlying schema check. */
117
+ issues;
118
+ /** The raw zod error that triggered this. */
119
+ cause;
120
+ constructor(error, value, label) {
121
+ super(formatZodError(error, value, label), { cause: error });
122
+ this.name = 'ArgumentValidationError';
123
+ this.issues = error.issues;
124
+ this.cause = error;
125
+ }
126
+ }
127
+ /**
128
+ * Parses `value` with `schema`, returning the typed result (with schema defaults applied).
129
+ * Throws {@link ArgumentValidationError} on failure.
130
+ *
131
+ * The optional `label` names the interface being validated and is appended to every error line
132
+ * (e.g. ``… at `maxRequestRetries` in `BasicCrawlerOptions` ``).
133
+ * @internal
134
+ */
135
+ export function parseArgument(value, schema, label) {
136
+ const result = schema.safeParse(value);
137
+ if (!result.success)
138
+ throw new ArgumentValidationError(result.error, value, label);
139
+ return result.data;
140
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlee/utils",
3
- "version": "4.0.0-beta.121",
3
+ "version": "4.0.0-beta.123",
4
4
  "description": "A set of shared utilities that can be used by crawlers",
5
5
  "engines": {
6
6
  "node": ">=22.0.0"
@@ -43,17 +43,17 @@
43
43
  },
44
44
  "dependencies": {
45
45
  "@apify/ps-tree": "^1.2.0",
46
- "@crawlee/http-client": "4.0.0-beta.121",
47
- "@crawlee/types": "4.0.0-beta.121",
46
+ "@crawlee/http-client": "4.0.0-beta.123",
47
+ "@crawlee/types": "4.0.0-beta.123",
48
48
  "@types/sax": "^1.2.7",
49
49
  "cheerio": "^1.0.0",
50
50
  "domhandler": "^5.0.3",
51
51
  "file-type": "^21.0.0",
52
- "ow": "^2.0.0",
53
52
  "robots-parser": "^3.0.1",
54
53
  "sax": "^1.4.1",
55
54
  "tslib": "^2.8.1",
56
- "whatwg-mimetype": "^4.0.0"
55
+ "whatwg-mimetype": "^4.0.0",
56
+ "zod": "^4.4.3"
57
57
  },
58
58
  "lerna": {
59
59
  "command": {
@@ -62,5 +62,5 @@
62
62
  }
63
63
  }
64
64
  },
65
- "gitHead": "5027317de626f5ba6de5047ae9341a898258cc5a"
65
+ "gitHead": "f77648095c6a3f5ed8815c7620ea765db430ae44"
66
66
  }