@signaliz/sdk 1.0.29 → 1.0.31
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 +4 -2
- package/dist/{chunk-R4DIAP7P.mjs → chunk-P3ICLKAE.mjs} +345 -133
- package/dist/index.d.mts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +345 -133
- package/dist/index.mjs +1 -1
- package/dist/mcp-config.js +345 -133
- package/dist/mcp-config.mjs +1 -1
- package/package.json +13 -3
package/dist/index.js
CHANGED
|
@@ -380,89 +380,51 @@ var Signaliz = class {
|
|
|
380
380
|
this.client = new HttpClient(config);
|
|
381
381
|
}
|
|
382
382
|
async findEmail(params) {
|
|
383
|
-
const data = await this.client.post("api/v1/find-email",
|
|
384
|
-
|
|
385
|
-
full_name: params.fullName,
|
|
386
|
-
first_name: params.firstName,
|
|
387
|
-
last_name: params.lastName,
|
|
388
|
-
linkedin_url: params.linkedinUrl,
|
|
389
|
-
company_name: params.companyName,
|
|
390
|
-
skip_cache: params.skipCache
|
|
391
|
-
}));
|
|
392
|
-
const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
393
|
-
const found = Boolean(email) && data.found !== false;
|
|
394
|
-
const verificationStatus = data.verification_status ?? data.status ?? "unknown";
|
|
395
|
-
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
396
|
-
const verificationFreshness = rawFreshness === "fresh" || rawFreshness === "stale" ? rawFreshness : "unknown";
|
|
397
|
-
const needsReverification = data.needs_reverification === true || verificationFreshness === "stale";
|
|
398
|
-
const explicitlyNotSendSafe = data.verified_for_sending === false || needsReverification;
|
|
399
|
-
const verified = !explicitlyNotSendSafe && (data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
400
|
-
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
401
|
-
return {
|
|
402
|
-
success: data.success !== false && found,
|
|
403
|
-
found,
|
|
404
|
-
email,
|
|
405
|
-
firstName: data.first_name,
|
|
406
|
-
lastName: data.last_name,
|
|
407
|
-
confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
|
|
408
|
-
verificationStatus,
|
|
409
|
-
isVerified: verified,
|
|
410
|
-
isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
|
|
411
|
-
isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
|
|
412
|
-
verificationFreshness,
|
|
413
|
-
verificationAgeDays,
|
|
414
|
-
verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
|
|
415
|
-
needsReverification,
|
|
416
|
-
providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
|
|
417
|
-
error: found ? void 0 : data.error ?? "No verified email found",
|
|
418
|
-
errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
|
|
419
|
-
raw: data
|
|
420
|
-
};
|
|
383
|
+
const data = await this.client.post("api/v1/find-email", findEmailRequestBody(params));
|
|
384
|
+
return normalizeFindEmailResult(data);
|
|
421
385
|
}
|
|
422
386
|
async findEmails(params, options) {
|
|
423
|
-
|
|
387
|
+
validateBatchSize(params);
|
|
388
|
+
const startedAt = Date.now();
|
|
389
|
+
const round = await this.runCoreBatchRound(
|
|
390
|
+
"api/v1/find-email",
|
|
391
|
+
params.map((item, index) => ({ index, request: findEmailRequestBody(item) })),
|
|
392
|
+
options
|
|
393
|
+
);
|
|
394
|
+
return finalizeCoreBatch(
|
|
395
|
+
params.length,
|
|
396
|
+
startedAt,
|
|
397
|
+
round,
|
|
398
|
+
(item) => normalizeFindEmailResult(item.raw)
|
|
399
|
+
);
|
|
424
400
|
}
|
|
425
401
|
async verifyEmail(email, options) {
|
|
426
402
|
const data = await this.client.post("api/v1/verify-email", {
|
|
427
403
|
email,
|
|
428
404
|
skip_cache: options?.skipCache
|
|
429
405
|
});
|
|
430
|
-
|
|
431
|
-
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
432
|
-
return {
|
|
433
|
-
email: data.email ?? email,
|
|
434
|
-
isValid: data.is_valid ?? data.valid ?? verified,
|
|
435
|
-
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
436
|
-
isCatchAll: data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
437
|
-
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
438
|
-
provider: data.provider,
|
|
439
|
-
verificationSource: data.verification_source,
|
|
440
|
-
raw: data
|
|
441
|
-
};
|
|
406
|
+
return normalizeVerifyEmailResult(email, data);
|
|
442
407
|
}
|
|
443
408
|
async verifyEmails(emails, options) {
|
|
444
|
-
|
|
409
|
+
validateBatchSize(emails);
|
|
410
|
+
const startedAt = Date.now();
|
|
411
|
+
const round = await this.runCoreBatchRound(
|
|
412
|
+
"api/v1/verify-email",
|
|
413
|
+
emails.map((email, index) => ({
|
|
414
|
+
index,
|
|
415
|
+
request: { email, skip_cache: options?.skipCache }
|
|
416
|
+
})),
|
|
417
|
+
options
|
|
418
|
+
);
|
|
419
|
+
return finalizeCoreBatch(
|
|
420
|
+
emails.length,
|
|
421
|
+
startedAt,
|
|
422
|
+
round,
|
|
423
|
+
(item) => normalizeVerifyEmailResult(emails[item.index], item.raw)
|
|
424
|
+
);
|
|
445
425
|
}
|
|
446
426
|
async enrichCompanySignals(params) {
|
|
447
|
-
const
|
|
448
|
-
const request = compact({
|
|
449
|
-
signal_run_id: params.signalRunId,
|
|
450
|
-
company_domain: params.companyDomain,
|
|
451
|
-
company_name: params.companyName,
|
|
452
|
-
research_prompt: params.researchPrompt,
|
|
453
|
-
signal_types: params.signalTypes,
|
|
454
|
-
target_signal_count: params.targetSignalCount,
|
|
455
|
-
lookback_days: params.lookbackDays,
|
|
456
|
-
online,
|
|
457
|
-
enable_deep_search: params.enableDeepSearch ?? online,
|
|
458
|
-
enable_outreach_intelligence: params.enableOutreachIntelligence,
|
|
459
|
-
enable_predictive_intelligence: params.enablePredictiveIntelligence,
|
|
460
|
-
skip_cache: params.skipCache,
|
|
461
|
-
// REST always returns a resumable run instead of holding the connection;
|
|
462
|
-
// waitForResult controls this SDK's polling loop below.
|
|
463
|
-
wait_for_result: false,
|
|
464
|
-
max_wait_ms: params.maxWaitMs
|
|
465
|
-
});
|
|
427
|
+
const request = companySignalRequestBody(params);
|
|
466
428
|
let data = await this.client.post("api/v1/company-signals", request);
|
|
467
429
|
if (params.waitForResult !== false && data.run_id && isPendingSignalResponse(data)) {
|
|
468
430
|
const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
|
|
@@ -490,47 +452,68 @@ var Signaliz = class {
|
|
|
490
452
|
throw new Error(`Company signal enrichment ${data.run_id} did not complete within ${maxWaitMs}ms`);
|
|
491
453
|
}
|
|
492
454
|
}
|
|
493
|
-
return
|
|
494
|
-
success: data.success ?? true,
|
|
495
|
-
status: data.status,
|
|
496
|
-
signalRunId: data.signal_run_id ?? data.run_id,
|
|
497
|
-
company: {
|
|
498
|
-
name: data.company?.name ?? params.companyName ?? null,
|
|
499
|
-
domain: data.company?.domain ?? params.companyDomain ?? null
|
|
500
|
-
},
|
|
501
|
-
signals: (data.signals ?? []).map((signal) => {
|
|
502
|
-
const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
|
|
503
|
-
return {
|
|
504
|
-
id: signal.id,
|
|
505
|
-
title: signal.title ?? "",
|
|
506
|
-
type: signal.type ?? signal.signal_type ?? "unknown",
|
|
507
|
-
content: signal.content ?? signal.description ?? "",
|
|
508
|
-
date: signal.date ?? signal.detected_at ?? null,
|
|
509
|
-
datePrecision: signal.date_precision,
|
|
510
|
-
sourceUrl: signal.source_url ?? signal.url ?? null,
|
|
511
|
-
sourceType: signal.source_type,
|
|
512
|
-
sourceProvenance: signal.source_provenance,
|
|
513
|
-
confidence: signal.confidence ?? signal.confidence_score ?? null,
|
|
514
|
-
entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
|
|
515
|
-
signalFamily: signal.signal_family,
|
|
516
|
-
eventType: signal.signal_event_type,
|
|
517
|
-
eventLabel: signal.signal_event_label,
|
|
518
|
-
classification: signal.signal_classification ?? null,
|
|
519
|
-
derived: signal.derived === true,
|
|
520
|
-
evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
|
|
521
|
-
signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
|
|
522
|
-
metadata
|
|
523
|
-
};
|
|
524
|
-
}),
|
|
525
|
-
signalCount: data.signal_count ?? data.total_signals ?? data.signals?.length ?? 0,
|
|
526
|
-
intelligence: data.intelligence ?? null,
|
|
527
|
-
credits: data.credits,
|
|
528
|
-
metadata: data.metadata,
|
|
529
|
-
raw: data
|
|
530
|
-
};
|
|
455
|
+
return normalizeCompanySignalResult(params, data);
|
|
531
456
|
}
|
|
532
457
|
async enrichCompanies(companies, options) {
|
|
533
|
-
|
|
458
|
+
validateBatchSize(companies);
|
|
459
|
+
const startedAt = Date.now();
|
|
460
|
+
const results = new Array(companies.length);
|
|
461
|
+
let pending = companies.map((params, index) => ({
|
|
462
|
+
index,
|
|
463
|
+
request: companySignalRequestBody(params)
|
|
464
|
+
}));
|
|
465
|
+
while (pending.length > 0) {
|
|
466
|
+
const round = await this.runCoreBatchRound("api/v1/company-signals", pending, options);
|
|
467
|
+
const taskByIndex = new Map(pending.map((task) => [task.index, task]));
|
|
468
|
+
const nextPending = [];
|
|
469
|
+
let nextDelayMs = 6e4;
|
|
470
|
+
for (const item of round) {
|
|
471
|
+
const params = companies[item.index];
|
|
472
|
+
const task = taskByIndex.get(item.index);
|
|
473
|
+
if (!item.success || !item.raw) {
|
|
474
|
+
results[item.index] = { index: item.index, success: false, error: item.error || "Company Signal batch request failed" };
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
if (!isPendingSignalResponse(item.raw) || params.waitForResult === false) {
|
|
478
|
+
results[item.index] = { index: item.index, success: true, data: normalizeCompanySignalResult(params, item.raw) };
|
|
479
|
+
continue;
|
|
480
|
+
}
|
|
481
|
+
const maxWaitMs = Math.max(1e3, params.maxWaitMs ?? 20 * 6e4);
|
|
482
|
+
if (Date.now() - startedAt >= maxWaitMs) {
|
|
483
|
+
results[item.index] = {
|
|
484
|
+
index: item.index,
|
|
485
|
+
success: false,
|
|
486
|
+
error: `Company signal enrichment ${item.raw.signal_run_id || item.raw.run_id || ""} did not complete within ${maxWaitMs}ms`
|
|
487
|
+
};
|
|
488
|
+
continue;
|
|
489
|
+
}
|
|
490
|
+
const signalRunId = item.raw.signal_run_id || item.raw.run_id;
|
|
491
|
+
if (!signalRunId) {
|
|
492
|
+
results[item.index] = { index: item.index, success: false, error: "Company signal enrichment is processing without a signal_run_id" };
|
|
493
|
+
continue;
|
|
494
|
+
}
|
|
495
|
+
nextDelayMs = Math.min(
|
|
496
|
+
nextDelayMs,
|
|
497
|
+
signalPollDelayMs(item.raw, params.pollIntervalMs),
|
|
498
|
+
maxWaitMs - (Date.now() - startedAt)
|
|
499
|
+
);
|
|
500
|
+
nextPending.push({
|
|
501
|
+
...task,
|
|
502
|
+
request: { ...task.request, signal_run_id: signalRunId }
|
|
503
|
+
});
|
|
504
|
+
}
|
|
505
|
+
if (nextPending.length === 0) break;
|
|
506
|
+
await sleep2(Math.max(1, nextDelayMs));
|
|
507
|
+
pending = nextPending;
|
|
508
|
+
}
|
|
509
|
+
const succeeded = results.filter((item) => item.success).length;
|
|
510
|
+
return {
|
|
511
|
+
total: companies.length,
|
|
512
|
+
succeeded,
|
|
513
|
+
failed: companies.length - succeeded,
|
|
514
|
+
durationMs: Date.now() - startedAt,
|
|
515
|
+
results
|
|
516
|
+
};
|
|
534
517
|
}
|
|
535
518
|
async signalToCopy(params) {
|
|
536
519
|
const request = signalToCopyRequestBody(params);
|
|
@@ -553,29 +536,31 @@ var Signaliz = class {
|
|
|
553
536
|
return normalizeSignalToCopyResult(data);
|
|
554
537
|
}
|
|
555
538
|
async createSignalCopyBatch(requests, options) {
|
|
556
|
-
|
|
557
|
-
throw new Error("Signaliz batch requests require at least one item");
|
|
558
|
-
}
|
|
559
|
-
if (requests.length > 5e3) {
|
|
560
|
-
throw new Error(`Signaliz batch requests support at most 5,000 items; received ${requests.length}`);
|
|
561
|
-
}
|
|
539
|
+
validateBatchSize(requests);
|
|
562
540
|
const startedAt = Date.now();
|
|
541
|
+
const deduplicated = dedupeExactBatchItems(requests, (params) => JSON.stringify({
|
|
542
|
+
request: signalToCopyRequestBody(params),
|
|
543
|
+
wait_for_result: params.waitForResult,
|
|
544
|
+
max_wait_ms: params.maxWaitMs,
|
|
545
|
+
poll_interval_ms: params.pollIntervalMs
|
|
546
|
+
}));
|
|
547
|
+
const uniqueRequests = deduplicated.uniqueItems;
|
|
563
548
|
const chunks = [];
|
|
564
|
-
for (let offset = 0; offset <
|
|
565
|
-
chunks.push({ offset, requests:
|
|
549
|
+
for (let offset = 0; offset < uniqueRequests.length; offset += 25) {
|
|
550
|
+
chunks.push({ offset, requests: uniqueRequests.slice(offset, offset + 25) });
|
|
566
551
|
}
|
|
567
|
-
const serverConcurrency =
|
|
552
|
+
const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
|
|
568
553
|
const chunkBatch = await runBatch(
|
|
569
554
|
chunks,
|
|
570
555
|
(chunk) => this.runSignalCopyBatchChunk(chunk.requests, serverConcurrency),
|
|
571
|
-
|
|
556
|
+
{ concurrency: chunkConcurrency }
|
|
572
557
|
);
|
|
573
|
-
const
|
|
558
|
+
const uniqueResults = new Array(uniqueRequests.length);
|
|
574
559
|
for (const chunkResult of chunkBatch.results) {
|
|
575
560
|
const chunk = chunks[chunkResult.index];
|
|
576
561
|
if (!chunkResult.success || !chunkResult.data) {
|
|
577
562
|
for (let index = 0; index < chunk.requests.length; index += 1) {
|
|
578
|
-
|
|
563
|
+
uniqueResults[chunk.offset + index] = {
|
|
579
564
|
index: chunk.offset + index,
|
|
580
565
|
success: false,
|
|
581
566
|
error: chunkResult.error || "Signal to Copy batch request failed"
|
|
@@ -584,9 +569,13 @@ var Signaliz = class {
|
|
|
584
569
|
continue;
|
|
585
570
|
}
|
|
586
571
|
for (const item of chunkResult.data) {
|
|
587
|
-
|
|
572
|
+
uniqueResults[chunk.offset + item.index] = { ...item, index: chunk.offset + item.index };
|
|
588
573
|
}
|
|
589
574
|
}
|
|
575
|
+
const results = requests.map((_, index) => ({
|
|
576
|
+
...uniqueResults[deduplicated.sourceIndexByInput[index]],
|
|
577
|
+
index
|
|
578
|
+
}));
|
|
590
579
|
const succeeded = results.filter((item) => item.success).length;
|
|
591
580
|
return {
|
|
592
581
|
total: requests.length,
|
|
@@ -658,6 +647,55 @@ var Signaliz = class {
|
|
|
658
647
|
}
|
|
659
648
|
return results;
|
|
660
649
|
}
|
|
650
|
+
async runCoreBatchRound(path, tasks, options) {
|
|
651
|
+
const { serverConcurrency, chunkConcurrency } = batchConcurrencyPlan(options);
|
|
652
|
+
const deduplicated = dedupeExactBatchItems(tasks, (task) => JSON.stringify(task.request));
|
|
653
|
+
const uniqueTasks = deduplicated.uniqueItems;
|
|
654
|
+
const chunks = [];
|
|
655
|
+
for (let offset = 0; offset < uniqueTasks.length; offset += 25) {
|
|
656
|
+
chunks.push({ offset, tasks: uniqueTasks.slice(offset, offset + 25) });
|
|
657
|
+
}
|
|
658
|
+
const chunkBatch = await runBatch(chunks, async (chunk) => {
|
|
659
|
+
const data = await this.client.post(path, {
|
|
660
|
+
requests: chunk.tasks.map((task) => task.request),
|
|
661
|
+
concurrency: serverConcurrency
|
|
662
|
+
});
|
|
663
|
+
if (!Array.isArray(data.results) || data.results.length !== chunk.tasks.length) {
|
|
664
|
+
throw new Error(`${path} batch returned an invalid result count`);
|
|
665
|
+
}
|
|
666
|
+
if (data.results.some((row, index) => row.index !== index)) {
|
|
667
|
+
throw new Error(`${path} batch returned results out of order`);
|
|
668
|
+
}
|
|
669
|
+
return data.results;
|
|
670
|
+
}, { concurrency: chunkConcurrency });
|
|
671
|
+
const uniqueResults = new Array(uniqueTasks.length);
|
|
672
|
+
for (const chunkResult of chunkBatch.results) {
|
|
673
|
+
const chunk = chunks[chunkResult.index];
|
|
674
|
+
if (!chunkResult.success || !chunkResult.data) {
|
|
675
|
+
for (let index = 0; index < chunk.tasks.length; index += 1) {
|
|
676
|
+
uniqueResults[chunk.offset + index] = {
|
|
677
|
+
index: chunk.tasks[index].index,
|
|
678
|
+
success: false,
|
|
679
|
+
error: chunkResult.error || `${path} batch request failed`
|
|
680
|
+
};
|
|
681
|
+
}
|
|
682
|
+
continue;
|
|
683
|
+
}
|
|
684
|
+
for (let index = 0; index < chunkResult.data.length; index += 1) {
|
|
685
|
+
const raw = chunkResult.data[index];
|
|
686
|
+
uniqueResults[chunk.offset + index] = {
|
|
687
|
+
index: chunk.tasks[index].index,
|
|
688
|
+
success: raw.success !== false,
|
|
689
|
+
raw,
|
|
690
|
+
error: raw.success === false ? raw.error || raw.message || raw.error_code || `${path} item failed` : void 0
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return tasks.map((task, index) => ({
|
|
695
|
+
...uniqueResults[deduplicated.sourceIndexByInput[index]],
|
|
696
|
+
index: task.index
|
|
697
|
+
}));
|
|
698
|
+
}
|
|
661
699
|
async listTools() {
|
|
662
700
|
const result = await this.client.mcp("tools/list");
|
|
663
701
|
return result.tools ?? [];
|
|
@@ -673,6 +711,188 @@ var Signaliz = class {
|
|
|
673
711
|
function compact(input) {
|
|
674
712
|
return Object.fromEntries(Object.entries(input).filter(([, value]) => value !== void 0));
|
|
675
713
|
}
|
|
714
|
+
function findEmailRequestBody(params) {
|
|
715
|
+
return compact({
|
|
716
|
+
company_domain: params.companyDomain,
|
|
717
|
+
full_name: params.fullName,
|
|
718
|
+
first_name: params.firstName,
|
|
719
|
+
last_name: params.lastName,
|
|
720
|
+
linkedin_url: params.linkedinUrl,
|
|
721
|
+
company_name: params.companyName,
|
|
722
|
+
skip_cache: params.skipCache
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
function normalizeFindEmailResult(data) {
|
|
726
|
+
const email = typeof data.email === "string" && data.email.trim() ? data.email.trim() : null;
|
|
727
|
+
const found = Boolean(email) && data.found !== false;
|
|
728
|
+
const verificationStatus = data.verification_status ?? data.status ?? "unknown";
|
|
729
|
+
const rawFreshness = String(data.verification_freshness ?? "").toLowerCase();
|
|
730
|
+
const verificationFreshness = rawFreshness === "fresh" || rawFreshness === "stale" ? rawFreshness : "unknown";
|
|
731
|
+
const needsReverification = data.needs_reverification === true || verificationFreshness === "stale";
|
|
732
|
+
const explicitlyNotSendSafe = data.verified_for_sending === false || needsReverification;
|
|
733
|
+
const verified = !explicitlyNotSendSafe && (data.email_verified === true || data.verified_for_sending === true || ["valid", "deliverable"].includes(String(verificationStatus).toLowerCase()));
|
|
734
|
+
const verificationAgeDays = typeof data.verification_age_days === "number" && Number.isFinite(data.verification_age_days) ? data.verification_age_days : null;
|
|
735
|
+
return {
|
|
736
|
+
success: data.success !== false && found,
|
|
737
|
+
found,
|
|
738
|
+
email,
|
|
739
|
+
firstName: data.first_name,
|
|
740
|
+
lastName: data.last_name,
|
|
741
|
+
confidence: data.confidence ?? data.confidence_score ?? (verified ? 1 : 0),
|
|
742
|
+
verificationStatus,
|
|
743
|
+
isVerified: verified,
|
|
744
|
+
isVerifiedForSending: !needsReverification && data.verified_for_sending === true,
|
|
745
|
+
isCatchAll: data.email_is_catch_all === true || data.is_catch_all === true,
|
|
746
|
+
verificationFreshness,
|
|
747
|
+
verificationAgeDays,
|
|
748
|
+
verifiedAt: typeof data.verified_at === "string" ? data.verified_at : null,
|
|
749
|
+
needsReverification,
|
|
750
|
+
providerUsed: data.provider_used ?? data.provider ?? data.email_source ?? data.source ?? "unknown",
|
|
751
|
+
error: found ? void 0 : data.error ?? "No verified email found",
|
|
752
|
+
errorCode: found ? void 0 : data.error_code ?? "EMAIL_NOT_FOUND",
|
|
753
|
+
raw: data
|
|
754
|
+
};
|
|
755
|
+
}
|
|
756
|
+
function normalizeVerifyEmailResult(email, data) {
|
|
757
|
+
const verificationStatus = String(data.verification_status ?? "").toLowerCase();
|
|
758
|
+
const verified = data.email_verified === true || ["valid", "deliverable"].includes(verificationStatus);
|
|
759
|
+
return {
|
|
760
|
+
email: data.email ?? email,
|
|
761
|
+
isValid: data.is_valid ?? data.valid ?? verified,
|
|
762
|
+
isDeliverable: data.is_deliverable ?? data.deliverable ?? verified,
|
|
763
|
+
isCatchAll: data.email_is_catch_all ?? data.is_catch_all ?? data.catch_all ?? data.diagnostics?.is_catch_all ?? false,
|
|
764
|
+
confidenceScore: data.confidence_score ?? data.confidence ?? data.diagnostics?.confidence_score ?? (verified ? 1 : 0),
|
|
765
|
+
provider: data.provider,
|
|
766
|
+
verificationSource: data.verification_source,
|
|
767
|
+
raw: data
|
|
768
|
+
};
|
|
769
|
+
}
|
|
770
|
+
function companySignalRequestBody(params) {
|
|
771
|
+
const online = params.online ?? true;
|
|
772
|
+
return compact({
|
|
773
|
+
signal_run_id: params.signalRunId,
|
|
774
|
+
company_domain: params.companyDomain,
|
|
775
|
+
company_name: params.companyName,
|
|
776
|
+
research_prompt: params.researchPrompt,
|
|
777
|
+
signal_types: params.signalTypes,
|
|
778
|
+
target_signal_count: params.targetSignalCount,
|
|
779
|
+
lookback_days: params.lookbackDays,
|
|
780
|
+
online,
|
|
781
|
+
enable_deep_search: params.enableDeepSearch ?? online,
|
|
782
|
+
enable_outreach_intelligence: params.enableOutreachIntelligence,
|
|
783
|
+
enable_predictive_intelligence: params.enablePredictiveIntelligence,
|
|
784
|
+
skip_cache: params.skipCache,
|
|
785
|
+
// REST always returns a resumable run instead of holding the connection;
|
|
786
|
+
// waitForResult controls the SDK polling loop.
|
|
787
|
+
wait_for_result: false,
|
|
788
|
+
max_wait_ms: params.maxWaitMs
|
|
789
|
+
});
|
|
790
|
+
}
|
|
791
|
+
function normalizeCompanySignalResult(params, data) {
|
|
792
|
+
return {
|
|
793
|
+
success: data.success ?? true,
|
|
794
|
+
status: data.status,
|
|
795
|
+
signalRunId: data.signal_run_id ?? data.run_id,
|
|
796
|
+
company: {
|
|
797
|
+
name: data.company?.name ?? params.companyName ?? null,
|
|
798
|
+
domain: data.company?.domain ?? params.companyDomain ?? null
|
|
799
|
+
},
|
|
800
|
+
signals: (data.signals ?? []).map((signal) => {
|
|
801
|
+
const metadata = signal.metadata && typeof signal.metadata === "object" && !Array.isArray(signal.metadata) ? signal.metadata : void 0;
|
|
802
|
+
return {
|
|
803
|
+
id: signal.id,
|
|
804
|
+
title: signal.title ?? "",
|
|
805
|
+
type: signal.type ?? signal.signal_type ?? "unknown",
|
|
806
|
+
content: signal.content ?? signal.description ?? "",
|
|
807
|
+
date: signal.date ?? signal.detected_at ?? null,
|
|
808
|
+
datePrecision: signal.date_precision,
|
|
809
|
+
sourceUrl: signal.source_url ?? signal.url ?? null,
|
|
810
|
+
sourceType: signal.source_type,
|
|
811
|
+
sourceProvenance: signal.source_provenance,
|
|
812
|
+
confidence: signal.confidence ?? signal.confidence_score ?? null,
|
|
813
|
+
entityConfidence: signal.entity_confidence ?? metadata?.entity_confidence ?? null,
|
|
814
|
+
signalFamily: signal.signal_family,
|
|
815
|
+
eventType: signal.signal_event_type,
|
|
816
|
+
eventLabel: signal.signal_event_label,
|
|
817
|
+
classification: signal.signal_classification ?? null,
|
|
818
|
+
derived: signal.derived === true,
|
|
819
|
+
evidencePublishedDate: signal.evidence_published_date ?? metadata?.evidence_published_date ?? null,
|
|
820
|
+
signalFeedSource: signal.signal_feed_source ?? metadata?.signal_feed_source,
|
|
821
|
+
metadata
|
|
822
|
+
};
|
|
823
|
+
}),
|
|
824
|
+
signalCount: data.signal_count ?? data.total_signals ?? data.signals?.length ?? 0,
|
|
825
|
+
intelligence: data.intelligence ?? null,
|
|
826
|
+
credits: data.credits,
|
|
827
|
+
metadata: data.metadata,
|
|
828
|
+
raw: data
|
|
829
|
+
};
|
|
830
|
+
}
|
|
831
|
+
function validateBatchSize(items) {
|
|
832
|
+
if (!Array.isArray(items) || items.length === 0) {
|
|
833
|
+
throw new Error("Signaliz batch requests require at least one item");
|
|
834
|
+
}
|
|
835
|
+
if (items.length > 5e3) {
|
|
836
|
+
throw new Error(`Signaliz batch requests support at most 5,000 items; received ${items.length}`);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
function validatedBatchConcurrency(options) {
|
|
840
|
+
const concurrency = options?.concurrency ?? 10;
|
|
841
|
+
if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 50) {
|
|
842
|
+
throw new Error("Signaliz batch concurrency must be an integer between 1 and 50");
|
|
843
|
+
}
|
|
844
|
+
return concurrency;
|
|
845
|
+
}
|
|
846
|
+
function batchConcurrencyPlan(options) {
|
|
847
|
+
const concurrency = validatedBatchConcurrency(options);
|
|
848
|
+
const serverConcurrency = Math.min(10, concurrency);
|
|
849
|
+
return {
|
|
850
|
+
serverConcurrency,
|
|
851
|
+
chunkConcurrency: Math.max(1, Math.floor(concurrency / serverConcurrency))
|
|
852
|
+
};
|
|
853
|
+
}
|
|
854
|
+
function dedupeExactBatchItems(items, keyForItem) {
|
|
855
|
+
const uniqueItems = [];
|
|
856
|
+
const sourceIndexByInput = [];
|
|
857
|
+
const uniqueIndexByKey = /* @__PURE__ */ new Map();
|
|
858
|
+
for (const item of items) {
|
|
859
|
+
const key = keyForItem(item);
|
|
860
|
+
let uniqueIndex = uniqueIndexByKey.get(key);
|
|
861
|
+
if (uniqueIndex === void 0) {
|
|
862
|
+
uniqueIndex = uniqueItems.length;
|
|
863
|
+
uniqueIndexByKey.set(key, uniqueIndex);
|
|
864
|
+
uniqueItems.push(item);
|
|
865
|
+
}
|
|
866
|
+
sourceIndexByInput.push(uniqueIndex);
|
|
867
|
+
}
|
|
868
|
+
return { uniqueItems, sourceIndexByInput };
|
|
869
|
+
}
|
|
870
|
+
function finalizeCoreBatch(total, startedAt, round, normalize) {
|
|
871
|
+
const results = new Array(total);
|
|
872
|
+
for (const item of round) {
|
|
873
|
+
if (!item.success || !item.raw) {
|
|
874
|
+
results[item.index] = { index: item.index, success: false, error: item.error || "Signaliz batch item failed" };
|
|
875
|
+
continue;
|
|
876
|
+
}
|
|
877
|
+
try {
|
|
878
|
+
results[item.index] = { index: item.index, success: true, data: normalize(item) };
|
|
879
|
+
} catch (error) {
|
|
880
|
+
results[item.index] = {
|
|
881
|
+
index: item.index,
|
|
882
|
+
success: false,
|
|
883
|
+
error: error instanceof Error ? error.message : String(error)
|
|
884
|
+
};
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
const succeeded = results.filter((item) => item.success).length;
|
|
888
|
+
return {
|
|
889
|
+
total,
|
|
890
|
+
succeeded,
|
|
891
|
+
failed: total - succeeded,
|
|
892
|
+
durationMs: Date.now() - startedAt,
|
|
893
|
+
results
|
|
894
|
+
};
|
|
895
|
+
}
|
|
676
896
|
function signalToCopyRequestBody(params) {
|
|
677
897
|
return compact({
|
|
678
898
|
company_domain: params.companyDomain,
|
|
@@ -734,16 +954,8 @@ function sleep2(ms) {
|
|
|
734
954
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
735
955
|
}
|
|
736
956
|
async function runBatch(items, execute, options) {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
}
|
|
740
|
-
if (items.length > 5e3) {
|
|
741
|
-
throw new Error(`Signaliz batch requests support at most 5,000 items; received ${items.length}`);
|
|
742
|
-
}
|
|
743
|
-
const concurrency = options?.concurrency ?? 10;
|
|
744
|
-
if (!Number.isInteger(concurrency) || concurrency < 1 || concurrency > 50) {
|
|
745
|
-
throw new Error("Signaliz batch concurrency must be an integer between 1 and 50");
|
|
746
|
-
}
|
|
957
|
+
validateBatchSize(items);
|
|
958
|
+
const concurrency = validatedBatchConcurrency(options);
|
|
747
959
|
const startedAt = Date.now();
|
|
748
960
|
const results = new Array(items.length);
|
|
749
961
|
let nextIndex = 0;
|