@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.
Files changed (288) hide show
  1. package/dist/db/index.d.ts +1 -1
  2. package/dist/db/index.d.ts.map +1 -1
  3. package/dist/db/index.js +1 -1
  4. package/dist/db/index.js.map +1 -1
  5. package/dist/db/repositories/action-budget.d.ts +29 -0
  6. package/dist/db/repositories/action-budget.d.ts.map +1 -0
  7. package/dist/db/repositories/action-budget.js +100 -0
  8. package/dist/db/repositories/action-budget.js.map +1 -0
  9. package/dist/db/repositories/action-budget.test.d.ts +2 -0
  10. package/dist/db/repositories/action-budget.test.d.ts.map +1 -0
  11. package/dist/db/repositories/action-budget.test.js +181 -0
  12. package/dist/db/repositories/action-budget.test.js.map +1 -0
  13. package/dist/db/repositories/campaign-hard-delete.integration.test.d.ts +2 -0
  14. package/dist/db/repositories/campaign-hard-delete.integration.test.d.ts.map +1 -0
  15. package/dist/db/repositories/campaign-hard-delete.integration.test.js +78 -0
  16. package/dist/db/repositories/campaign-hard-delete.integration.test.js.map +1 -0
  17. package/dist/db/repositories/campaign.d.ts +14 -0
  18. package/dist/db/repositories/campaign.d.ts.map +1 -1
  19. package/dist/db/repositories/campaign.js +125 -0
  20. package/dist/db/repositories/campaign.js.map +1 -1
  21. package/dist/db/repositories/index.d.ts +1 -0
  22. package/dist/db/repositories/index.d.ts.map +1 -1
  23. package/dist/db/repositories/index.js +1 -0
  24. package/dist/db/repositories/index.js.map +1 -1
  25. package/dist/index.d.ts +5 -4
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +24 -4
  28. package/dist/index.js.map +1 -1
  29. package/dist/linkedin/__tests__/dom-automation.integration.test.d.ts +2 -0
  30. package/dist/linkedin/__tests__/dom-automation.integration.test.d.ts.map +1 -0
  31. package/dist/linkedin/__tests__/dom-automation.integration.test.js +160 -0
  32. package/dist/linkedin/__tests__/dom-automation.integration.test.js.map +1 -0
  33. package/dist/linkedin/__tests__/selectors.integration.test.d.ts +2 -0
  34. package/dist/linkedin/__tests__/selectors.integration.test.d.ts.map +1 -0
  35. package/dist/linkedin/__tests__/selectors.integration.test.js +258 -0
  36. package/dist/linkedin/__tests__/selectors.integration.test.js.map +1 -0
  37. package/dist/linkedin/dom-automation.d.ts +67 -0
  38. package/dist/linkedin/dom-automation.d.ts.map +1 -0
  39. package/dist/linkedin/dom-automation.js +139 -0
  40. package/dist/linkedin/dom-automation.js.map +1 -0
  41. package/dist/linkedin/index.d.ts +3 -0
  42. package/dist/linkedin/index.d.ts.map +1 -0
  43. package/dist/linkedin/index.js +5 -0
  44. package/dist/linkedin/index.js.map +1 -0
  45. package/dist/linkedin/selectors.d.ts +67 -0
  46. package/dist/linkedin/selectors.d.ts.map +1 -0
  47. package/dist/linkedin/selectors.js +74 -0
  48. package/dist/linkedin/selectors.js.map +1 -0
  49. package/dist/operations/campaign-delete.d.ts +6 -2
  50. package/dist/operations/campaign-delete.d.ts.map +1 -1
  51. package/dist/operations/campaign-delete.js +9 -2
  52. package/dist/operations/campaign-delete.js.map +1 -1
  53. package/dist/operations/campaign-delete.test.js +41 -1
  54. package/dist/operations/campaign-delete.test.js.map +1 -1
  55. package/dist/operations/campaign-erase.d.ts +19 -0
  56. package/dist/operations/campaign-erase.d.ts.map +1 -0
  57. package/dist/operations/campaign-erase.js +22 -0
  58. package/dist/operations/campaign-erase.js.map +1 -0
  59. package/dist/operations/campaign-erase.test.d.ts +2 -0
  60. package/dist/operations/campaign-erase.test.d.ts.map +1 -0
  61. package/dist/operations/campaign-erase.test.js +101 -0
  62. package/dist/operations/campaign-erase.test.js.map +1 -0
  63. package/dist/operations/comment-on-post.d.ts +34 -0
  64. package/dist/operations/comment-on-post.d.ts.map +1 -0
  65. package/dist/operations/comment-on-post.js +108 -0
  66. package/dist/operations/comment-on-post.js.map +1 -0
  67. package/dist/operations/comment-on-post.test.d.ts +2 -0
  68. package/dist/operations/comment-on-post.test.d.ts.map +1 -0
  69. package/dist/operations/comment-on-post.test.js +240 -0
  70. package/dist/operations/comment-on-post.test.js.map +1 -0
  71. package/dist/operations/dismiss-errors.d.ts +22 -0
  72. package/dist/operations/dismiss-errors.d.ts.map +1 -0
  73. package/dist/operations/dismiss-errors.js +55 -0
  74. package/dist/operations/dismiss-errors.js.map +1 -0
  75. package/dist/operations/dismiss-errors.test.d.ts +2 -0
  76. package/dist/operations/dismiss-errors.test.d.ts.map +1 -0
  77. package/dist/operations/dismiss-errors.test.js +136 -0
  78. package/dist/operations/dismiss-errors.test.js.map +1 -0
  79. package/dist/operations/endorse-skills.d.ts +10 -0
  80. package/dist/operations/endorse-skills.d.ts.map +1 -0
  81. package/dist/operations/endorse-skills.js +12 -0
  82. package/dist/operations/endorse-skills.js.map +1 -0
  83. package/dist/operations/enrich-profile.d.ts +18 -0
  84. package/dist/operations/enrich-profile.d.ts.map +1 -0
  85. package/dist/operations/enrich-profile.js +15 -0
  86. package/dist/operations/enrich-profile.js.map +1 -0
  87. package/dist/operations/ephemeral-action.d.ts +22 -0
  88. package/dist/operations/ephemeral-action.d.ts.map +1 -0
  89. package/dist/operations/ephemeral-action.js +31 -0
  90. package/dist/operations/ephemeral-action.js.map +1 -0
  91. package/dist/operations/follow-person.d.ts +9 -0
  92. package/dist/operations/follow-person.d.ts.map +1 -0
  93. package/dist/operations/follow-person.js +11 -0
  94. package/dist/operations/follow-person.js.map +1 -0
  95. package/dist/operations/get-action-budget.d.ts +6 -0
  96. package/dist/operations/get-action-budget.d.ts.map +1 -0
  97. package/dist/operations/get-action-budget.js +22 -0
  98. package/dist/operations/get-action-budget.js.map +1 -0
  99. package/dist/operations/get-action-budget.test.d.ts +2 -0
  100. package/dist/operations/get-action-budget.test.d.ts.map +1 -0
  101. package/dist/operations/get-action-budget.test.js +79 -0
  102. package/dist/operations/get-action-budget.test.js.map +1 -0
  103. package/dist/operations/get-errors.d.ts +9 -3
  104. package/dist/operations/get-errors.d.ts.map +1 -1
  105. package/dist/operations/get-errors.js +41 -4
  106. package/dist/operations/get-errors.js.map +1 -1
  107. package/dist/operations/get-errors.test.js +108 -42
  108. package/dist/operations/get-errors.test.js.map +1 -1
  109. package/dist/operations/get-feed.d.ts +33 -0
  110. package/dist/operations/get-feed.d.ts.map +1 -0
  111. package/dist/operations/get-feed.js +220 -0
  112. package/dist/operations/get-feed.js.map +1 -0
  113. package/dist/operations/get-feed.test.d.ts +2 -0
  114. package/dist/operations/get-feed.test.d.ts.map +1 -0
  115. package/dist/operations/get-feed.test.js +276 -0
  116. package/dist/operations/get-feed.test.js.map +1 -0
  117. package/dist/operations/get-post-engagers.d.ts +40 -0
  118. package/dist/operations/get-post-engagers.d.ts.map +1 -0
  119. package/dist/operations/get-post-engagers.js +128 -0
  120. package/dist/operations/get-post-engagers.js.map +1 -0
  121. package/dist/operations/get-post-engagers.test.d.ts +2 -0
  122. package/dist/operations/get-post-engagers.test.d.ts.map +1 -0
  123. package/dist/operations/get-post-engagers.test.js +19 -0
  124. package/dist/operations/get-post-engagers.test.js.map +1 -0
  125. package/dist/operations/get-post-stats.d.ts +38 -0
  126. package/dist/operations/get-post-stats.d.ts.map +1 -0
  127. package/dist/operations/get-post-stats.js +100 -0
  128. package/dist/operations/get-post-stats.js.map +1 -0
  129. package/dist/operations/get-post-stats.test.d.ts +2 -0
  130. package/dist/operations/get-post-stats.test.d.ts.map +1 -0
  131. package/dist/operations/get-post-stats.test.js +34 -0
  132. package/dist/operations/get-post-stats.test.js.map +1 -0
  133. package/dist/operations/get-post.d.ts +183 -0
  134. package/dist/operations/get-post.d.ts.map +1 -0
  135. package/dist/operations/get-post.js +270 -0
  136. package/dist/operations/get-post.js.map +1 -0
  137. package/dist/operations/get-post.test.d.ts +2 -0
  138. package/dist/operations/get-post.test.d.ts.map +1 -0
  139. package/dist/operations/get-post.test.js +449 -0
  140. package/dist/operations/get-post.test.js.map +1 -0
  141. package/dist/operations/get-profile-activity.d.ts +129 -0
  142. package/dist/operations/get-profile-activity.d.ts.map +1 -0
  143. package/dist/operations/get-profile-activity.js +181 -0
  144. package/dist/operations/get-profile-activity.js.map +1 -0
  145. package/dist/operations/get-profile-activity.test.d.ts +2 -0
  146. package/dist/operations/get-profile-activity.test.d.ts.map +1 -0
  147. package/dist/operations/get-profile-activity.test.js +205 -0
  148. package/dist/operations/get-profile-activity.test.js.map +1 -0
  149. package/dist/operations/get-throttle-status.d.ts +6 -0
  150. package/dist/operations/get-throttle-status.d.ts.map +1 -0
  151. package/dist/operations/get-throttle-status.js +30 -0
  152. package/dist/operations/get-throttle-status.js.map +1 -0
  153. package/dist/operations/get-throttle-status.test.d.ts +2 -0
  154. package/dist/operations/get-throttle-status.test.d.ts.map +1 -0
  155. package/dist/operations/get-throttle-status.test.js +62 -0
  156. package/dist/operations/get-throttle-status.test.js.map +1 -0
  157. package/dist/operations/index.d.ts +22 -0
  158. package/dist/operations/index.d.ts.map +1 -1
  159. package/dist/operations/index.js +32 -0
  160. package/dist/operations/index.js.map +1 -1
  161. package/dist/operations/like-person-posts.d.ts +14 -0
  162. package/dist/operations/like-person-posts.d.ts.map +1 -0
  163. package/dist/operations/like-person-posts.js +28 -0
  164. package/dist/operations/like-person-posts.js.map +1 -0
  165. package/dist/operations/message-person.d.ts +11 -0
  166. package/dist/operations/message-person.d.ts.map +1 -0
  167. package/dist/operations/message-person.js +19 -0
  168. package/dist/operations/message-person.js.map +1 -0
  169. package/dist/operations/react-to-post.d.ts +38 -0
  170. package/dist/operations/react-to-post.d.ts.map +1 -0
  171. package/dist/operations/react-to-post.js +82 -0
  172. package/dist/operations/react-to-post.js.map +1 -0
  173. package/dist/operations/react-to-post.test.d.ts +2 -0
  174. package/dist/operations/react-to-post.test.d.ts.map +1 -0
  175. package/dist/operations/react-to-post.test.js +154 -0
  176. package/dist/operations/react-to-post.test.js.map +1 -0
  177. package/dist/operations/remove-connection.d.ts +6 -0
  178. package/dist/operations/remove-connection.d.ts.map +1 -0
  179. package/dist/operations/remove-connection.js +7 -0
  180. package/dist/operations/remove-connection.js.map +1 -0
  181. package/dist/operations/search-posts.d.ts +143 -0
  182. package/dist/operations/search-posts.d.ts.map +1 -0
  183. package/dist/operations/search-posts.js +220 -0
  184. package/dist/operations/search-posts.js.map +1 -0
  185. package/dist/operations/search-posts.test.d.ts +2 -0
  186. package/dist/operations/search-posts.test.d.ts.map +1 -0
  187. package/dist/operations/search-posts.test.js +261 -0
  188. package/dist/operations/search-posts.test.js.map +1 -0
  189. package/dist/operations/send-inmail.d.ts +11 -0
  190. package/dist/operations/send-inmail.d.ts.map +1 -0
  191. package/dist/operations/send-inmail.js +19 -0
  192. package/dist/operations/send-inmail.js.map +1 -0
  193. package/dist/operations/send-invite.d.ts +9 -0
  194. package/dist/operations/send-invite.d.ts.map +1 -0
  195. package/dist/operations/send-invite.js +14 -0
  196. package/dist/operations/send-invite.js.map +1 -0
  197. package/dist/operations/visit-profile.d.ts +14 -0
  198. package/dist/operations/visit-profile.d.ts.map +1 -0
  199. package/dist/operations/visit-profile.js +49 -0
  200. package/dist/operations/visit-profile.js.map +1 -0
  201. package/dist/operations/visit-profile.test.d.ts +2 -0
  202. package/dist/operations/visit-profile.test.d.ts.map +1 -0
  203. package/dist/operations/visit-profile.test.js +193 -0
  204. package/dist/operations/visit-profile.test.js.map +1 -0
  205. package/dist/services/campaign.d.ts +10 -0
  206. package/dist/services/campaign.d.ts.map +1 -1
  207. package/dist/services/campaign.js +16 -0
  208. package/dist/services/campaign.js.map +1 -1
  209. package/dist/services/collection.d.ts +5 -2
  210. package/dist/services/collection.d.ts.map +1 -1
  211. package/dist/services/collection.js +24 -5
  212. package/dist/services/collection.js.map +1 -1
  213. package/dist/services/collection.test.js +51 -9
  214. package/dist/services/collection.test.js.map +1 -1
  215. package/dist/services/ephemeral-campaign.d.ts +64 -0
  216. package/dist/services/ephemeral-campaign.d.ts.map +1 -0
  217. package/dist/services/ephemeral-campaign.js +210 -0
  218. package/dist/services/ephemeral-campaign.js.map +1 -0
  219. package/dist/services/ephemeral-campaign.test.d.ts +2 -0
  220. package/dist/services/ephemeral-campaign.test.d.ts.map +1 -0
  221. package/dist/services/ephemeral-campaign.test.js +333 -0
  222. package/dist/services/ephemeral-campaign.test.js.map +1 -0
  223. package/dist/services/errors.d.ts +10 -0
  224. package/dist/services/errors.d.ts.map +1 -1
  225. package/dist/services/errors.js +20 -0
  226. package/dist/services/errors.js.map +1 -1
  227. package/dist/services/index.d.ts +3 -1
  228. package/dist/services/index.d.ts.map +1 -1
  229. package/dist/services/index.js +3 -1
  230. package/dist/services/index.js.map +1 -1
  231. package/dist/services/instance-context.d.ts.map +1 -1
  232. package/dist/services/instance-context.js +9 -1
  233. package/dist/services/instance-context.js.map +1 -1
  234. package/dist/services/instance-context.test.js +77 -1
  235. package/dist/services/instance-context.test.js.map +1 -1
  236. package/dist/services/instance.d.ts +31 -0
  237. package/dist/services/instance.d.ts.map +1 -1
  238. package/dist/services/instance.js +123 -0
  239. package/dist/services/instance.js.map +1 -1
  240. package/dist/services/instance.test.js +70 -0
  241. package/dist/services/instance.test.js.map +1 -1
  242. package/dist/services/launcher.d.ts +7 -0
  243. package/dist/services/launcher.d.ts.map +1 -1
  244. package/dist/services/launcher.js +18 -1
  245. package/dist/services/launcher.js.map +1 -1
  246. package/dist/types/action-budget.d.ts +52 -0
  247. package/dist/types/action-budget.d.ts.map +1 -0
  248. package/dist/types/action-budget.js +4 -0
  249. package/dist/types/action-budget.js.map +1 -0
  250. package/dist/types/campaign.d.ts +24 -0
  251. package/dist/types/campaign.d.ts.map +1 -1
  252. package/dist/types/feed.d.ts +32 -0
  253. package/dist/types/feed.d.ts.map +1 -0
  254. package/dist/types/feed.js +4 -0
  255. package/dist/types/feed.js.map +1 -0
  256. package/dist/types/index.d.ts +7 -2
  257. package/dist/types/index.d.ts.map +1 -1
  258. package/dist/types/post-analytics.d.ts +40 -0
  259. package/dist/types/post-analytics.d.ts.map +1 -0
  260. package/dist/types/post-analytics.js +4 -0
  261. package/dist/types/post-analytics.js.map +1 -0
  262. package/dist/types/post.d.ts +43 -0
  263. package/dist/types/post.d.ts.map +1 -0
  264. package/dist/types/post.js +4 -0
  265. package/dist/types/post.js.map +1 -0
  266. package/dist/types/search-posts.d.ts +22 -0
  267. package/dist/types/search-posts.d.ts.map +1 -0
  268. package/dist/types/search-posts.js +4 -0
  269. package/dist/types/search-posts.js.map +1 -0
  270. package/dist/types/ui-health.d.ts +16 -0
  271. package/dist/types/ui-health.d.ts.map +1 -1
  272. package/dist/voyager/index.d.ts +2 -0
  273. package/dist/voyager/index.d.ts.map +1 -0
  274. package/dist/voyager/index.js +4 -0
  275. package/dist/voyager/index.js.map +1 -0
  276. package/dist/voyager/interceptor.d.ts +100 -0
  277. package/dist/voyager/interceptor.d.ts.map +1 -0
  278. package/dist/voyager/interceptor.integration.test.d.ts +2 -0
  279. package/dist/voyager/interceptor.integration.test.d.ts.map +1 -0
  280. package/dist/voyager/interceptor.integration.test.js +89 -0
  281. package/dist/voyager/interceptor.integration.test.js.map +1 -0
  282. package/dist/voyager/interceptor.js +235 -0
  283. package/dist/voyager/interceptor.js.map +1 -0
  284. package/dist/voyager/interceptor.test.d.ts +2 -0
  285. package/dist/voyager/interceptor.test.d.ts.map +1 -0
  286. package/dist/voyager/interceptor.test.js +372 -0
  287. package/dist/voyager/interceptor.test.js.map +1 -0
  288. package/package.json +1 -1
@@ -0,0 +1,220 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { CDPClient } from "../cdp/client.js";
4
+ import { discoverTargets } from "../cdp/discovery.js";
5
+ import { VoyagerInterceptor } from "../voyager/interceptor.js";
6
+ import { DEFAULT_CDP_PORT } from "../constants.js";
7
+ /**
8
+ * Extract a LinkedIn public identifier from a navigation URL.
9
+ *
10
+ * Handles patterns like:
11
+ * - `https://www.linkedin.com/in/johndoe`
12
+ * - `https://www.linkedin.com/in/johndoe?miniProfileUrn=...`
13
+ */
14
+ export function extractPublicId(url) {
15
+ if (!url)
16
+ return null;
17
+ const match = /linkedin\.com\/in\/([^/?]+)/.exec(url);
18
+ return match?.[1] ?? null;
19
+ }
20
+ /**
21
+ * Resolve a headline value that may be a string or an object with a `text` field.
22
+ */
23
+ function resolveTextOrWrapper(value) {
24
+ if (value === undefined || value === null)
25
+ return null;
26
+ if (typeof value === "string")
27
+ return value;
28
+ return value.text ?? null;
29
+ }
30
+ /**
31
+ * Extract the activity URN from the entity URN.
32
+ *
33
+ * The search API may return URNs in several formats:
34
+ * - `urn:li:fs_updateV2:(urn:li:activity:1234,...)` → extract `urn:li:activity:1234`
35
+ * - `urn:li:activity:1234` → use directly
36
+ * - `urn:li:ugcPost:1234` → use directly
37
+ */
38
+ export function extractActivityUrn(urn) {
39
+ if (!urn)
40
+ return null;
41
+ // Extract nested activity URN from fs_updateV2 wrapper
42
+ // e.g. urn:li:fs_updateV2:(urn:li:activity:123,FEED_DETAIL)
43
+ const nestedMatch = /\((urn:li:(?:activity|ugcPost):\d+)[,)]/.exec(urn);
44
+ if (nestedMatch?.[1])
45
+ return nestedMatch[1];
46
+ // Direct activity/ugcPost URN
47
+ if (/^urn:li:(?:activity|ugcPost):\d+$/.test(urn))
48
+ return urn;
49
+ return urn;
50
+ }
51
+ /**
52
+ * Parse the Voyager content search response into normalised search results.
53
+ *
54
+ * LinkedIn's search API returns results in a "clusters" structure with
55
+ * entities referenced via URN in the `included` array. This parser
56
+ * handles both inline and reference-based entity resolution.
57
+ */
58
+ export function parseSearchResponse(raw) {
59
+ const clusters = raw.data?.elements ?? raw.elements ?? [];
60
+ const paging = raw.data?.paging ?? raw.paging;
61
+ const included = raw.included ?? [];
62
+ // Build lookup maps for included entities by URN
63
+ const entitiesByUrn = new Map();
64
+ for (const entity of included) {
65
+ if (entity.entityUrn) {
66
+ entitiesByUrn.set(entity.entityUrn, entity);
67
+ }
68
+ }
69
+ const posts = [];
70
+ for (const cluster of clusters) {
71
+ for (const searchItem of cluster.items ?? []) {
72
+ const entityResult = searchItem.item?.entityResult;
73
+ if (!entityResult)
74
+ continue;
75
+ const postUrn = extractActivityUrn(entityResult.entityUrn);
76
+ if (!postUrn)
77
+ continue;
78
+ // Try to find the update entity in included
79
+ const entityRef = entityResult["*entity"] ?? entityResult.entityUrn;
80
+ const updateEntity = entityRef
81
+ ? entitiesByUrn.get(entityRef)
82
+ : undefined;
83
+ // Extract post text from entity result summary or update commentary
84
+ const text = entityResult.summary?.text ??
85
+ updateEntity?.commentary?.text ??
86
+ null;
87
+ // Extract author info from entity result or included actor
88
+ let authorFirstName = null;
89
+ let authorLastName = null;
90
+ let authorPublicId = null;
91
+ let authorHeadline = null;
92
+ // Try entity result title (author name in search results)
93
+ const authorName = entityResult.title?.text ?? null;
94
+ if (authorName) {
95
+ const nameParts = authorName.split(" ");
96
+ authorFirstName = nameParts[0] ?? null;
97
+ authorLastName = nameParts.slice(1).join(" ") || null;
98
+ }
99
+ authorHeadline =
100
+ entityResult.primarySubtitle?.text ?? null;
101
+ // Try to resolve from included actor profile
102
+ if (updateEntity?.["*actor"]) {
103
+ const actorProfile = entitiesByUrn.get(updateEntity["*actor"]);
104
+ if (actorProfile) {
105
+ if (!authorFirstName) {
106
+ authorFirstName = actorProfile.firstName ?? null;
107
+ }
108
+ if (!authorLastName) {
109
+ authorLastName = actorProfile.lastName ?? null;
110
+ }
111
+ if (!authorPublicId) {
112
+ authorPublicId = actorProfile.publicIdentifier ?? null;
113
+ }
114
+ if (!authorHeadline) {
115
+ authorHeadline = resolveTextOrWrapper(actorProfile.headline) ??
116
+ actorProfile.occupation ?? null;
117
+ }
118
+ }
119
+ }
120
+ // Try to extract publicId from actor navigation URL
121
+ if (!authorPublicId && updateEntity?.actor?.navigationUrl) {
122
+ authorPublicId = extractPublicId(updateEntity.actor.navigationUrl);
123
+ }
124
+ // Extract engagement counts
125
+ let reactionCount = 0;
126
+ let commentCount = 0;
127
+ if (updateEntity?.socialDetail && typeof updateEntity.socialDetail === "object") {
128
+ reactionCount =
129
+ updateEntity.socialDetail.totalSocialActivityCounts?.numLikes ?? 0;
130
+ commentCount =
131
+ updateEntity.socialDetail.totalSocialActivityCounts?.numComments ?? 0;
132
+ }
133
+ else {
134
+ reactionCount = updateEntity?.numLikes ?? 0;
135
+ commentCount = updateEntity?.numComments ?? 0;
136
+ }
137
+ posts.push({
138
+ postUrn,
139
+ text,
140
+ authorFirstName,
141
+ authorLastName,
142
+ authorPublicId,
143
+ authorHeadline,
144
+ reactionCount,
145
+ commentCount,
146
+ });
147
+ }
148
+ }
149
+ return {
150
+ posts,
151
+ paging: {
152
+ start: paging?.start ?? 0,
153
+ count: paging?.count ?? posts.length,
154
+ total: paging?.total ?? posts.length,
155
+ },
156
+ };
157
+ }
158
+ /**
159
+ * Search LinkedIn for posts matching a keyword query.
160
+ *
161
+ * Connects to the LinkedIn webview in LinkedHelper and calls the
162
+ * Voyager search API with content-type filtering to find posts.
163
+ * Supports keyword search, hashtag search, and cursor-based pagination.
164
+ *
165
+ * @param input - Search query, pagination parameters, and CDP connection options.
166
+ * @returns List of matching posts with pagination metadata.
167
+ */
168
+ export async function searchPosts(input) {
169
+ const cdpPort = input.cdpPort ?? DEFAULT_CDP_PORT;
170
+ const cdpHost = input.cdpHost ?? "127.0.0.1";
171
+ const allowRemote = input.allowRemote ?? false;
172
+ const count = input.count ?? 10;
173
+ const start = input.start ?? 0;
174
+ if (!input.query.trim()) {
175
+ throw new Error("Search query must not be empty");
176
+ }
177
+ // Enforce loopback guard
178
+ if (!allowRemote && cdpHost !== "127.0.0.1" && cdpHost !== "localhost") {
179
+ throw new Error(`Non-loopback CDP host "${cdpHost}" requires --allow-remote. ` +
180
+ "This is a security measure to prevent remote code execution.");
181
+ }
182
+ const targets = await discoverTargets(cdpPort, cdpHost);
183
+ const linkedInTarget = targets.find((t) => t.type === "page" && t.url?.includes("linkedin.com"));
184
+ if (!linkedInTarget) {
185
+ throw new Error("No LinkedIn page found in LinkedHelper. " +
186
+ "Ensure LinkedHelper is running with an active LinkedIn session.");
187
+ }
188
+ const client = new CDPClient(cdpPort, { host: cdpHost, allowRemote });
189
+ await client.connect(linkedInTarget.id);
190
+ try {
191
+ const voyager = new VoyagerInterceptor(client);
192
+ const encodedQuery = encodeURIComponent(input.query);
193
+ const encodedFilters = encodeURIComponent("List(resultType->CONTENT)");
194
+ const path = `/voyager/api/search/dash/clusters` +
195
+ `?q=all` +
196
+ `&keywords=${encodedQuery}` +
197
+ `&filters=${encodedFilters}` +
198
+ `&origin=GLOBAL_SEARCH_HEADER` +
199
+ `&start=${String(start)}` +
200
+ `&count=${String(count)}`;
201
+ const response = await voyager.fetch(path);
202
+ if (response.status !== 200) {
203
+ throw new Error(`Voyager API returned HTTP ${String(response.status)} for post search`);
204
+ }
205
+ const body = response.body;
206
+ if (body === null || typeof body !== "object") {
207
+ throw new Error("Voyager API returned an unexpected response format for post search");
208
+ }
209
+ const parsed = parseSearchResponse(body);
210
+ return {
211
+ query: input.query,
212
+ posts: parsed.posts,
213
+ paging: parsed.paging,
214
+ };
215
+ }
216
+ finally {
217
+ client.disconnect();
218
+ }
219
+ }
220
+ //# sourceMappingURL=search-posts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-posts.js","sourceRoot":"","sources":["../../src/operations/search-posts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=search-posts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-posts.test.d.ts","sourceRoot":"","sources":["../../src/operations/search-posts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,261 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { describe, expect, it } from "vitest";
4
+ import { extractActivityUrn, extractPublicId, parseSearchResponse, } from "./search-posts.js";
5
+ describe("extractActivityUrn", () => {
6
+ it("returns null for undefined", () => {
7
+ expect(extractActivityUrn(undefined)).toBeNull();
8
+ });
9
+ it("passes through a direct activity URN", () => {
10
+ expect(extractActivityUrn("urn:li:activity:7123456789012345678")).toBe("urn:li:activity:7123456789012345678");
11
+ });
12
+ it("passes through a direct ugcPost URN", () => {
13
+ expect(extractActivityUrn("urn:li:ugcPost:7123456789012345678")).toBe("urn:li:ugcPost:7123456789012345678");
14
+ });
15
+ it("extracts activity URN from fs_updateV2 wrapper", () => {
16
+ expect(extractActivityUrn("urn:li:fs_updateV2:(urn:li:activity:7123456789012345678,FEED_DETAIL)")).toBe("urn:li:activity:7123456789012345678");
17
+ });
18
+ it("extracts ugcPost URN from fs_updateV2 wrapper", () => {
19
+ expect(extractActivityUrn("urn:li:fs_updateV2:(urn:li:ugcPost:7123456789012345678,FEED_DETAIL)")).toBe("urn:li:ugcPost:7123456789012345678");
20
+ });
21
+ it("returns unknown URN as-is", () => {
22
+ expect(extractActivityUrn("urn:li:other:123")).toBe("urn:li:other:123");
23
+ });
24
+ });
25
+ describe("extractPublicId", () => {
26
+ it("returns null for undefined", () => {
27
+ expect(extractPublicId(undefined)).toBeNull();
28
+ });
29
+ it("returns null for empty string", () => {
30
+ expect(extractPublicId("")).toBeNull();
31
+ });
32
+ it("extracts public ID from profile URL", () => {
33
+ expect(extractPublicId("https://www.linkedin.com/in/johndoe")).toBe("johndoe");
34
+ });
35
+ it("extracts public ID from profile URL with query params", () => {
36
+ expect(extractPublicId("https://www.linkedin.com/in/johndoe?miniProfileUrn=urn%3Ali%3Afs_miniProfile")).toBe("johndoe");
37
+ });
38
+ it("returns null for non-profile URL", () => {
39
+ expect(extractPublicId("https://www.linkedin.com/company/foo")).toBeNull();
40
+ });
41
+ });
42
+ describe("parseSearchResponse", () => {
43
+ it("returns empty results for empty response", () => {
44
+ const result = parseSearchResponse({});
45
+ expect(result.posts).toEqual([]);
46
+ expect(result.paging).toEqual({ start: 0, count: 0, total: 0 });
47
+ });
48
+ it("parses a single post result from nested data structure", () => {
49
+ const result = parseSearchResponse({
50
+ data: {
51
+ elements: [
52
+ {
53
+ items: [
54
+ {
55
+ item: {
56
+ entityResult: {
57
+ entityUrn: "urn:li:activity:7123456789012345678",
58
+ title: { text: "Jane Smith" },
59
+ primarySubtitle: { text: "CEO at Acme Corp" },
60
+ summary: { text: "Excited about AI agents!" },
61
+ },
62
+ },
63
+ },
64
+ ],
65
+ },
66
+ ],
67
+ paging: { start: 0, count: 10, total: 42 },
68
+ },
69
+ });
70
+ expect(result.posts).toHaveLength(1);
71
+ expect(result.posts[0]).toEqual({
72
+ postUrn: "urn:li:activity:7123456789012345678",
73
+ text: "Excited about AI agents!",
74
+ authorFirstName: "Jane",
75
+ authorLastName: "Smith",
76
+ authorPublicId: null,
77
+ authorHeadline: "CEO at Acme Corp",
78
+ reactionCount: 0,
79
+ commentCount: 0,
80
+ });
81
+ expect(result.paging).toEqual({ start: 0, count: 10, total: 42 });
82
+ });
83
+ it("resolves author from included entities", () => {
84
+ const result = parseSearchResponse({
85
+ data: {
86
+ elements: [
87
+ {
88
+ items: [
89
+ {
90
+ item: {
91
+ entityResult: {
92
+ entityUrn: "urn:li:fs_updateV2:(urn:li:activity:1234567890,FEED_DETAIL)",
93
+ "*entity": "urn:li:fs_updateV2:(urn:li:activity:1234567890,FEED_DETAIL)",
94
+ title: { text: "John Doe" },
95
+ summary: { text: "Great post about tech" },
96
+ },
97
+ },
98
+ },
99
+ ],
100
+ },
101
+ ],
102
+ paging: { start: 0, count: 10, total: 1 },
103
+ },
104
+ included: [
105
+ {
106
+ $type: "com.linkedin.voyager.dash.feed.Update",
107
+ entityUrn: "urn:li:fs_updateV2:(urn:li:activity:1234567890,FEED_DETAIL)",
108
+ "*actor": "urn:li:fs_miniProfile:abc123",
109
+ numLikes: 15,
110
+ numComments: 3,
111
+ },
112
+ {
113
+ $type: "com.linkedin.voyager.dash.identity.profile.Profile",
114
+ entityUrn: "urn:li:fs_miniProfile:abc123",
115
+ firstName: "John",
116
+ lastName: "Doe",
117
+ publicIdentifier: "johndoe",
118
+ headline: { text: "Software Engineer" },
119
+ },
120
+ ],
121
+ });
122
+ expect(result.posts).toHaveLength(1);
123
+ expect(result.posts[0]).toEqual({
124
+ postUrn: "urn:li:activity:1234567890",
125
+ text: "Great post about tech",
126
+ authorFirstName: "John",
127
+ authorLastName: "Doe",
128
+ authorPublicId: "johndoe",
129
+ authorHeadline: "Software Engineer",
130
+ reactionCount: 15,
131
+ commentCount: 3,
132
+ });
133
+ });
134
+ it("handles flat response structure (no data wrapper)", () => {
135
+ const result = parseSearchResponse({
136
+ elements: [
137
+ {
138
+ items: [
139
+ {
140
+ item: {
141
+ entityResult: {
142
+ entityUrn: "urn:li:activity:9999999999",
143
+ title: { text: "Alice" },
144
+ summary: { text: "A post" },
145
+ },
146
+ },
147
+ },
148
+ ],
149
+ },
150
+ ],
151
+ paging: { start: 5, count: 10, total: 50 },
152
+ });
153
+ expect(result.posts).toHaveLength(1);
154
+ expect(result.posts[0]?.postUrn).toBe("urn:li:activity:9999999999");
155
+ expect(result.paging).toEqual({ start: 5, count: 10, total: 50 });
156
+ });
157
+ it("skips items without entityResult", () => {
158
+ const result = parseSearchResponse({
159
+ data: {
160
+ elements: [
161
+ {
162
+ items: [
163
+ { item: {} },
164
+ {
165
+ item: {
166
+ entityResult: {
167
+ entityUrn: "urn:li:activity:111",
168
+ title: { text: "Bob" },
169
+ },
170
+ },
171
+ },
172
+ ],
173
+ },
174
+ ],
175
+ },
176
+ });
177
+ expect(result.posts).toHaveLength(1);
178
+ expect(result.posts[0]?.postUrn).toBe("urn:li:activity:111");
179
+ });
180
+ it("extracts engagement counts from socialDetail", () => {
181
+ const result = parseSearchResponse({
182
+ data: {
183
+ elements: [
184
+ {
185
+ items: [
186
+ {
187
+ item: {
188
+ entityResult: {
189
+ entityUrn: "urn:li:activity:555",
190
+ "*entity": "urn:li:update:555",
191
+ },
192
+ },
193
+ },
194
+ ],
195
+ },
196
+ ],
197
+ },
198
+ included: [
199
+ {
200
+ entityUrn: "urn:li:update:555",
201
+ socialDetail: {
202
+ totalSocialActivityCounts: {
203
+ numLikes: 42,
204
+ numComments: 7,
205
+ },
206
+ },
207
+ },
208
+ ],
209
+ });
210
+ expect(result.posts[0]?.reactionCount).toBe(42);
211
+ expect(result.posts[0]?.commentCount).toBe(7);
212
+ });
213
+ it("handles multiple clusters with multiple items", () => {
214
+ const result = parseSearchResponse({
215
+ data: {
216
+ elements: [
217
+ {
218
+ items: [
219
+ {
220
+ item: {
221
+ entityResult: {
222
+ entityUrn: "urn:li:activity:111",
223
+ title: { text: "Author A" },
224
+ },
225
+ },
226
+ },
227
+ {
228
+ item: {
229
+ entityResult: {
230
+ entityUrn: "urn:li:activity:222",
231
+ title: { text: "Author B" },
232
+ },
233
+ },
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ items: [
239
+ {
240
+ item: {
241
+ entityResult: {
242
+ entityUrn: "urn:li:activity:333",
243
+ title: { text: "Author C" },
244
+ },
245
+ },
246
+ },
247
+ ],
248
+ },
249
+ ],
250
+ paging: { start: 0, count: 10, total: 3 },
251
+ },
252
+ });
253
+ expect(result.posts).toHaveLength(3);
254
+ expect(result.posts.map((p) => p.postUrn)).toEqual([
255
+ "urn:li:activity:111",
256
+ "urn:li:activity:222",
257
+ "urn:li:activity:333",
258
+ ]);
259
+ });
260
+ });
261
+ //# sourceMappingURL=search-posts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-posts.test.js","sourceRoot":"","sources":["../../src/operations/search-posts.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { ActionSettings, EphemeralActionResult } from "../types/index.js";
2
+ import { type EphemeralActionInput } from "./ephemeral-action.js";
3
+ export interface SendInmailInput extends EphemeralActionInput {
4
+ readonly messageTemplate: ActionSettings;
5
+ readonly subjectTemplate?: ActionSettings | undefined;
6
+ readonly rejectIfReplied?: boolean | undefined;
7
+ readonly proceedOnOutOfCredits?: boolean | undefined;
8
+ }
9
+ export type SendInmailOutput = EphemeralActionResult;
10
+ export declare function sendInmail(input: SendInmailInput): Promise<SendInmailOutput>;
11
+ //# sourceMappingURL=send-inmail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-inmail.d.ts","sourceRoot":"","sources":["../../src/operations/send-inmail.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,eAAgB,SAAQ,oBAAoB;IAC3D,QAAQ,CAAC,eAAe,EAAE,cAAc,CAAC;IACzC,QAAQ,CAAC,eAAe,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,qBAAqB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CACtD;AAED,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAErD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAe3B"}
@@ -0,0 +1,19 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { executeEphemeralAction, } from "./ephemeral-action.js";
4
+ export async function sendInmail(input) {
5
+ const actionSettings = {
6
+ messageTemplate: input.messageTemplate,
7
+ ...(input.subjectTemplate !== undefined && {
8
+ subjectTemplate: input.subjectTemplate,
9
+ }),
10
+ ...(input.rejectIfReplied !== undefined && {
11
+ rejectIfReplied: input.rejectIfReplied,
12
+ }),
13
+ ...(input.proceedOnOutOfCredits !== undefined && {
14
+ proceedOnOutOfCredits: input.proceedOnOutOfCredits,
15
+ }),
16
+ };
17
+ return executeEphemeralAction("InMail", input, actionSettings);
18
+ }
19
+ //# sourceMappingURL=send-inmail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-inmail.js","sourceRoot":"","sources":["../../src/operations/send-inmail.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EACL,sBAAsB,GAEvB,MAAM,uBAAuB,CAAC;AAW/B,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAsB;IAEtB,MAAM,cAAc,GAAmB;QACrC,eAAe,EAAE,KAAK,CAAC,eAAe;QACtC,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS,IAAI;YACzC,eAAe,EAAE,KAAK,CAAC,eAAe;SACvC,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,SAAS,IAAI;YACzC,eAAe,EAAE,KAAK,CAAC,eAAe;SACvC,CAAC;QACF,GAAG,CAAC,KAAK,CAAC,qBAAqB,KAAK,SAAS,IAAI;YAC/C,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;SACnD,CAAC;KACH,CAAC;IAEF,OAAO,sBAAsB,CAAC,QAAQ,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;AACjE,CAAC"}
@@ -0,0 +1,9 @@
1
+ import type { ActionSettings, EphemeralActionResult } from "../types/index.js";
2
+ import { type EphemeralActionInput } from "./ephemeral-action.js";
3
+ export interface SendInviteInput extends EphemeralActionInput {
4
+ readonly messageTemplate?: ActionSettings | undefined;
5
+ readonly saveAsLeadSN?: boolean | undefined;
6
+ }
7
+ export type SendInviteOutput = EphemeralActionResult;
8
+ export declare function sendInvite(input: SendInviteInput): Promise<SendInviteOutput>;
9
+ //# sourceMappingURL=send-invite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-invite.d.ts","sourceRoot":"","sources":["../../src/operations/send-invite.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,uBAAuB,CAAC;AAE/B,MAAM,WAAW,eAAgB,SAAQ,oBAAoB;IAC3D,QAAQ,CAAC,eAAe,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACtD,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7C;AAED,MAAM,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAErD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,gBAAgB,CAAC,CAU3B"}
@@ -0,0 +1,14 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { executeEphemeralAction, } from "./ephemeral-action.js";
4
+ export async function sendInvite(input) {
5
+ const actionSettings = {
6
+ messageTemplate: input.messageTemplate ?? {
7
+ type: "variants",
8
+ variants: [],
9
+ },
10
+ saveAsLeadSN: input.saveAsLeadSN ?? false,
11
+ };
12
+ return executeEphemeralAction("InvitePerson", input, actionSettings);
13
+ }
14
+ //# sourceMappingURL=send-invite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-invite.js","sourceRoot":"","sources":["../../src/operations/send-invite.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAGpC,OAAO,EACL,sBAAsB,GAEvB,MAAM,uBAAuB,CAAC;AAS/B,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,KAAsB;IAEtB,MAAM,cAAc,GAAmB;QACrC,eAAe,EAAE,KAAK,CAAC,eAAe,IAAI;YACxC,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,EAAE;SACb;QACD,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,KAAK;KAC1C,CAAC;IAEF,OAAO,sBAAsB,CAAC,cAAc,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;AACvE,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Profile } from "../types/index.js";
2
+ import type { ConnectionOptions } from "./types.js";
3
+ export interface VisitProfileInput extends ConnectionOptions {
4
+ readonly personId?: number | undefined;
5
+ readonly url?: string | undefined;
6
+ readonly extractCurrentOrganizations?: boolean | undefined;
7
+ }
8
+ export interface VisitProfileOutput {
9
+ readonly success: true;
10
+ readonly actionType: "VisitAndExtract";
11
+ readonly profile: Profile;
12
+ }
13
+ export declare function visitProfile(input: VisitProfileInput): Promise<VisitProfileOutput>;
14
+ //# sourceMappingURL=visit-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"visit-profile.d.ts","sourceRoot":"","sources":["../../src/operations/visit-profile.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAKjD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpD,MAAM,WAAW,iBAAkB,SAAQ,iBAAiB;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5D;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B;AAcD,wBAAsB,YAAY,CAChC,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,kBAAkB,CAAC,CAuC7B"}
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { resolveAccount } from "../services/account-resolution.js";
4
+ import { withInstanceDatabase } from "../services/instance-context.js";
5
+ import { ProfileRepository } from "../db/index.js";
6
+ import { DEFAULT_CDP_PORT } from "../constants.js";
7
+ const LINKEDIN_PROFILE_RE = /linkedin\.com\/in\/([^/?#]+)/;
8
+ function extractPublicId(url) {
9
+ const match = LINKEDIN_PROFILE_RE.exec(url);
10
+ if (!match?.[1]) {
11
+ throw new Error(`Invalid LinkedIn profile URL: ${url}. Expected format: https://www.linkedin.com/in/<public-id>`);
12
+ }
13
+ return decodeURIComponent(match[1]);
14
+ }
15
+ export async function visitProfile(input) {
16
+ if ((input.personId == null) === (input.url == null)) {
17
+ throw new Error("Exactly one of personId or url must be provided");
18
+ }
19
+ const cdpPort = input.cdpPort ?? DEFAULT_CDP_PORT;
20
+ const accountId = await resolveAccount(cdpPort, {
21
+ ...(input.cdpHost !== undefined && { host: input.cdpHost }),
22
+ ...(input.allowRemote !== undefined && { allowRemote: input.allowRemote }),
23
+ });
24
+ return withInstanceDatabase(cdpPort, accountId, async ({ instance, db }) => {
25
+ const repo = new ProfileRepository(db);
26
+ let personId;
27
+ if (input.personId != null) {
28
+ personId = input.personId;
29
+ }
30
+ else {
31
+ const publicId = extractPublicId(input.url);
32
+ const existing = repo.findByPublicId(publicId);
33
+ personId = existing.id;
34
+ }
35
+ await instance.executeAction("VisitAndExtract", {
36
+ personIds: [personId],
37
+ ...(input.extractCurrentOrganizations !== undefined && {
38
+ extractCurrentOrganizations: input.extractCurrentOrganizations,
39
+ }),
40
+ });
41
+ const profile = repo.findById(personId, { includePositions: true });
42
+ return {
43
+ success: true,
44
+ actionType: "VisitAndExtract",
45
+ profile,
46
+ };
47
+ }, { instanceTimeout: 120_000 });
48
+ }
49
+ //# sourceMappingURL=visit-profile.js.map