salesprompter-cli 0.1.57 → 0.1.59
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 +1 -1
- package/dist/cli.js +110 -74
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ salesprompter companies:resolve-linkedin-urls --in ./companies.txt --out ./compa
|
|
|
66
66
|
salesprompter contacts:resolve-emails --in ./contacts.tsv --out-dir ./email-run --dry-run
|
|
67
67
|
|
|
68
68
|
# Collect a Sales Navigator people search into the active workspace
|
|
69
|
-
#
|
|
69
|
+
# Oversized or pagination-short searches are split by company headcount and deduplicated.
|
|
70
70
|
salesprompter leads:collect \
|
|
71
71
|
--linkedin-url "$SALES_NAV_PEOPLE_URL"
|
|
72
72
|
|
package/dist/cli.js
CHANGED
|
@@ -8752,99 +8752,135 @@ async function fetchCompleteLocalSalesNavigatorPeople(sourceQueryUrl, requestHea
|
|
|
8752
8752
|
const dimensions = localPeopleSplitDimensions(root.sourceQueryUrl);
|
|
8753
8753
|
const queue = [root];
|
|
8754
8754
|
const queuedUrls = new Set([root.slicedQueryUrl]);
|
|
8755
|
+
const rootRecoveryDimensionKeys = new Set();
|
|
8755
8756
|
const peopleByKey = new Map();
|
|
8756
8757
|
const slices = [];
|
|
8757
8758
|
let rootTotalResults = null;
|
|
8758
8759
|
let fetchedPages = 0;
|
|
8759
8760
|
let totalDelayMs = 0;
|
|
8760
8761
|
let retryCount = 0;
|
|
8761
|
-
while (
|
|
8762
|
-
|
|
8763
|
-
|
|
8764
|
-
|
|
8765
|
-
|
|
8766
|
-
|
|
8767
|
-
|
|
8768
|
-
|
|
8769
|
-
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
catch (error) {
|
|
8788
|
-
if (!(error instanceof SalesNavigatorSliceTooBroadError)) {
|
|
8789
|
-
throw error;
|
|
8762
|
+
while (true) {
|
|
8763
|
+
while (queue.length > 0) {
|
|
8764
|
+
const attempt = queue.shift();
|
|
8765
|
+
const parsedRequest = {
|
|
8766
|
+
url: buildSalesNavigatorLeadApiUrlFromSearchUrl(attempt.slicedQueryUrl, options.pageSize),
|
|
8767
|
+
headers: requestHeaders,
|
|
8768
|
+
};
|
|
8769
|
+
let collected = null;
|
|
8770
|
+
let tooBroadTotal = null;
|
|
8771
|
+
let probeFetchedPages = 0;
|
|
8772
|
+
try {
|
|
8773
|
+
collected = await fetchAllLocalSalesNavigatorPeople(parsedRequest, {
|
|
8774
|
+
requestedProfiles: options.maxResultsPerSearch,
|
|
8775
|
+
maxAllowedResults: options.maxResultsPerSearch,
|
|
8776
|
+
pageSize: options.pageSize,
|
|
8777
|
+
pageDelayMinMs: options.pageDelayMinMs,
|
|
8778
|
+
pageDelayMaxMs: options.pageDelayMaxMs,
|
|
8779
|
+
retry: options.retry,
|
|
8780
|
+
executeRequest: options.executeRequest,
|
|
8781
|
+
});
|
|
8782
|
+
fetchedPages += collected.fetchedPages;
|
|
8783
|
+
totalDelayMs += collected.pacing.totalDelayMs;
|
|
8784
|
+
retryCount += collected.pacing.retryCount;
|
|
8785
|
+
if (attempt.depth === 0) {
|
|
8786
|
+
rootTotalResults = collected.totalResults;
|
|
8787
|
+
}
|
|
8790
8788
|
}
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8789
|
+
catch (error) {
|
|
8790
|
+
if (!(error instanceof SalesNavigatorSliceTooBroadError)) {
|
|
8791
|
+
throw error;
|
|
8792
|
+
}
|
|
8793
|
+
tooBroadTotal = error.totalResults;
|
|
8794
|
+
const details = error.details && typeof error.details === "object"
|
|
8795
|
+
? error.details
|
|
8796
|
+
: {};
|
|
8797
|
+
probeFetchedPages = Number(details.fetchedPages ?? 1);
|
|
8798
|
+
fetchedPages += probeFetchedPages;
|
|
8799
|
+
retryCount += Number(details.retryCount ?? 0);
|
|
8800
|
+
totalDelayMs += Number(details.totalDelayMs ?? 0);
|
|
8801
|
+
if (attempt.depth === 0) {
|
|
8802
|
+
rootTotalResults = tooBroadTotal;
|
|
8803
|
+
}
|
|
8801
8804
|
}
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
|
|
8811
|
-
|
|
8805
|
+
const needsSplit = tooBroadTotal != null ||
|
|
8806
|
+
(collected?.totalResults == null &&
|
|
8807
|
+
collected != null &&
|
|
8808
|
+
collected.people.length >= options.maxResultsPerSearch) ||
|
|
8809
|
+
(attempt.depth === 0 &&
|
|
8810
|
+
collected?.totalResults != null &&
|
|
8811
|
+
collected.people.length < collected.totalResults);
|
|
8812
|
+
if (needsSplit) {
|
|
8813
|
+
const usedDimensionKeys = new Set(attempt.splitTrail.map((entry) => entry.key.replace(/-residual$/, "")));
|
|
8814
|
+
const nextDimension = dimensions.find((dimension) => !usedDimensionKeys.has(dimension.key));
|
|
8815
|
+
if (!nextDimension) {
|
|
8816
|
+
throw new Error(`Sales Navigator search could not be completed within the ${options.maxResultsPerSearch}-person window after all safe split dimensions were used. Narrow the source search further.`);
|
|
8817
|
+
}
|
|
8818
|
+
if (attempt.depth === 0) {
|
|
8819
|
+
rootRecoveryDimensionKeys.add(nextDimension.key);
|
|
8820
|
+
}
|
|
8821
|
+
const children = expandSalesNavigatorCrawlAttempt(attempt, nextDimension, "people");
|
|
8822
|
+
if (nextDimension.supportsResidualExclusion !== false) {
|
|
8823
|
+
children.push(buildSalesNavigatorResidualCrawlAttempt(attempt, nextDimension, "people"));
|
|
8824
|
+
}
|
|
8825
|
+
for (const child of children) {
|
|
8826
|
+
if (queuedUrls.has(child.slicedQueryUrl))
|
|
8827
|
+
continue;
|
|
8828
|
+
queuedUrls.add(child.slicedQueryUrl);
|
|
8829
|
+
queue.push(child);
|
|
8830
|
+
}
|
|
8831
|
+
slices.push({
|
|
8832
|
+
depth: attempt.depth,
|
|
8833
|
+
splitTrail: attempt.splitTrail,
|
|
8834
|
+
totalResults: tooBroadTotal ?? collected?.totalResults ?? null,
|
|
8835
|
+
collected: 0,
|
|
8836
|
+
fetchedPages: probeFetchedPages || collected?.fetchedPages || 0,
|
|
8837
|
+
status: "split",
|
|
8838
|
+
splitDimension: nextDimension.key,
|
|
8839
|
+
});
|
|
8840
|
+
continue;
|
|
8812
8841
|
}
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
children.push(buildSalesNavigatorResidualCrawlAttempt(attempt, nextDimension, "people"));
|
|
8842
|
+
if (!collected) {
|
|
8843
|
+
throw new Error("Sales Navigator slice did not return a collection result.");
|
|
8816
8844
|
}
|
|
8817
|
-
for (const
|
|
8818
|
-
|
|
8819
|
-
continue;
|
|
8820
|
-
queuedUrls.add(child.slicedQueryUrl);
|
|
8821
|
-
queue.push(child);
|
|
8845
|
+
for (const person of collected.people) {
|
|
8846
|
+
peopleByKey.set(canonicalLocalSalesNavigatorLeadKey(person), person);
|
|
8822
8847
|
}
|
|
8823
8848
|
slices.push({
|
|
8824
8849
|
depth: attempt.depth,
|
|
8825
8850
|
splitTrail: attempt.splitTrail,
|
|
8826
|
-
totalResults:
|
|
8827
|
-
collected:
|
|
8828
|
-
fetchedPages:
|
|
8829
|
-
status: "
|
|
8830
|
-
splitDimension:
|
|
8851
|
+
totalResults: collected.totalResults,
|
|
8852
|
+
collected: collected.people.length,
|
|
8853
|
+
fetchedPages: collected.fetchedPages,
|
|
8854
|
+
status: "collected",
|
|
8855
|
+
splitDimension: null,
|
|
8831
8856
|
});
|
|
8832
|
-
continue;
|
|
8833
8857
|
}
|
|
8834
|
-
if (
|
|
8835
|
-
|
|
8858
|
+
if (rootTotalResults == null || peopleByKey.size >= rootTotalResults) {
|
|
8859
|
+
break;
|
|
8860
|
+
}
|
|
8861
|
+
const nextRecoveryDimension = dimensions.find((dimension) => !rootRecoveryDimensionKeys.has(dimension.key));
|
|
8862
|
+
if (!nextRecoveryDimension) {
|
|
8863
|
+
break;
|
|
8836
8864
|
}
|
|
8837
|
-
|
|
8838
|
-
|
|
8865
|
+
rootRecoveryDimensionKeys.add(nextRecoveryDimension.key);
|
|
8866
|
+
const recoveryChildren = expandSalesNavigatorCrawlAttempt(root, nextRecoveryDimension, "people");
|
|
8867
|
+
if (nextRecoveryDimension.supportsResidualExclusion !== false) {
|
|
8868
|
+
recoveryChildren.push(buildSalesNavigatorResidualCrawlAttempt(root, nextRecoveryDimension, "people"));
|
|
8869
|
+
}
|
|
8870
|
+
for (const child of recoveryChildren) {
|
|
8871
|
+
if (queuedUrls.has(child.slicedQueryUrl))
|
|
8872
|
+
continue;
|
|
8873
|
+
queuedUrls.add(child.slicedQueryUrl);
|
|
8874
|
+
queue.push(child);
|
|
8839
8875
|
}
|
|
8840
8876
|
slices.push({
|
|
8841
|
-
depth:
|
|
8842
|
-
splitTrail:
|
|
8843
|
-
totalResults:
|
|
8844
|
-
collected:
|
|
8845
|
-
fetchedPages:
|
|
8846
|
-
status: "
|
|
8847
|
-
splitDimension:
|
|
8877
|
+
depth: 0,
|
|
8878
|
+
splitTrail: [],
|
|
8879
|
+
totalResults: rootTotalResults,
|
|
8880
|
+
collected: 0,
|
|
8881
|
+
fetchedPages: 0,
|
|
8882
|
+
status: "split",
|
|
8883
|
+
splitDimension: nextRecoveryDimension.key,
|
|
8848
8884
|
});
|
|
8849
8885
|
}
|
|
8850
8886
|
const people = [...peopleByKey.values()];
|
package/package.json
CHANGED