@lhremote/core 0.6.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 (356) hide show
  1. package/README.md +39 -0
  2. package/dist/cdp/client.d.ts +5 -1
  3. package/dist/cdp/client.d.ts.map +1 -1
  4. package/dist/cdp/client.js +11 -3
  5. package/dist/cdp/client.js.map +1 -1
  6. package/dist/data/index.d.ts +1 -0
  7. package/dist/data/index.d.ts.map +1 -1
  8. package/dist/data/index.js +1 -0
  9. package/dist/data/index.js.map +1 -1
  10. package/dist/data/linkedin-reference.d.ts +44 -0
  11. package/dist/data/linkedin-reference.d.ts.map +1 -0
  12. package/dist/data/linkedin-reference.js +316 -0
  13. package/dist/data/linkedin-reference.js.map +1 -0
  14. package/dist/data/linkedin-reference.test.d.ts +2 -0
  15. package/dist/data/linkedin-reference.test.d.ts.map +1 -0
  16. package/dist/data/linkedin-reference.test.js +124 -0
  17. package/dist/data/linkedin-reference.test.js.map +1 -0
  18. package/dist/db/index.d.ts +1 -1
  19. package/dist/db/index.d.ts.map +1 -1
  20. package/dist/db/index.js +1 -1
  21. package/dist/db/index.js.map +1 -1
  22. package/dist/db/repositories/action-budget.d.ts +29 -0
  23. package/dist/db/repositories/action-budget.d.ts.map +1 -0
  24. package/dist/db/repositories/action-budget.js +100 -0
  25. package/dist/db/repositories/action-budget.js.map +1 -0
  26. package/dist/db/repositories/action-budget.test.d.ts +2 -0
  27. package/dist/db/repositories/action-budget.test.d.ts.map +1 -0
  28. package/dist/db/repositories/action-budget.test.js +181 -0
  29. package/dist/db/repositories/action-budget.test.js.map +1 -0
  30. package/dist/db/repositories/campaign-hard-delete.integration.test.d.ts +2 -0
  31. package/dist/db/repositories/campaign-hard-delete.integration.test.d.ts.map +1 -0
  32. package/dist/db/repositories/campaign-hard-delete.integration.test.js +78 -0
  33. package/dist/db/repositories/campaign-hard-delete.integration.test.js.map +1 -0
  34. package/dist/db/repositories/campaign.d.ts +14 -0
  35. package/dist/db/repositories/campaign.d.ts.map +1 -1
  36. package/dist/db/repositories/campaign.js +125 -0
  37. package/dist/db/repositories/campaign.js.map +1 -1
  38. package/dist/db/repositories/index.d.ts +1 -0
  39. package/dist/db/repositories/index.d.ts.map +1 -1
  40. package/dist/db/repositories/index.js +1 -0
  41. package/dist/db/repositories/index.js.map +1 -1
  42. package/dist/index.d.ts +6 -5
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +28 -6
  45. package/dist/index.js.map +1 -1
  46. package/dist/linkedin/__tests__/dom-automation.integration.test.d.ts +2 -0
  47. package/dist/linkedin/__tests__/dom-automation.integration.test.d.ts.map +1 -0
  48. package/dist/linkedin/__tests__/dom-automation.integration.test.js +160 -0
  49. package/dist/linkedin/__tests__/dom-automation.integration.test.js.map +1 -0
  50. package/dist/linkedin/__tests__/selectors.integration.test.d.ts +2 -0
  51. package/dist/linkedin/__tests__/selectors.integration.test.d.ts.map +1 -0
  52. package/dist/linkedin/__tests__/selectors.integration.test.js +258 -0
  53. package/dist/linkedin/__tests__/selectors.integration.test.js.map +1 -0
  54. package/dist/linkedin/dom-automation.d.ts +67 -0
  55. package/dist/linkedin/dom-automation.d.ts.map +1 -0
  56. package/dist/linkedin/dom-automation.js +139 -0
  57. package/dist/linkedin/dom-automation.js.map +1 -0
  58. package/dist/linkedin/index.d.ts +3 -0
  59. package/dist/linkedin/index.d.ts.map +1 -0
  60. package/dist/linkedin/index.js +5 -0
  61. package/dist/linkedin/index.js.map +1 -0
  62. package/dist/linkedin/selectors.d.ts +67 -0
  63. package/dist/linkedin/selectors.d.ts.map +1 -0
  64. package/dist/linkedin/selectors.js +74 -0
  65. package/dist/linkedin/selectors.js.map +1 -0
  66. package/dist/operations/build-linkedin-url.d.ts +39 -0
  67. package/dist/operations/build-linkedin-url.d.ts.map +1 -0
  68. package/dist/operations/build-linkedin-url.js +72 -0
  69. package/dist/operations/build-linkedin-url.js.map +1 -0
  70. package/dist/operations/campaign-delete.d.ts +6 -2
  71. package/dist/operations/campaign-delete.d.ts.map +1 -1
  72. package/dist/operations/campaign-delete.js +9 -2
  73. package/dist/operations/campaign-delete.js.map +1 -1
  74. package/dist/operations/campaign-delete.test.js +41 -1
  75. package/dist/operations/campaign-delete.test.js.map +1 -1
  76. package/dist/operations/campaign-erase.d.ts +19 -0
  77. package/dist/operations/campaign-erase.d.ts.map +1 -0
  78. package/dist/operations/campaign-erase.js +22 -0
  79. package/dist/operations/campaign-erase.js.map +1 -0
  80. package/dist/operations/campaign-erase.test.d.ts +2 -0
  81. package/dist/operations/campaign-erase.test.d.ts.map +1 -0
  82. package/dist/operations/campaign-erase.test.js +101 -0
  83. package/dist/operations/campaign-erase.test.js.map +1 -0
  84. package/dist/operations/comment-on-post.d.ts +34 -0
  85. package/dist/operations/comment-on-post.d.ts.map +1 -0
  86. package/dist/operations/comment-on-post.js +108 -0
  87. package/dist/operations/comment-on-post.js.map +1 -0
  88. package/dist/operations/comment-on-post.test.d.ts +2 -0
  89. package/dist/operations/comment-on-post.test.d.ts.map +1 -0
  90. package/dist/operations/comment-on-post.test.js +240 -0
  91. package/dist/operations/comment-on-post.test.js.map +1 -0
  92. package/dist/operations/dismiss-errors.d.ts +22 -0
  93. package/dist/operations/dismiss-errors.d.ts.map +1 -0
  94. package/dist/operations/dismiss-errors.js +55 -0
  95. package/dist/operations/dismiss-errors.js.map +1 -0
  96. package/dist/operations/dismiss-errors.test.d.ts +2 -0
  97. package/dist/operations/dismiss-errors.test.d.ts.map +1 -0
  98. package/dist/operations/dismiss-errors.test.js +136 -0
  99. package/dist/operations/dismiss-errors.test.js.map +1 -0
  100. package/dist/operations/endorse-skills.d.ts +10 -0
  101. package/dist/operations/endorse-skills.d.ts.map +1 -0
  102. package/dist/operations/endorse-skills.js +12 -0
  103. package/dist/operations/endorse-skills.js.map +1 -0
  104. package/dist/operations/enrich-profile.d.ts +18 -0
  105. package/dist/operations/enrich-profile.d.ts.map +1 -0
  106. package/dist/operations/enrich-profile.js +15 -0
  107. package/dist/operations/enrich-profile.js.map +1 -0
  108. package/dist/operations/ephemeral-action.d.ts +22 -0
  109. package/dist/operations/ephemeral-action.d.ts.map +1 -0
  110. package/dist/operations/ephemeral-action.js +31 -0
  111. package/dist/operations/ephemeral-action.js.map +1 -0
  112. package/dist/operations/follow-person.d.ts +9 -0
  113. package/dist/operations/follow-person.d.ts.map +1 -0
  114. package/dist/operations/follow-person.js +11 -0
  115. package/dist/operations/follow-person.js.map +1 -0
  116. package/dist/operations/get-action-budget.d.ts +6 -0
  117. package/dist/operations/get-action-budget.d.ts.map +1 -0
  118. package/dist/operations/get-action-budget.js +22 -0
  119. package/dist/operations/get-action-budget.js.map +1 -0
  120. package/dist/operations/get-action-budget.test.d.ts +2 -0
  121. package/dist/operations/get-action-budget.test.d.ts.map +1 -0
  122. package/dist/operations/get-action-budget.test.js +79 -0
  123. package/dist/operations/get-action-budget.test.js.map +1 -0
  124. package/dist/operations/get-errors.d.ts +9 -3
  125. package/dist/operations/get-errors.d.ts.map +1 -1
  126. package/dist/operations/get-errors.js +41 -4
  127. package/dist/operations/get-errors.js.map +1 -1
  128. package/dist/operations/get-errors.test.js +108 -42
  129. package/dist/operations/get-errors.test.js.map +1 -1
  130. package/dist/operations/get-feed.d.ts +33 -0
  131. package/dist/operations/get-feed.d.ts.map +1 -0
  132. package/dist/operations/get-feed.js +220 -0
  133. package/dist/operations/get-feed.js.map +1 -0
  134. package/dist/operations/get-feed.test.d.ts +2 -0
  135. package/dist/operations/get-feed.test.d.ts.map +1 -0
  136. package/dist/operations/get-feed.test.js +276 -0
  137. package/dist/operations/get-feed.test.js.map +1 -0
  138. package/dist/operations/get-post-engagers.d.ts +40 -0
  139. package/dist/operations/get-post-engagers.d.ts.map +1 -0
  140. package/dist/operations/get-post-engagers.js +128 -0
  141. package/dist/operations/get-post-engagers.js.map +1 -0
  142. package/dist/operations/get-post-engagers.test.d.ts +2 -0
  143. package/dist/operations/get-post-engagers.test.d.ts.map +1 -0
  144. package/dist/operations/get-post-engagers.test.js +19 -0
  145. package/dist/operations/get-post-engagers.test.js.map +1 -0
  146. package/dist/operations/get-post-stats.d.ts +38 -0
  147. package/dist/operations/get-post-stats.d.ts.map +1 -0
  148. package/dist/operations/get-post-stats.js +100 -0
  149. package/dist/operations/get-post-stats.js.map +1 -0
  150. package/dist/operations/get-post-stats.test.d.ts +2 -0
  151. package/dist/operations/get-post-stats.test.d.ts.map +1 -0
  152. package/dist/operations/get-post-stats.test.js +34 -0
  153. package/dist/operations/get-post-stats.test.js.map +1 -0
  154. package/dist/operations/get-post.d.ts +183 -0
  155. package/dist/operations/get-post.d.ts.map +1 -0
  156. package/dist/operations/get-post.js +270 -0
  157. package/dist/operations/get-post.js.map +1 -0
  158. package/dist/operations/get-post.test.d.ts +2 -0
  159. package/dist/operations/get-post.test.d.ts.map +1 -0
  160. package/dist/operations/get-post.test.js +449 -0
  161. package/dist/operations/get-post.test.js.map +1 -0
  162. package/dist/operations/get-profile-activity.d.ts +129 -0
  163. package/dist/operations/get-profile-activity.d.ts.map +1 -0
  164. package/dist/operations/get-profile-activity.js +181 -0
  165. package/dist/operations/get-profile-activity.js.map +1 -0
  166. package/dist/operations/get-profile-activity.test.d.ts +2 -0
  167. package/dist/operations/get-profile-activity.test.d.ts.map +1 -0
  168. package/dist/operations/get-profile-activity.test.js +205 -0
  169. package/dist/operations/get-profile-activity.test.js.map +1 -0
  170. package/dist/operations/get-throttle-status.d.ts +6 -0
  171. package/dist/operations/get-throttle-status.d.ts.map +1 -0
  172. package/dist/operations/get-throttle-status.js +30 -0
  173. package/dist/operations/get-throttle-status.js.map +1 -0
  174. package/dist/operations/get-throttle-status.test.d.ts +2 -0
  175. package/dist/operations/get-throttle-status.test.d.ts.map +1 -0
  176. package/dist/operations/get-throttle-status.test.js +62 -0
  177. package/dist/operations/get-throttle-status.test.js.map +1 -0
  178. package/dist/operations/index.d.ts +24 -0
  179. package/dist/operations/index.d.ts.map +1 -1
  180. package/dist/operations/index.js +35 -0
  181. package/dist/operations/index.js.map +1 -1
  182. package/dist/operations/like-person-posts.d.ts +14 -0
  183. package/dist/operations/like-person-posts.d.ts.map +1 -0
  184. package/dist/operations/like-person-posts.js +28 -0
  185. package/dist/operations/like-person-posts.js.map +1 -0
  186. package/dist/operations/message-person.d.ts +11 -0
  187. package/dist/operations/message-person.d.ts.map +1 -0
  188. package/dist/operations/message-person.js +19 -0
  189. package/dist/operations/message-person.js.map +1 -0
  190. package/dist/operations/react-to-post.d.ts +38 -0
  191. package/dist/operations/react-to-post.d.ts.map +1 -0
  192. package/dist/operations/react-to-post.js +82 -0
  193. package/dist/operations/react-to-post.js.map +1 -0
  194. package/dist/operations/react-to-post.test.d.ts +2 -0
  195. package/dist/operations/react-to-post.test.d.ts.map +1 -0
  196. package/dist/operations/react-to-post.test.js +154 -0
  197. package/dist/operations/react-to-post.test.js.map +1 -0
  198. package/dist/operations/remove-connection.d.ts +6 -0
  199. package/dist/operations/remove-connection.d.ts.map +1 -0
  200. package/dist/operations/remove-connection.js +7 -0
  201. package/dist/operations/remove-connection.js.map +1 -0
  202. package/dist/operations/resolve-linkedin-entity.d.ts +33 -0
  203. package/dist/operations/resolve-linkedin-entity.d.ts.map +1 -0
  204. package/dist/operations/resolve-linkedin-entity.js +198 -0
  205. package/dist/operations/resolve-linkedin-entity.js.map +1 -0
  206. package/dist/operations/search-posts.d.ts +143 -0
  207. package/dist/operations/search-posts.d.ts.map +1 -0
  208. package/dist/operations/search-posts.js +220 -0
  209. package/dist/operations/search-posts.js.map +1 -0
  210. package/dist/operations/search-posts.test.d.ts +2 -0
  211. package/dist/operations/search-posts.test.d.ts.map +1 -0
  212. package/dist/operations/search-posts.test.js +261 -0
  213. package/dist/operations/search-posts.test.js.map +1 -0
  214. package/dist/operations/send-inmail.d.ts +11 -0
  215. package/dist/operations/send-inmail.d.ts.map +1 -0
  216. package/dist/operations/send-inmail.js +19 -0
  217. package/dist/operations/send-inmail.js.map +1 -0
  218. package/dist/operations/send-invite.d.ts +9 -0
  219. package/dist/operations/send-invite.d.ts.map +1 -0
  220. package/dist/operations/send-invite.js +14 -0
  221. package/dist/operations/send-invite.js.map +1 -0
  222. package/dist/operations/visit-profile.d.ts +14 -0
  223. package/dist/operations/visit-profile.d.ts.map +1 -0
  224. package/dist/operations/visit-profile.js +49 -0
  225. package/dist/operations/visit-profile.js.map +1 -0
  226. package/dist/operations/visit-profile.test.d.ts +2 -0
  227. package/dist/operations/visit-profile.test.d.ts.map +1 -0
  228. package/dist/operations/visit-profile.test.js +193 -0
  229. package/dist/operations/visit-profile.test.js.map +1 -0
  230. package/dist/services/app.d.ts.map +1 -1
  231. package/dist/services/app.js +37 -12
  232. package/dist/services/app.js.map +1 -1
  233. package/dist/services/app.test.js +57 -0
  234. package/dist/services/app.test.js.map +1 -1
  235. package/dist/services/boolean-expression.d.ts +29 -0
  236. package/dist/services/boolean-expression.d.ts.map +1 -0
  237. package/dist/services/boolean-expression.js +79 -0
  238. package/dist/services/boolean-expression.js.map +1 -0
  239. package/dist/services/boolean-expression.test.d.ts +2 -0
  240. package/dist/services/boolean-expression.test.d.ts.map +1 -0
  241. package/dist/services/boolean-expression.test.js +64 -0
  242. package/dist/services/boolean-expression.test.js.map +1 -0
  243. package/dist/services/campaign.d.ts +10 -0
  244. package/dist/services/campaign.d.ts.map +1 -1
  245. package/dist/services/campaign.js +16 -0
  246. package/dist/services/campaign.js.map +1 -1
  247. package/dist/services/collection.d.ts +5 -2
  248. package/dist/services/collection.d.ts.map +1 -1
  249. package/dist/services/collection.js +33 -5
  250. package/dist/services/collection.js.map +1 -1
  251. package/dist/services/collection.test.js +64 -6
  252. package/dist/services/collection.test.js.map +1 -1
  253. package/dist/services/ephemeral-campaign.d.ts +64 -0
  254. package/dist/services/ephemeral-campaign.d.ts.map +1 -0
  255. package/dist/services/ephemeral-campaign.js +210 -0
  256. package/dist/services/ephemeral-campaign.js.map +1 -0
  257. package/dist/services/ephemeral-campaign.test.d.ts +2 -0
  258. package/dist/services/ephemeral-campaign.test.d.ts.map +1 -0
  259. package/dist/services/ephemeral-campaign.test.js +333 -0
  260. package/dist/services/ephemeral-campaign.test.js.map +1 -0
  261. package/dist/services/errors.d.ts +21 -0
  262. package/dist/services/errors.d.ts.map +1 -1
  263. package/dist/services/errors.js +35 -0
  264. package/dist/services/errors.js.map +1 -1
  265. package/dist/services/index.d.ts +7 -1
  266. package/dist/services/index.d.ts.map +1 -1
  267. package/dist/services/index.js +7 -1
  268. package/dist/services/index.js.map +1 -1
  269. package/dist/services/instance-context.d.ts.map +1 -1
  270. package/dist/services/instance-context.js +9 -1
  271. package/dist/services/instance-context.js.map +1 -1
  272. package/dist/services/instance-context.test.js +77 -1
  273. package/dist/services/instance-context.test.js.map +1 -1
  274. package/dist/services/instance.d.ts +43 -0
  275. package/dist/services/instance.d.ts.map +1 -1
  276. package/dist/services/instance.js +151 -0
  277. package/dist/services/instance.js.map +1 -1
  278. package/dist/services/instance.test.js +101 -0
  279. package/dist/services/instance.test.js.map +1 -1
  280. package/dist/services/launcher.d.ts +23 -0
  281. package/dist/services/launcher.d.ts.map +1 -1
  282. package/dist/services/launcher.js +81 -11
  283. package/dist/services/launcher.js.map +1 -1
  284. package/dist/services/launcher.test.js +109 -42
  285. package/dist/services/launcher.test.js.map +1 -1
  286. package/dist/services/sn-url-builder.d.ts +21 -0
  287. package/dist/services/sn-url-builder.d.ts.map +1 -0
  288. package/dist/services/sn-url-builder.js +132 -0
  289. package/dist/services/sn-url-builder.js.map +1 -0
  290. package/dist/services/sn-url-builder.test.d.ts +2 -0
  291. package/dist/services/sn-url-builder.test.d.ts.map +1 -0
  292. package/dist/services/sn-url-builder.test.js +130 -0
  293. package/dist/services/sn-url-builder.test.js.map +1 -0
  294. package/dist/services/url-builder.d.ts +12 -0
  295. package/dist/services/url-builder.d.ts.map +1 -0
  296. package/dist/services/url-builder.js +100 -0
  297. package/dist/services/url-builder.js.map +1 -0
  298. package/dist/services/url-builder.test.d.ts +2 -0
  299. package/dist/services/url-builder.test.d.ts.map +1 -0
  300. package/dist/services/url-builder.test.js +79 -0
  301. package/dist/services/url-builder.test.js.map +1 -0
  302. package/dist/services/url-templates.d.ts +41 -0
  303. package/dist/services/url-templates.d.ts.map +1 -0
  304. package/dist/services/url-templates.js +118 -0
  305. package/dist/services/url-templates.js.map +1 -0
  306. package/dist/services/url-templates.test.d.ts +2 -0
  307. package/dist/services/url-templates.test.d.ts.map +1 -0
  308. package/dist/services/url-templates.test.js +159 -0
  309. package/dist/services/url-templates.test.js.map +1 -0
  310. package/dist/types/action-budget.d.ts +52 -0
  311. package/dist/types/action-budget.d.ts.map +1 -0
  312. package/dist/types/action-budget.js +4 -0
  313. package/dist/types/action-budget.js.map +1 -0
  314. package/dist/types/campaign.d.ts +24 -0
  315. package/dist/types/campaign.d.ts.map +1 -1
  316. package/dist/types/feed.d.ts +32 -0
  317. package/dist/types/feed.d.ts.map +1 -0
  318. package/dist/types/feed.js +4 -0
  319. package/dist/types/feed.js.map +1 -0
  320. package/dist/types/index.d.ts +8 -2
  321. package/dist/types/index.d.ts.map +1 -1
  322. package/dist/types/linkedin-url.d.ts +109 -0
  323. package/dist/types/linkedin-url.d.ts.map +1 -0
  324. package/dist/types/linkedin-url.js +4 -0
  325. package/dist/types/linkedin-url.js.map +1 -0
  326. package/dist/types/post-analytics.d.ts +40 -0
  327. package/dist/types/post-analytics.d.ts.map +1 -0
  328. package/dist/types/post-analytics.js +4 -0
  329. package/dist/types/post-analytics.js.map +1 -0
  330. package/dist/types/post.d.ts +43 -0
  331. package/dist/types/post.d.ts.map +1 -0
  332. package/dist/types/post.js +4 -0
  333. package/dist/types/post.js.map +1 -0
  334. package/dist/types/search-posts.d.ts +22 -0
  335. package/dist/types/search-posts.d.ts.map +1 -0
  336. package/dist/types/search-posts.js +4 -0
  337. package/dist/types/search-posts.js.map +1 -0
  338. package/dist/types/ui-health.d.ts +16 -0
  339. package/dist/types/ui-health.d.ts.map +1 -1
  340. package/dist/voyager/index.d.ts +2 -0
  341. package/dist/voyager/index.d.ts.map +1 -0
  342. package/dist/voyager/index.js +4 -0
  343. package/dist/voyager/index.js.map +1 -0
  344. package/dist/voyager/interceptor.d.ts +100 -0
  345. package/dist/voyager/interceptor.d.ts.map +1 -0
  346. package/dist/voyager/interceptor.integration.test.d.ts +2 -0
  347. package/dist/voyager/interceptor.integration.test.d.ts.map +1 -0
  348. package/dist/voyager/interceptor.integration.test.js +89 -0
  349. package/dist/voyager/interceptor.integration.test.js.map +1 -0
  350. package/dist/voyager/interceptor.js +235 -0
  351. package/dist/voyager/interceptor.js.map +1 -0
  352. package/dist/voyager/interceptor.test.d.ts +2 -0
  353. package/dist/voyager/interceptor.test.d.ts.map +1 -0
  354. package/dist/voyager/interceptor.test.js +372 -0
  355. package/dist/voyager/interceptor.test.js.map +1 -0
  356. package/package.json +1 -1
@@ -0,0 +1,124 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { describe, expect, it } from "vitest";
4
+ import { getFunctionById, getIndustryById, getLinkedInReferenceData, getSeniorityById, isReferenceDataType, } from "./linkedin-reference.js";
5
+ describe("getLinkedInReferenceData", () => {
6
+ it("returns industries with correct structure", () => {
7
+ const industries = getLinkedInReferenceData("INDUSTRY");
8
+ expect(industries.length).toBeGreaterThanOrEqual(140);
9
+ for (const entry of industries) {
10
+ expect(entry).toHaveProperty("id");
11
+ expect(entry).toHaveProperty("name");
12
+ expect(typeof entry.id).toBe("number");
13
+ expect(typeof entry.name).toBe("string");
14
+ expect(entry.name.length).toBeGreaterThan(0);
15
+ }
16
+ });
17
+ it("returns seniority levels with correct structure", () => {
18
+ const levels = getLinkedInReferenceData("SENIORITY");
19
+ expect(levels).toHaveLength(10);
20
+ for (const entry of levels) {
21
+ expect(typeof entry.id).toBe("number");
22
+ expect(typeof entry.name).toBe("string");
23
+ }
24
+ });
25
+ it("returns functions with correct structure", () => {
26
+ const functions = getLinkedInReferenceData("FUNCTION");
27
+ expect(functions.length).toBeGreaterThanOrEqual(20);
28
+ for (const entry of functions) {
29
+ expect(typeof entry.id).toBe("number");
30
+ expect(typeof entry.name).toBe("string");
31
+ }
32
+ });
33
+ it("returns company sizes with correct structure", () => {
34
+ const sizes = getLinkedInReferenceData("COMPANY_SIZE");
35
+ expect(sizes.length).toBeGreaterThanOrEqual(8);
36
+ for (const entry of sizes) {
37
+ expect(typeof entry.id).toBe("string");
38
+ expect(typeof entry.label).toBe("string");
39
+ }
40
+ });
41
+ it("returns connection degrees with correct structure", () => {
42
+ const degrees = getLinkedInReferenceData("CONNECTION_DEGREE");
43
+ expect(degrees).toHaveLength(3);
44
+ const codes = degrees.map((d) => d.code);
45
+ expect(codes).toContain("F");
46
+ expect(codes).toContain("S");
47
+ expect(codes).toContain("O");
48
+ });
49
+ it("returns profile languages with correct structure", () => {
50
+ const languages = getLinkedInReferenceData("PROFILE_LANGUAGE");
51
+ expect(languages.length).toBeGreaterThanOrEqual(20);
52
+ for (const entry of languages) {
53
+ expect(typeof entry.code).toBe("string");
54
+ expect(typeof entry.name).toBe("string");
55
+ expect(entry.code.length).toBeGreaterThanOrEqual(2);
56
+ }
57
+ });
58
+ it("includes known industry IDs", () => {
59
+ const industries = getLinkedInReferenceData("INDUSTRY");
60
+ const ids = new Set(industries.map((i) => i.id));
61
+ // Spot-check well-known industries
62
+ expect(ids.has(4)).toBe(true); // Computer Software
63
+ expect(ids.has(6)).toBe(true); // Internet
64
+ expect(ids.has(96)).toBe(true); // IT and Services
65
+ });
66
+ it("has no duplicate IDs in industries", () => {
67
+ const industries = getLinkedInReferenceData("INDUSTRY");
68
+ const ids = industries.map((i) => i.id);
69
+ expect(new Set(ids).size).toBe(ids.length);
70
+ });
71
+ it("has no duplicate IDs in seniority levels", () => {
72
+ const levels = getLinkedInReferenceData("SENIORITY");
73
+ const ids = levels.map((l) => l.id);
74
+ expect(new Set(ids).size).toBe(ids.length);
75
+ });
76
+ it("has no duplicate IDs in functions", () => {
77
+ const functions = getLinkedInReferenceData("FUNCTION");
78
+ const ids = functions.map((f) => f.id);
79
+ expect(new Set(ids).size).toBe(ids.length);
80
+ });
81
+ });
82
+ describe("getIndustryById", () => {
83
+ it("returns correct industry for known ID", () => {
84
+ const industry = getIndustryById(4);
85
+ expect(industry?.name).toBe("Computer Software");
86
+ });
87
+ it("returns undefined for unknown ID", () => {
88
+ expect(getIndustryById(99999)).toBeUndefined();
89
+ });
90
+ });
91
+ describe("getSeniorityById", () => {
92
+ it("returns correct seniority for known ID", () => {
93
+ const seniority = getSeniorityById(8);
94
+ expect(seniority?.name).toBe("CXO");
95
+ });
96
+ it("returns undefined for unknown ID", () => {
97
+ expect(getSeniorityById(99)).toBeUndefined();
98
+ });
99
+ });
100
+ describe("getFunctionById", () => {
101
+ it("returns correct function for known ID", () => {
102
+ const fn = getFunctionById(8);
103
+ expect(fn?.name).toBe("Engineering");
104
+ });
105
+ it("returns undefined for unknown ID", () => {
106
+ expect(getFunctionById(99)).toBeUndefined();
107
+ });
108
+ });
109
+ describe("isReferenceDataType", () => {
110
+ it("returns true for valid types", () => {
111
+ expect(isReferenceDataType("INDUSTRY")).toBe(true);
112
+ expect(isReferenceDataType("SENIORITY")).toBe(true);
113
+ expect(isReferenceDataType("FUNCTION")).toBe(true);
114
+ expect(isReferenceDataType("COMPANY_SIZE")).toBe(true);
115
+ expect(isReferenceDataType("CONNECTION_DEGREE")).toBe(true);
116
+ expect(isReferenceDataType("PROFILE_LANGUAGE")).toBe(true);
117
+ });
118
+ it("returns false for invalid types", () => {
119
+ expect(isReferenceDataType("UNKNOWN")).toBe(false);
120
+ expect(isReferenceDataType("")).toBe(false);
121
+ expect(isReferenceDataType("industry")).toBe(false);
122
+ });
123
+ });
124
+ //# sourceMappingURL=linkedin-reference.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"linkedin-reference.test.js","sourceRoot":"","sources":["../../src/data/linkedin-reference.test.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  export { DatabaseClient, type DatabaseClientOptions } from "./client.js";
2
2
  export { discoverAllDatabases, discoverDatabase } from "./discovery.js";
3
3
  export { ActionNotFoundError, CampaignNotFoundError, ChatNotFoundError, DatabaseError, DatabaseNotFoundError, ExcludeListNotFoundError, NoNextActionError, ProfileNotFoundError, } from "./errors.js";
4
- export { CampaignExcludeListRepository, CampaignRepository, CampaignStatisticsRepository, CollectionListRepository, type CollectionSummary, MessageRepository, ProfileRepository, } from "./repositories/index.js";
4
+ export { ActionBudgetRepository, CampaignExcludeListRepository, CampaignRepository, CampaignStatisticsRepository, CollectionListRepository, type CollectionSummary, MessageRepository, ProfileRepository, } from "./repositories/index.js";
5
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6BAA6B,EAC7B,kBAAkB,EAClB,4BAA4B,EAC5B,wBAAwB,EACxB,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,KAAK,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,kBAAkB,EAClB,4BAA4B,EAC5B,wBAAwB,EACxB,KAAK,iBAAiB,EACtB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
package/dist/db/index.js CHANGED
@@ -3,5 +3,5 @@
3
3
  export { DatabaseClient } from "./client.js";
4
4
  export { discoverAllDatabases, discoverDatabase } from "./discovery.js";
5
5
  export { ActionNotFoundError, CampaignNotFoundError, ChatNotFoundError, DatabaseError, DatabaseNotFoundError, ExcludeListNotFoundError, NoNextActionError, ProfileNotFoundError, } from "./errors.js";
6
- export { CampaignExcludeListRepository, CampaignRepository, CampaignStatisticsRepository, CollectionListRepository, MessageRepository, ProfileRepository, } from "./repositories/index.js";
6
+ export { ActionBudgetRepository, CampaignExcludeListRepository, CampaignRepository, CampaignStatisticsRepository, CollectionListRepository, MessageRepository, ProfileRepository, } from "./repositories/index.js";
7
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,6BAA6B,EAC7B,kBAAkB,EAClB,4BAA4B,EAC5B,wBAAwB,EAExB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,oCAAoC;AAEpC,OAAO,EAAE,cAAc,EAA8B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACxE,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,iBAAiB,EACjB,aAAa,EACb,qBAAqB,EACrB,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,sBAAsB,EACtB,6BAA6B,EAC7B,kBAAkB,EAClB,4BAA4B,EAC5B,wBAAwB,EAExB,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { ActionBudgetEntry, LimitType } from "../../types/index.js";
2
+ import type { DatabaseClient } from "../client.js";
3
+ /**
4
+ * Repository for reading LinkedHelper rate limit data.
5
+ *
6
+ * Reads from LH's `limit_types`, `daily_limits`, and `action_results`
7
+ * tables to compute the current action budget.
8
+ */
9
+ export declare class ActionBudgetRepository {
10
+ private readonly stmtLimitTypes;
11
+ private readonly stmtDailyLimits;
12
+ private readonly stmtTodayCountsByType;
13
+ constructor(client: DatabaseClient);
14
+ /**
15
+ * Get all limit types defined by LinkedHelper.
16
+ */
17
+ getLimitTypes(): LimitType[];
18
+ /**
19
+ * Get the full action budget: limit types, daily limits, and today's usage.
20
+ *
21
+ * Campaign usage comes from LH's `action_results` table.
22
+ * Direct usage (CDP-direct actions like comments/reactions) is accepted
23
+ * as a parameter since it is tracked externally.
24
+ *
25
+ * @param directCounts Map of limit type ID → count of CDP-direct actions today.
26
+ */
27
+ getActionBudget(directCounts?: ReadonlyMap<number, number>): ActionBudgetEntry[];
28
+ }
29
+ //# sourceMappingURL=action-budget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-budget.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/action-budget.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAwCnD;;;;;GAKG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAC;gBAE3B,MAAM,EAAE,cAAc;IAqBlC;;OAEG;IACH,aAAa,IAAI,SAAS,EAAE;IAK5B;;;;;;;;OAQG;IACH,eAAe,CACb,YAAY,GAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAa,GACpD,iBAAiB,EAAE;CAyCvB"}
@@ -0,0 +1,100 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ /**
4
+ * Maps LinkedHelper action config types to their corresponding limit type IDs.
5
+ *
6
+ * These IDs match the `limit_types` table in the LH database.
7
+ * Action types that do not consume daily limits (e.g. Waiter,
8
+ * FilterContactsOutOfMyNetwork) are intentionally omitted.
9
+ */
10
+ const ACTION_TYPE_TO_LIMIT_TYPE = new Map([
11
+ ["SaveCurrentProfile", 1],
12
+ ["InvitePerson", 8],
13
+ ["SendMessage", 9],
14
+ ["MessageToEventAttendees", 10],
15
+ ["SendInMail", 11],
16
+ ["EndorseSkills", 12],
17
+ ["InviteToGroup", 13],
18
+ ["Follow", 16],
19
+ ["Unfollow", 17],
20
+ ["LikePost", 18],
21
+ ["SendPersonToWebhook", 23],
22
+ ["GetEmailFromPAS", 24],
23
+ ["SendPersonToExternalCRM", 31],
24
+ ]);
25
+ /**
26
+ * Repository for reading LinkedHelper rate limit data.
27
+ *
28
+ * Reads from LH's `limit_types`, `daily_limits`, and `action_results`
29
+ * tables to compute the current action budget.
30
+ */
31
+ export class ActionBudgetRepository {
32
+ stmtLimitTypes;
33
+ stmtDailyLimits;
34
+ stmtTodayCountsByType;
35
+ constructor(client) {
36
+ const { db } = client;
37
+ this.stmtLimitTypes = db.prepare(`SELECT id, type FROM limit_types ORDER BY id`);
38
+ this.stmtDailyLimits = db.prepare(`SELECT id, max_limit FROM daily_limits`);
39
+ this.stmtTodayCountsByType = db.prepare(`SELECT ac.actionType AS action_type, COUNT(*) AS count_today
40
+ FROM action_results ar
41
+ JOIN action_versions av ON ar.action_version_id = av.id
42
+ JOIN action_configs ac ON av.config_id = ac.id
43
+ WHERE date(ar.created_at) = date('now', 'localtime')
44
+ GROUP BY ac.actionType`);
45
+ }
46
+ /**
47
+ * Get all limit types defined by LinkedHelper.
48
+ */
49
+ getLimitTypes() {
50
+ const rows = this.stmtLimitTypes.all();
51
+ return rows.map((r) => ({ id: r.id, type: r.type }));
52
+ }
53
+ /**
54
+ * Get the full action budget: limit types, daily limits, and today's usage.
55
+ *
56
+ * Campaign usage comes from LH's `action_results` table.
57
+ * Direct usage (CDP-direct actions like comments/reactions) is accepted
58
+ * as a parameter since it is tracked externally.
59
+ *
60
+ * @param directCounts Map of limit type ID → count of CDP-direct actions today.
61
+ */
62
+ getActionBudget(directCounts = new Map()) {
63
+ const limitTypes = this.stmtLimitTypes.all();
64
+ const dailyLimits = this.stmtDailyLimits.all();
65
+ const todayCounts = this.stmtTodayCountsByType.all();
66
+ // Build daily limit lookup: limit_type_id → max_limit
67
+ const limitMap = new Map();
68
+ for (const dl of dailyLimits) {
69
+ limitMap.set(dl.id, dl.max_limit);
70
+ }
71
+ // Build campaign usage lookup: limit_type_id → count
72
+ const campaignUsageMap = new Map();
73
+ for (const row of todayCounts) {
74
+ const limitTypeId = ACTION_TYPE_TO_LIMIT_TYPE.get(row.action_type);
75
+ if (limitTypeId !== undefined) {
76
+ const existing = campaignUsageMap.get(limitTypeId) ?? 0;
77
+ campaignUsageMap.set(limitTypeId, existing + row.count_today);
78
+ }
79
+ }
80
+ return limitTypes.map((lt) => {
81
+ const dailyLimit = limitMap.get(lt.id) ?? null;
82
+ const campaignUsed = campaignUsageMap.get(lt.id) ?? 0;
83
+ const directUsed = directCounts.get(lt.id) ?? 0;
84
+ const totalUsed = campaignUsed + directUsed;
85
+ const remaining = dailyLimit !== null
86
+ ? Math.max(0, dailyLimit - totalUsed)
87
+ : null;
88
+ return {
89
+ limitTypeId: lt.id,
90
+ limitType: lt.type,
91
+ dailyLimit,
92
+ campaignUsed,
93
+ directUsed,
94
+ totalUsed,
95
+ remaining,
96
+ };
97
+ });
98
+ }
99
+ }
100
+ //# sourceMappingURL=action-budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-budget.js","sourceRoot":"","sources":["../../../src/db/repositories/action-budget.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=action-budget.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-budget.test.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/action-budget.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,181 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { DatabaseSync } from "node:sqlite";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { ActionBudgetRepository } from "./action-budget.js";
6
+ function createBudgetDb() {
7
+ const db = new DatabaseSync(":memory:");
8
+ db.exec(`
9
+ CREATE TABLE limit_types (
10
+ id INTEGER PRIMARY KEY,
11
+ type TEXT NOT NULL
12
+ )
13
+ `);
14
+ db.exec(`
15
+ INSERT INTO limit_types (id, type) VALUES
16
+ (8, 'Invite'),
17
+ (9, 'Message'),
18
+ (16, 'Follow'),
19
+ (18, 'PostLike')
20
+ `);
21
+ db.exec(`
22
+ CREATE TABLE daily_limits (
23
+ id INTEGER PRIMARY KEY,
24
+ max_limit INTEGER NOT NULL
25
+ )
26
+ `);
27
+ db.exec(`
28
+ INSERT INTO daily_limits (id, max_limit) VALUES
29
+ (8, 100),
30
+ (16, 150)
31
+ `);
32
+ db.exec(`
33
+ CREATE TABLE action_configs (
34
+ id INTEGER PRIMARY KEY,
35
+ actionType TEXT NOT NULL
36
+ )
37
+ `);
38
+ db.exec(`INSERT INTO action_configs (id, actionType) VALUES (1, 'InvitePerson')`);
39
+ db.exec(`INSERT INTO action_configs (id, actionType) VALUES (2, 'Follow')`);
40
+ db.exec(`
41
+ CREATE TABLE action_versions (
42
+ id INTEGER PRIMARY KEY,
43
+ action_id INTEGER NOT NULL,
44
+ config_id INTEGER NOT NULL
45
+ )
46
+ `);
47
+ db.exec(`INSERT INTO action_versions (id, action_id, config_id) VALUES (1, 1, 1)`);
48
+ db.exec(`INSERT INTO action_versions (id, action_id, config_id) VALUES (2, 2, 2)`);
49
+ db.exec(`
50
+ CREATE TABLE action_results (
51
+ id INTEGER PRIMARY KEY,
52
+ action_version_id INTEGER NOT NULL,
53
+ person_id INTEGER NOT NULL,
54
+ result INTEGER NOT NULL DEFAULT 0,
55
+ created_at DATETIME NOT NULL
56
+ )
57
+ `);
58
+ // Insert today's results
59
+ const today = new Date().toISOString().split("T")[0] ?? "";
60
+ db.exec(`
61
+ INSERT INTO action_results (action_version_id, person_id, result, created_at)
62
+ VALUES
63
+ (1, 100, 1, '${today} 10:00:00'),
64
+ (1, 101, 1, '${today} 10:05:00'),
65
+ (1, 102, -1, '${today} 10:10:00'),
66
+ (2, 200, 1, '${today} 11:00:00')
67
+ `);
68
+ // Insert yesterday's results (should NOT be counted)
69
+ const yesterday = new Date(Date.now() - 86_400_000).toISOString().split("T")[0] ?? "";
70
+ db.exec(`
71
+ INSERT INTO action_results (action_version_id, person_id, result, created_at)
72
+ VALUES
73
+ (1, 103, 1, '${yesterday} 10:00:00'),
74
+ (2, 201, 1, '${yesterday} 11:00:00')
75
+ `);
76
+ return db;
77
+ }
78
+ describe("ActionBudgetRepository", () => {
79
+ let db;
80
+ let repo;
81
+ beforeEach(() => {
82
+ db = createBudgetDb();
83
+ repo = new ActionBudgetRepository({ db });
84
+ });
85
+ afterEach(() => {
86
+ db.close();
87
+ });
88
+ describe("getLimitTypes", () => {
89
+ it("returns all limit types ordered by ID", () => {
90
+ const types = repo.getLimitTypes();
91
+ expect(types).toEqual([
92
+ { id: 8, type: "Invite" },
93
+ { id: 9, type: "Message" },
94
+ { id: 16, type: "Follow" },
95
+ { id: 18, type: "PostLike" },
96
+ ]);
97
+ });
98
+ });
99
+ describe("getActionBudget", () => {
100
+ it("combines limit types, daily limits, and today's usage", () => {
101
+ const entries = repo.getActionBudget();
102
+ // Invite: limit 100, 3 today (2 success + 1 fail — all results counted)
103
+ const invite = entries.find((e) => e.limitType === "Invite");
104
+ expect(invite).toEqual({
105
+ limitTypeId: 8,
106
+ limitType: "Invite",
107
+ dailyLimit: 100,
108
+ campaignUsed: 3,
109
+ directUsed: 0,
110
+ totalUsed: 3,
111
+ remaining: 97,
112
+ });
113
+ // Follow: limit 150, 1 today
114
+ const follow = entries.find((e) => e.limitType === "Follow");
115
+ expect(follow).toEqual({
116
+ limitTypeId: 16,
117
+ limitType: "Follow",
118
+ dailyLimit: 150,
119
+ campaignUsed: 1,
120
+ directUsed: 0,
121
+ totalUsed: 1,
122
+ remaining: 149,
123
+ });
124
+ // Message: no daily limit configured, 0 used
125
+ const message = entries.find((e) => e.limitType === "Message");
126
+ expect(message).toEqual({
127
+ limitTypeId: 9,
128
+ limitType: "Message",
129
+ dailyLimit: null,
130
+ campaignUsed: 0,
131
+ directUsed: 0,
132
+ totalUsed: 0,
133
+ remaining: null,
134
+ });
135
+ });
136
+ it("includes direct counts in budget", () => {
137
+ const directCounts = new Map([[18, 5]]);
138
+ const entries = repo.getActionBudget(directCounts);
139
+ const postLike = entries.find((e) => e.limitType === "PostLike");
140
+ expect(postLike).toEqual({
141
+ limitTypeId: 18,
142
+ limitType: "PostLike",
143
+ dailyLimit: null,
144
+ campaignUsed: 0,
145
+ directUsed: 5,
146
+ totalUsed: 5,
147
+ remaining: null,
148
+ });
149
+ });
150
+ it("clamps remaining to zero when over limit", () => {
151
+ const directCounts = new Map([[8, 200]]);
152
+ const entries = repo.getActionBudget(directCounts);
153
+ const invite = entries.find((e) => e.limitType === "Invite");
154
+ expect(invite?.remaining).toBe(0);
155
+ expect(invite?.totalUsed).toBe(203); // 3 campaign + 200 direct
156
+ });
157
+ it("returns empty entries when no limit types exist", () => {
158
+ const emptyDb = new DatabaseSync(":memory:");
159
+ emptyDb.exec(`CREATE TABLE limit_types (id INTEGER PRIMARY KEY, type TEXT NOT NULL)`);
160
+ emptyDb.exec(`CREATE TABLE daily_limits (id INTEGER PRIMARY KEY, max_limit INTEGER NOT NULL)`);
161
+ emptyDb.exec(`
162
+ CREATE TABLE action_results (
163
+ id INTEGER PRIMARY KEY, action_version_id INTEGER NOT NULL,
164
+ person_id INTEGER NOT NULL, result INTEGER NOT NULL DEFAULT 0,
165
+ created_at DATETIME NOT NULL
166
+ )
167
+ `);
168
+ emptyDb.exec(`
169
+ CREATE TABLE action_versions (
170
+ id INTEGER PRIMARY KEY, action_id INTEGER NOT NULL, config_id INTEGER NOT NULL
171
+ )
172
+ `);
173
+ emptyDb.exec(`CREATE TABLE action_configs (id INTEGER PRIMARY KEY, actionType TEXT NOT NULL)`);
174
+ const emptyRepo = new ActionBudgetRepository({ db: emptyDb });
175
+ const entries = emptyRepo.getActionBudget();
176
+ expect(entries).toEqual([]);
177
+ emptyDb.close();
178
+ });
179
+ });
180
+ });
181
+ //# sourceMappingURL=action-budget.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"action-budget.test.js","sourceRoot":"","sources":["../../../src/db/repositories/action-budget.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=campaign-hard-delete.integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-hard-delete.integration.test.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/campaign-hard-delete.integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,78 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { afterAll, beforeAll, describe, expect, it } from "vitest";
4
+ import { DatabaseClient } from "../client.js";
5
+ import { openFixture } from "../testing/open-fixture.js";
6
+ import { CampaignRepository } from "./campaign.js";
7
+ import { CampaignNotFoundError } from "../errors.js";
8
+ describe("CampaignRepository.deleteCampaign (integration)", () => {
9
+ let rawDb;
10
+ let client;
11
+ let repo;
12
+ beforeAll(() => {
13
+ // Use openFixture() for an isolated writable copy
14
+ rawDb = openFixture();
15
+ // Ensure SQLite enforces foreign key constraints so delete order is validated
16
+ rawDb.exec("PRAGMA foreign_keys = ON");
17
+ const fkPragma = rawDb
18
+ .prepare("PRAGMA foreign_keys")
19
+ .get();
20
+ expect(fkPragma.foreign_keys).toBe(1);
21
+ // Pause campaign 1 so it can be hard-deleted
22
+ // (fixture has it as active: is_paused=0, is_archived=0, is_valid=1)
23
+ rawDb.exec("UPDATE campaigns SET is_paused = 1 WHERE id = 1");
24
+ // Wrap the raw DatabaseSync in a DatabaseClient for the repo
25
+ client = { db: rawDb, close: () => rawDb.close() };
26
+ repo = new CampaignRepository(client);
27
+ });
28
+ afterAll(() => {
29
+ rawDb.close();
30
+ });
31
+ function countRows(table, where, params) {
32
+ const row = rawDb.prepare(`SELECT COUNT(*) AS cnt FROM ${table} WHERE ${where}`).get(...params);
33
+ return row.cnt;
34
+ }
35
+ it("removes campaign 1 and all related rows", () => {
36
+ // Pre-conditions: campaign 1 has data in all related tables
37
+ expect(countRows("campaigns", "id = ?", [1])).toBe(1);
38
+ expect(countRows("actions", "campaign_id = ?", [1])).toBeGreaterThan(0);
39
+ expect(countRows("action_versions", "action_id IN (SELECT id FROM actions WHERE campaign_id = ?)", [1])).toBeGreaterThan(0);
40
+ expect(countRows("action_configs", "id IN (SELECT DISTINCT av.config_id FROM action_versions av JOIN actions a ON av.action_id = a.id WHERE a.campaign_id = ?)", [1])).toBeGreaterThan(0);
41
+ expect(countRows("action_target_people", "action_id IN (SELECT id FROM actions WHERE campaign_id = ?)", [1])).toBeGreaterThan(0);
42
+ expect(countRows("action_results", "action_version_id IN (SELECT av.id FROM action_versions av JOIN actions a ON av.action_id = a.id WHERE a.campaign_id = ?)", [1])).toBeGreaterThan(0);
43
+ expect(countRows("person_in_campaigns_history", "campaign_id = ?", [1])).toBeGreaterThan(0);
44
+ expect(countRows("campaign_versions", "campaign_id = ?", [1])).toBeGreaterThan(0);
45
+ // Exclude list chain pre-conditions
46
+ const excludeListCount = countRows("collection_people_versions", "id IN (SELECT av.exclude_list_id FROM action_versions av JOIN actions a ON av.action_id = a.id WHERE a.campaign_id = ? AND av.exclude_list_id IS NOT NULL UNION SELECT cv.exclude_list_id FROM campaign_versions cv WHERE cv.campaign_id = ? AND cv.exclude_list_id IS NOT NULL)", [1, 1]);
47
+ expect(excludeListCount).toBeGreaterThan(0);
48
+ // Perform the hard delete (with FK constraints enforced)
49
+ repo.deleteCampaign(1);
50
+ // Post-conditions: all related rows are gone
51
+ expect(countRows("campaigns", "id = ?", [1])).toBe(0);
52
+ expect(countRows("actions", "campaign_id = ?", [1])).toBe(0);
53
+ expect(countRows("action_versions", "action_id IN (SELECT id FROM actions WHERE campaign_id = ?)", [1])).toBe(0);
54
+ expect(countRows("action_target_people", "action_id IN (SELECT id FROM actions WHERE campaign_id = ?)", [1])).toBe(0);
55
+ expect(countRows("action_results", "action_version_id IN (SELECT av.id FROM action_versions av JOIN actions a ON av.action_id = a.id WHERE a.campaign_id = ?)", [1])).toBe(0);
56
+ expect(countRows("action_result_flags", "action_result_id IN (SELECT ar.id FROM action_results ar JOIN action_versions av ON ar.action_version_id = av.id JOIN actions a ON av.action_id = a.id WHERE a.campaign_id = ?)", [1])).toBe(0);
57
+ expect(countRows("action_result_messages", "action_result_id IN (SELECT ar.id FROM action_results ar JOIN action_versions av ON ar.action_version_id = av.id JOIN actions a ON av.action_id = a.id WHERE a.campaign_id = ?)", [1])).toBe(0);
58
+ expect(countRows("person_in_campaigns_history", "campaign_id = ?", [1])).toBe(0);
59
+ expect(countRows("campaign_versions", "campaign_id = ?", [1])).toBe(0);
60
+ // Verify action_configs for campaign 1 are deleted
61
+ // (config ID 1 belonged to campaign 1's action)
62
+ expect(countRows("action_configs", "id = ?", [1])).toBe(0);
63
+ // Verify exclude list chain is cleaned up
64
+ expect(countRows("collection_people_versions", "id IN (1, 2)", [])).toBe(0);
65
+ expect(countRows("collections", "id IN (1, 2)", [])).toBe(0);
66
+ });
67
+ it("throws CampaignNotFoundError for non-existent campaign", () => {
68
+ expect(() => repo.deleteCampaign(9999)).toThrow(CampaignNotFoundError);
69
+ });
70
+ it("does not affect other campaigns", () => {
71
+ // Campaign 2 should still exist after deleting campaign 1
72
+ expect(countRows("campaigns", "id = ?", [2])).toBe(1);
73
+ expect(countRows("actions", "campaign_id = ?", [2])).toBeGreaterThan(0);
74
+ expect(countRows("action_versions", "action_id IN (SELECT id FROM actions WHERE campaign_id = ?)", [2])).toBeGreaterThan(0);
75
+ expect(countRows("action_configs", "id = ?", [2])).toBe(1);
76
+ });
77
+ });
78
+ //# sourceMappingURL=campaign-hard-delete.integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-hard-delete.integration.test.js","sourceRoot":"","sources":["../../../src/db/repositories/campaign-hard-delete.integration.test.ts"],"names":[],"mappings":"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"}
@@ -63,6 +63,20 @@ export declare class CampaignRepository {
63
63
  * @throws {CampaignNotFoundError} if no campaign exists with the given ID.
64
64
  */
65
65
  updateCampaign(campaignId: number, updates: CampaignUpdateConfig): Campaign;
66
+ /**
67
+ * Hard-delete a campaign and all related rows from the database.
68
+ *
69
+ * Removes all data across: action_result_flags, action_result_messages,
70
+ * action_results, action_target_people, person_in_campaigns_history,
71
+ * campaign_versions, action_versions, actions, action_configs,
72
+ * and the exclude list chain (collection_people, collection_people_versions,
73
+ * collections).
74
+ *
75
+ * Callers must verify the campaign is not active before calling this method.
76
+ *
77
+ * @throws {CampaignNotFoundError} if no campaign exists with the given ID.
78
+ */
79
+ deleteCampaign(campaignId: number): void;
66
80
  /**
67
81
  * Prepare write statements lazily (only when needed).
68
82
  * This avoids issues when the client is opened in read-only mode.
@@ -1 +1 @@
1
- {"version":3,"file":"campaign.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/campaign.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACd,mBAAmB,EAEnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAuFnD;;;;;;;;;GASG;AACH,qBAAa,kBAAkB;IAsBjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IArBnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAGhC,OAAO,CAAC,eAAe,CAYP;gBAEa,MAAM,EAAE,cAAc;IAuDnD;;OAEG;IACH,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,eAAe,EAAE;IAoBpE;;;;OAIG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ;IAiBzC;;;;OAIG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE;IAoCxD;;;;OAIG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,oBAAoB,EAAE;IA+BzB;;;;;OAKG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,yBAA8B,GACtC;QAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAsEnD;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAKnD;;;;OAIG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,QAAQ;IAyB3E;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAuD1B;;;;;;OAMG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKpC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAmCvE;;;;;;;OAOG;IACH,SAAS,CACP,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,oBAAoB,EAClC,WAAW,EAAE,MAAM,GAClB,cAAc;IA0EjB;;;;;;;;OAQG;IACH,YAAY,CACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,0BAA0B,GAClC,cAAc;IAuEjB;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE;CAoD5B"}
1
+ {"version":3,"file":"campaign.d.ts","sourceRoot":"","sources":["../../../src/db/repositories/campaign.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAGV,oBAAoB,EACpB,oBAAoB,EACpB,0BAA0B,EAC1B,QAAQ,EACR,cAAc,EACd,mBAAmB,EAEnB,aAAa,EACb,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAuFnD;;;;;;;;;GASG;AACH,qBAAa,kBAAkB;IAqCjB,OAAO,CAAC,QAAQ,CAAC,MAAM;IApCnC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;IACnC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC;IACtC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC;IACxC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;IAGhC,OAAO,CAAC,eAAe,CA2BP;gBAEa,MAAM,EAAE,cAAc;IAuDnD;;OAEG;IACH,aAAa,CAAC,OAAO,GAAE,oBAAyB,GAAG,eAAe,EAAE;IAoBpE;;;;OAIG;IACH,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ;IAiBzC;;;;OAIG;IACH,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE;IAoCxD;;;;OAIG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,iBAAsB,GAC9B,oBAAoB,EAAE;IA+BzB;;;;;OAKG;IACH,UAAU,CACR,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE,yBAA8B,GACtC;QAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAsEnD;;;;OAIG;IACH,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa;IAKnD;;;;OAIG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,oBAAoB,GAAG,QAAQ;IAyB3E;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAoExC;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAmJ1B;;;;;;OAMG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAKpC;;;;;;;;OAQG;IACH,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI;IAmCvE;;;;;;;OAOG;IACH,SAAS,CACP,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,oBAAoB,EAClC,WAAW,EAAE,MAAM,GAClB,cAAc;IA0EjB;;;;;;;;OAQG;IACH,YAAY,CACV,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,0BAA0B,GAClC,cAAc;IAuEjB;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EAAE,GAClB;QAAE,YAAY,EAAE,MAAM,CAAA;KAAE;CAoD5B"}