@hanivanrizky/nestjs-browser-action 0.20.1 → 0.22.0

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 (75) hide show
  1. package/README.md +72 -31
  2. package/dist/browser-action.module-definition.d.ts +1 -0
  3. package/dist/browser-action.module.d.ts +3 -0
  4. package/dist/browser-action.module.js +146 -27
  5. package/dist/browser-action.module.js.map +1 -1
  6. package/dist/common/index.d.ts +1 -0
  7. package/dist/common/index.js +18 -0
  8. package/dist/common/index.js.map +1 -0
  9. package/dist/common/tokens.d.ts +7 -0
  10. package/dist/common/tokens.js +36 -0
  11. package/dist/common/tokens.js.map +1 -0
  12. package/dist/decorators/index.d.ts +1 -0
  13. package/dist/decorators/index.js +1 -0
  14. package/dist/decorators/index.js.map +1 -1
  15. package/dist/decorators/inject-browser.decorator.d.ts +2 -1
  16. package/dist/decorators/inject-browser.decorator.js +2 -1
  17. package/dist/decorators/inject-browser.decorator.js.map +1 -1
  18. package/dist/decorators/inject-page-controller.decorator.d.ts +2 -0
  19. package/dist/decorators/inject-page-controller.decorator.js +8 -0
  20. package/dist/decorators/inject-page-controller.decorator.js.map +1 -0
  21. package/dist/decorators/inject-page.decorator.d.ts +2 -1
  22. package/dist/decorators/inject-page.decorator.js +2 -1
  23. package/dist/decorators/inject-page.decorator.js.map +1 -1
  24. package/dist/examples/named-browser-example.d.ts +1 -0
  25. package/dist/examples/named-browser-example.js +183 -0
  26. package/dist/examples/named-browser-example.js.map +1 -0
  27. package/dist/index.d.ts +5 -0
  28. package/dist/index.js +5 -0
  29. package/dist/index.js.map +1 -1
  30. package/dist/interfaces/browser-action-options.d.ts +1 -0
  31. package/dist/operators/capture.operator.d.ts +11 -0
  32. package/dist/operators/capture.operator.js +62 -0
  33. package/dist/operators/capture.operator.js.map +1 -0
  34. package/dist/operators/container.operator.d.ts +13 -0
  35. package/dist/operators/container.operator.js +149 -0
  36. package/dist/operators/container.operator.js.map +1 -0
  37. package/dist/operators/extraction.operator.d.ts +22 -0
  38. package/dist/operators/extraction.operator.js +204 -0
  39. package/dist/operators/extraction.operator.js.map +1 -0
  40. package/dist/operators/index.d.ts +5 -0
  41. package/dist/operators/index.js +14 -0
  42. package/dist/operators/index.js.map +1 -0
  43. package/dist/operators/pagination.operator.d.ts +24 -0
  44. package/dist/operators/pagination.operator.js +182 -0
  45. package/dist/operators/pagination.operator.js.map +1 -0
  46. package/dist/operators/workflow.operator.d.ts +35 -0
  47. package/dist/operators/workflow.operator.js +501 -0
  48. package/dist/operators/workflow.operator.js.map +1 -0
  49. package/dist/services/browser-action.service.d.ts +10 -30
  50. package/dist/services/browser-action.service.js +72 -995
  51. package/dist/services/browser-action.service.js.map +1 -1
  52. package/dist/services/browser-holder.d.ts +7 -0
  53. package/dist/services/browser-holder.js +26 -0
  54. package/dist/services/browser-holder.js.map +1 -0
  55. package/dist/services/browser-manager.service.js +3 -2
  56. package/dist/services/browser-manager.service.js.map +1 -1
  57. package/dist/services/browser-pool.service.d.ts +4 -4
  58. package/dist/services/browser-pool.service.js +45 -104
  59. package/dist/services/browser-pool.service.js.map +1 -1
  60. package/dist/services/named-browser-shutdown.d.ts +9 -0
  61. package/dist/services/named-browser-shutdown.js +47 -0
  62. package/dist/services/named-browser-shutdown.js.map +1 -0
  63. package/dist/services/page-controller.d.ts +39 -0
  64. package/dist/services/page-controller.js +325 -0
  65. package/dist/services/page-controller.js.map +1 -0
  66. package/dist/services/page-session.d.ts +26 -0
  67. package/dist/services/page-session.js +135 -0
  68. package/dist/services/page-session.js.map +1 -0
  69. package/dist/services/page.service.js +14 -3
  70. package/dist/services/page.service.js.map +1 -1
  71. package/dist/tsconfig.build.tsbuildinfo +1 -1
  72. package/dist/utils/browser-launcher.d.ts +6 -0
  73. package/dist/utils/browser-launcher.js +100 -0
  74. package/dist/utils/browser-launcher.js.map +1 -0
  75. package/package.json +2 -2
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.NamedBrowserShutdown = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const tokens_1 = require("../common/tokens");
15
+ const browser_holder_1 = require("./browser-holder");
16
+ let NamedBrowserShutdown = class NamedBrowserShutdown {
17
+ name;
18
+ holder;
19
+ isRemote;
20
+ constructor(name, holder, isRemote) {
21
+ this.name = name;
22
+ this.holder = holder;
23
+ this.isRemote = isRemote;
24
+ }
25
+ async onApplicationShutdown() {
26
+ try {
27
+ const browser = this.holder.browser;
28
+ if (browser.connected) {
29
+ if (this.isRemote)
30
+ await browser.disconnect();
31
+ else
32
+ await browser.close();
33
+ }
34
+ }
35
+ catch {
36
+ }
37
+ finally {
38
+ (0, tokens_1.releaseBrowserName)(this.name);
39
+ }
40
+ }
41
+ };
42
+ exports.NamedBrowserShutdown = NamedBrowserShutdown;
43
+ exports.NamedBrowserShutdown = NamedBrowserShutdown = __decorate([
44
+ (0, common_1.Injectable)(),
45
+ __metadata("design:paramtypes", [String, browser_holder_1.BrowserHolder, Boolean])
46
+ ], NamedBrowserShutdown);
47
+ //# sourceMappingURL=named-browser-shutdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"named-browser-shutdown.js","sourceRoot":"","sources":["../../src/services/named-browser-shutdown.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAAmE;AACnE,6CAAsD;AACtD,qDAAiD;AAa1C,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAEZ;IACA;IACA;IAHnB,YACmB,IAAY,EACZ,MAAqB,EACrB,QAAiB;QAFjB,SAAI,GAAJ,IAAI,CAAQ;QACZ,WAAM,GAAN,MAAM,CAAe;QACrB,aAAQ,GAAR,QAAQ,CAAS;IACjC,CAAC;IAEJ,KAAK,CAAC,qBAAqB;QACzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;YACpC,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;gBACtB,IAAI,IAAI,CAAC,QAAQ;oBAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;;oBACzC,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;gBAAS,CAAC;YACT,IAAA,2BAAkB,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;CACF,CAAA;AApBY,oDAAoB;+BAApB,oBAAoB;IADhC,IAAA,mBAAU,GAAE;6CAIgB,8BAAa;GAH7B,oBAAoB,CAoBhC"}
@@ -0,0 +1,39 @@
1
+ import type { Browser, Page, ScreenshotOptions, PDFOptions } from 'puppeteer-core';
2
+ import { PageSession } from './page-session';
3
+ import type { NavigateOptions } from './page.service';
4
+ import { ExtractionOperator, CaptureOperator, ContainerOperator, WorkflowOperator, PaginationOperator } from '../operators';
5
+ import type { SelectorMap, ScraperOptions, ScrapeResult, ScrapeAllResult, WorkflowResultTyped, ContainerDescriptor, ContainerScrapeResult, EvaluateOptions, EvaluateResult } from '../interfaces/types';
6
+ import type { WorkflowDefinition, VariableContext } from '../interfaces/workflow-options';
7
+ import type { TlsFingerprint } from '../interfaces/tls-fingerprint';
8
+ import { LoggerWithLevel } from '../utils/logger.util';
9
+ export type ControllerScraperOptions = Omit<ScraperOptions, 'cloak' | 'useRandomUserAgent'>;
10
+ export declare class PageController {
11
+ private readonly session;
12
+ private readonly extraction;
13
+ private readonly container;
14
+ private readonly workflow;
15
+ private readonly pagination;
16
+ private readonly capture;
17
+ private readonly logger;
18
+ private readonly debugLogMaxLength;
19
+ private readonly pipeEngine;
20
+ constructor(session: PageSession, extraction: ExtractionOperator, container: ContainerOperator, workflow: WorkflowOperator, pagination: PaginationOperator, capture: CaptureOperator, logger: LoggerWithLevel, debugLogMaxLength?: number);
21
+ get page(): Page;
22
+ get browser(): Browser;
23
+ private navOptions;
24
+ private prepare;
25
+ scrape<T extends SelectorMap>(url: string, selectors: T, options?: ControllerScraperOptions): Promise<ScrapeResult>;
26
+ extract<T extends SelectorMap>(selectors: T, options?: ControllerScraperOptions): Promise<ScrapeResult>;
27
+ scrapeAll<T extends SelectorMap>(url: string, selectors: T, options?: ControllerScraperOptions): Promise<ScrapeAllResult>;
28
+ scrapeContainerFields<T = Record<string, unknown>>(url: string, descriptor: ContainerDescriptor<T>, options?: ControllerScraperOptions): Promise<ContainerScrapeResult<T>>;
29
+ evaluateWebsite<T = Record<string, unknown>>(options: Omit<EvaluateOptions, 'cloak' | 'useRandomUserAgent'>): Promise<EvaluateResult<T>>;
30
+ takeScreenshot(url: string, path: string, options?: ScreenshotOptions, scraperOptions?: ControllerScraperOptions): Promise<Buffer>;
31
+ generatePDF(url: string, path: string, options?: PDFOptions, scraperOptions?: ControllerScraperOptions): Promise<Buffer>;
32
+ captureTlsFingerprint(path: string, url?: string): Promise<TlsFingerprint>;
33
+ waitForSelector(url: string, selector: string, timeout?: number, scraperOptions?: ControllerScraperOptions): Promise<Page>;
34
+ evaluate<T = unknown>(url: string, script: string | (() => unknown), options?: ControllerScraperOptions): Promise<T>;
35
+ scrapeWithWorkflow<T = Record<string, unknown>>(url: string, workflow: Omit<WorkflowDefinition, 'cloak'>, variables?: VariableContext): Promise<WorkflowResultTyped<T>>;
36
+ scrapeAllWithWorkflow<T = Record<string, unknown>>(url: string, workflow: Omit<WorkflowDefinition, 'cloak'>, variables?: VariableContext): Promise<WorkflowResultTyped<T>>;
37
+ goto(url: string, options?: NavigateOptions): Promise<void>;
38
+ close(): Promise<void>;
39
+ }
@@ -0,0 +1,325 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PageController = void 0;
4
+ const workflow_validator_1 = require("../validators/workflow.validator");
5
+ const dom_util_1 = require("../utils/dom.util");
6
+ const truncate_log_util_1 = require("../utils/truncate-log.util");
7
+ const pipe_engine_1 = require("../pipes/pipe-engine");
8
+ const browser_action_constants_1 = require("../constants/browser-action.constants");
9
+ const path_util_1 = require("../utils/path.util");
10
+ class PageController {
11
+ session;
12
+ extraction;
13
+ container;
14
+ workflow;
15
+ pagination;
16
+ capture;
17
+ logger;
18
+ debugLogMaxLength;
19
+ pipeEngine = new pipe_engine_1.PipeEngine();
20
+ constructor(session, extraction, container, workflow, pagination, capture, logger, debugLogMaxLength = browser_action_constants_1.DEFAULT_DEBUG_LOG_MAX_LENGTH) {
21
+ this.session = session;
22
+ this.extraction = extraction;
23
+ this.container = container;
24
+ this.workflow = workflow;
25
+ this.pagination = pagination;
26
+ this.capture = capture;
27
+ this.logger = logger;
28
+ this.debugLogMaxLength = debugLogMaxLength;
29
+ }
30
+ get page() {
31
+ return this.session.page;
32
+ }
33
+ get browser() {
34
+ return this.session.browser;
35
+ }
36
+ navOptions(options) {
37
+ if (!options?.waitUntil && !options?.timeout)
38
+ return undefined;
39
+ return { waitUntil: options?.waitUntil, timeout: options?.timeout };
40
+ }
41
+ async prepare(url, options) {
42
+ await this.session.ensureAlive();
43
+ if (options?.interceptResource !== undefined) {
44
+ await this.session.setInterception(!!options.interceptResource);
45
+ }
46
+ return this.session.goto(url, this.navOptions(options));
47
+ }
48
+ async scrape(url, selectors, options) {
49
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Scraping ${url}`));
50
+ const page = await this.prepare(url, options);
51
+ return this.extraction.extractSingle(page, url, selectors, options?.pipes);
52
+ }
53
+ async extract(selectors, options) {
54
+ const page = await this.session.ensureAlive();
55
+ if (options?.interceptResource !== undefined) {
56
+ await this.session.setInterception(!!options.interceptResource);
57
+ }
58
+ return this.extraction.extractSingle(page, page.url(), selectors, options?.pipes);
59
+ }
60
+ async scrapeAll(url, selectors, options) {
61
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Scraping all elements from ${url}`));
62
+ const page = await this.prepare(url, options);
63
+ const result = {};
64
+ const evalAll = page['$$eval'].bind(page);
65
+ Object.entries(selectors).forEach(([key, selector]) => this.extraction.validateSelector(key, selector));
66
+ await Promise.all(Object.entries(selectors).map(async ([key, rawSelector]) => {
67
+ const { selector, attribute } = this.extraction.parseSelector(rawSelector);
68
+ try {
69
+ const isXPath = (0, dom_util_1.isXPathSelector)(selector);
70
+ let values;
71
+ if (isXPath && attribute) {
72
+ values = await page.evaluate((xpathSelector, attr) => {
73
+ const results = document.evaluate(xpathSelector, document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
74
+ const vals = [];
75
+ let node;
76
+ while ((node = results.iterateNext())) {
77
+ vals.push(node instanceof Element
78
+ ? node.getAttribute(attr) || ''
79
+ : node?.textContent?.trim() || '');
80
+ }
81
+ return vals;
82
+ }, selector, attribute);
83
+ }
84
+ else if (isXPath) {
85
+ values = await page.evaluate((xpathSelector) => {
86
+ const results = document.evaluate(xpathSelector, document, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null);
87
+ const vals = [];
88
+ let node;
89
+ while ((node = results.iterateNext())) {
90
+ vals.push(node?.textContent?.trim() || '');
91
+ }
92
+ return vals;
93
+ }, selector);
94
+ }
95
+ else if (attribute) {
96
+ values = await evalAll(selector, (elements, attr) => elements.map((el) => el.getAttribute(attr) || ''), attribute);
97
+ }
98
+ else {
99
+ values = await evalAll(selector, (elements) => elements.map((el) => el.textContent?.trim() || ''));
100
+ }
101
+ if (options?.pipes?.[key]) {
102
+ result[key] = values.map((value) => this.pipeEngine.apply(value, options.pipes[key], url));
103
+ }
104
+ else {
105
+ result[key] = values;
106
+ }
107
+ }
108
+ catch (err) {
109
+ this.logger.warn(`Failed to scrape '${key}' (${rawSelector}): ${err instanceof Error ? err.message : String(err)}`);
110
+ }
111
+ }));
112
+ return result;
113
+ }
114
+ async scrapeContainerFields(url, descriptor, options) {
115
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Scraping container fields from ${url}`));
116
+ const page = await this.prepare(url, options);
117
+ const raw = await this.container.executeContainerExtraction(page, descriptor, options?.currentPage ?? 1);
118
+ const items = raw.items.map((item) => {
119
+ const out = {};
120
+ for (const key of Object.keys(item)) {
121
+ const val = item[key];
122
+ if (options?.pipes?.[key]) {
123
+ const toStr = (v) => typeof v === 'string' ? v : String(v);
124
+ out[key] = Array.isArray(val)
125
+ ? val.map((v) => v == null
126
+ ? null
127
+ : this.pipeEngine.apply(toStr(v), options.pipes[key], url))
128
+ : val == null
129
+ ? null
130
+ : this.pipeEngine.apply(toStr(val), options.pipes[key], url);
131
+ }
132
+ else {
133
+ out[key] = val;
134
+ }
135
+ }
136
+ return out;
137
+ });
138
+ return { items, pagination: raw.pagination };
139
+ }
140
+ async evaluateWebsite(options) {
141
+ const { url, patterns, pagination, ...scraperOptions } = options;
142
+ if (!url) {
143
+ throw new Error('evaluateWebsite requires a url');
144
+ }
145
+ const containerPattern = patterns.find((p) => p.meta?.isContainer);
146
+ if (!containerPattern) {
147
+ if (pagination) {
148
+ throw new Error('pagination requires a container pattern (meta.isContainer: true)');
149
+ }
150
+ const selectors = Object.fromEntries(patterns.map((p) => [p.key, p.patterns[0]]));
151
+ const pipes = Object.fromEntries(patterns.filter((p) => p.pipes).map((p) => [p.key, p.pipes]));
152
+ const rawResult = await this.scrape(url, selectors, {
153
+ ...scraperOptions,
154
+ pipes,
155
+ });
156
+ return { results: [rawResult] };
157
+ }
158
+ const fieldPatterns = patterns.filter((p) => !p.meta?.isContainer && !p.meta?.isPage);
159
+ const fields = Object.fromEntries(fieldPatterns.map((p) => [
160
+ p.key,
161
+ {
162
+ selector: p.patterns[0],
163
+ returnType: p.returnType === 'rawHTML'
164
+ ? 'html'
165
+ : p.returnType === 'html'
166
+ ? 'html'
167
+ : 'text',
168
+ multiple: !!p.meta?.multiple,
169
+ fallback: [...p.patterns.slice(1), ...(p.meta?.alterPattern ?? [])],
170
+ },
171
+ ]));
172
+ const descriptor = {
173
+ container: containerPattern.patterns[0],
174
+ fields: fields,
175
+ };
176
+ const pipeMap = Object.fromEntries(fieldPatterns.filter((p) => p.pipes).map((p) => [p.key, p.pipes]));
177
+ if (!pagination) {
178
+ const { items } = await this.scrapeContainerFields(url, descriptor, {
179
+ ...scraperOptions,
180
+ pipes: pipeMap,
181
+ });
182
+ return { results: items };
183
+ }
184
+ const scraperOpts = { ...scraperOptions, pipes: pipeMap };
185
+ if (pagination.type === 'url-increment') {
186
+ const template = pagination.urlTemplate ?? url;
187
+ const startPage = pagination.startPage ?? 2;
188
+ const { items: page1Items } = await this.scrapeContainerFields(url, descriptor, scraperOpts);
189
+ const { items: restItems, pages: restPages } = await this.pagination.paginateUrlIncrement(template, async (pageUrl) => {
190
+ const { items } = await this.scrapeContainerFields(pageUrl, descriptor, scraperOpts);
191
+ return items;
192
+ }, pagination, startPage);
193
+ return {
194
+ results: [...page1Items, ...restItems],
195
+ totalPages: 1 + restPages,
196
+ };
197
+ }
198
+ const page = await this.prepare(url, scraperOpts);
199
+ const containerFn = async (p) => {
200
+ const raw = await this.container.executeContainerExtraction(p, descriptor, 1);
201
+ return raw.items.map((item) => {
202
+ const out = {};
203
+ for (const key of Object.keys(item)) {
204
+ const val = item[key];
205
+ if (pipeMap[key]) {
206
+ const toStr = (v) => typeof v === 'string' ? v : String(v);
207
+ out[key] = Array.isArray(val)
208
+ ? val.map((v) => v == null
209
+ ? null
210
+ : this.pipeEngine.apply(toStr(v), pipeMap[key], url))
211
+ : val == null
212
+ ? null
213
+ : this.pipeEngine.apply(toStr(val), pipeMap[key], url);
214
+ }
215
+ else {
216
+ out[key] = val;
217
+ }
218
+ }
219
+ return out;
220
+ });
221
+ };
222
+ if (pagination.type === 'click-next') {
223
+ const { items, pages } = await this.pagination.paginateClickNext(page, containerFn, pagination);
224
+ return { results: items, totalPages: pages };
225
+ }
226
+ else if (pagination.type === 'load-more') {
227
+ const { items, pages } = await this.pagination.paginateLoadMore(page, containerFn, pagination);
228
+ return { results: items, totalPages: pages };
229
+ }
230
+ else {
231
+ const { items, pages } = await this.pagination.paginateInfiniteScroll(page, containerFn, pagination);
232
+ return { results: items, totalPages: pages };
233
+ }
234
+ }
235
+ async takeScreenshot(url, path, options, scraperOptions) {
236
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Taking screenshot of ${url}`));
237
+ const page = await this.prepare(url, scraperOptions);
238
+ return this.capture.screenshot(page, path, options);
239
+ }
240
+ async generatePDF(url, path, options, scraperOptions) {
241
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Generating PDF for ${url}`));
242
+ const page = await this.prepare(url, scraperOptions);
243
+ return this.capture.pdf(page, path, options);
244
+ }
245
+ async captureTlsFingerprint(path, url = browser_action_constants_1.TLS_CAPTURE_URL) {
246
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Capturing TLS fingerprint from ${url}`));
247
+ const page = await this.session.goto(url);
248
+ return this.capture.tlsFingerprint(page, path);
249
+ }
250
+ async waitForSelector(url, selector, timeout, scraperOptions) {
251
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Waiting for ${selector} on ${url}`));
252
+ const page = await this.prepare(url, scraperOptions);
253
+ await page.waitForSelector(selector, { timeout });
254
+ return page;
255
+ }
256
+ async evaluate(url, script, options) {
257
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(this.debugLogMaxLength, `Evaluating script on ${url}`));
258
+ const page = await this.prepare(url, options);
259
+ const result = typeof script === 'function'
260
+ ? await page.evaluate(script)
261
+ : await page.evaluate(script);
262
+ return result;
263
+ }
264
+ async scrapeWithWorkflow(url, workflow, variables) {
265
+ (0, workflow_validator_1.validateWorkflow)(workflow);
266
+ const debugLogMaxLength = workflow.debugLogMaxLength ?? this.debugLogMaxLength;
267
+ this.logger.debug((0, truncate_log_util_1.truncateLog)(debugLogMaxLength, `Starting workflow execution for ${url}`));
268
+ await this.session.ensureAlive();
269
+ if (workflow.interceptResource !== undefined) {
270
+ await this.session.setInterception(!!workflow.interceptResource);
271
+ }
272
+ const page = await this.session.goto(url);
273
+ const result = {
274
+ success: false,
275
+ data: {},
276
+ errors: [],
277
+ screenshots: [],
278
+ };
279
+ try {
280
+ const context = variables || {};
281
+ const errorConfig = workflow.onError || {};
282
+ for (const action of workflow.actions) {
283
+ try {
284
+ await this.workflow.executeAction(page, action, context, debugLogMaxLength);
285
+ }
286
+ catch (error) {
287
+ const errorMessage = error instanceof Error ? error.message : String(error);
288
+ this.logger.error(`Action failed: ${errorMessage}`);
289
+ if (action.onError === 'continue' || action.onError === 'skip') {
290
+ continue;
291
+ }
292
+ if (errorConfig.screenshot) {
293
+ const screenshotPath = (0, path_util_1.sanitizeScreenshotPath)(errorConfig.screenshotPath ||
294
+ `${browser_action_constants_1.DEFAULT_ERROR_SCREENSHOT_FILENAME}-${Date.now()}.png`);
295
+ await page.screenshot({ path: screenshotPath });
296
+ result.screenshots?.push(screenshotPath);
297
+ }
298
+ if (!errorConfig.continue) {
299
+ result.errors.push(errorMessage);
300
+ return result;
301
+ }
302
+ }
303
+ }
304
+ result.success = true;
305
+ result.data = context;
306
+ }
307
+ catch (error) {
308
+ const errorMessage = error instanceof Error ? error.message : String(error);
309
+ result.errors.push(errorMessage);
310
+ this.logger.error(`Workflow execution failed: ${errorMessage}`);
311
+ }
312
+ return result;
313
+ }
314
+ async scrapeAllWithWorkflow(url, workflow, variables) {
315
+ return this.scrapeWithWorkflow(url, workflow, variables);
316
+ }
317
+ async goto(url, options) {
318
+ await this.session.goto(url, options);
319
+ }
320
+ async close() {
321
+ await this.session.close();
322
+ }
323
+ }
324
+ exports.PageController = PageController;
325
+ //# sourceMappingURL=page-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-controller.js","sourceRoot":"","sources":["../../src/services/page-controller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Browser, Page } from 'puppeteer-core';
2
+ import type { NavigateOptions } from './page.service';
3
+ import type { BrowserActionOptions } from '../interfaces/browser-action-options';
4
+ import { BrowserHolder } from './browser-holder';
5
+ import { LoggerWithLevel } from '../utils/logger.util';
6
+ export declare class PageSession {
7
+ private readonly name;
8
+ private readonly options;
9
+ private readonly logger;
10
+ private readonly holder;
11
+ private currentPage;
12
+ private interceptionEnabled;
13
+ private interceptionHandler?;
14
+ private recreating?;
15
+ private focusEmulatedOn?;
16
+ constructor(name: string, browser: Browser | BrowserHolder, page: Page, options: BrowserActionOptions, logger: LoggerWithLevel);
17
+ get page(): Page;
18
+ get browser(): Browser;
19
+ ensureAlive(): Promise<Page>;
20
+ private recreate;
21
+ private emulateFocus;
22
+ goto(url: string, options?: NavigateOptions): Promise<Page>;
23
+ setInterception(enabled: boolean): Promise<void>;
24
+ private applyInterception;
25
+ close(): Promise<void>;
26
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PageSession = void 0;
4
+ const browser_holder_1 = require("./browser-holder");
5
+ const browser_launcher_1 = require("../utils/browser-launcher");
6
+ class PageSession {
7
+ name;
8
+ options;
9
+ logger;
10
+ holder;
11
+ currentPage;
12
+ interceptionEnabled = false;
13
+ interceptionHandler;
14
+ recreating;
15
+ focusEmulatedOn;
16
+ constructor(name, browser, page, options, logger) {
17
+ this.name = name;
18
+ this.options = options;
19
+ this.logger = logger;
20
+ this.holder =
21
+ browser instanceof browser_holder_1.BrowserHolder ? browser : new browser_holder_1.BrowserHolder(browser);
22
+ this.currentPage = page;
23
+ }
24
+ get page() {
25
+ return this.currentPage;
26
+ }
27
+ get browser() {
28
+ return this.holder.browser;
29
+ }
30
+ async ensureAlive() {
31
+ if (!this.currentPage.isClosed() && this.holder.browser.connected) {
32
+ return this.currentPage;
33
+ }
34
+ this.recreating ??= this.recreate();
35
+ try {
36
+ return await this.recreating;
37
+ }
38
+ finally {
39
+ this.recreating = undefined;
40
+ }
41
+ }
42
+ async recreate() {
43
+ if (this.holder.browser.connected) {
44
+ this.logger.debug(`[PAGE-SESSION:${this.name}] page dead, reopening`);
45
+ this.currentPage = await this.holder.browser.newPage();
46
+ }
47
+ else {
48
+ this.logger.debug(`[PAGE-SESSION:${this.name}] browser dead, relaunching`);
49
+ const browser = await this.holder.relaunch(() => this.options.remote
50
+ ? (0, browser_launcher_1.connectRemoteBrowser)(this.options.remote, this.logger)
51
+ : (0, browser_launcher_1.launchLocalBrowser)(this.options, undefined, this.logger));
52
+ this.currentPage = await browser.newPage();
53
+ }
54
+ this.interceptionHandler = undefined;
55
+ if (this.interceptionEnabled) {
56
+ await this.applyInterception(this.currentPage);
57
+ }
58
+ return this.currentPage;
59
+ }
60
+ async emulateFocus(page) {
61
+ if (this.focusEmulatedOn === page)
62
+ return;
63
+ try {
64
+ const client = await page.createCDPSession();
65
+ await client.send('Emulation.setFocusEmulationEnabled', {
66
+ enabled: true,
67
+ });
68
+ this.focusEmulatedOn = page;
69
+ }
70
+ catch (err) {
71
+ this.logger.warn(`[PAGE-SESSION:${this.name}] focus emulation failed — continuing without it: ${err instanceof Error ? err.message : String(err)}`);
72
+ }
73
+ }
74
+ async goto(url, options) {
75
+ const page = await this.ensureAlive();
76
+ await this.emulateFocus(page);
77
+ const gotoOptions = {};
78
+ if (options?.waitUntil)
79
+ gotoOptions.waitUntil = options.waitUntil;
80
+ if (options?.timeout !== undefined)
81
+ gotoOptions.timeout = options.timeout;
82
+ try {
83
+ await page.goto(url, Object.keys(gotoOptions).length ? gotoOptions : undefined);
84
+ }
85
+ catch (err) {
86
+ if (err instanceof Error && err.message.includes('Navigation timeout')) {
87
+ this.logger.warn(`Navigation timeout on goto — continuing: ${url}`);
88
+ }
89
+ else {
90
+ throw err;
91
+ }
92
+ }
93
+ return page;
94
+ }
95
+ async setInterception(enabled) {
96
+ this.interceptionEnabled = enabled;
97
+ if (enabled) {
98
+ await this.applyInterception(this.currentPage);
99
+ }
100
+ else {
101
+ if (this.interceptionHandler) {
102
+ this.currentPage.off('request', this.interceptionHandler);
103
+ this.interceptionHandler = undefined;
104
+ }
105
+ await this.currentPage.setRequestInterception(false);
106
+ }
107
+ }
108
+ async applyInterception(page) {
109
+ if (this.interceptionHandler) {
110
+ page.off('request', this.interceptionHandler);
111
+ }
112
+ const blocked = new Set(['stylesheet', 'image', 'media', 'font']);
113
+ await page.setRequestInterception(true);
114
+ this.interceptionHandler = (request) => {
115
+ if (request.isInterceptResolutionHandled())
116
+ return;
117
+ if (blocked.has(request.resourceType())) {
118
+ void request.abort();
119
+ }
120
+ else {
121
+ void request.continue();
122
+ }
123
+ };
124
+ page.on('request', this.interceptionHandler);
125
+ }
126
+ async close() {
127
+ try {
128
+ await this.currentPage.close();
129
+ }
130
+ catch {
131
+ }
132
+ }
133
+ }
134
+ exports.PageSession = PageSession;
135
+ //# sourceMappingURL=page-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"page-session.js","sourceRoot":"","sources":["../../src/services/page-session.ts"],"names":[],"mappings":"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"}
@@ -26,7 +26,7 @@ let PageService = PageService_1 = class PageService {
26
26
  this.logger = new logger_util_1.LoggerWithLevel(PageService_1.name, this.browserManager.getLogLevel());
27
27
  }
28
28
  async createPage(cloak, interceptResource) {
29
- this.logger.debug('Creating new page');
29
+ this.logger.debug(`[PAGE] creating page (dedicated=${!!cloak} intercept=${!!interceptResource})`);
30
30
  if (cloak) {
31
31
  this.currentBrowser =
32
32
  await this.browserManager.createDedicatedBrowser(cloak);
@@ -74,7 +74,7 @@ let PageService = PageService_1 = class PageService {
74
74
  if (!this.currentPage) {
75
75
  await this.createPage(cloak, interceptResource);
76
76
  }
77
- this.logger.debug(`Navigating to ${url}`);
77
+ this.logger.debug(`[PAGE] navigating to ${url} (reusedPage=${!needsNewPage})`);
78
78
  if (!this.currentPage)
79
79
  throw new Error('Failed to create page');
80
80
  const gotoOptions = {};
@@ -82,11 +82,22 @@ let PageService = PageService_1 = class PageService {
82
82
  gotoOptions.waitUntil = options.waitUntil;
83
83
  if (options?.timeout !== undefined)
84
84
  gotoOptions.timeout = options.timeout;
85
- await this.currentPage.goto(url, Object.keys(gotoOptions).length ? gotoOptions : undefined);
85
+ try {
86
+ await this.currentPage.goto(url, Object.keys(gotoOptions).length ? gotoOptions : undefined);
87
+ }
88
+ catch (err) {
89
+ if (err instanceof Error && err.message.includes('Navigation timeout')) {
90
+ this.logger.warn(`Navigation timeout on goto — continuing: ${url}`);
91
+ }
92
+ else {
93
+ throw err;
94
+ }
95
+ }
86
96
  return this.currentPage;
87
97
  }
88
98
  async closePage() {
89
99
  if (this.currentPage) {
100
+ this.logger.debug(`[PAGE] closing page (dedicated=${this.dedicated})`);
90
101
  try {
91
102
  await this.currentPage.close();
92
103
  }