@lhremote/core 0.7.0 → 0.8.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.
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/index.js.map +1 -1
- package/dist/db/repositories/action-budget.d.ts +29 -0
- package/dist/db/repositories/action-budget.d.ts.map +1 -0
- package/dist/db/repositories/action-budget.js +100 -0
- package/dist/db/repositories/action-budget.js.map +1 -0
- package/dist/db/repositories/action-budget.test.d.ts +2 -0
- package/dist/db/repositories/action-budget.test.d.ts.map +1 -0
- package/dist/db/repositories/action-budget.test.js +181 -0
- package/dist/db/repositories/action-budget.test.js.map +1 -0
- package/dist/db/repositories/campaign-hard-delete.integration.test.d.ts +2 -0
- package/dist/db/repositories/campaign-hard-delete.integration.test.d.ts.map +1 -0
- package/dist/db/repositories/campaign-hard-delete.integration.test.js +78 -0
- package/dist/db/repositories/campaign-hard-delete.integration.test.js.map +1 -0
- package/dist/db/repositories/campaign.d.ts +14 -0
- package/dist/db/repositories/campaign.d.ts.map +1 -1
- package/dist/db/repositories/campaign.js +125 -0
- package/dist/db/repositories/campaign.js.map +1 -1
- package/dist/db/repositories/index.d.ts +1 -0
- package/dist/db/repositories/index.d.ts.map +1 -1
- package/dist/db/repositories/index.js +1 -0
- package/dist/db/repositories/index.js.map +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +24 -4
- package/dist/index.js.map +1 -1
- package/dist/linkedin/__tests__/dom-automation.integration.test.d.ts +2 -0
- package/dist/linkedin/__tests__/dom-automation.integration.test.d.ts.map +1 -0
- package/dist/linkedin/__tests__/dom-automation.integration.test.js +160 -0
- package/dist/linkedin/__tests__/dom-automation.integration.test.js.map +1 -0
- package/dist/linkedin/__tests__/selectors.integration.test.d.ts +2 -0
- package/dist/linkedin/__tests__/selectors.integration.test.d.ts.map +1 -0
- package/dist/linkedin/__tests__/selectors.integration.test.js +258 -0
- package/dist/linkedin/__tests__/selectors.integration.test.js.map +1 -0
- package/dist/linkedin/dom-automation.d.ts +67 -0
- package/dist/linkedin/dom-automation.d.ts.map +1 -0
- package/dist/linkedin/dom-automation.js +139 -0
- package/dist/linkedin/dom-automation.js.map +1 -0
- package/dist/linkedin/index.d.ts +3 -0
- package/dist/linkedin/index.d.ts.map +1 -0
- package/dist/linkedin/index.js +5 -0
- package/dist/linkedin/index.js.map +1 -0
- package/dist/linkedin/selectors.d.ts +67 -0
- package/dist/linkedin/selectors.d.ts.map +1 -0
- package/dist/linkedin/selectors.js +74 -0
- package/dist/linkedin/selectors.js.map +1 -0
- package/dist/operations/campaign-delete.d.ts +6 -2
- package/dist/operations/campaign-delete.d.ts.map +1 -1
- package/dist/operations/campaign-delete.js +9 -2
- package/dist/operations/campaign-delete.js.map +1 -1
- package/dist/operations/campaign-delete.test.js +41 -1
- package/dist/operations/campaign-delete.test.js.map +1 -1
- package/dist/operations/campaign-erase.d.ts +19 -0
- package/dist/operations/campaign-erase.d.ts.map +1 -0
- package/dist/operations/campaign-erase.js +22 -0
- package/dist/operations/campaign-erase.js.map +1 -0
- package/dist/operations/campaign-erase.test.d.ts +2 -0
- package/dist/operations/campaign-erase.test.d.ts.map +1 -0
- package/dist/operations/campaign-erase.test.js +101 -0
- package/dist/operations/campaign-erase.test.js.map +1 -0
- package/dist/operations/comment-on-post.d.ts +34 -0
- package/dist/operations/comment-on-post.d.ts.map +1 -0
- package/dist/operations/comment-on-post.js +108 -0
- package/dist/operations/comment-on-post.js.map +1 -0
- package/dist/operations/comment-on-post.test.d.ts +2 -0
- package/dist/operations/comment-on-post.test.d.ts.map +1 -0
- package/dist/operations/comment-on-post.test.js +240 -0
- package/dist/operations/comment-on-post.test.js.map +1 -0
- package/dist/operations/dismiss-errors.d.ts +22 -0
- package/dist/operations/dismiss-errors.d.ts.map +1 -0
- package/dist/operations/dismiss-errors.js +55 -0
- package/dist/operations/dismiss-errors.js.map +1 -0
- package/dist/operations/dismiss-errors.test.d.ts +2 -0
- package/dist/operations/dismiss-errors.test.d.ts.map +1 -0
- package/dist/operations/dismiss-errors.test.js +136 -0
- package/dist/operations/dismiss-errors.test.js.map +1 -0
- package/dist/operations/endorse-skills.d.ts +10 -0
- package/dist/operations/endorse-skills.d.ts.map +1 -0
- package/dist/operations/endorse-skills.js +12 -0
- package/dist/operations/endorse-skills.js.map +1 -0
- package/dist/operations/enrich-profile.d.ts +18 -0
- package/dist/operations/enrich-profile.d.ts.map +1 -0
- package/dist/operations/enrich-profile.js +15 -0
- package/dist/operations/enrich-profile.js.map +1 -0
- package/dist/operations/ephemeral-action.d.ts +22 -0
- package/dist/operations/ephemeral-action.d.ts.map +1 -0
- package/dist/operations/ephemeral-action.js +31 -0
- package/dist/operations/ephemeral-action.js.map +1 -0
- package/dist/operations/follow-person.d.ts +9 -0
- package/dist/operations/follow-person.d.ts.map +1 -0
- package/dist/operations/follow-person.js +11 -0
- package/dist/operations/follow-person.js.map +1 -0
- package/dist/operations/get-action-budget.d.ts +6 -0
- package/dist/operations/get-action-budget.d.ts.map +1 -0
- package/dist/operations/get-action-budget.js +22 -0
- package/dist/operations/get-action-budget.js.map +1 -0
- package/dist/operations/get-action-budget.test.d.ts +2 -0
- package/dist/operations/get-action-budget.test.d.ts.map +1 -0
- package/dist/operations/get-action-budget.test.js +79 -0
- package/dist/operations/get-action-budget.test.js.map +1 -0
- package/dist/operations/get-errors.d.ts +9 -3
- package/dist/operations/get-errors.d.ts.map +1 -1
- package/dist/operations/get-errors.js +41 -4
- package/dist/operations/get-errors.js.map +1 -1
- package/dist/operations/get-errors.test.js +108 -42
- package/dist/operations/get-errors.test.js.map +1 -1
- package/dist/operations/get-feed.d.ts +33 -0
- package/dist/operations/get-feed.d.ts.map +1 -0
- package/dist/operations/get-feed.js +220 -0
- package/dist/operations/get-feed.js.map +1 -0
- package/dist/operations/get-feed.test.d.ts +2 -0
- package/dist/operations/get-feed.test.d.ts.map +1 -0
- package/dist/operations/get-feed.test.js +276 -0
- package/dist/operations/get-feed.test.js.map +1 -0
- package/dist/operations/get-post-engagers.d.ts +40 -0
- package/dist/operations/get-post-engagers.d.ts.map +1 -0
- package/dist/operations/get-post-engagers.js +128 -0
- package/dist/operations/get-post-engagers.js.map +1 -0
- package/dist/operations/get-post-engagers.test.d.ts +2 -0
- package/dist/operations/get-post-engagers.test.d.ts.map +1 -0
- package/dist/operations/get-post-engagers.test.js +19 -0
- package/dist/operations/get-post-engagers.test.js.map +1 -0
- package/dist/operations/get-post-stats.d.ts +38 -0
- package/dist/operations/get-post-stats.d.ts.map +1 -0
- package/dist/operations/get-post-stats.js +100 -0
- package/dist/operations/get-post-stats.js.map +1 -0
- package/dist/operations/get-post-stats.test.d.ts +2 -0
- package/dist/operations/get-post-stats.test.d.ts.map +1 -0
- package/dist/operations/get-post-stats.test.js +34 -0
- package/dist/operations/get-post-stats.test.js.map +1 -0
- package/dist/operations/get-post.d.ts +183 -0
- package/dist/operations/get-post.d.ts.map +1 -0
- package/dist/operations/get-post.js +270 -0
- package/dist/operations/get-post.js.map +1 -0
- package/dist/operations/get-post.test.d.ts +2 -0
- package/dist/operations/get-post.test.d.ts.map +1 -0
- package/dist/operations/get-post.test.js +449 -0
- package/dist/operations/get-post.test.js.map +1 -0
- package/dist/operations/get-profile-activity.d.ts +129 -0
- package/dist/operations/get-profile-activity.d.ts.map +1 -0
- package/dist/operations/get-profile-activity.js +181 -0
- package/dist/operations/get-profile-activity.js.map +1 -0
- package/dist/operations/get-profile-activity.test.d.ts +2 -0
- package/dist/operations/get-profile-activity.test.d.ts.map +1 -0
- package/dist/operations/get-profile-activity.test.js +205 -0
- package/dist/operations/get-profile-activity.test.js.map +1 -0
- package/dist/operations/get-throttle-status.d.ts +6 -0
- package/dist/operations/get-throttle-status.d.ts.map +1 -0
- package/dist/operations/get-throttle-status.js +30 -0
- package/dist/operations/get-throttle-status.js.map +1 -0
- package/dist/operations/get-throttle-status.test.d.ts +2 -0
- package/dist/operations/get-throttle-status.test.d.ts.map +1 -0
- package/dist/operations/get-throttle-status.test.js +62 -0
- package/dist/operations/get-throttle-status.test.js.map +1 -0
- package/dist/operations/index.d.ts +22 -0
- package/dist/operations/index.d.ts.map +1 -1
- package/dist/operations/index.js +32 -0
- package/dist/operations/index.js.map +1 -1
- package/dist/operations/like-person-posts.d.ts +14 -0
- package/dist/operations/like-person-posts.d.ts.map +1 -0
- package/dist/operations/like-person-posts.js +28 -0
- package/dist/operations/like-person-posts.js.map +1 -0
- package/dist/operations/message-person.d.ts +11 -0
- package/dist/operations/message-person.d.ts.map +1 -0
- package/dist/operations/message-person.js +19 -0
- package/dist/operations/message-person.js.map +1 -0
- package/dist/operations/react-to-post.d.ts +38 -0
- package/dist/operations/react-to-post.d.ts.map +1 -0
- package/dist/operations/react-to-post.js +82 -0
- package/dist/operations/react-to-post.js.map +1 -0
- package/dist/operations/react-to-post.test.d.ts +2 -0
- package/dist/operations/react-to-post.test.d.ts.map +1 -0
- package/dist/operations/react-to-post.test.js +154 -0
- package/dist/operations/react-to-post.test.js.map +1 -0
- package/dist/operations/remove-connection.d.ts +6 -0
- package/dist/operations/remove-connection.d.ts.map +1 -0
- package/dist/operations/remove-connection.js +7 -0
- package/dist/operations/remove-connection.js.map +1 -0
- package/dist/operations/search-posts.d.ts +143 -0
- package/dist/operations/search-posts.d.ts.map +1 -0
- package/dist/operations/search-posts.js +220 -0
- package/dist/operations/search-posts.js.map +1 -0
- package/dist/operations/search-posts.test.d.ts +2 -0
- package/dist/operations/search-posts.test.d.ts.map +1 -0
- package/dist/operations/search-posts.test.js +261 -0
- package/dist/operations/search-posts.test.js.map +1 -0
- package/dist/operations/send-inmail.d.ts +11 -0
- package/dist/operations/send-inmail.d.ts.map +1 -0
- package/dist/operations/send-inmail.js +19 -0
- package/dist/operations/send-inmail.js.map +1 -0
- package/dist/operations/send-invite.d.ts +9 -0
- package/dist/operations/send-invite.d.ts.map +1 -0
- package/dist/operations/send-invite.js +14 -0
- package/dist/operations/send-invite.js.map +1 -0
- package/dist/operations/visit-profile.d.ts +14 -0
- package/dist/operations/visit-profile.d.ts.map +1 -0
- package/dist/operations/visit-profile.js +49 -0
- package/dist/operations/visit-profile.js.map +1 -0
- package/dist/operations/visit-profile.test.d.ts +2 -0
- package/dist/operations/visit-profile.test.d.ts.map +1 -0
- package/dist/operations/visit-profile.test.js +193 -0
- package/dist/operations/visit-profile.test.js.map +1 -0
- package/dist/services/campaign.d.ts +10 -0
- package/dist/services/campaign.d.ts.map +1 -1
- package/dist/services/campaign.js +16 -0
- package/dist/services/campaign.js.map +1 -1
- package/dist/services/collection.d.ts +5 -2
- package/dist/services/collection.d.ts.map +1 -1
- package/dist/services/collection.js +24 -5
- package/dist/services/collection.js.map +1 -1
- package/dist/services/collection.test.js +51 -9
- package/dist/services/collection.test.js.map +1 -1
- package/dist/services/ephemeral-campaign.d.ts +64 -0
- package/dist/services/ephemeral-campaign.d.ts.map +1 -0
- package/dist/services/ephemeral-campaign.js +210 -0
- package/dist/services/ephemeral-campaign.js.map +1 -0
- package/dist/services/ephemeral-campaign.test.d.ts +2 -0
- package/dist/services/ephemeral-campaign.test.d.ts.map +1 -0
- package/dist/services/ephemeral-campaign.test.js +333 -0
- package/dist/services/ephemeral-campaign.test.js.map +1 -0
- package/dist/services/errors.d.ts +10 -0
- package/dist/services/errors.d.ts.map +1 -1
- package/dist/services/errors.js +20 -0
- package/dist/services/errors.js.map +1 -1
- package/dist/services/index.d.ts +3 -1
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +3 -1
- package/dist/services/index.js.map +1 -1
- package/dist/services/instance-context.d.ts.map +1 -1
- package/dist/services/instance-context.js +9 -1
- package/dist/services/instance-context.js.map +1 -1
- package/dist/services/instance-context.test.js +77 -1
- package/dist/services/instance-context.test.js.map +1 -1
- package/dist/services/instance.d.ts +31 -0
- package/dist/services/instance.d.ts.map +1 -1
- package/dist/services/instance.js +123 -0
- package/dist/services/instance.js.map +1 -1
- package/dist/services/instance.test.js +70 -0
- package/dist/services/instance.test.js.map +1 -1
- package/dist/services/launcher.d.ts +7 -0
- package/dist/services/launcher.d.ts.map +1 -1
- package/dist/services/launcher.js +18 -1
- package/dist/services/launcher.js.map +1 -1
- package/dist/types/action-budget.d.ts +52 -0
- package/dist/types/action-budget.d.ts.map +1 -0
- package/dist/types/action-budget.js +4 -0
- package/dist/types/action-budget.js.map +1 -0
- package/dist/types/campaign.d.ts +24 -0
- package/dist/types/campaign.d.ts.map +1 -1
- package/dist/types/feed.d.ts +32 -0
- package/dist/types/feed.d.ts.map +1 -0
- package/dist/types/feed.js +4 -0
- package/dist/types/feed.js.map +1 -0
- package/dist/types/index.d.ts +7 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/post-analytics.d.ts +40 -0
- package/dist/types/post-analytics.d.ts.map +1 -0
- package/dist/types/post-analytics.js +4 -0
- package/dist/types/post-analytics.js.map +1 -0
- package/dist/types/post.d.ts +43 -0
- package/dist/types/post.d.ts.map +1 -0
- package/dist/types/post.js +4 -0
- package/dist/types/post.js.map +1 -0
- package/dist/types/search-posts.d.ts +22 -0
- package/dist/types/search-posts.d.ts.map +1 -0
- package/dist/types/search-posts.js +4 -0
- package/dist/types/search-posts.js.map +1 -0
- package/dist/types/ui-health.d.ts +16 -0
- package/dist/types/ui-health.d.ts.map +1 -1
- package/dist/voyager/index.d.ts +2 -0
- package/dist/voyager/index.d.ts.map +1 -0
- package/dist/voyager/index.js +4 -0
- package/dist/voyager/index.js.map +1 -0
- package/dist/voyager/interceptor.d.ts +100 -0
- package/dist/voyager/interceptor.d.ts.map +1 -0
- package/dist/voyager/interceptor.integration.test.d.ts +2 -0
- package/dist/voyager/interceptor.integration.test.d.ts.map +1 -0
- package/dist/voyager/interceptor.integration.test.js +89 -0
- package/dist/voyager/interceptor.integration.test.js.map +1 -0
- package/dist/voyager/interceptor.js +235 -0
- package/dist/voyager/interceptor.js.map +1 -0
- package/dist/voyager/interceptor.test.d.ts +2 -0
- package/dist/voyager/interceptor.test.d.ts.map +1 -0
- package/dist/voyager/interceptor.test.js +372 -0
- package/dist/voyager/interceptor.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { ProfileRepository } from "../db/index.js";
|
|
4
|
+
import { delay } from "../utils/delay.js";
|
|
5
|
+
import { CampaignService } from "./campaign.js";
|
|
6
|
+
import { CampaignExecutionError, CampaignTimeoutError } from "./errors.js";
|
|
7
|
+
/** Default timeout for ephemeral action execution (5 minutes). */
|
|
8
|
+
const DEFAULT_TIMEOUT = 300_000;
|
|
9
|
+
/** Default interval between status polls (2 seconds). */
|
|
10
|
+
const DEFAULT_POLL_INTERVAL = 2_000;
|
|
11
|
+
/** Prefix for ephemeral campaign names. */
|
|
12
|
+
const CAMPAIGN_NAME_PREFIX = "[ephemeral]";
|
|
13
|
+
/**
|
|
14
|
+
* Executes a single LinkedHelper action on a single person without
|
|
15
|
+
* manual campaign setup.
|
|
16
|
+
*
|
|
17
|
+
* Creates a temporary campaign, adds the requested action, imports the
|
|
18
|
+
* target person, starts the campaign runner, polls for completion,
|
|
19
|
+
* extracts the result, then hard-deletes the campaign (or archives it
|
|
20
|
+
* if `keepCampaign: true`).
|
|
21
|
+
*/
|
|
22
|
+
export class EphemeralCampaignService {
|
|
23
|
+
campaignService;
|
|
24
|
+
profileRepo;
|
|
25
|
+
constructor(instance, db) {
|
|
26
|
+
this.campaignService = new CampaignService(instance, db);
|
|
27
|
+
this.profileRepo = new ProfileRepository(db);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Execute a single action on a single person using a temporary campaign.
|
|
31
|
+
*
|
|
32
|
+
* @param actionType - Action type identifier (e.g., 'MessageToPerson', 'InvitePerson').
|
|
33
|
+
* @param target - Person ID (number) or LinkedIn profile URL (string).
|
|
34
|
+
* @param actionSettings - Action-specific settings (e.g., message template).
|
|
35
|
+
* @param options - Execution options (timeout, keepCampaign, etc.).
|
|
36
|
+
* @returns Action result with success status, person ID, and action results.
|
|
37
|
+
*
|
|
38
|
+
* @throws {CampaignExecutionError} if the target cannot be resolved, import fails,
|
|
39
|
+
* or the campaign cannot be started.
|
|
40
|
+
* @throws {CampaignTimeoutError} if the action does not complete within the timeout.
|
|
41
|
+
*/
|
|
42
|
+
async execute(actionType, target, actionSettings, options) {
|
|
43
|
+
const timeout = options?.timeout ?? DEFAULT_TIMEOUT;
|
|
44
|
+
const pollInterval = options?.pollInterval ?? DEFAULT_POLL_INTERVAL;
|
|
45
|
+
const keepCampaign = options?.keepCampaign ?? false;
|
|
46
|
+
// Step 1: Resolve target to LinkedIn URL and person ID (if known)
|
|
47
|
+
const resolved = this.resolveTarget(target);
|
|
48
|
+
// Step 2: Create temporary campaign
|
|
49
|
+
const campaign = await this.campaignService.create({
|
|
50
|
+
name: `${CAMPAIGN_NAME_PREFIX} ${actionType} ${new Date().toISOString()}`,
|
|
51
|
+
actions: [
|
|
52
|
+
{
|
|
53
|
+
name: actionType,
|
|
54
|
+
actionType,
|
|
55
|
+
...(actionSettings !== undefined && { actionSettings }),
|
|
56
|
+
coolDown: 0,
|
|
57
|
+
maxActionResultsPerIteration: 1,
|
|
58
|
+
},
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
try {
|
|
62
|
+
// Step 3: Import target person
|
|
63
|
+
const importResult = await this.campaignService.importPeopleFromUrls(campaign.id, [resolved.linkedInUrl]);
|
|
64
|
+
if (importResult.successful === 0 && importResult.alreadyInQueue === 0 && importResult.alreadyProcessed === 0) {
|
|
65
|
+
throw new CampaignExecutionError(`Failed to import target into campaign: ${resolved.linkedInUrl}`, campaign.id);
|
|
66
|
+
}
|
|
67
|
+
// Resolve person ID if not yet known (URL-based target)
|
|
68
|
+
const personId = resolved.personId ?? this.resolvePersonIdFromUrl(resolved.linkedInUrl);
|
|
69
|
+
// Step 4: Start campaign
|
|
70
|
+
await this.campaignService.start(campaign.id, []);
|
|
71
|
+
// Step 5: Poll for completion
|
|
72
|
+
await this.pollForCompletion(campaign.id, timeout, pollInterval);
|
|
73
|
+
// Step 6: Get results
|
|
74
|
+
const runResult = await this.campaignService.getResults(campaign.id);
|
|
75
|
+
const results = runResult.results;
|
|
76
|
+
const success = results.some((r) => r.result > 0);
|
|
77
|
+
// Step 7: Cleanup
|
|
78
|
+
await this.cleanup(campaign.id, keepCampaign);
|
|
79
|
+
return {
|
|
80
|
+
success,
|
|
81
|
+
personId,
|
|
82
|
+
results,
|
|
83
|
+
...(keepCampaign && { campaignId: campaign.id }),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
await this.cleanup(campaign.id, keepCampaign);
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Resolve a target (person ID or URL) to a LinkedIn URL and optional person ID.
|
|
93
|
+
*/
|
|
94
|
+
resolveTarget(target) {
|
|
95
|
+
if (typeof target === "number") {
|
|
96
|
+
// Person ID → look up LinkedIn URL from profile
|
|
97
|
+
const profiles = this.profileRepo.findByIds([target]);
|
|
98
|
+
const profile = profiles[0];
|
|
99
|
+
if (!profile) {
|
|
100
|
+
throw new CampaignExecutionError(`Person ${String(target)} not found in database`);
|
|
101
|
+
}
|
|
102
|
+
const publicId = profile.externalIds.find((e) => e.typeGroup === "public");
|
|
103
|
+
if (!publicId) {
|
|
104
|
+
throw new CampaignExecutionError(`Person ${String(target)} has no LinkedIn public ID`);
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
linkedInUrl: `https://www.linkedin.com/in/${publicId.externalId}`,
|
|
108
|
+
personId: target,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
// String target → validate and normalize LinkedIn URL; person ID resolved after import
|
|
112
|
+
const slug = this.extractSlug(target);
|
|
113
|
+
return {
|
|
114
|
+
linkedInUrl: `https://www.linkedin.com/in/${slug}`,
|
|
115
|
+
personId: undefined,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolve person ID from a LinkedIn profile URL after import.
|
|
120
|
+
*/
|
|
121
|
+
resolvePersonIdFromUrl(linkedInUrl) {
|
|
122
|
+
const slug = this.extractSlug(linkedInUrl);
|
|
123
|
+
try {
|
|
124
|
+
const profile = this.profileRepo.findByPublicId(slug);
|
|
125
|
+
return profile.id;
|
|
126
|
+
}
|
|
127
|
+
catch (cause) {
|
|
128
|
+
throw new CampaignExecutionError(`Could not resolve person ID for ${linkedInUrl} after import`, undefined, { cause: cause instanceof Error ? cause : undefined });
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Extract the LinkedIn public ID (slug) from a profile URL.
|
|
133
|
+
*/
|
|
134
|
+
extractSlug(url) {
|
|
135
|
+
const match = /linkedin\.com\/in\/([^/?#]+)/.exec(url);
|
|
136
|
+
if (!match?.[1]) {
|
|
137
|
+
throw new CampaignExecutionError(`Invalid LinkedIn profile URL: ${url}`);
|
|
138
|
+
}
|
|
139
|
+
return match[1];
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Poll campaign status until the target person's action completes or times out.
|
|
143
|
+
*/
|
|
144
|
+
async pollForCompletion(campaignId, timeout, pollInterval) {
|
|
145
|
+
const deadline = Date.now() + timeout;
|
|
146
|
+
while (Date.now() < deadline) {
|
|
147
|
+
const status = await this.campaignService.getStatus(campaignId);
|
|
148
|
+
const counts = status.actionCounts[0];
|
|
149
|
+
// Action complete when at least one person is successful or failed
|
|
150
|
+
if (counts && (counts.successful > 0 || counts.failed > 0)) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
// Runner returned to idle with no queued people — action is done
|
|
154
|
+
if (status.runnerState === "idle" && counts && counts.queued === 0) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const remaining = deadline - Date.now();
|
|
158
|
+
if (remaining <= 0)
|
|
159
|
+
break;
|
|
160
|
+
await delay(Math.min(pollInterval, remaining));
|
|
161
|
+
}
|
|
162
|
+
throw new CampaignTimeoutError(`Ephemeral action did not complete within ${String(timeout)}ms`, campaignId);
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Stop and remove/archive an ephemeral campaign (best-effort).
|
|
166
|
+
*/
|
|
167
|
+
async cleanup(campaignId, keepCampaign) {
|
|
168
|
+
await this.safeStop(campaignId);
|
|
169
|
+
if (keepCampaign) {
|
|
170
|
+
await this.safeArchive(campaignId);
|
|
171
|
+
}
|
|
172
|
+
else {
|
|
173
|
+
this.safeHardDelete(campaignId);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Stop campaign without throwing on failure.
|
|
178
|
+
*/
|
|
179
|
+
async safeStop(campaignId) {
|
|
180
|
+
try {
|
|
181
|
+
await this.campaignService.stop(campaignId);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Best-effort cleanup — campaign may already be stopped
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Archive campaign without throwing on failure.
|
|
189
|
+
*/
|
|
190
|
+
async safeArchive(campaignId) {
|
|
191
|
+
try {
|
|
192
|
+
await this.campaignService.delete(campaignId);
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
// Best-effort cleanup
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Hard-delete campaign without throwing on failure.
|
|
200
|
+
*/
|
|
201
|
+
safeHardDelete(campaignId) {
|
|
202
|
+
try {
|
|
203
|
+
this.campaignService.hardDelete(campaignId);
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
// Best-effort cleanup
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=ephemeral-campaign.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ephemeral-campaign.js","sourceRoot":"","sources":["../../src/services/ephemeral-campaign.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ephemeral-campaign.test.d.ts","sourceRoot":"","sources":["../../src/services/ephemeral-campaign.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-only
|
|
2
|
+
// Copyright (C) 2026 Oleksii PELYKH
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
4
|
+
import { CampaignExecutionError, CampaignTimeoutError, } from "./errors.js";
|
|
5
|
+
import { EphemeralCampaignService } from "./ephemeral-campaign.js";
|
|
6
|
+
// Mock InstanceService
|
|
7
|
+
const mockEvaluateUI = vi.fn();
|
|
8
|
+
vi.mock("./instance.js", () => ({
|
|
9
|
+
InstanceService: vi.fn().mockImplementation(function () {
|
|
10
|
+
this.evaluateUI = mockEvaluateUI;
|
|
11
|
+
}),
|
|
12
|
+
}));
|
|
13
|
+
// Mock CampaignRepository (via db/index.js)
|
|
14
|
+
const mockListCampaigns = vi.fn();
|
|
15
|
+
const mockGetCampaign = vi.fn();
|
|
16
|
+
const mockGetCampaignActions = vi.fn();
|
|
17
|
+
const mockGetResults = vi.fn();
|
|
18
|
+
const mockFixIsValid = vi.fn();
|
|
19
|
+
const mockCreateActionExcludeLists = vi.fn();
|
|
20
|
+
const mockDeleteCampaign = vi.fn();
|
|
21
|
+
// Mock CampaignStatisticsRepository
|
|
22
|
+
const mockResetForRerun = vi.fn();
|
|
23
|
+
// Mock ProfileRepository
|
|
24
|
+
const mockFindByIds = vi.fn();
|
|
25
|
+
const mockFindByPublicId = vi.fn();
|
|
26
|
+
vi.mock("../db/index.js", async (importOriginal) => {
|
|
27
|
+
const original = await importOriginal();
|
|
28
|
+
return {
|
|
29
|
+
CampaignRepository: vi.fn().mockImplementation(function () {
|
|
30
|
+
this.listCampaigns = mockListCampaigns;
|
|
31
|
+
this.getCampaign = mockGetCampaign;
|
|
32
|
+
this.getCampaignActions = mockGetCampaignActions;
|
|
33
|
+
this.getResults = mockGetResults;
|
|
34
|
+
this.fixIsValid = mockFixIsValid;
|
|
35
|
+
this.createActionExcludeLists = mockCreateActionExcludeLists;
|
|
36
|
+
this.deleteCampaign = mockDeleteCampaign;
|
|
37
|
+
}),
|
|
38
|
+
CampaignStatisticsRepository: vi.fn().mockImplementation(function () {
|
|
39
|
+
this.resetForRerun = mockResetForRerun;
|
|
40
|
+
}),
|
|
41
|
+
ProfileRepository: vi.fn().mockImplementation(function () {
|
|
42
|
+
this.findByIds = mockFindByIds;
|
|
43
|
+
this.findByPublicId = mockFindByPublicId;
|
|
44
|
+
}),
|
|
45
|
+
CampaignNotFoundError: original.CampaignNotFoundError,
|
|
46
|
+
ActionNotFoundError: original.ActionNotFoundError,
|
|
47
|
+
ProfileNotFoundError: original.ProfileNotFoundError,
|
|
48
|
+
};
|
|
49
|
+
});
|
|
50
|
+
import { InstanceService } from "./instance.js";
|
|
51
|
+
const MOCK_CAMPAIGN = {
|
|
52
|
+
id: 99,
|
|
53
|
+
name: "[ephemeral] MessageToPerson",
|
|
54
|
+
description: null,
|
|
55
|
+
state: "paused",
|
|
56
|
+
liAccountId: 1,
|
|
57
|
+
isPaused: true,
|
|
58
|
+
isArchived: false,
|
|
59
|
+
isValid: true,
|
|
60
|
+
createdAt: "2025-01-15T00:00:00Z",
|
|
61
|
+
};
|
|
62
|
+
const MOCK_ACTIONS = [
|
|
63
|
+
{
|
|
64
|
+
id: 10,
|
|
65
|
+
campaignId: 99,
|
|
66
|
+
name: "MessageToPerson",
|
|
67
|
+
description: null,
|
|
68
|
+
config: {
|
|
69
|
+
id: 100,
|
|
70
|
+
actionType: "MessageToPerson",
|
|
71
|
+
actionSettings: { message: "Hello" },
|
|
72
|
+
coolDown: 0,
|
|
73
|
+
maxActionResultsPerIteration: 1,
|
|
74
|
+
isDraft: false,
|
|
75
|
+
},
|
|
76
|
+
versionId: 1000,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
const MOCK_PROFILE = {
|
|
80
|
+
id: 42,
|
|
81
|
+
miniProfile: { firstName: "Ada", lastName: "Lovelace", headline: "Engineer", avatar: null },
|
|
82
|
+
externalIds: [
|
|
83
|
+
{ externalId: "ada-lovelace", typeGroup: "public", isMemberId: false },
|
|
84
|
+
{ externalId: "123456789", typeGroup: "member", isMemberId: true },
|
|
85
|
+
],
|
|
86
|
+
currentPosition: null,
|
|
87
|
+
education: [],
|
|
88
|
+
skills: [],
|
|
89
|
+
emails: [],
|
|
90
|
+
};
|
|
91
|
+
const MOCK_RESULT = {
|
|
92
|
+
id: 1,
|
|
93
|
+
actionVersionId: 1000,
|
|
94
|
+
personId: 42,
|
|
95
|
+
result: 1,
|
|
96
|
+
platform: "LINKEDIN",
|
|
97
|
+
createdAt: "2025-01-15T12:00:00Z",
|
|
98
|
+
profile: { firstName: "Ada", lastName: "Lovelace", headline: "Engineer", company: null, title: null },
|
|
99
|
+
};
|
|
100
|
+
afterEach(() => {
|
|
101
|
+
vi.restoreAllMocks();
|
|
102
|
+
});
|
|
103
|
+
describe("EphemeralCampaignService", () => {
|
|
104
|
+
let service;
|
|
105
|
+
beforeEach(() => {
|
|
106
|
+
vi.useFakeTimers();
|
|
107
|
+
vi.clearAllMocks();
|
|
108
|
+
mockEvaluateUI.mockResolvedValue(undefined);
|
|
109
|
+
const instance = new InstanceService(9223);
|
|
110
|
+
service = new EphemeralCampaignService(instance, {});
|
|
111
|
+
});
|
|
112
|
+
afterEach(() => {
|
|
113
|
+
vi.useRealTimers();
|
|
114
|
+
});
|
|
115
|
+
/**
|
|
116
|
+
* Set up mocks for a successful execute() flow:
|
|
117
|
+
* create → import → start (idle + unpause + runner) → poll (status) → results → stop → cleanup
|
|
118
|
+
*/
|
|
119
|
+
function setupSuccessFlow() {
|
|
120
|
+
// create: CDP createCampaign returns campaign ID
|
|
121
|
+
mockEvaluateUI.mockResolvedValueOnce({ id: 99 });
|
|
122
|
+
mockGetCampaign.mockReturnValue(MOCK_CAMPAIGN);
|
|
123
|
+
mockGetCampaignActions.mockReturnValue(MOCK_ACTIONS);
|
|
124
|
+
// import: CDP importPeopleFromUrls
|
|
125
|
+
mockEvaluateUI.mockResolvedValueOnce({
|
|
126
|
+
total: { addToTarget: { successful: 1, alreadyInQueue: 0, alreadyProcessed: 0, failed: 0 } },
|
|
127
|
+
});
|
|
128
|
+
// start: waitForIdle (idle), unpause, start runner
|
|
129
|
+
mockEvaluateUI
|
|
130
|
+
.mockResolvedValueOnce("idle") // getRunnerState
|
|
131
|
+
.mockResolvedValueOnce(undefined) // unpause
|
|
132
|
+
.mockResolvedValueOnce(true); // start
|
|
133
|
+
// poll: getStatus (campaign + actions + runnerState + isPaused + actionCounts)
|
|
134
|
+
mockEvaluateUI
|
|
135
|
+
.mockResolvedValueOnce("idle") // runnerState
|
|
136
|
+
.mockResolvedValueOnce(false) // isPaused
|
|
137
|
+
.mockResolvedValueOnce({ queued: 0, processed: 0, successful: 1, failed: 0 }); // actionCounts
|
|
138
|
+
// results
|
|
139
|
+
mockGetResults.mockReturnValue([MOCK_RESULT]);
|
|
140
|
+
// stop: pause + stop runner
|
|
141
|
+
mockEvaluateUI
|
|
142
|
+
.mockResolvedValueOnce(undefined) // pause
|
|
143
|
+
.mockResolvedValueOnce(undefined); // stop runner
|
|
144
|
+
// hardDelete is sync (db only)
|
|
145
|
+
}
|
|
146
|
+
describe("execute with person ID target", () => {
|
|
147
|
+
it("executes full lifecycle: create → import → start → poll → results → cleanup", async () => {
|
|
148
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
149
|
+
setupSuccessFlow();
|
|
150
|
+
const promise = service.execute("MessageToPerson", 42, { message: "Hello" });
|
|
151
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
152
|
+
const result = await promise;
|
|
153
|
+
expect(result.success).toBe(true);
|
|
154
|
+
expect(result.personId).toBe(42);
|
|
155
|
+
expect(result.results).toEqual([MOCK_RESULT]);
|
|
156
|
+
expect(result.campaignId).toBeUndefined();
|
|
157
|
+
});
|
|
158
|
+
it("resolves LinkedIn URL from person profile", async () => {
|
|
159
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
160
|
+
setupSuccessFlow();
|
|
161
|
+
const promise = service.execute("MessageToPerson", 42);
|
|
162
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
163
|
+
await promise;
|
|
164
|
+
// import call should include the resolved LinkedIn URL
|
|
165
|
+
const importExpr = mockEvaluateUI.mock.calls[1]?.[0];
|
|
166
|
+
expect(importExpr).toContain("ada-lovelace");
|
|
167
|
+
});
|
|
168
|
+
it("throws CampaignExecutionError when person ID not found", async () => {
|
|
169
|
+
mockFindByIds.mockReturnValue([null]);
|
|
170
|
+
await expect(service.execute("MessageToPerson", 999)).rejects.toThrow(CampaignExecutionError);
|
|
171
|
+
});
|
|
172
|
+
it("throws CampaignExecutionError when person has no public ID", async () => {
|
|
173
|
+
mockFindByIds.mockReturnValue([{
|
|
174
|
+
...MOCK_PROFILE,
|
|
175
|
+
externalIds: [{ externalId: "123", typeGroup: "member", isMemberId: true }],
|
|
176
|
+
}]);
|
|
177
|
+
await expect(service.execute("MessageToPerson", 42)).rejects.toThrow(CampaignExecutionError);
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe("execute with LinkedIn URL target", () => {
|
|
181
|
+
it("imports from URL and resolves person ID after import", async () => {
|
|
182
|
+
mockFindByPublicId.mockReturnValue(MOCK_PROFILE);
|
|
183
|
+
setupSuccessFlow();
|
|
184
|
+
const promise = service.execute("InvitePerson", "https://www.linkedin.com/in/ada-lovelace");
|
|
185
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
186
|
+
const result = await promise;
|
|
187
|
+
expect(result.success).toBe(true);
|
|
188
|
+
expect(result.personId).toBe(42);
|
|
189
|
+
expect(mockFindByPublicId).toHaveBeenCalledWith("ada-lovelace");
|
|
190
|
+
});
|
|
191
|
+
it("throws CampaignExecutionError for invalid LinkedIn URL before campaign creation", async () => {
|
|
192
|
+
await expect(service.execute("InvitePerson", "https://example.com/not-linkedin")).rejects.toThrow(CampaignExecutionError);
|
|
193
|
+
// No CDP calls should have been made (validation fails before create)
|
|
194
|
+
expect(mockEvaluateUI).not.toHaveBeenCalled();
|
|
195
|
+
});
|
|
196
|
+
});
|
|
197
|
+
describe("import failure", () => {
|
|
198
|
+
it("throws CampaignExecutionError when import fails and cleans up", async () => {
|
|
199
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
200
|
+
// create succeeds
|
|
201
|
+
mockEvaluateUI.mockResolvedValueOnce({ id: 99 });
|
|
202
|
+
mockGetCampaign.mockReturnValue(MOCK_CAMPAIGN);
|
|
203
|
+
mockGetCampaignActions.mockReturnValue(MOCK_ACTIONS);
|
|
204
|
+
// import returns zero successful
|
|
205
|
+
mockEvaluateUI.mockResolvedValueOnce({
|
|
206
|
+
total: { addToTarget: { successful: 0, alreadyInQueue: 0, alreadyProcessed: 0, failed: 1 } },
|
|
207
|
+
});
|
|
208
|
+
await expect(service.execute("MessageToPerson", 42)).rejects.toThrow(CampaignExecutionError);
|
|
209
|
+
// Verify cleanup happened (hardDelete is sync)
|
|
210
|
+
expect(mockDeleteCampaign).toHaveBeenCalledWith(99);
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
describe("timeout handling", () => {
|
|
214
|
+
it("throws CampaignTimeoutError when action does not complete", async () => {
|
|
215
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
216
|
+
// create
|
|
217
|
+
mockEvaluateUI.mockResolvedValueOnce({ id: 99 });
|
|
218
|
+
mockGetCampaign.mockReturnValue(MOCK_CAMPAIGN);
|
|
219
|
+
mockGetCampaignActions.mockReturnValue(MOCK_ACTIONS);
|
|
220
|
+
// import
|
|
221
|
+
mockEvaluateUI.mockResolvedValueOnce({
|
|
222
|
+
total: { addToTarget: { successful: 1, alreadyInQueue: 0, alreadyProcessed: 0, failed: 0 } },
|
|
223
|
+
});
|
|
224
|
+
// start
|
|
225
|
+
mockEvaluateUI
|
|
226
|
+
.mockResolvedValueOnce("idle")
|
|
227
|
+
.mockResolvedValueOnce(undefined)
|
|
228
|
+
.mockResolvedValueOnce(true);
|
|
229
|
+
// poll: return type-correct shapes that keep the poll going (never completes)
|
|
230
|
+
// getStatus calls 3 CDP methods: runnerState, isPaused, actionCounts
|
|
231
|
+
let pollCall = 0;
|
|
232
|
+
mockEvaluateUI.mockImplementation(() => {
|
|
233
|
+
const phase = pollCall % 3;
|
|
234
|
+
pollCall++;
|
|
235
|
+
if (phase === 0)
|
|
236
|
+
return Promise.resolve("campaigns");
|
|
237
|
+
if (phase === 1)
|
|
238
|
+
return Promise.resolve(false);
|
|
239
|
+
return Promise.resolve({ queued: 1, processed: 0, successful: 0, failed: 0 });
|
|
240
|
+
});
|
|
241
|
+
const promise = service.execute("MessageToPerson", 42, undefined, { timeout: 5_000 });
|
|
242
|
+
const caughtPromise = promise.catch((e) => e);
|
|
243
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
244
|
+
const error = await caughtPromise;
|
|
245
|
+
expect(error).toBeInstanceOf(CampaignTimeoutError);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
describe("keepCampaign option", () => {
|
|
249
|
+
it("archives instead of hard-deleting when keepCampaign is true", async () => {
|
|
250
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
251
|
+
setupSuccessFlow();
|
|
252
|
+
const promise = service.execute("MessageToPerson", 42, undefined, { keepCampaign: true });
|
|
253
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
254
|
+
const result = await promise;
|
|
255
|
+
expect(result.campaignId).toBe(99);
|
|
256
|
+
// Should NOT hard-delete
|
|
257
|
+
expect(mockDeleteCampaign).not.toHaveBeenCalled();
|
|
258
|
+
// Archive is done via CDP (setCampaignArchivedStatus) — verify the call
|
|
259
|
+
const archiveCall = mockEvaluateUI.mock.calls.find((call) => call[0].includes("setCampaignArchivedStatus"));
|
|
260
|
+
expect(archiveCall).toBeDefined();
|
|
261
|
+
});
|
|
262
|
+
});
|
|
263
|
+
describe("failed action result", () => {
|
|
264
|
+
it("returns success=false when action result is negative", async () => {
|
|
265
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
266
|
+
// create
|
|
267
|
+
mockEvaluateUI.mockResolvedValueOnce({ id: 99 });
|
|
268
|
+
mockGetCampaign.mockReturnValue(MOCK_CAMPAIGN);
|
|
269
|
+
mockGetCampaignActions.mockReturnValue(MOCK_ACTIONS);
|
|
270
|
+
// import
|
|
271
|
+
mockEvaluateUI.mockResolvedValueOnce({
|
|
272
|
+
total: { addToTarget: { successful: 1, alreadyInQueue: 0, alreadyProcessed: 0, failed: 0 } },
|
|
273
|
+
});
|
|
274
|
+
// start
|
|
275
|
+
mockEvaluateUI
|
|
276
|
+
.mockResolvedValueOnce("idle")
|
|
277
|
+
.mockResolvedValueOnce(undefined)
|
|
278
|
+
.mockResolvedValueOnce(true);
|
|
279
|
+
// poll: action failed
|
|
280
|
+
mockEvaluateUI
|
|
281
|
+
.mockResolvedValueOnce("idle")
|
|
282
|
+
.mockResolvedValueOnce(false)
|
|
283
|
+
.mockResolvedValueOnce({ queued: 0, processed: 0, successful: 0, failed: 1 });
|
|
284
|
+
// results
|
|
285
|
+
const failedResult = { ...MOCK_RESULT, result: -1 };
|
|
286
|
+
mockGetResults.mockReturnValue([failedResult]);
|
|
287
|
+
// stop
|
|
288
|
+
mockEvaluateUI
|
|
289
|
+
.mockResolvedValueOnce(undefined)
|
|
290
|
+
.mockResolvedValueOnce(undefined);
|
|
291
|
+
const promise = service.execute("MessageToPerson", 42);
|
|
292
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
293
|
+
const result = await promise;
|
|
294
|
+
expect(result.success).toBe(false);
|
|
295
|
+
expect(result.results[0]?.result).toBe(-1);
|
|
296
|
+
});
|
|
297
|
+
});
|
|
298
|
+
describe("runner idle with no queued", () => {
|
|
299
|
+
it("completes when runner returns to idle with zero queued", async () => {
|
|
300
|
+
mockFindByIds.mockReturnValue([MOCK_PROFILE]);
|
|
301
|
+
// create
|
|
302
|
+
mockEvaluateUI.mockResolvedValueOnce({ id: 99 });
|
|
303
|
+
mockGetCampaign.mockReturnValue(MOCK_CAMPAIGN);
|
|
304
|
+
mockGetCampaignActions.mockReturnValue(MOCK_ACTIONS);
|
|
305
|
+
// import
|
|
306
|
+
mockEvaluateUI.mockResolvedValueOnce({
|
|
307
|
+
total: { addToTarget: { successful: 1, alreadyInQueue: 0, alreadyProcessed: 0, failed: 0 } },
|
|
308
|
+
});
|
|
309
|
+
// start
|
|
310
|
+
mockEvaluateUI
|
|
311
|
+
.mockResolvedValueOnce("idle")
|
|
312
|
+
.mockResolvedValueOnce(undefined)
|
|
313
|
+
.mockResolvedValueOnce(true);
|
|
314
|
+
// poll: idle with zero queued but zero successful/failed (edge case)
|
|
315
|
+
mockEvaluateUI
|
|
316
|
+
.mockResolvedValueOnce("idle")
|
|
317
|
+
.mockResolvedValueOnce(false)
|
|
318
|
+
.mockResolvedValueOnce({ queued: 0, processed: 0, successful: 0, failed: 0 });
|
|
319
|
+
// results (empty — person was processed but no result recorded)
|
|
320
|
+
mockGetResults.mockReturnValue([]);
|
|
321
|
+
// stop
|
|
322
|
+
mockEvaluateUI
|
|
323
|
+
.mockResolvedValueOnce(undefined)
|
|
324
|
+
.mockResolvedValueOnce(undefined);
|
|
325
|
+
const promise = service.execute("MessageToPerson", 42);
|
|
326
|
+
await vi.advanceTimersByTimeAsync(10_000);
|
|
327
|
+
const result = await promise;
|
|
328
|
+
expect(result.success).toBe(false);
|
|
329
|
+
expect(result.results).toEqual([]);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
});
|
|
333
|
+
//# sourceMappingURL=ephemeral-campaign.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ephemeral-campaign.test.js","sourceRoot":"","sources":["../../src/services/ephemeral-campaign.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -121,6 +121,16 @@ export declare class CampaignTimeoutError extends ServiceError {
|
|
|
121
121
|
readonly campaignId: number | undefined;
|
|
122
122
|
constructor(message: string, campaignId?: number, options?: ErrorOptions);
|
|
123
123
|
}
|
|
124
|
+
/**
|
|
125
|
+
* Thrown when an action cannot proceed because its daily budget
|
|
126
|
+
* has been exhausted.
|
|
127
|
+
*/
|
|
128
|
+
export declare class BudgetExceededError extends ServiceError {
|
|
129
|
+
readonly limitType: string;
|
|
130
|
+
readonly dailyLimit: number;
|
|
131
|
+
readonly totalUsed: number;
|
|
132
|
+
constructor(limitType: string, dailyLimit: number, totalUsed: number);
|
|
133
|
+
}
|
|
124
134
|
/**
|
|
125
135
|
* Thrown when the LinkedHelper UI is in a blocked state due to
|
|
126
136
|
* a dialog, critical error, or blocking popup.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED;;;GAGG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;gBACpC,OAAO,CAAC,EAAE,MAAM;CAM7B;AAED;;GAEG;AACH,qBAAa,cAAe,SAAQ,YAAY;gBAClC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,YAAY;gBAC/C,IAAI,EAAE,MAAM;CAMzB;AAED;;;;;;;GAOG;AACH,qBAAa,4BAA6B,SAAQ,YAAY;IAC5D,QAAQ,CAAC,SAAS,EAAE,aAAa,EAAE,CAAC;gBAExB,SAAS,EAAE,aAAa,EAAE;CASvC;AAED;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;gBACtC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAM/C;AAED;;GAEG;AACH,qBAAa,uBAAwB,SAAQ,YAAY;gBAC3C,OAAO,CAAC,EAAE,MAAM;CAI7B;AAED;;;GAGG;AACH,qBAAa,cAAe,SAAQ,YAAY;gBAClC,IAAI,EAAE,MAAM;CAOzB;AAED;;;;;;;GAOG;AACH,qBAAa,+BAAgC,SAAQ,YAAY;;CAQhE;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,oEAAoE;IACpE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAQzE;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,YAAY;gBAC1C,GAAG,EAAE,MAAM;CAMxB;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,YAAY;gBAC1C,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAMlD;AAED;;;GAGG;AACH,qBAAa,eAAgB,SAAQ,YAAY;gBACnC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,eAAe;IACtD,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;gBAEjB,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAQxD;AAED;;;GAGG;AACH,qBAAa,sBAAuB,SAAQ,YAAY;IACtD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE5B,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKzE;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;gBAE5B,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAKzE;AAED;;;;;;GAMG;AACH,qBAAa,cAAe,SAAQ,YAAY;IAC9C,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;gBAEpB,MAAM,EAAE,cAAc,EAAE,OAAO,CAAC,EAAE,YAAY;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/services/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/services/errors.js
CHANGED
|
@@ -179,6 +179,23 @@ export class CampaignTimeoutError extends ServiceError {
|
|
|
179
179
|
this.campaignId = campaignId;
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Thrown when an action cannot proceed because its daily budget
|
|
184
|
+
* has been exhausted.
|
|
185
|
+
*/
|
|
186
|
+
export class BudgetExceededError extends ServiceError {
|
|
187
|
+
limitType;
|
|
188
|
+
dailyLimit;
|
|
189
|
+
totalUsed;
|
|
190
|
+
constructor(limitType, dailyLimit, totalUsed) {
|
|
191
|
+
super(`Action budget exceeded for ${limitType}: ` +
|
|
192
|
+
`${String(totalUsed)}/${String(dailyLimit)} used today`);
|
|
193
|
+
this.name = "BudgetExceededError";
|
|
194
|
+
this.limitType = limitType;
|
|
195
|
+
this.dailyLimit = dailyLimit;
|
|
196
|
+
this.totalUsed = totalUsed;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
182
199
|
/**
|
|
183
200
|
* Thrown when the LinkedHelper UI is in a blocked state due to
|
|
184
201
|
* a dialog, critical error, or blocking popup.
|
|
@@ -201,6 +218,9 @@ export class UIBlockedError extends ServiceError {
|
|
|
201
218
|
if (health.popup?.blocked) {
|
|
202
219
|
reasons.push(`Popup: ${health.popup.message ?? "blocking overlay active"}`);
|
|
203
220
|
}
|
|
221
|
+
for (const instancePopup of health.instancePopups) {
|
|
222
|
+
reasons.push(`Instance popup: ${instancePopup.title}${instancePopup.description ? ` — ${instancePopup.description}` : ""}`);
|
|
223
|
+
}
|
|
204
224
|
super(`LinkedHelper UI is blocked — ${reasons.join("; ")}`, options);
|
|
205
225
|
this.name = "UIBlockedError";
|
|
206
226
|
this.health = health;
|