@detiq/crawler 0.2.9 → 0.2.11
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/dist/ai-login.js +59 -5
- package/dist/ai-login.js.map +2 -2
- package/dist/crawler.js +2 -2
- package/dist/crawler.js.map +2 -2
- package/dist/job-queue.js +1 -1
- package/dist/job-queue.js.map +2 -2
- package/package.json +1 -1
- package/src/crawler.ts +6 -3
- package/src/job-queue.ts +4 -1
package/package.json
CHANGED
package/src/crawler.ts
CHANGED
|
@@ -20,7 +20,7 @@ import StealthPlugin from 'puppeteer-extra-plugin-stealth';
|
|
|
20
20
|
// Option 3: Camoufox — Firefox-based browser with built-in fingerprint randomisation.
|
|
21
21
|
// Loaded dynamically (not at startup) to avoid ESM/CJS conflict when API imports crawler.
|
|
22
22
|
import { spawn, execSync, type ChildProcess } from 'node:child_process';
|
|
23
|
-
import { readFileSync } from 'node:fs';
|
|
23
|
+
import { readFileSync, existsSync as existsSyncFs } from 'node:fs';
|
|
24
24
|
import { createRequire } from 'node:module';
|
|
25
25
|
|
|
26
26
|
stealthChromium.use(StealthPlugin());
|
|
@@ -510,6 +510,7 @@ export async function crawlProject(opts: {
|
|
|
510
510
|
// Upload screenshot to cloud storage if configured, returns cloudUrl or undefined
|
|
511
511
|
const uploadToCloud = async (localPath: string, key: string): Promise<string | undefined> => {
|
|
512
512
|
if (!opts.storageConfig) return undefined;
|
|
513
|
+
if (!existsSyncFs(localPath)) return undefined;
|
|
513
514
|
try {
|
|
514
515
|
const { uploadScreenshotToTenantStorage } = await import('@detiq/app-brain');
|
|
515
516
|
return await uploadScreenshotToTenantStorage(opts.storageConfig as any, localPath, key);
|
|
@@ -4313,13 +4314,15 @@ async function captureAuthDiscoveryScreen(
|
|
|
4313
4314
|
const screen = await AppBrain.saveScreen(opts.tenantId, opts.projectId, name, screenUrl, opts.jobId, source === 'entry' ? 'ENTRY_POINT' : 'SEED_URL').catch(() => null);
|
|
4314
4315
|
if (!screen) return { captured: false, finalUrl, flowType };
|
|
4315
4316
|
let authCloudUrl: string | undefined;
|
|
4316
|
-
if (opts.storageConfig) {
|
|
4317
|
+
if (opts.storageConfig && existsSyncFs(shotPath)) {
|
|
4317
4318
|
try {
|
|
4318
4319
|
const { uploadScreenshotToTenantStorage } = await import('@detiq/app-brain');
|
|
4319
4320
|
authCloudUrl = await uploadScreenshotToTenantStorage(opts.storageConfig as any, shotPath, `${opts.tenantId}/${opts.projectId}/screenshots/${path.basename(shotPath)}`);
|
|
4320
4321
|
} catch { /* non-fatal */ }
|
|
4321
4322
|
}
|
|
4322
|
-
|
|
4323
|
+
if (existsSyncFs(shotPath)) {
|
|
4324
|
+
await AppBrain.saveScreenshot(opts.tenantId, opts.projectId, screen.id, shotPath, screen.version, 'DESKTOP', authCloudUrl).catch(() => { });
|
|
4325
|
+
}
|
|
4323
4326
|
await AppBrain.saveCrawlEvidence(opts.tenantId, opts.projectId, {
|
|
4324
4327
|
screenId: screen.id,
|
|
4325
4328
|
jobId: opts.jobId,
|
package/src/job-queue.ts
CHANGED
|
@@ -383,7 +383,10 @@ export async function enqueueJob(type: string, config: any): Promise<string> {
|
|
|
383
383
|
if (type === 'CRAWL' && process.env.JOB_QUEUE_BACKEND === 'sqs') {
|
|
384
384
|
const { sendJobToSqs } = await import('./sqs-queue.js');
|
|
385
385
|
await sendJobToSqs(job.id, tenantId, config);
|
|
386
|
-
} else {
|
|
386
|
+
} else if (process.env.DISABLE_WORKER !== 'true') {
|
|
387
|
+
// Skip inline dispatch when DISABLE_WORKER=true — the dedicated crawler process
|
|
388
|
+
// will pick this up via its poll loop. Inline dispatch in the API container
|
|
389
|
+
// would launch Playwright browsers and crash the API.
|
|
387
390
|
setImmediate(() => claimSpecificJob(job.id).then((claimed) => claimed && dispatchClaimedJob(claimed)));
|
|
388
391
|
}
|
|
389
392
|
|