@crawlee/core 4.0.0-beta.8 → 4.0.0-beta.80
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/README.md +17 -13
- package/autoscaling/autoscaled_pool.d.ts +5 -6
- package/autoscaling/autoscaled_pool.js +12 -11
- package/autoscaling/client_load_signal.d.ts +25 -0
- package/autoscaling/client_load_signal.js +36 -0
- package/autoscaling/cpu_load_signal.d.ts +28 -0
- package/autoscaling/cpu_load_signal.js +24 -0
- package/autoscaling/event_loop_load_signal.d.ts +23 -0
- package/autoscaling/event_loop_load_signal.js +35 -0
- package/autoscaling/index.d.ts +5 -1
- package/autoscaling/index.js +5 -1
- package/autoscaling/load_signal.d.ts +99 -0
- package/autoscaling/load_signal.js +135 -0
- package/autoscaling/memory_load_signal.d.ts +43 -0
- package/autoscaling/memory_load_signal.js +102 -0
- package/autoscaling/snapshotter.d.ts +35 -72
- package/autoscaling/snapshotter.js +78 -181
- package/autoscaling/system_status.d.ts +21 -36
- package/autoscaling/system_status.js +46 -84
- package/configuration.d.ts +88 -228
- package/configuration.js +162 -224
- package/cookie_utils.d.ts +4 -3
- package/cookie_utils.js +20 -13
- package/crawlers/context_pipeline.d.ts +70 -0
- package/crawlers/context_pipeline.js +122 -0
- package/crawlers/crawler_commons.d.ts +20 -30
- package/crawlers/crawler_commons.js +12 -21
- package/crawlers/crawler_utils.d.ts +2 -3
- package/crawlers/crawler_utils.js +1 -2
- package/crawlers/error_snapshotter.d.ts +3 -3
- package/crawlers/error_snapshotter.js +2 -3
- package/crawlers/error_tracker.d.ts +2 -2
- package/crawlers/error_tracker.js +0 -1
- package/crawlers/index.d.ts +1 -2
- package/crawlers/index.js +1 -2
- package/crawlers/internals/types.d.ts +7 -0
- package/crawlers/internals/types.js +1 -0
- package/crawlers/statistics.d.ts +22 -17
- package/crawlers/statistics.js +30 -26
- package/enqueue_links/enqueue_links.d.ts +44 -22
- package/enqueue_links/enqueue_links.js +51 -30
- package/enqueue_links/index.d.ts +0 -1
- package/enqueue_links/index.js +0 -1
- package/enqueue_links/shared.d.ts +25 -9
- package/enqueue_links/shared.js +69 -38
- package/errors.d.ts +53 -4
- package/errors.js +70 -5
- package/events/event_manager.d.ts +34 -8
- package/events/event_manager.js +8 -10
- package/events/index.d.ts +0 -1
- package/events/index.js +0 -1
- package/events/local_event_manager.d.ts +15 -5
- package/events/local_event_manager.js +37 -40
- package/index.d.ts +4 -3
- package/index.js +3 -2
- package/log.d.ts +82 -3
- package/log.js +102 -1
- package/memory-storage/consts.d.ts +4 -0
- package/memory-storage/consts.js +4 -0
- package/memory-storage/index.d.ts +1 -0
- package/memory-storage/index.js +1 -0
- package/memory-storage/memory-storage.d.ts +46 -0
- package/memory-storage/memory-storage.js +136 -0
- package/memory-storage/resource-clients/common/base-client.d.ts +4 -0
- package/memory-storage/resource-clients/common/base-client.js +6 -0
- package/memory-storage/resource-clients/dataset.d.ts +40 -0
- package/memory-storage/resource-clients/dataset.js +113 -0
- package/memory-storage/resource-clients/key-value-store.d.ts +63 -0
- package/memory-storage/resource-clients/key-value-store.js +203 -0
- package/memory-storage/resource-clients/request-queue.d.ts +96 -0
- package/memory-storage/resource-clients/request-queue.js +421 -0
- package/memory-storage/utils.d.ts +17 -0
- package/memory-storage/utils.js +42 -0
- package/package.json +12 -10
- package/proxy_configuration.d.ts +14 -149
- package/proxy_configuration.js +19 -168
- package/recoverable_state.d.ts +120 -0
- package/recoverable_state.js +141 -0
- package/request.d.ts +84 -13
- package/request.js +107 -28
- package/router.d.ts +117 -15
- package/router.js +124 -30
- package/serialization.d.ts +0 -1
- package/serialization.js +1 -2
- package/service_locator.d.ts +156 -0
- package/service_locator.js +238 -0
- package/session_pool/consts.d.ts +1 -2
- package/session_pool/consts.js +1 -2
- package/session_pool/errors.d.ts +0 -1
- package/session_pool/errors.js +0 -1
- package/session_pool/fingerprint.d.ts +9 -0
- package/session_pool/fingerprint.js +30 -0
- package/session_pool/index.d.ts +0 -2
- package/session_pool/index.js +0 -2
- package/session_pool/session.d.ts +35 -73
- package/session_pool/session.js +46 -99
- package/session_pool/session_pool.d.ts +71 -72
- package/session_pool/session_pool.js +111 -100
- package/storages/access_checking.d.ts +0 -1
- package/storages/access_checking.js +5 -2
- package/storages/dataset.d.ts +101 -51
- package/storages/dataset.js +168 -126
- package/storages/index.d.ts +8 -7
- package/storages/index.js +6 -7
- package/storages/key_value_store.d.ts +165 -36
- package/storages/key_value_store.js +269 -122
- package/storages/key_value_store_codec.d.ts +32 -0
- package/storages/key_value_store_codec.js +113 -0
- package/storages/request_dedup_cache.d.ts +23 -0
- package/storages/request_dedup_cache.js +48 -0
- package/storages/request_list.d.ts +38 -82
- package/storages/request_list.js +65 -41
- package/storages/request_loader.d.ts +96 -0
- package/storages/request_loader.js +1 -0
- package/storages/request_manager.d.ts +33 -0
- package/storages/request_manager.js +1 -0
- package/storages/request_manager_tandem.d.ts +106 -0
- package/storages/request_manager_tandem.js +197 -0
- package/storages/request_queue.d.ts +303 -46
- package/storages/request_queue.js +629 -214
- package/storages/{sitemap_request_list.d.ts → sitemap_request_loader.d.ts} +28 -24
- package/storages/{sitemap_request_list.js → sitemap_request_loader.js} +49 -46
- package/storages/storage_instance_manager.d.ts +91 -0
- package/storages/storage_instance_manager.js +258 -0
- package/storages/storage_stats.d.ts +48 -0
- package/storages/storage_stats.js +29 -0
- package/storages/utils.d.ts +51 -6
- package/storages/utils.js +60 -9
- package/system-info/cpu-info.d.ts +67 -0
- package/system-info/cpu-info.js +216 -0
- package/system-info/memory-info.d.ts +31 -0
- package/system-info/memory-info.js +115 -0
- package/system-info/ps-tree.d.ts +17 -0
- package/system-info/ps-tree.js +144 -0
- package/system-info/runtime.d.ts +14 -0
- package/system-info/runtime.js +80 -0
- package/typedefs.d.ts +1 -2
- package/typedefs.js +0 -1
- package/validators.d.ts +8 -1
- package/validators.js +8 -1
- package/autoscaling/autoscaled_pool.d.ts.map +0 -1
- package/autoscaling/autoscaled_pool.js.map +0 -1
- package/autoscaling/index.d.ts.map +0 -1
- package/autoscaling/index.js.map +0 -1
- package/autoscaling/snapshotter.d.ts.map +0 -1
- package/autoscaling/snapshotter.js.map +0 -1
- package/autoscaling/system_status.d.ts.map +0 -1
- package/autoscaling/system_status.js.map +0 -1
- package/configuration.d.ts.map +0 -1
- package/configuration.js.map +0 -1
- package/cookie_utils.d.ts.map +0 -1
- package/cookie_utils.js.map +0 -1
- package/crawlers/crawler_commons.d.ts.map +0 -1
- package/crawlers/crawler_commons.js.map +0 -1
- package/crawlers/crawler_extension.d.ts +0 -12
- package/crawlers/crawler_extension.d.ts.map +0 -1
- package/crawlers/crawler_extension.js +0 -14
- package/crawlers/crawler_extension.js.map +0 -1
- package/crawlers/crawler_utils.d.ts.map +0 -1
- package/crawlers/crawler_utils.js.map +0 -1
- package/crawlers/error_snapshotter.d.ts.map +0 -1
- package/crawlers/error_snapshotter.js.map +0 -1
- package/crawlers/error_tracker.d.ts.map +0 -1
- package/crawlers/error_tracker.js.map +0 -1
- package/crawlers/index.d.ts.map +0 -1
- package/crawlers/index.js.map +0 -1
- package/crawlers/statistics.d.ts.map +0 -1
- package/crawlers/statistics.js.map +0 -1
- package/enqueue_links/enqueue_links.d.ts.map +0 -1
- package/enqueue_links/enqueue_links.js.map +0 -1
- package/enqueue_links/index.d.ts.map +0 -1
- package/enqueue_links/index.js.map +0 -1
- package/enqueue_links/shared.d.ts.map +0 -1
- package/enqueue_links/shared.js.map +0 -1
- package/errors.d.ts.map +0 -1
- package/errors.js.map +0 -1
- package/events/event_manager.d.ts.map +0 -1
- package/events/event_manager.js.map +0 -1
- package/events/index.d.ts.map +0 -1
- package/events/index.js.map +0 -1
- package/events/local_event_manager.d.ts.map +0 -1
- package/events/local_event_manager.js.map +0 -1
- package/http_clients/base-http-client.d.ts +0 -134
- package/http_clients/base-http-client.d.ts.map +0 -1
- package/http_clients/base-http-client.js +0 -33
- package/http_clients/base-http-client.js.map +0 -1
- package/http_clients/form-data-like.d.ts +0 -67
- package/http_clients/form-data-like.d.ts.map +0 -1
- package/http_clients/form-data-like.js +0 -5
- package/http_clients/form-data-like.js.map +0 -1
- package/http_clients/got-scraping-http-client.d.ts +0 -15
- package/http_clients/got-scraping-http-client.d.ts.map +0 -1
- package/http_clients/got-scraping-http-client.js +0 -69
- package/http_clients/got-scraping-http-client.js.map +0 -1
- package/http_clients/index.d.ts +0 -3
- package/http_clients/index.d.ts.map +0 -1
- package/http_clients/index.js +0 -3
- package/http_clients/index.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/index.js.map +0 -1
- package/log.d.ts.map +0 -1
- package/log.js.map +0 -1
- package/proxy_configuration.d.ts.map +0 -1
- package/proxy_configuration.js.map +0 -1
- package/request.d.ts.map +0 -1
- package/request.js.map +0 -1
- package/router.d.ts.map +0 -1
- package/router.js.map +0 -1
- package/serialization.d.ts.map +0 -1
- package/serialization.js.map +0 -1
- package/session_pool/consts.d.ts.map +0 -1
- package/session_pool/consts.js.map +0 -1
- package/session_pool/errors.d.ts.map +0 -1
- package/session_pool/errors.js.map +0 -1
- package/session_pool/events.d.ts +0 -3
- package/session_pool/events.d.ts.map +0 -1
- package/session_pool/events.js +0 -3
- package/session_pool/events.js.map +0 -1
- package/session_pool/index.d.ts.map +0 -1
- package/session_pool/index.js.map +0 -1
- package/session_pool/session.d.ts.map +0 -1
- package/session_pool/session.js.map +0 -1
- package/session_pool/session_pool.d.ts.map +0 -1
- package/session_pool/session_pool.js.map +0 -1
- package/storages/access_checking.d.ts.map +0 -1
- package/storages/access_checking.js.map +0 -1
- package/storages/dataset.d.ts.map +0 -1
- package/storages/dataset.js.map +0 -1
- package/storages/index.d.ts.map +0 -1
- package/storages/index.js.map +0 -1
- package/storages/key_value_store.d.ts.map +0 -1
- package/storages/key_value_store.js.map +0 -1
- package/storages/request_list.d.ts.map +0 -1
- package/storages/request_list.js.map +0 -1
- package/storages/request_provider.d.ts +0 -307
- package/storages/request_provider.d.ts.map +0 -1
- package/storages/request_provider.js +0 -555
- package/storages/request_provider.js.map +0 -1
- package/storages/request_queue.d.ts.map +0 -1
- package/storages/request_queue.js.map +0 -1
- package/storages/request_queue_v2.d.ts +0 -87
- package/storages/request_queue_v2.d.ts.map +0 -1
- package/storages/request_queue_v2.js +0 -438
- package/storages/request_queue_v2.js.map +0 -1
- package/storages/sitemap_request_list.d.ts.map +0 -1
- package/storages/sitemap_request_list.js.map +0 -1
- package/storages/storage_manager.d.ts +0 -58
- package/storages/storage_manager.d.ts.map +0 -1
- package/storages/storage_manager.js +0 -105
- package/storages/storage_manager.js.map +0 -1
- package/storages/utils.d.ts.map +0 -1
- package/storages/utils.js.map +0 -1
- package/tsconfig.build.tsbuildinfo +0 -1
- package/typedefs.d.ts.map +0 -1
- package/typedefs.js.map +0 -1
- package/validators.d.ts.map +0 -1
- package/validators.js.map +0 -1
package/crawlers/statistics.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import ow from 'ow';
|
|
2
|
-
import {
|
|
3
|
-
import { log as defaultLog } from '../log.js';
|
|
2
|
+
import { serviceLocator } from '../service_locator.js';
|
|
4
3
|
import { KeyValueStore } from '../storages/key_value_store.js';
|
|
5
4
|
import { ErrorTracker } from './error_tracker.js';
|
|
6
5
|
/**
|
|
@@ -30,7 +29,7 @@ const errorTrackerConfig = {
|
|
|
30
29
|
* statistics for requests.
|
|
31
30
|
*
|
|
32
31
|
* All statistic information is saved on key value store
|
|
33
|
-
* under the key `
|
|
32
|
+
* under the key `CRAWLEE_CRAWLER_STATISTICS_*`, persists between
|
|
34
33
|
* migrations and abort/resurrect
|
|
35
34
|
*
|
|
36
35
|
* @category Crawlers
|
|
@@ -48,7 +47,7 @@ export class Statistics {
|
|
|
48
47
|
/**
|
|
49
48
|
* Statistic instance id.
|
|
50
49
|
*/
|
|
51
|
-
id
|
|
50
|
+
id;
|
|
52
51
|
/**
|
|
53
52
|
* Current statistic state used for doing calculations on {@link Statistics.calculate} calls
|
|
54
53
|
*/
|
|
@@ -57,12 +56,8 @@ export class Statistics {
|
|
|
57
56
|
* Contains the current retries histogram. Index 0 means 0 retries, index 2, 2 retries, and so on
|
|
58
57
|
*/
|
|
59
58
|
requestRetryHistogram = [];
|
|
60
|
-
/**
|
|
61
|
-
* Contains the associated Configuration instance
|
|
62
|
-
*/
|
|
63
|
-
config;
|
|
64
59
|
keyValueStore = undefined;
|
|
65
|
-
persistStateKey
|
|
60
|
+
persistStateKey;
|
|
66
61
|
logIntervalMillis;
|
|
67
62
|
logMessage;
|
|
68
63
|
listener;
|
|
@@ -70,8 +65,14 @@ export class Statistics {
|
|
|
70
65
|
log;
|
|
71
66
|
instanceStart;
|
|
72
67
|
logInterval;
|
|
73
|
-
|
|
68
|
+
_events;
|
|
74
69
|
persistenceOptions;
|
|
70
|
+
get events() {
|
|
71
|
+
if (!this._events) {
|
|
72
|
+
this._events = serviceLocator.getEventManager();
|
|
73
|
+
}
|
|
74
|
+
return this._events;
|
|
75
|
+
}
|
|
75
76
|
/**
|
|
76
77
|
* @internal
|
|
77
78
|
*/
|
|
@@ -81,22 +82,22 @@ export class Statistics {
|
|
|
81
82
|
logMessage: ow.optional.string,
|
|
82
83
|
log: ow.optional.object,
|
|
83
84
|
keyValueStore: ow.optional.object,
|
|
84
|
-
config: ow.optional.object,
|
|
85
85
|
persistenceOptions: ow.optional.object,
|
|
86
86
|
saveErrorSnapshots: ow.optional.boolean,
|
|
87
|
+
id: ow.optional.any(ow.number, ow.string),
|
|
87
88
|
}));
|
|
88
|
-
const { logIntervalSecs = 60, logMessage = 'Statistics', keyValueStore,
|
|
89
|
+
const { logIntervalSecs = 60, logMessage = 'Statistics', keyValueStore, persistenceOptions = {
|
|
89
90
|
enable: true,
|
|
90
|
-
}, saveErrorSnapshots = false, } = options;
|
|
91
|
-
this.
|
|
91
|
+
}, saveErrorSnapshots = false, id, } = options;
|
|
92
|
+
this.id = id ?? String(Statistics.id++);
|
|
93
|
+
this.persistStateKey = `CRAWLEE_CRAWLER_STATISTICS_${this.id}`;
|
|
94
|
+
this.log = (options.log ?? serviceLocator.getLogger()).child({ prefix: 'Statistics' });
|
|
92
95
|
this.errorTracker = new ErrorTracker({ ...errorTrackerConfig, saveErrorSnapshots });
|
|
93
96
|
this.errorTrackerRetry = new ErrorTracker({ ...errorTrackerConfig, saveErrorSnapshots });
|
|
94
97
|
this.logIntervalMillis = logIntervalSecs * 1000;
|
|
95
98
|
this.logMessage = logMessage;
|
|
96
99
|
this.keyValueStore = keyValueStore;
|
|
97
100
|
this.listener = this.persistState.bind(this);
|
|
98
|
-
this.events = config.getEventManager();
|
|
99
|
-
this.config = config;
|
|
100
101
|
this.persistenceOptions = persistenceOptions;
|
|
101
102
|
// initialize by "resetting"
|
|
102
103
|
this.reset();
|
|
@@ -194,6 +195,14 @@ export class Statistics {
|
|
|
194
195
|
this._saveRetryCountForJob(retryCount);
|
|
195
196
|
this.requestsInProgress.delete(id);
|
|
196
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Discards a started job without affecting the finished/failed counters, e.g. when a request
|
|
200
|
+
* turns out to be skipped (robots.txt, enqueue strategy) after `startJob` was already called for it.
|
|
201
|
+
* @ignore
|
|
202
|
+
*/
|
|
203
|
+
discardJob(id) {
|
|
204
|
+
this.requestsInProgress.delete(id);
|
|
205
|
+
}
|
|
197
206
|
/**
|
|
198
207
|
* Calculate the current statistics
|
|
199
208
|
*/
|
|
@@ -216,7 +225,7 @@ export class Statistics {
|
|
|
216
225
|
* displaying the current state in predefined intervals
|
|
217
226
|
*/
|
|
218
227
|
async startCapturing() {
|
|
219
|
-
this.keyValueStore ??= await KeyValueStore.open(null, { config:
|
|
228
|
+
this.keyValueStore ??= await KeyValueStore.open(null, { config: serviceLocator.getConfiguration() });
|
|
220
229
|
if (this.state.crawlerStartedAt === null) {
|
|
221
230
|
this.state.crawlerStartedAt = new Date();
|
|
222
231
|
}
|
|
@@ -258,14 +267,8 @@ export class Statistics {
|
|
|
258
267
|
return;
|
|
259
268
|
}
|
|
260
269
|
this.log.debug('Persisting state', { persistStateKey: this.persistStateKey });
|
|
261
|
-
// use half the interval of `persistState` to avoid race conditions
|
|
262
|
-
const persistStateIntervalMillis = this.config.get('persistStateIntervalMillis');
|
|
263
|
-
const timeoutSecs = persistStateIntervalMillis / 2_000;
|
|
264
270
|
await this.keyValueStore
|
|
265
|
-
.setValue(this.persistStateKey, this.toJSON()
|
|
266
|
-
timeoutSecs,
|
|
267
|
-
doNotRetryTimeouts: true,
|
|
268
|
-
})
|
|
271
|
+
.setValue(this.persistStateKey, this.toJSON())
|
|
269
272
|
.catch((error) => this.log.warning(`Failed to persist the statistics to ${this.persistStateKey}`, { error }));
|
|
270
273
|
}
|
|
271
274
|
/**
|
|
@@ -308,7 +311,9 @@ export class Statistics {
|
|
|
308
311
|
}
|
|
309
312
|
_teardown() {
|
|
310
313
|
// this can be called before a call to startCapturing happens (or in a 'finally' block)
|
|
311
|
-
|
|
314
|
+
// Only unsubscribe if event manager was already resolved — avoid eagerly resolving it
|
|
315
|
+
// (e.g. during the constructor's reset() call, which would capture the wrong context)
|
|
316
|
+
this._events?.off("persistState" /* EventType.PERSIST_STATE */, this.listener);
|
|
312
317
|
if (this.logInterval) {
|
|
313
318
|
clearInterval(this.logInterval);
|
|
314
319
|
this.logInterval = null;
|
|
@@ -343,4 +348,3 @@ export class Statistics {
|
|
|
343
348
|
return result;
|
|
344
349
|
}
|
|
345
350
|
}
|
|
346
|
-
//# sourceMappingURL=statistics.js.map
|
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { BatchAddRequestsResult, Dictionary } from '@crawlee/types';
|
|
2
2
|
import { type RobotsTxtFile } from '@crawlee/utils';
|
|
3
3
|
import type { SetRequired } from 'type-fest';
|
|
4
|
-
import
|
|
5
|
-
import type {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
reason: 'robotsTxt';
|
|
9
|
-
}) => Awaitable<void>;
|
|
4
|
+
import { Request } from '../request.js';
|
|
5
|
+
import type { IRequestManager } from '../storages/request_manager.js';
|
|
6
|
+
import type { AddRequestsBatchedOptions, AddRequestsBatchedResult, RequestQueueOperationOptions } from '../storages/request_queue.js';
|
|
7
|
+
import type { GlobInput, PseudoUrlInput, RegExpInput, RequestTransform, SkippedRequestCallback } from './shared.js';
|
|
10
8
|
export interface EnqueueLinksOptions extends RequestQueueOperationOptions {
|
|
11
9
|
/** Limit the amount of actually enqueued URLs to this number. Useful for testing across the entire crawling scope. */
|
|
12
10
|
limit?: number;
|
|
13
11
|
/** An array of URLs to enqueue. */
|
|
14
12
|
urls?: readonly string[];
|
|
15
|
-
/** A request
|
|
16
|
-
|
|
13
|
+
/** A request manager to which the URLs will be enqueued. */
|
|
14
|
+
requestManager?: IRequestManager;
|
|
17
15
|
/** A CSS selector matching links to be enqueued. */
|
|
18
16
|
selector?: string;
|
|
19
17
|
/** Sets {@link Request.userData} for newly enqueued requests. */
|
|
20
18
|
userData?: Dictionary;
|
|
21
|
-
/**
|
|
19
|
+
/**
|
|
20
|
+
* Sets {@link Request.label} for newly enqueued requests.
|
|
21
|
+
*
|
|
22
|
+
* This option has the lowest priority and can be overwritten by request options
|
|
23
|
+
* specified in `globs`, `regexps`, or `pseudoUrls` objects, as well as by `transformRequestFunction`.
|
|
24
|
+
*/
|
|
22
25
|
label?: string;
|
|
26
|
+
/** Sets {@link Request.sessionId} for newly enqueued requests. */
|
|
27
|
+
sessionId?: string;
|
|
23
28
|
/**
|
|
24
29
|
* If set to `true`, tells the crawler to skip navigation and process the request directly.
|
|
25
30
|
* @default false
|
|
@@ -49,7 +54,6 @@ export interface EnqueueLinksOptions extends RequestQueueOperationOptions {
|
|
|
49
54
|
* containing patterns matching URLs that will **never** be enqueued.
|
|
50
55
|
*
|
|
51
56
|
* The plain objects must include either the `glob` property or the `regexp` property.
|
|
52
|
-
* All remaining keys will be used as request options for the corresponding enqueued {@link Request} objects.
|
|
53
57
|
*
|
|
54
58
|
* Glob matching is always case-insensitive.
|
|
55
59
|
* If you need case-sensitive matching, provide a regexp.
|
|
@@ -86,12 +90,12 @@ export interface EnqueueLinksOptions extends RequestQueueOperationOptions {
|
|
|
86
90
|
*/
|
|
87
91
|
pseudoUrls?: readonly PseudoUrlInput[];
|
|
88
92
|
/**
|
|
89
|
-
*
|
|
90
|
-
* to remove
|
|
93
|
+
* After request options are filtered by patterns, this function can be used
|
|
94
|
+
* to remove them or modify their contents such as `userData`, `payload` or, most importantly `uniqueKey`. This is useful
|
|
91
95
|
* when you need to enqueue multiple `Requests` to the queue that share the same URL, but differ in methods or payloads,
|
|
92
96
|
* or to dynamically update or create `userData`.
|
|
93
97
|
*
|
|
94
|
-
* For example: by adding `keepUrlFragment: true` to the
|
|
98
|
+
* For example: by adding `keepUrlFragment: true` to the request options, URL fragments will not be removed
|
|
95
99
|
* when `uniqueKey` is computed.
|
|
96
100
|
*
|
|
97
101
|
* **Example:**
|
|
@@ -105,9 +109,13 @@ export interface EnqueueLinksOptions extends RequestQueueOperationOptions {
|
|
|
105
109
|
* }
|
|
106
110
|
* ```
|
|
107
111
|
*
|
|
108
|
-
* Note that `transformRequestFunction` has
|
|
109
|
-
* specified in `globs`, `regexps`, or `pseudoUrls` objects,
|
|
110
|
-
*
|
|
112
|
+
* Note that `transformRequestFunction` has the highest priority and can overwrite request options
|
|
113
|
+
* specified in `globs`, `regexps`, or `pseudoUrls` objects, as well as the global `label` option.
|
|
114
|
+
*
|
|
115
|
+
* The function receives a {@link RequestOptions} object and can return either:
|
|
116
|
+
* - The modified {@link RequestOptions} object
|
|
117
|
+
* - `'unchanged'` to keep the original options as-is
|
|
118
|
+
* - A falsy value or `'skip'` to exclude the request from the queue
|
|
111
119
|
*/
|
|
112
120
|
transformRequestFunction?: RequestTransform;
|
|
113
121
|
/**
|
|
@@ -138,10 +146,21 @@ export interface EnqueueLinksOptions extends RequestQueueOperationOptions {
|
|
|
138
146
|
* RobotsTxtFile instance for the current request that triggered the `enqueueLinks`.
|
|
139
147
|
* If provided, disallowed URLs will be ignored.
|
|
140
148
|
*/
|
|
141
|
-
robotsTxtFile?: RobotsTxtFile
|
|
149
|
+
robotsTxtFile?: Pick<RobotsTxtFile, 'isAllowed'>;
|
|
150
|
+
/**
|
|
151
|
+
* Mirrors {@link BasicCrawlerOptions.respectRobotsTxtFile}: pass `false` to disable filtering or
|
|
152
|
+
* `{ userAgent }` to evaluate rules for a specific user-agent. Defaults to `*` when
|
|
153
|
+
* {@link EnqueueLinksOptions.robotsTxtFile|`robotsTxtFile`} is provided.
|
|
154
|
+
*/
|
|
155
|
+
respectRobotsTxtFile?: boolean | {
|
|
156
|
+
userAgent?: string;
|
|
157
|
+
};
|
|
142
158
|
/**
|
|
143
159
|
* When a request is skipped for some reason, you can use this callback to act on it.
|
|
144
|
-
* This is currently fired
|
|
160
|
+
* This is currently fired for requests skipped
|
|
161
|
+
* 1. based on robots.txt file,
|
|
162
|
+
* 2. because they don't match enqueueLinks filters,
|
|
163
|
+
* 3. or because the maxRequestsPerCrawl limit has been reached
|
|
145
164
|
*/
|
|
146
165
|
onSkippedRequest?: SkippedRequestCallback;
|
|
147
166
|
}
|
|
@@ -208,7 +227,7 @@ export declare enum EnqueueStrategy {
|
|
|
208
227
|
* ```javascript
|
|
209
228
|
* await enqueueLinks({
|
|
210
229
|
* urls: aListOfFoundUrls,
|
|
211
|
-
*
|
|
230
|
+
* requestManager,
|
|
212
231
|
* selector: 'a.product-detail',
|
|
213
232
|
* globs: [
|
|
214
233
|
* 'https://www.example.com/handbags/*',
|
|
@@ -220,7 +239,11 @@ export declare enum EnqueueStrategy {
|
|
|
220
239
|
* @param options All `enqueueLinks()` parameters are passed via an options object.
|
|
221
240
|
* @returns Promise that resolves to {@link BatchAddRequestsResult} object.
|
|
222
241
|
*/
|
|
223
|
-
export declare function enqueueLinks(options: SetRequired<EnqueueLinksOptions, '
|
|
242
|
+
export declare function enqueueLinks(options: SetRequired<Omit<EnqueueLinksOptions, 'requestManager'>, 'urls'> & {
|
|
243
|
+
requestManager: {
|
|
244
|
+
addRequestsBatched: (requests: Request<Dictionary>[], options: AddRequestsBatchedOptions) => Promise<AddRequestsBatchedResult>;
|
|
245
|
+
};
|
|
246
|
+
}): Promise<BatchAddRequestsResult>;
|
|
224
247
|
/**
|
|
225
248
|
* @internal
|
|
226
249
|
* This method helps resolve the baseUrl that will be used for filtering in {@link enqueueLinks}.
|
|
@@ -239,4 +262,3 @@ export interface ResolveBaseUrl {
|
|
|
239
262
|
originalRequestUrl: string;
|
|
240
263
|
finalRequestUrl?: string;
|
|
241
264
|
}
|
|
242
|
-
//# sourceMappingURL=enqueue_links.d.ts.map
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import ow from 'ow';
|
|
2
2
|
import { getDomain } from 'tldts';
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
3
|
+
import { Request } from '../request.js';
|
|
4
|
+
import { serviceLocator } from '../service_locator.js';
|
|
5
|
+
import { applyRequestTransform, constructGlobObjectsFromGlobs, constructRegExpObjectsFromPseudoUrls, constructRegExpObjectsFromRegExps, createRequestOptions, filterRequestOptionsByPatterns, } from './shared.js';
|
|
5
6
|
/**
|
|
6
7
|
* The different enqueueing strategies available.
|
|
7
8
|
*
|
|
@@ -66,7 +67,7 @@ export var EnqueueStrategy;
|
|
|
66
67
|
* ```javascript
|
|
67
68
|
* await enqueueLinks({
|
|
68
69
|
* urls: aListOfFoundUrls,
|
|
69
|
-
*
|
|
70
|
+
* requestManager,
|
|
70
71
|
* selector: 'a.product-detail',
|
|
71
72
|
* globs: [
|
|
72
73
|
* 'https://www.example.com/handbags/*',
|
|
@@ -87,11 +88,13 @@ export async function enqueueLinks(options) {
|
|
|
87
88
|
}
|
|
88
89
|
ow(options, ow.object.exactShape({
|
|
89
90
|
urls: ow.array.ofType(ow.string),
|
|
90
|
-
|
|
91
|
+
requestManager: ow.object.hasKeys('addRequestsBatched'),
|
|
91
92
|
robotsTxtFile: ow.optional.object.hasKeys('isAllowed'),
|
|
93
|
+
respectRobotsTxtFile: ow.optional.any(ow.boolean, ow.object.exactShape({ userAgent: ow.optional.string })),
|
|
92
94
|
onSkippedRequest: ow.optional.function,
|
|
93
95
|
forefront: ow.optional.boolean,
|
|
94
96
|
skipNavigation: ow.optional.boolean,
|
|
97
|
+
sessionId: ow.optional.string,
|
|
95
98
|
limit: ow.optional.number,
|
|
96
99
|
selector: ow.optional.string,
|
|
97
100
|
baseUrl: ow.optional.string,
|
|
@@ -105,7 +108,9 @@ export async function enqueueLinks(options) {
|
|
|
105
108
|
strategy: ow.optional.string.oneOf(Object.values(EnqueueStrategy)),
|
|
106
109
|
waitForAllRequestsToBeAdded: ow.optional.boolean,
|
|
107
110
|
}));
|
|
108
|
-
const {
|
|
111
|
+
const { requestManager, limit, urls,
|
|
112
|
+
// oxlint-disable-next-line typescript/no-deprecated -- still accepted for backwards compat
|
|
113
|
+
pseudoUrls, exclude, globs, regexps, transformRequestFunction, forefront, waitForAllRequestsToBeAdded, robotsTxtFile, onSkippedRequest, } = options;
|
|
109
114
|
const urlExcludePatternObjects = [];
|
|
110
115
|
const urlPatternObjects = [];
|
|
111
116
|
if (exclude?.length) {
|
|
@@ -119,7 +124,7 @@ export async function enqueueLinks(options) {
|
|
|
119
124
|
}
|
|
120
125
|
}
|
|
121
126
|
if (pseudoUrls?.length) {
|
|
122
|
-
|
|
127
|
+
serviceLocator.getLogger().deprecated('`pseudoUrls` option is deprecated, use `globs` or `regexps` instead');
|
|
123
128
|
urlPatternObjects.push(...constructRegExpObjectsFromPseudoUrls(pseudoUrls));
|
|
124
129
|
}
|
|
125
130
|
if (globs?.length) {
|
|
@@ -167,44 +172,61 @@ export async function enqueueLinks(options) {
|
|
|
167
172
|
break;
|
|
168
173
|
}
|
|
169
174
|
}
|
|
175
|
+
async function reportSkippedRequests(skippedRequests, reason) {
|
|
176
|
+
if (onSkippedRequest && skippedRequests.length > 0) {
|
|
177
|
+
await Promise.all(skippedRequests.map((request) => {
|
|
178
|
+
return onSkippedRequest({
|
|
179
|
+
url: request.url,
|
|
180
|
+
reason: request.skippedReason ?? reason,
|
|
181
|
+
});
|
|
182
|
+
}));
|
|
183
|
+
}
|
|
184
|
+
}
|
|
170
185
|
let requestOptions = createRequestOptions(urls, options);
|
|
171
|
-
if (robotsTxtFile) {
|
|
186
|
+
if (robotsTxtFile && options.respectRobotsTxtFile !== false) {
|
|
187
|
+
const robotsUserAgent = typeof options.respectRobotsTxtFile === 'object' ? (options.respectRobotsTxtFile.userAgent ?? '*') : '*';
|
|
172
188
|
const skippedRequests = [];
|
|
173
189
|
requestOptions = requestOptions.filter((request) => {
|
|
174
|
-
if (robotsTxtFile.isAllowed(request.url)) {
|
|
190
|
+
if (robotsTxtFile.isAllowed(request.url, robotsUserAgent)) {
|
|
175
191
|
return true;
|
|
176
192
|
}
|
|
177
193
|
skippedRequests.push(request);
|
|
178
194
|
return false;
|
|
179
195
|
});
|
|
180
|
-
|
|
181
|
-
await Promise.all(skippedRequests.map((request) => {
|
|
182
|
-
return onSkippedRequest({ url: request.url, reason: 'robotsTxt' });
|
|
183
|
-
}));
|
|
184
|
-
}
|
|
196
|
+
await reportSkippedRequests(skippedRequests, 'robotsTxt');
|
|
185
197
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
function createFilteredRequests() {
|
|
192
|
-
// No user provided patterns means we can skip an extra filtering step
|
|
198
|
+
async function createFilteredRequests() {
|
|
199
|
+
const skippedRequests = [];
|
|
200
|
+
// Step 1: Filter request options by exclude patterns, user patterns (globs/regexps), and strategy patterns.
|
|
201
|
+
// Pattern-level options (label, userData, method, etc.) are merged during this step.
|
|
202
|
+
let filteredOptions;
|
|
193
203
|
if (urlPatternObjects.length === 0) {
|
|
194
|
-
|
|
204
|
+
filteredOptions = filterRequestOptionsByPatterns(requestOptions, enqueueStrategyPatterns.length > 0 ? enqueueStrategyPatterns : undefined, urlExcludePatternObjects, options.strategy, (url) => skippedRequests.push(url));
|
|
195
205
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
206
|
+
else {
|
|
207
|
+
// Filter by user patterns first (with exclude)
|
|
208
|
+
const afterUserPatterns = filterRequestOptionsByPatterns(requestOptions, urlPatternObjects, urlExcludePatternObjects, options.strategy, (url) => skippedRequests.push(url));
|
|
209
|
+
// ...then filter by the enqueue links strategy (making this an AND check)
|
|
210
|
+
filteredOptions = filterRequestOptionsByPatterns(afterUserPatterns, enqueueStrategyPatterns.length > 0 ? enqueueStrategyPatterns : undefined, [], options.strategy, (url) => skippedRequests.push(url));
|
|
211
|
+
}
|
|
212
|
+
await reportSkippedRequests(skippedRequests.map((url) => ({ url })), 'filters');
|
|
213
|
+
// Step 2: Apply transformRequestFunction on request options - it has the highest priority
|
|
214
|
+
if (transformRequestFunction) {
|
|
215
|
+
const skippedByTransform = [];
|
|
216
|
+
filteredOptions = applyRequestTransform(filteredOptions, transformRequestFunction, (r) => skippedByTransform.push(r));
|
|
217
|
+
await reportSkippedRequests(skippedByTransform, 'transform');
|
|
218
|
+
}
|
|
219
|
+
// Step 3: Create Request instances from the final request options
|
|
220
|
+
return filteredOptions.map((opts) => new Request(opts));
|
|
200
221
|
}
|
|
201
|
-
|
|
202
|
-
if (limit)
|
|
203
|
-
requests = requests.slice(0, limit);
|
|
204
|
-
const { addedRequests } = await requestQueue.addRequestsBatched(requests, {
|
|
222
|
+
const { addedRequests, requestsOverLimit } = await requestManager.addRequestsBatched(await createFilteredRequests(), {
|
|
205
223
|
forefront,
|
|
206
224
|
waitForAllRequestsToBeAdded,
|
|
225
|
+
maxNewRequests: limit,
|
|
207
226
|
});
|
|
227
|
+
if (requestsOverLimit?.length !== undefined && requestsOverLimit.length > 0) {
|
|
228
|
+
await reportSkippedRequests(requestsOverLimit.map((r) => ({ url: typeof r === 'string' ? r : r.url })), 'enqueueLimit');
|
|
229
|
+
}
|
|
208
230
|
return { processedRequests: addedRequests, unprocessedRequests: [] };
|
|
209
231
|
}
|
|
210
232
|
/**
|
|
@@ -247,4 +269,3 @@ export function resolveBaseUrlForEnqueueLinksFiltering({ enqueueStrategy, finalR
|
|
|
247
269
|
function ignoreHttpSchema(pattern) {
|
|
248
270
|
return pattern.replace(/^(https?):\/\//, 'http{s,}://');
|
|
249
271
|
}
|
|
250
|
-
//# sourceMappingURL=enqueue_links.js.map
|
package/enqueue_links/index.d.ts
CHANGED
package/enqueue_links/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import type { Awaitable } from '@crawlee/types';
|
|
1
2
|
import type { RequestOptions } from '../request.js';
|
|
2
|
-
import { Request } from '../request.js';
|
|
3
3
|
import type { EnqueueLinksOptions } from './enqueue_links.js';
|
|
4
4
|
export { tryAbsoluteURL } from '@crawlee/utils';
|
|
5
5
|
export type UrlPatternObject = {
|
|
@@ -18,6 +18,11 @@ export type RegExpObject = {
|
|
|
18
18
|
regexp: RegExp;
|
|
19
19
|
} & Pick<RequestOptions, 'method' | 'payload' | 'label' | 'userData' | 'headers'>;
|
|
20
20
|
export type RegExpInput = RegExp | RegExpObject;
|
|
21
|
+
export type SkippedRequestReason = 'robotsTxt' | 'limit' | 'enqueueLimit' | 'filters' | 'transform' | 'redirect' | 'depth';
|
|
22
|
+
export type SkippedRequestCallback = (args: {
|
|
23
|
+
url: string;
|
|
24
|
+
reason: SkippedRequestReason;
|
|
25
|
+
}) => Awaitable<void>;
|
|
21
26
|
/**
|
|
22
27
|
* @ignore
|
|
23
28
|
*/
|
|
@@ -45,23 +50,34 @@ export declare function validateGlobPattern(glob: string): string;
|
|
|
45
50
|
*/
|
|
46
51
|
export declare function constructRegExpObjectsFromRegExps(regexps: readonly RegExpInput[]): RegExpObject[];
|
|
47
52
|
/**
|
|
53
|
+
* Filters request options by URL patterns and merges pattern-level options (label, userData, method, payload, headers)
|
|
54
|
+
* from the first matching pattern into each RequestOptions entry.
|
|
55
|
+
*
|
|
56
|
+
* When `includePatterns` is empty/undefined, all options pass through (only exclude filtering applies).
|
|
48
57
|
* @ignore
|
|
49
58
|
*/
|
|
50
|
-
export declare function
|
|
51
|
-
export declare function filterRequestsByPatterns(requests: Request[], patterns?: UrlPatternObject[]): Request[];
|
|
59
|
+
export declare function filterRequestOptionsByPatterns(requestOptions: RequestOptions[], includePatterns: UrlPatternObject[] | undefined, excludePatterns?: UrlPatternObject[], strategy?: EnqueueLinksOptions['strategy'], onSkippedUrl?: (url: string) => void): RequestOptions[];
|
|
52
60
|
/**
|
|
53
61
|
* @ignore
|
|
54
62
|
*/
|
|
55
|
-
export declare function createRequestOptions(sources: readonly (string | Record<string, unknown>)[], options?: Pick<EnqueueLinksOptions, 'label' | 'userData' | 'baseUrl' | 'skipNavigation' | 'strategy'>): RequestOptions[];
|
|
63
|
+
export declare function createRequestOptions(sources: readonly (string | Record<string, unknown>)[], options?: Pick<EnqueueLinksOptions, 'label' | 'userData' | 'baseUrl' | 'skipNavigation' | 'sessionId' | 'strategy'>): RequestOptions[];
|
|
56
64
|
/**
|
|
57
|
-
* Takes
|
|
58
|
-
* {@link enqueueLinks} to modify
|
|
65
|
+
* Takes a {@link RequestOptions} object and changes its attributes in a desired way. This user-function is used
|
|
66
|
+
* by {@link enqueueLinks} to modify request options before they are converted to {@link Request} instances.
|
|
59
67
|
*/
|
|
60
68
|
export interface RequestTransform {
|
|
61
69
|
/**
|
|
62
70
|
* @param original Request options to be modified.
|
|
63
|
-
* @returns The modified request options to enqueue
|
|
71
|
+
* @returns The modified request options to enqueue, `'unchanged'` to keep the original options as-is,
|
|
72
|
+
* or a falsy value / `'skip'` to exclude the request from the queue.
|
|
64
73
|
*/
|
|
65
|
-
(original: RequestOptions): RequestOptions | false | undefined | null;
|
|
74
|
+
(original: RequestOptions): RequestOptions | false | undefined | null | 'skip' | 'unchanged';
|
|
66
75
|
}
|
|
67
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Applies a {@link RequestTransform} function to a list of request options.
|
|
78
|
+
* Options for which the transform returns a falsy value are removed from the list.
|
|
79
|
+
* @param onSkipped Called with the original request options when the transform returns a falsy value (i.e. the request is skipped).
|
|
80
|
+
* @ignore
|
|
81
|
+
* @internal
|
|
82
|
+
*/
|
|
83
|
+
export declare function applyRequestTransform(requestOptions: RequestOptions[], transformFn: RequestTransform, onSkipped?: (requestOptions: RequestOptions) => void): RequestOptions[];
|
package/enqueue_links/shared.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { URL } from 'node:url';
|
|
2
|
-
import {
|
|
2
|
+
import { Minimatch } from 'minimatch';
|
|
3
3
|
import { purlToRegExp } from '@apify/pseudo_url';
|
|
4
|
-
import { Request } from '../request.js';
|
|
5
4
|
export { tryAbsoluteURL } from '@crawlee/utils';
|
|
6
5
|
const MAX_ENQUEUE_LINKS_CACHE_SIZE = 1000;
|
|
7
6
|
/**
|
|
@@ -110,51 +109,37 @@ export function constructRegExpObjectsFromRegExps(regexps) {
|
|
|
110
109
|
});
|
|
111
110
|
}
|
|
112
111
|
/**
|
|
112
|
+
* Filters request options by URL patterns and merges pattern-level options (label, userData, method, payload, headers)
|
|
113
|
+
* from the first matching pattern into each RequestOptions entry.
|
|
114
|
+
*
|
|
115
|
+
* When `includePatterns` is empty/undefined, all options pass through (only exclude filtering applies).
|
|
113
116
|
* @ignore
|
|
114
117
|
*/
|
|
115
|
-
export function
|
|
118
|
+
export function filterRequestOptionsByPatterns(requestOptions, includePatterns, excludePatterns = [], strategy, onSkippedUrl) {
|
|
119
|
+
const excludeMatchers = excludePatterns.map(createPatternObjectMatcher);
|
|
120
|
+
const includeMatchers = includePatterns?.length ? includePatterns.map(createPatternObjectMatcher) : undefined;
|
|
116
121
|
return requestOptions
|
|
117
|
-
.map((opts) => ({ url: typeof opts === 'string' ? opts : opts.url, opts }))
|
|
118
122
|
.filter(({ url }) => {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
+
const matchesExclude = excludeMatchers.some(({ match }) => match(url));
|
|
124
|
+
if (matchesExclude) {
|
|
125
|
+
onSkippedUrl?.(url);
|
|
126
|
+
}
|
|
127
|
+
return !matchesExclude;
|
|
123
128
|
})
|
|
124
|
-
.map((
|
|
125
|
-
if (!
|
|
126
|
-
return
|
|
127
|
-
}
|
|
128
|
-
for (const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const request = typeof opts === 'string'
|
|
132
|
-
? { url: opts, ...requestRegExpOptions, enqueueStrategy: strategy }
|
|
133
|
-
: { ...opts, ...requestRegExpOptions, enqueueStrategy: strategy };
|
|
134
|
-
return new Request(request);
|
|
129
|
+
.map((opts) => {
|
|
130
|
+
if (!includeMatchers) {
|
|
131
|
+
return { ...opts, enqueueStrategy: strategy };
|
|
132
|
+
}
|
|
133
|
+
for (const { match, glob, regexp, ...patternOptions } of includeMatchers) {
|
|
134
|
+
if (match(opts.url)) {
|
|
135
|
+
return { ...opts, ...patternOptions, enqueueStrategy: strategy };
|
|
135
136
|
}
|
|
136
137
|
}
|
|
137
138
|
// didn't match any positive pattern
|
|
139
|
+
onSkippedUrl?.(opts.url);
|
|
138
140
|
return null;
|
|
139
141
|
})
|
|
140
|
-
.filter((
|
|
141
|
-
}
|
|
142
|
-
export function filterRequestsByPatterns(requests, patterns) {
|
|
143
|
-
if (!patterns?.length) {
|
|
144
|
-
return requests;
|
|
145
|
-
}
|
|
146
|
-
const filtered = [];
|
|
147
|
-
for (const request of requests) {
|
|
148
|
-
for (const urlPatternObject of patterns) {
|
|
149
|
-
const { regexp, glob } = urlPatternObject;
|
|
150
|
-
if ((regexp && request.url.match(regexp)) || (glob && minimatch(request.url, glob, { nocase: true }))) {
|
|
151
|
-
filtered.push(request);
|
|
152
|
-
// Break the pattern loop, as we already matched this request once
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
return filtered;
|
|
142
|
+
.filter((opts) => opts !== null);
|
|
158
143
|
}
|
|
159
144
|
/**
|
|
160
145
|
* @ignore
|
|
@@ -184,7 +169,53 @@ export function createRequestOptions(sources, options = {}) {
|
|
|
184
169
|
if (options.skipNavigation) {
|
|
185
170
|
requestOptions.skipNavigation = true;
|
|
186
171
|
}
|
|
172
|
+
if (options.sessionId) {
|
|
173
|
+
requestOptions.sessionId = options.sessionId;
|
|
174
|
+
}
|
|
187
175
|
return requestOptions;
|
|
188
176
|
});
|
|
189
177
|
}
|
|
190
|
-
|
|
178
|
+
/**
|
|
179
|
+
* @ignore
|
|
180
|
+
*/
|
|
181
|
+
function createPatternObjectMatcher(urlPatternObject) {
|
|
182
|
+
const { regexp, glob } = urlPatternObject;
|
|
183
|
+
let match;
|
|
184
|
+
if (regexp) {
|
|
185
|
+
match = (url) => regexp.test(url);
|
|
186
|
+
}
|
|
187
|
+
else if (glob) {
|
|
188
|
+
const m = new Minimatch(glob, { nocase: true });
|
|
189
|
+
match = (url) => m.match(url);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
match = () => false;
|
|
193
|
+
}
|
|
194
|
+
return { ...urlPatternObject, match };
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Applies a {@link RequestTransform} function to a list of request options.
|
|
198
|
+
* Options for which the transform returns a falsy value are removed from the list.
|
|
199
|
+
* @param onSkipped Called with the original request options when the transform returns a falsy value (i.e. the request is skipped).
|
|
200
|
+
* @ignore
|
|
201
|
+
* @internal
|
|
202
|
+
*/
|
|
203
|
+
export function applyRequestTransform(requestOptions, transformFn, onSkipped) {
|
|
204
|
+
return requestOptions
|
|
205
|
+
.map((opts) => {
|
|
206
|
+
const transformed = transformFn(opts);
|
|
207
|
+
if (transformed === 'skip') {
|
|
208
|
+
onSkipped?.(opts);
|
|
209
|
+
return null;
|
|
210
|
+
}
|
|
211
|
+
if (transformed === 'unchanged') {
|
|
212
|
+
return opts;
|
|
213
|
+
}
|
|
214
|
+
if (!transformed) {
|
|
215
|
+
onSkipped?.(opts);
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
return transformed;
|
|
219
|
+
})
|
|
220
|
+
.filter((r) => r !== null);
|
|
221
|
+
}
|