@lhremote/core 0.1.0 → 0.2.1

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 (499) hide show
  1. package/README.md +124 -0
  2. package/dist/cdp/app-discovery.d.ts +22 -0
  3. package/dist/cdp/app-discovery.d.ts.map +1 -0
  4. package/dist/cdp/app-discovery.js +60 -0
  5. package/dist/cdp/app-discovery.js.map +1 -0
  6. package/dist/cdp/app-discovery.test.d.ts +2 -0
  7. package/dist/cdp/app-discovery.test.d.ts.map +1 -0
  8. package/dist/cdp/app-discovery.test.js +124 -0
  9. package/dist/cdp/app-discovery.test.js.map +1 -0
  10. package/dist/cdp/client.d.ts +14 -0
  11. package/dist/cdp/client.d.ts.map +1 -1
  12. package/dist/cdp/client.integration.test.js +10 -3
  13. package/dist/cdp/client.integration.test.js.map +1 -1
  14. package/dist/cdp/client.js +41 -8
  15. package/dist/cdp/client.js.map +1 -1
  16. package/dist/cdp/client.test.js +267 -3
  17. package/dist/cdp/client.test.js.map +1 -1
  18. package/dist/cdp/discovery.d.ts.map +1 -1
  19. package/dist/cdp/discovery.integration.test.js +2 -0
  20. package/dist/cdp/discovery.integration.test.js.map +1 -1
  21. package/dist/cdp/discovery.js +2 -0
  22. package/dist/cdp/discovery.js.map +1 -1
  23. package/dist/cdp/discovery.test.js +2 -0
  24. package/dist/cdp/discovery.test.js.map +1 -1
  25. package/dist/cdp/errors.d.ts.map +1 -1
  26. package/dist/cdp/errors.js +2 -0
  27. package/dist/cdp/errors.js.map +1 -1
  28. package/dist/cdp/errors.test.js +2 -0
  29. package/dist/cdp/errors.test.js.map +1 -1
  30. package/dist/cdp/index.d.ts +1 -0
  31. package/dist/cdp/index.d.ts.map +1 -1
  32. package/dist/cdp/index.js +3 -0
  33. package/dist/cdp/index.js.map +1 -1
  34. package/dist/cdp/instance-discovery.d.ts.map +1 -1
  35. package/dist/cdp/instance-discovery.integration.test.js +2 -0
  36. package/dist/cdp/instance-discovery.integration.test.js.map +1 -1
  37. package/dist/cdp/instance-discovery.js +5 -17
  38. package/dist/cdp/instance-discovery.js.map +1 -1
  39. package/dist/cdp/instance-discovery.test.js +2 -0
  40. package/dist/cdp/instance-discovery.test.js.map +1 -1
  41. package/dist/cdp/testing/launch-chromium.d.ts.map +1 -1
  42. package/dist/cdp/testing/launch-chromium.js +4 -1
  43. package/dist/cdp/testing/launch-chromium.js.map +1 -1
  44. package/dist/constants.d.ts +5 -0
  45. package/dist/constants.d.ts.map +1 -0
  46. package/dist/constants.js +7 -0
  47. package/dist/constants.js.map +1 -0
  48. package/dist/data/action-types.d.ts +39 -0
  49. package/dist/data/action-types.d.ts.map +1 -0
  50. package/dist/data/action-types.js +497 -0
  51. package/dist/data/action-types.js.map +1 -0
  52. package/dist/data/action-types.test.d.ts +2 -0
  53. package/dist/data/action-types.test.d.ts.map +1 -0
  54. package/dist/data/action-types.test.js +544 -0
  55. package/dist/data/action-types.test.js.map +1 -0
  56. package/dist/data/index.d.ts +3 -0
  57. package/dist/data/index.d.ts.map +1 -0
  58. package/dist/data/index.js +4 -0
  59. package/dist/data/index.js.map +1 -0
  60. package/dist/db/client.d.ts +19 -5
  61. package/dist/db/client.d.ts.map +1 -1
  62. package/dist/db/client.integration.test.js +5 -1
  63. package/dist/db/client.integration.test.js.map +1 -1
  64. package/dist/db/client.js +11 -5
  65. package/dist/db/client.js.map +1 -1
  66. package/dist/db/client.test.js +2 -0
  67. package/dist/db/client.test.js.map +1 -1
  68. package/dist/db/discovery.d.ts.map +1 -1
  69. package/dist/db/discovery.integration.test.js +2 -0
  70. package/dist/db/discovery.integration.test.js.map +1 -1
  71. package/dist/db/discovery.js +2 -0
  72. package/dist/db/discovery.js.map +1 -1
  73. package/dist/db/discovery.test.js +2 -0
  74. package/dist/db/discovery.test.js.map +1 -1
  75. package/dist/db/errors.d.ts +31 -0
  76. package/dist/db/errors.d.ts.map +1 -1
  77. package/dist/db/errors.js +49 -0
  78. package/dist/db/errors.js.map +1 -1
  79. package/dist/db/errors.test.js +2 -0
  80. package/dist/db/errors.test.js.map +1 -1
  81. package/dist/db/escape-like.d.ts +8 -0
  82. package/dist/db/escape-like.d.ts.map +1 -0
  83. package/dist/db/escape-like.js +12 -0
  84. package/dist/db/escape-like.js.map +1 -0
  85. package/dist/db/escape-like.test.d.ts +2 -0
  86. package/dist/db/escape-like.test.d.ts.map +1 -0
  87. package/dist/db/escape-like.test.js +25 -0
  88. package/dist/db/escape-like.test.js.map +1 -0
  89. package/dist/db/index.d.ts +3 -3
  90. package/dist/db/index.d.ts.map +1 -1
  91. package/dist/db/index.js +4 -2
  92. package/dist/db/index.js.map +1 -1
  93. package/dist/db/repositories/campaign-exclude-list.d.ts +89 -0
  94. package/dist/db/repositories/campaign-exclude-list.d.ts.map +1 -0
  95. package/dist/db/repositories/campaign-exclude-list.js +204 -0
  96. package/dist/db/repositories/campaign-exclude-list.js.map +1 -0
  97. package/dist/db/repositories/campaign-exclude-list.test.d.ts +2 -0
  98. package/dist/db/repositories/campaign-exclude-list.test.d.ts.map +1 -0
  99. package/dist/db/repositories/campaign-exclude-list.test.js +132 -0
  100. package/dist/db/repositories/campaign-exclude-list.test.js.map +1 -0
  101. package/dist/db/repositories/campaign-statistics.d.ts +58 -0
  102. package/dist/db/repositories/campaign-statistics.d.ts.map +1 -0
  103. package/dist/db/repositories/campaign-statistics.js +278 -0
  104. package/dist/db/repositories/campaign-statistics.js.map +1 -0
  105. package/dist/db/repositories/campaign-statistics.test.d.ts +2 -0
  106. package/dist/db/repositories/campaign-statistics.test.d.ts.map +1 -0
  107. package/dist/db/repositories/campaign-statistics.test.js +266 -0
  108. package/dist/db/repositories/campaign-statistics.test.js.map +1 -0
  109. package/dist/db/repositories/campaign.d.ts +103 -0
  110. package/dist/db/repositories/campaign.d.ts.map +1 -0
  111. package/dist/db/repositories/campaign.js +388 -0
  112. package/dist/db/repositories/campaign.js.map +1 -0
  113. package/dist/db/repositories/campaign.test.d.ts +2 -0
  114. package/dist/db/repositories/campaign.test.d.ts.map +1 -0
  115. package/dist/db/repositories/campaign.test.js +392 -0
  116. package/dist/db/repositories/campaign.test.js.map +1 -0
  117. package/dist/db/repositories/index.d.ts +4 -0
  118. package/dist/db/repositories/index.d.ts.map +1 -1
  119. package/dist/db/repositories/index.js +6 -0
  120. package/dist/db/repositories/index.js.map +1 -1
  121. package/dist/db/repositories/message.d.ts +57 -0
  122. package/dist/db/repositories/message.d.ts.map +1 -0
  123. package/dist/db/repositories/message.integration.test.d.ts +2 -0
  124. package/dist/db/repositories/message.integration.test.d.ts.map +1 -0
  125. package/dist/db/repositories/message.integration.test.js +137 -0
  126. package/dist/db/repositories/message.integration.test.js.map +1 -0
  127. package/dist/db/repositories/message.js +308 -0
  128. package/dist/db/repositories/message.js.map +1 -0
  129. package/dist/db/repositories/message.test.d.ts +2 -0
  130. package/dist/db/repositories/message.test.d.ts.map +1 -0
  131. package/dist/db/repositories/message.test.js +179 -0
  132. package/dist/db/repositories/message.test.js.map +1 -0
  133. package/dist/db/repositories/profile.d.ts +11 -1
  134. package/dist/db/repositories/profile.d.ts.map +1 -1
  135. package/dist/db/repositories/profile.integration.test.js +103 -0
  136. package/dist/db/repositories/profile.integration.test.js.map +1 -1
  137. package/dist/db/repositories/profile.js +52 -15
  138. package/dist/db/repositories/profile.js.map +1 -1
  139. package/dist/db/repositories/profile.test.js +90 -0
  140. package/dist/db/repositories/profile.test.js.map +1 -1
  141. package/dist/db/testing/create-fixture.d.ts +0 -6
  142. package/dist/db/testing/create-fixture.d.ts.map +1 -1
  143. package/dist/db/testing/create-fixture.js +463 -4
  144. package/dist/db/testing/create-fixture.js.map +1 -1
  145. package/dist/db/testing/open-fixture.d.ts +5 -4
  146. package/dist/db/testing/open-fixture.d.ts.map +1 -1
  147. package/dist/db/testing/open-fixture.js +24 -6
  148. package/dist/db/testing/open-fixture.js.map +1 -1
  149. package/dist/formats/campaign-format.d.ts +31 -0
  150. package/dist/formats/campaign-format.d.ts.map +1 -0
  151. package/dist/formats/campaign-format.js +225 -0
  152. package/dist/formats/campaign-format.js.map +1 -0
  153. package/dist/formats/campaign-format.test.d.ts +2 -0
  154. package/dist/formats/campaign-format.test.d.ts.map +1 -0
  155. package/dist/formats/campaign-format.test.js +442 -0
  156. package/dist/formats/campaign-format.test.js.map +1 -0
  157. package/dist/formats/errors.d.ts +7 -0
  158. package/dist/formats/errors.d.ts.map +1 -0
  159. package/dist/formats/errors.js +12 -0
  160. package/dist/formats/errors.js.map +1 -0
  161. package/dist/formats/index.d.ts +3 -0
  162. package/dist/formats/index.d.ts.map +1 -0
  163. package/dist/formats/index.js +5 -0
  164. package/dist/formats/index.js.map +1 -0
  165. package/dist/index.d.ts +10 -5
  166. package/dist/index.d.ts.map +1 -1
  167. package/dist/index.js +26 -4
  168. package/dist/index.js.map +1 -1
  169. package/dist/operations/campaign-add-action.d.ts +14 -0
  170. package/dist/operations/campaign-add-action.d.ts.map +1 -0
  171. package/dist/operations/campaign-add-action.js +33 -0
  172. package/dist/operations/campaign-add-action.js.map +1 -0
  173. package/dist/operations/campaign-add-action.test.d.ts +2 -0
  174. package/dist/operations/campaign-add-action.test.d.ts.map +1 -0
  175. package/dist/operations/campaign-add-action.test.js +122 -0
  176. package/dist/operations/campaign-add-action.test.js.map +1 -0
  177. package/dist/operations/campaign-create.d.ts +17 -0
  178. package/dist/operations/campaign-create.d.ts.map +1 -0
  179. package/dist/operations/campaign-create.js +21 -0
  180. package/dist/operations/campaign-create.js.map +1 -0
  181. package/dist/operations/campaign-create.test.d.ts +2 -0
  182. package/dist/operations/campaign-create.test.d.ts.map +1 -0
  183. package/dist/operations/campaign-create.test.js +121 -0
  184. package/dist/operations/campaign-create.test.js.map +1 -0
  185. package/dist/operations/campaign-delete.d.ts +20 -0
  186. package/dist/operations/campaign-delete.d.ts.map +1 -0
  187. package/dist/operations/campaign-delete.js +22 -0
  188. package/dist/operations/campaign-delete.js.map +1 -0
  189. package/dist/operations/campaign-delete.test.d.ts +2 -0
  190. package/dist/operations/campaign-delete.test.d.ts.map +1 -0
  191. package/dist/operations/campaign-delete.test.js +92 -0
  192. package/dist/operations/campaign-delete.test.js.map +1 -0
  193. package/dist/operations/campaign-exclude-add.d.ts +16 -0
  194. package/dist/operations/campaign-exclude-add.d.ts.map +1 -0
  195. package/dist/operations/campaign-exclude-add.js +27 -0
  196. package/dist/operations/campaign-exclude-add.js.map +1 -0
  197. package/dist/operations/campaign-exclude-add.test.d.ts +2 -0
  198. package/dist/operations/campaign-exclude-add.test.d.ts.map +1 -0
  199. package/dist/operations/campaign-exclude-add.test.js +114 -0
  200. package/dist/operations/campaign-exclude-add.test.js.map +1 -0
  201. package/dist/operations/campaign-exclude-list.d.ts +14 -0
  202. package/dist/operations/campaign-exclude-list.d.ts.map +1 -0
  203. package/dist/operations/campaign-exclude-list.js +26 -0
  204. package/dist/operations/campaign-exclude-list.js.map +1 -0
  205. package/dist/operations/campaign-exclude-list.test.d.ts +2 -0
  206. package/dist/operations/campaign-exclude-list.test.d.ts.map +1 -0
  207. package/dist/operations/campaign-exclude-list.test.js +113 -0
  208. package/dist/operations/campaign-exclude-list.test.js.map +1 -0
  209. package/dist/operations/campaign-exclude-remove.d.ts +16 -0
  210. package/dist/operations/campaign-exclude-remove.d.ts.map +1 -0
  211. package/dist/operations/campaign-exclude-remove.js +27 -0
  212. package/dist/operations/campaign-exclude-remove.js.map +1 -0
  213. package/dist/operations/campaign-exclude-remove.test.d.ts +2 -0
  214. package/dist/operations/campaign-exclude-remove.test.d.ts.map +1 -0
  215. package/dist/operations/campaign-exclude-remove.test.js +114 -0
  216. package/dist/operations/campaign-exclude-remove.test.js.map +1 -0
  217. package/dist/operations/campaign-export.d.ts +12 -0
  218. package/dist/operations/campaign-export.d.ts.map +1 -0
  219. package/dist/operations/campaign-export.js +24 -0
  220. package/dist/operations/campaign-export.js.map +1 -0
  221. package/dist/operations/campaign-export.test.d.ts +2 -0
  222. package/dist/operations/campaign-export.test.d.ts.map +1 -0
  223. package/dist/operations/campaign-export.test.js +134 -0
  224. package/dist/operations/campaign-export.test.js.map +1 -0
  225. package/dist/operations/campaign-get.d.ts +19 -0
  226. package/dist/operations/campaign-get.d.ts.map +1 -0
  227. package/dist/operations/campaign-get.js +23 -0
  228. package/dist/operations/campaign-get.js.map +1 -0
  229. package/dist/operations/campaign-get.test.d.ts +2 -0
  230. package/dist/operations/campaign-get.test.d.ts.map +1 -0
  231. package/dist/operations/campaign-get.test.js +99 -0
  232. package/dist/operations/campaign-get.test.js.map +1 -0
  233. package/dist/operations/campaign-list.d.ts +20 -0
  234. package/dist/operations/campaign-list.d.ts.map +1 -0
  235. package/dist/operations/campaign-list.js +23 -0
  236. package/dist/operations/campaign-list.js.map +1 -0
  237. package/dist/operations/campaign-list.test.d.ts +2 -0
  238. package/dist/operations/campaign-list.test.d.ts.map +1 -0
  239. package/dist/operations/campaign-list.test.js +106 -0
  240. package/dist/operations/campaign-list.test.js.map +1 -0
  241. package/dist/operations/campaign-move-next.d.ts +15 -0
  242. package/dist/operations/campaign-move-next.d.ts.map +1 -0
  243. package/dist/operations/campaign-move-next.js +25 -0
  244. package/dist/operations/campaign-move-next.js.map +1 -0
  245. package/dist/operations/campaign-move-next.test.d.ts +2 -0
  246. package/dist/operations/campaign-move-next.test.d.ts.map +1 -0
  247. package/dist/operations/campaign-move-next.test.js +105 -0
  248. package/dist/operations/campaign-move-next.test.js.map +1 -0
  249. package/dist/operations/campaign-remove-action.d.ts +12 -0
  250. package/dist/operations/campaign-remove-action.d.ts.map +1 -0
  251. package/dist/operations/campaign-remove-action.js +23 -0
  252. package/dist/operations/campaign-remove-action.js.map +1 -0
  253. package/dist/operations/campaign-remove-action.test.d.ts +2 -0
  254. package/dist/operations/campaign-remove-action.test.d.ts.map +1 -0
  255. package/dist/operations/campaign-remove-action.test.js +95 -0
  256. package/dist/operations/campaign-remove-action.test.js.map +1 -0
  257. package/dist/operations/campaign-reorder-actions.d.ts +13 -0
  258. package/dist/operations/campaign-reorder-actions.d.ts.map +1 -0
  259. package/dist/operations/campaign-reorder-actions.js +19 -0
  260. package/dist/operations/campaign-reorder-actions.js.map +1 -0
  261. package/dist/operations/campaign-reorder-actions.test.d.ts +2 -0
  262. package/dist/operations/campaign-reorder-actions.test.d.ts.map +1 -0
  263. package/dist/operations/campaign-reorder-actions.test.js +103 -0
  264. package/dist/operations/campaign-reorder-actions.test.js.map +1 -0
  265. package/dist/operations/campaign-retry.d.ts +13 -0
  266. package/dist/operations/campaign-retry.d.ts.map +1 -0
  267. package/dist/operations/campaign-retry.js +24 -0
  268. package/dist/operations/campaign-retry.js.map +1 -0
  269. package/dist/operations/campaign-retry.test.d.ts +2 -0
  270. package/dist/operations/campaign-retry.test.d.ts.map +1 -0
  271. package/dist/operations/campaign-retry.test.js +100 -0
  272. package/dist/operations/campaign-retry.test.js.map +1 -0
  273. package/dist/operations/campaign-start.d.ts +13 -0
  274. package/dist/operations/campaign-start.d.ts.map +1 -0
  275. package/dist/operations/campaign-start.js +24 -0
  276. package/dist/operations/campaign-start.js.map +1 -0
  277. package/dist/operations/campaign-start.test.d.ts +2 -0
  278. package/dist/operations/campaign-start.test.d.ts.map +1 -0
  279. package/dist/operations/campaign-start.test.js +105 -0
  280. package/dist/operations/campaign-start.test.js.map +1 -0
  281. package/dist/operations/campaign-statistics.d.ts +10 -0
  282. package/dist/operations/campaign-statistics.d.ts.map +1 -0
  283. package/dist/operations/campaign-statistics.js +23 -0
  284. package/dist/operations/campaign-statistics.js.map +1 -0
  285. package/dist/operations/campaign-statistics.test.d.ts +2 -0
  286. package/dist/operations/campaign-statistics.test.d.ts.map +1 -0
  287. package/dist/operations/campaign-statistics.test.js +120 -0
  288. package/dist/operations/campaign-statistics.test.js.map +1 -0
  289. package/dist/operations/campaign-status.d.ts +26 -0
  290. package/dist/operations/campaign-status.d.ts.map +1 -0
  291. package/dist/operations/campaign-status.js +32 -0
  292. package/dist/operations/campaign-status.js.map +1 -0
  293. package/dist/operations/campaign-status.test.d.ts +2 -0
  294. package/dist/operations/campaign-status.test.d.ts.map +1 -0
  295. package/dist/operations/campaign-status.test.js +142 -0
  296. package/dist/operations/campaign-status.test.js.map +1 -0
  297. package/dist/operations/campaign-stop.d.ts +11 -0
  298. package/dist/operations/campaign-stop.d.ts.map +1 -0
  299. package/dist/operations/campaign-stop.js +23 -0
  300. package/dist/operations/campaign-stop.js.map +1 -0
  301. package/dist/operations/campaign-stop.test.d.ts +2 -0
  302. package/dist/operations/campaign-stop.test.d.ts.map +1 -0
  303. package/dist/operations/campaign-stop.test.js +92 -0
  304. package/dist/operations/campaign-stop.test.js.map +1 -0
  305. package/dist/operations/campaign-update.d.ts +18 -0
  306. package/dist/operations/campaign-update.d.ts.map +1 -0
  307. package/dist/operations/campaign-update.js +21 -0
  308. package/dist/operations/campaign-update.js.map +1 -0
  309. package/dist/operations/campaign-update.test.d.ts +2 -0
  310. package/dist/operations/campaign-update.test.d.ts.map +1 -0
  311. package/dist/operations/campaign-update.test.js +105 -0
  312. package/dist/operations/campaign-update.test.js.map +1 -0
  313. package/dist/operations/check-replies.d.ts +12 -0
  314. package/dist/operations/check-replies.d.ts.map +1 -0
  315. package/dist/operations/check-replies.js +26 -0
  316. package/dist/operations/check-replies.js.map +1 -0
  317. package/dist/operations/check-replies.test.d.ts +2 -0
  318. package/dist/operations/check-replies.test.d.ts.map +1 -0
  319. package/dist/operations/check-replies.test.js +118 -0
  320. package/dist/operations/check-replies.test.js.map +1 -0
  321. package/dist/operations/import-people-from-urls.d.ts +16 -0
  322. package/dist/operations/import-people-from-urls.d.ts.map +1 -0
  323. package/dist/operations/import-people-from-urls.js +27 -0
  324. package/dist/operations/import-people-from-urls.js.map +1 -0
  325. package/dist/operations/import-people-from-urls.test.d.ts +2 -0
  326. package/dist/operations/import-people-from-urls.test.d.ts.map +1 -0
  327. package/dist/operations/import-people-from-urls.test.js +118 -0
  328. package/dist/operations/import-people-from-urls.test.js.map +1 -0
  329. package/dist/operations/index.d.ts +24 -0
  330. package/dist/operations/index.d.ts.map +1 -0
  331. package/dist/operations/index.js +30 -0
  332. package/dist/operations/index.js.map +1 -0
  333. package/dist/operations/query-messages.d.ts +23 -0
  334. package/dist/operations/query-messages.d.ts.map +1 -0
  335. package/dist/operations/query-messages.js +33 -0
  336. package/dist/operations/query-messages.js.map +1 -0
  337. package/dist/operations/query-messages.test.d.ts +2 -0
  338. package/dist/operations/query-messages.test.d.ts.map +1 -0
  339. package/dist/operations/query-messages.test.js +134 -0
  340. package/dist/operations/query-messages.test.js.map +1 -0
  341. package/dist/operations/scrape-messaging-history.d.ts +10 -0
  342. package/dist/operations/scrape-messaging-history.d.ts.map +1 -0
  343. package/dist/operations/scrape-messaging-history.js +24 -0
  344. package/dist/operations/scrape-messaging-history.js.map +1 -0
  345. package/dist/operations/scrape-messaging-history.test.d.ts +2 -0
  346. package/dist/operations/scrape-messaging-history.test.d.ts.map +1 -0
  347. package/dist/operations/scrape-messaging-history.test.js +112 -0
  348. package/dist/operations/scrape-messaging-history.test.js.map +1 -0
  349. package/dist/operations/types.d.ts +10 -0
  350. package/dist/operations/types.d.ts.map +1 -0
  351. package/dist/operations/types.js +4 -0
  352. package/dist/operations/types.js.map +1 -0
  353. package/dist/services/account-resolution.d.ts +22 -0
  354. package/dist/services/account-resolution.d.ts.map +1 -0
  355. package/dist/services/account-resolution.js +45 -0
  356. package/dist/services/account-resolution.js.map +1 -0
  357. package/dist/services/account-resolution.test.d.ts +2 -0
  358. package/dist/services/account-resolution.test.d.ts.map +1 -0
  359. package/dist/services/account-resolution.test.js +91 -0
  360. package/dist/services/account-resolution.test.js.map +1 -0
  361. package/dist/services/app.d.ts.map +1 -1
  362. package/dist/services/app.js +2 -0
  363. package/dist/services/app.js.map +1 -1
  364. package/dist/services/app.test.js +2 -0
  365. package/dist/services/app.test.js.map +1 -1
  366. package/dist/services/campaign.d.ts +143 -0
  367. package/dist/services/campaign.d.ts.map +1 -0
  368. package/dist/services/campaign.js +409 -0
  369. package/dist/services/campaign.js.map +1 -0
  370. package/dist/services/campaign.test.d.ts +2 -0
  371. package/dist/services/campaign.test.d.ts.map +1 -0
  372. package/dist/services/campaign.test.js +481 -0
  373. package/dist/services/campaign.test.js.map +1 -0
  374. package/dist/services/errors.d.ts +38 -0
  375. package/dist/services/errors.d.ts.map +1 -1
  376. package/dist/services/errors.js +60 -0
  377. package/dist/services/errors.js.map +1 -1
  378. package/dist/services/errors.test.js +53 -1
  379. package/dist/services/errors.test.js.map +1 -1
  380. package/dist/services/index.d.ts +5 -3
  381. package/dist/services/index.d.ts.map +1 -1
  382. package/dist/services/index.js +6 -2
  383. package/dist/services/index.js.map +1 -1
  384. package/dist/services/instance-context.d.ts +37 -0
  385. package/dist/services/instance-context.d.ts.map +1 -0
  386. package/dist/services/instance-context.js +49 -0
  387. package/dist/services/instance-context.js.map +1 -0
  388. package/dist/services/instance-context.test.d.ts +2 -0
  389. package/dist/services/instance-context.test.d.ts.map +1 -0
  390. package/dist/services/instance-context.test.js +203 -0
  391. package/dist/services/instance-context.test.js.map +1 -0
  392. package/dist/services/instance-lifecycle.d.ts.map +1 -1
  393. package/dist/services/instance-lifecycle.js +6 -6
  394. package/dist/services/instance-lifecycle.js.map +1 -1
  395. package/dist/services/instance-lifecycle.test.js +8 -2
  396. package/dist/services/instance-lifecycle.test.js.map +1 -1
  397. package/dist/services/instance.d.ts +40 -0
  398. package/dist/services/instance.d.ts.map +1 -1
  399. package/dist/services/instance.js +66 -9
  400. package/dist/services/instance.js.map +1 -1
  401. package/dist/services/instance.test.js +116 -6
  402. package/dist/services/instance.test.js.map +1 -1
  403. package/dist/services/launcher.d.ts +3 -0
  404. package/dist/services/launcher.d.ts.map +1 -1
  405. package/dist/services/launcher.js +25 -10
  406. package/dist/services/launcher.js.map +1 -1
  407. package/dist/services/launcher.test.js +39 -2
  408. package/dist/services/launcher.test.js.map +1 -1
  409. package/dist/services/status.d.ts +5 -1
  410. package/dist/services/status.d.ts.map +1 -1
  411. package/dist/services/status.js +24 -15
  412. package/dist/services/status.js.map +1 -1
  413. package/dist/services/status.test.js +42 -1
  414. package/dist/services/status.test.js.map +1 -1
  415. package/dist/testing/e2e-helpers.d.ts.map +1 -1
  416. package/dist/testing/e2e-helpers.js +7 -4
  417. package/dist/testing/e2e-helpers.js.map +1 -1
  418. package/dist/testing/index.d.ts +2 -0
  419. package/dist/testing/index.d.ts.map +1 -0
  420. package/dist/testing/index.js +4 -0
  421. package/dist/testing/index.js.map +1 -0
  422. package/dist/types/account.d.ts.map +1 -1
  423. package/dist/types/account.js +2 -0
  424. package/dist/types/account.js.map +1 -1
  425. package/dist/types/account.test.js +2 -0
  426. package/dist/types/account.test.js.map +1 -1
  427. package/dist/types/campaign.d.ts +267 -0
  428. package/dist/types/campaign.d.ts.map +1 -0
  429. package/dist/types/campaign.js +4 -0
  430. package/dist/types/campaign.js.map +1 -0
  431. package/dist/types/cdp.d.ts.map +1 -1
  432. package/dist/types/cdp.js +2 -0
  433. package/dist/types/cdp.js.map +1 -1
  434. package/dist/types/cdp.test.js +2 -0
  435. package/dist/types/cdp.test.js.map +1 -1
  436. package/dist/types/index.d.ts +3 -1
  437. package/dist/types/index.d.ts.map +1 -1
  438. package/dist/types/index.js +2 -0
  439. package/dist/types/index.js.map +1 -1
  440. package/dist/types/instance.d.ts.map +1 -1
  441. package/dist/types/instance.js +2 -6
  442. package/dist/types/instance.js.map +1 -1
  443. package/dist/types/instance.test.js +2 -0
  444. package/dist/types/instance.test.js.map +1 -1
  445. package/dist/types/messaging.d.ts +51 -0
  446. package/dist/types/messaging.d.ts.map +1 -0
  447. package/dist/types/messaging.js +4 -0
  448. package/dist/types/messaging.js.map +1 -0
  449. package/dist/types/profile.d.ts +31 -0
  450. package/dist/types/profile.d.ts.map +1 -1
  451. package/dist/types/profile.js +2 -6
  452. package/dist/types/profile.js.map +1 -1
  453. package/dist/types/profile.test.js +2 -0
  454. package/dist/types/profile.test.js.map +1 -1
  455. package/dist/utils/cdp-port.d.ts +5 -0
  456. package/dist/utils/cdp-port.d.ts.map +1 -0
  457. package/dist/utils/cdp-port.js +15 -0
  458. package/dist/utils/cdp-port.js.map +1 -0
  459. package/dist/utils/cdp-port.test.d.ts +2 -0
  460. package/dist/utils/cdp-port.test.d.ts.map +1 -0
  461. package/dist/utils/cdp-port.test.js +23 -0
  462. package/dist/utils/cdp-port.test.js.map +1 -0
  463. package/dist/utils/delay.d.ts +5 -0
  464. package/dist/utils/delay.d.ts.map +1 -0
  465. package/dist/utils/delay.js +9 -0
  466. package/dist/utils/delay.js.map +1 -0
  467. package/dist/utils/delay.test.d.ts +2 -0
  468. package/dist/utils/delay.test.d.ts.map +1 -0
  469. package/dist/utils/delay.test.js +17 -0
  470. package/dist/utils/delay.test.js.map +1 -0
  471. package/dist/utils/error-message.d.ts +5 -0
  472. package/dist/utils/error-message.d.ts.map +1 -0
  473. package/dist/utils/error-message.js +9 -0
  474. package/dist/utils/error-message.js.map +1 -0
  475. package/dist/utils/error-message.test.d.ts +2 -0
  476. package/dist/utils/error-message.test.d.ts.map +1 -0
  477. package/dist/utils/error-message.test.js +28 -0
  478. package/dist/utils/error-message.test.js.map +1 -0
  479. package/dist/utils/index.d.ts +5 -0
  480. package/dist/utils/index.d.ts.map +1 -0
  481. package/dist/utils/index.js +7 -0
  482. package/dist/utils/index.js.map +1 -0
  483. package/dist/utils/loopback.d.ts +10 -0
  484. package/dist/utils/loopback.d.ts.map +1 -0
  485. package/dist/utils/loopback.js +28 -0
  486. package/dist/utils/loopback.js.map +1 -0
  487. package/dist/utils/loopback.test.d.ts +2 -0
  488. package/dist/utils/loopback.test.d.ts.map +1 -0
  489. package/dist/utils/loopback.test.js +34 -0
  490. package/dist/utils/loopback.test.js.map +1 -0
  491. package/package.json +13 -8
  492. package/dist/services/profile.d.ts +0 -44
  493. package/dist/services/profile.d.ts.map +0 -1
  494. package/dist/services/profile.js +0 -83
  495. package/dist/services/profile.js.map +0 -1
  496. package/dist/services/profile.test.d.ts +0 -2
  497. package/dist/services/profile.test.d.ts.map +0 -1
  498. package/dist/services/profile.test.js +0 -145
  499. package/dist/services/profile.test.js.map +0 -1
@@ -0,0 +1,225 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { parse as parseYaml, stringify as stringifyYaml } from "yaml";
4
+ import { errorMessage } from "../utils/error-message.js";
5
+ import { FormatError } from "./errors.js";
6
+ /** Current version of the campaign document format. */
7
+ const CURRENT_VERSION = "1";
8
+ /**
9
+ * Thrown when a campaign document fails structural validation.
10
+ */
11
+ export class CampaignFormatError extends FormatError {
12
+ constructor(message) {
13
+ super(message);
14
+ this.name = "CampaignFormatError";
15
+ }
16
+ }
17
+ // ---------------------------------------------------------------------------
18
+ // Parse
19
+ // ---------------------------------------------------------------------------
20
+ /**
21
+ * Parse a YAML string into a CampaignConfig.
22
+ *
23
+ * @throws {CampaignFormatError} if the YAML is malformed or the document
24
+ * fails structural validation.
25
+ */
26
+ export function parseCampaignYaml(yamlString) {
27
+ let doc;
28
+ try {
29
+ doc = parseYaml(yamlString);
30
+ }
31
+ catch (error) {
32
+ const message = errorMessage(error);
33
+ throw new CampaignFormatError(`Invalid YAML: ${message}`);
34
+ }
35
+ return parseCampaignDocument(doc);
36
+ }
37
+ /**
38
+ * Parse a JSON string into a CampaignConfig.
39
+ *
40
+ * @throws {CampaignFormatError} if the JSON is malformed or the document
41
+ * fails structural validation.
42
+ */
43
+ export function parseCampaignJson(jsonString) {
44
+ let doc;
45
+ try {
46
+ doc = JSON.parse(jsonString);
47
+ }
48
+ catch (error) {
49
+ const message = errorMessage(error);
50
+ throw new CampaignFormatError(`Invalid JSON: ${message}`);
51
+ }
52
+ return parseCampaignDocument(doc);
53
+ }
54
+ // ---------------------------------------------------------------------------
55
+ // Serialize
56
+ // ---------------------------------------------------------------------------
57
+ /**
58
+ * Serialize a campaign and its actions to a YAML string.
59
+ */
60
+ export function serializeCampaignYaml(campaign, actions) {
61
+ const doc = toCampaignDocument(campaign, actions);
62
+ return stringifyYaml(doc);
63
+ }
64
+ /**
65
+ * Serialize a campaign and its actions to a JSON string.
66
+ */
67
+ export function serializeCampaignJson(campaign, actions) {
68
+ const doc = toCampaignDocument(campaign, actions);
69
+ return JSON.stringify(doc, null, 2) + "\n";
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // Internal: parse
73
+ // ---------------------------------------------------------------------------
74
+ function parseCampaignDocument(doc) {
75
+ if (doc === null || typeof doc !== "object") {
76
+ throw new CampaignFormatError("Campaign document must be an object");
77
+ }
78
+ const obj = doc;
79
+ // Version
80
+ if (!("version" in obj) || obj["version"] === undefined) {
81
+ throw new CampaignFormatError("Missing required field: version");
82
+ }
83
+ if (String(obj["version"]) !== CURRENT_VERSION) {
84
+ throw new CampaignFormatError(`Unsupported version: ${String(obj["version"])} (expected ${CURRENT_VERSION})`);
85
+ }
86
+ // Name
87
+ if (!("name" in obj) || typeof obj["name"] !== "string" || obj["name"].trim() === "") {
88
+ throw new CampaignFormatError("Missing or empty required field: name");
89
+ }
90
+ const name = obj["name"].trim();
91
+ // Description
92
+ const description = "description" in obj && typeof obj["description"] === "string"
93
+ ? obj["description"]
94
+ : undefined;
95
+ // Settings (campaign-level defaults)
96
+ const settings = parseDocumentSettings(obj["settings"]);
97
+ // Actions
98
+ if (!("actions" in obj) || obj["actions"] === undefined) {
99
+ throw new CampaignFormatError("Missing required field: actions");
100
+ }
101
+ if (!Array.isArray(obj["actions"])) {
102
+ throw new CampaignFormatError("Invalid field: actions must be an array");
103
+ }
104
+ if (obj["actions"].length === 0) {
105
+ throw new CampaignFormatError("Actions array must not be empty");
106
+ }
107
+ const actions = obj["actions"].map((raw, index) => parseDocumentAction(raw, index, settings));
108
+ const config = { name, actions };
109
+ if (description !== undefined) {
110
+ config.description = description;
111
+ }
112
+ return config;
113
+ }
114
+ function parseDocumentSettings(raw) {
115
+ if (raw === null || raw === undefined) {
116
+ return {};
117
+ }
118
+ if (Array.isArray(raw) || typeof raw !== "object") {
119
+ throw new CampaignFormatError("Invalid field: settings must be an object");
120
+ }
121
+ const obj = raw;
122
+ const settings = {};
123
+ if ("cooldownMs" in obj && typeof obj["cooldownMs"] === "number" && Number.isFinite(obj["cooldownMs"])) {
124
+ settings.cooldownMs = obj["cooldownMs"];
125
+ }
126
+ if ("maxActionsPerRun" in obj && typeof obj["maxActionsPerRun"] === "number" && Number.isFinite(obj["maxActionsPerRun"])) {
127
+ settings.maxActionsPerRun = obj["maxActionsPerRun"];
128
+ }
129
+ return settings;
130
+ }
131
+ function parseDocumentAction(raw, index, defaults) {
132
+ if (raw === null || typeof raw !== "object") {
133
+ throw new CampaignFormatError(`Action at index ${String(index)} must be an object`);
134
+ }
135
+ const obj = raw;
136
+ if (!("type" in obj) || typeof obj["type"] !== "string" || obj["type"].trim() === "") {
137
+ throw new CampaignFormatError(`Action at index ${String(index)} is missing required field: type`);
138
+ }
139
+ const actionType = obj["type"].trim();
140
+ const actionSettings = "config" in obj && obj["config"] !== null && typeof obj["config"] === "object" && !Array.isArray(obj["config"])
141
+ ? obj["config"]
142
+ : undefined;
143
+ const action = {
144
+ name: actionType,
145
+ actionType,
146
+ };
147
+ if (actionSettings !== undefined) {
148
+ action.actionSettings = actionSettings;
149
+ }
150
+ // Apply coolDown: per-action override > campaign-level default
151
+ const coolDown = getFiniteNumberField(obj, "cooldownMs") ?? defaults.cooldownMs;
152
+ if (coolDown !== undefined) {
153
+ action.coolDown = coolDown;
154
+ }
155
+ // Apply maxActionResultsPerIteration: per-action > campaign-level
156
+ const maxActions = getFiniteNumberField(obj, "maxActionsPerRun") ?? defaults.maxActionsPerRun;
157
+ if (maxActions !== undefined) {
158
+ action.maxActionResultsPerIteration = maxActions;
159
+ }
160
+ return action;
161
+ }
162
+ function getFiniteNumberField(obj, key) {
163
+ if (key in obj && typeof obj[key] === "number" && Number.isFinite(obj[key])) {
164
+ return obj[key];
165
+ }
166
+ return undefined;
167
+ }
168
+ // ---------------------------------------------------------------------------
169
+ // Internal: serialize
170
+ // ---------------------------------------------------------------------------
171
+ function toCampaignDocument(campaign, actions) {
172
+ // Extract common settings first so we know what goes at campaign-level
173
+ const commonSettings = extractCommonSettings(actions);
174
+ const docActions = actions.map((a) => {
175
+ const docAction = { type: a.config.actionType };
176
+ const settings = a.config.actionSettings;
177
+ if (settings !== undefined && Object.keys(settings).length > 0) {
178
+ docAction.config = settings;
179
+ }
180
+ // Emit per-action settings when they differ from campaign-level defaults
181
+ const coolDown = a.config.coolDown;
182
+ if (commonSettings?.cooldownMs === undefined && Number.isFinite(coolDown)) {
183
+ docAction.cooldownMs = coolDown;
184
+ }
185
+ const maxResults = a.config.maxActionResultsPerIteration;
186
+ if (commonSettings?.maxActionsPerRun === undefined && Number.isFinite(maxResults)) {
187
+ docAction.maxActionsPerRun = maxResults;
188
+ }
189
+ return docAction;
190
+ });
191
+ const doc = {
192
+ version: CURRENT_VERSION,
193
+ name: campaign.name,
194
+ actions: docActions,
195
+ };
196
+ if (campaign.description !== null) {
197
+ doc.description = campaign.description;
198
+ }
199
+ if (commonSettings !== undefined) {
200
+ doc.settings = commonSettings;
201
+ }
202
+ return doc;
203
+ }
204
+ function extractCommonSettings(actions) {
205
+ if (actions.length === 0)
206
+ return undefined;
207
+ const first = actions[0];
208
+ if (first === undefined)
209
+ return undefined;
210
+ const coolDown = first.config.coolDown;
211
+ const maxResults = first.config.maxActionResultsPerIteration;
212
+ const allSameCoolDown = actions.every((a) => a.config.coolDown === coolDown);
213
+ const allSameMaxResults = actions.every((a) => a.config.maxActionResultsPerIteration === maxResults);
214
+ if (!allSameCoolDown && !allSameMaxResults)
215
+ return undefined;
216
+ const settings = {};
217
+ if (allSameCoolDown) {
218
+ settings.cooldownMs = coolDown;
219
+ }
220
+ if (allSameMaxResults) {
221
+ settings.maxActionsPerRun = maxResults;
222
+ }
223
+ return settings;
224
+ }
225
+ //# sourceMappingURL=campaign-format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-format.js","sourceRoot":"","sources":["../../src/formats/campaign-format.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=campaign-format.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"campaign-format.test.d.ts","sourceRoot":"","sources":["../../src/formats/campaign-format.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,442 @@
1
+ // SPDX-License-Identifier: AGPL-3.0-only
2
+ // Copyright (C) 2026 Oleksii PELYKH
3
+ import { describe, expect, it } from "vitest";
4
+ import { CampaignFormatError, parseCampaignJson, parseCampaignYaml, serializeCampaignJson, serializeCampaignYaml, } from "./campaign-format.js";
5
+ const MINIMAL_YAML = `
6
+ version: "1"
7
+ name: "Test Campaign"
8
+ actions:
9
+ - type: VisitAndExtract
10
+ `;
11
+ const FULL_YAML = `
12
+ version: "1"
13
+ name: "Outreach Campaign"
14
+ description: "A test campaign"
15
+ settings:
16
+ cooldownMs: 30000
17
+ maxActionsPerRun: 5
18
+ actions:
19
+ - type: VisitAndExtract
20
+ config:
21
+ extractCurrentOrganizations: true
22
+ - type: MessageToPerson
23
+ config:
24
+ messageTemplate: "Hi {firstName}"
25
+ `;
26
+ const MOCK_CAMPAIGN = {
27
+ id: 1,
28
+ name: "Test Campaign",
29
+ description: "Test description",
30
+ state: "paused",
31
+ liAccountId: 1,
32
+ isPaused: true,
33
+ isArchived: false,
34
+ isValid: true,
35
+ createdAt: "2025-01-15T00:00:00Z",
36
+ };
37
+ const MOCK_ACTIONS = [
38
+ {
39
+ id: 10,
40
+ campaignId: 1,
41
+ name: "Visit & Extract",
42
+ description: null,
43
+ config: {
44
+ id: 100,
45
+ actionType: "VisitAndExtract",
46
+ actionSettings: { extractCurrentOrganizations: true },
47
+ coolDown: 60000,
48
+ maxActionResultsPerIteration: 10,
49
+ isDraft: false,
50
+ },
51
+ versionId: 1000,
52
+ },
53
+ {
54
+ id: 11,
55
+ campaignId: 1,
56
+ name: "Message",
57
+ description: null,
58
+ config: {
59
+ id: 101,
60
+ actionType: "MessageToPerson",
61
+ actionSettings: { messageTemplate: "Hi {firstName}" },
62
+ coolDown: 60000,
63
+ maxActionResultsPerIteration: 10,
64
+ isDraft: false,
65
+ },
66
+ versionId: 1001,
67
+ },
68
+ ];
69
+ describe("parseCampaignYaml", () => {
70
+ it("parses minimal valid YAML", () => {
71
+ const config = parseCampaignYaml(MINIMAL_YAML);
72
+ expect(config.name).toBe("Test Campaign");
73
+ expect(config.description).toBeUndefined();
74
+ expect(config.actions).toHaveLength(1);
75
+ expect(config.actions[0]?.actionType).toBe("VisitAndExtract");
76
+ });
77
+ it("parses full YAML with settings and description", () => {
78
+ const config = parseCampaignYaml(FULL_YAML);
79
+ expect(config.name).toBe("Outreach Campaign");
80
+ expect(config.description).toBe("A test campaign");
81
+ expect(config.actions).toHaveLength(2);
82
+ expect(config.actions[0]?.actionType).toBe("VisitAndExtract");
83
+ expect(config.actions[0]?.actionSettings).toEqual({ extractCurrentOrganizations: true });
84
+ expect(config.actions[1]?.actionType).toBe("MessageToPerson");
85
+ expect(config.actions[1]?.actionSettings).toEqual({
86
+ messageTemplate: "Hi {firstName}",
87
+ });
88
+ });
89
+ it("applies campaign-level settings as action defaults", () => {
90
+ const config = parseCampaignYaml(FULL_YAML);
91
+ expect(config.actions[0]?.coolDown).toBe(30000);
92
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBe(5);
93
+ expect(config.actions[1]?.coolDown).toBe(30000);
94
+ expect(config.actions[1]?.maxActionResultsPerIteration).toBe(5);
95
+ });
96
+ it("allows per-action overrides of settings", () => {
97
+ const yaml = `
98
+ version: "1"
99
+ name: "Test"
100
+ settings:
101
+ cooldownMs: 30000
102
+ maxActionsPerRun: 5
103
+ actions:
104
+ - type: VisitAndExtract
105
+ cooldownMs: 10000
106
+ maxActionsPerRun: 20
107
+ `;
108
+ const config = parseCampaignYaml(yaml);
109
+ expect(config.actions[0]?.coolDown).toBe(10000);
110
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBe(20);
111
+ });
112
+ it("derives action name from type", () => {
113
+ const config = parseCampaignYaml(MINIMAL_YAML);
114
+ expect(config.actions[0]?.name).toBe("VisitAndExtract");
115
+ });
116
+ it("does not set coolDown/maxActionResultsPerIteration when no settings", () => {
117
+ const config = parseCampaignYaml(MINIMAL_YAML);
118
+ expect(config.actions[0]?.coolDown).toBeUndefined();
119
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBeUndefined();
120
+ });
121
+ it("throws CampaignFormatError for missing version", () => {
122
+ const yaml = `
123
+ name: "Test"
124
+ actions:
125
+ - type: VisitAndExtract
126
+ `;
127
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
128
+ expect(() => parseCampaignYaml(yaml)).toThrow("Missing required field: version");
129
+ });
130
+ it("throws CampaignFormatError for wrong version", () => {
131
+ const yaml = `
132
+ version: "2"
133
+ name: "Test"
134
+ actions:
135
+ - type: VisitAndExtract
136
+ `;
137
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
138
+ expect(() => parseCampaignYaml(yaml)).toThrow("Unsupported version: 2");
139
+ });
140
+ it("throws CampaignFormatError for missing name", () => {
141
+ const yaml = `
142
+ version: "1"
143
+ actions:
144
+ - type: VisitAndExtract
145
+ `;
146
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
147
+ expect(() => parseCampaignYaml(yaml)).toThrow("Missing or empty required field: name");
148
+ });
149
+ it("throws CampaignFormatError for empty name", () => {
150
+ const yaml = `
151
+ version: "1"
152
+ name: ""
153
+ actions:
154
+ - type: VisitAndExtract
155
+ `;
156
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
157
+ expect(() => parseCampaignYaml(yaml)).toThrow("Missing or empty required field: name");
158
+ });
159
+ it("throws CampaignFormatError for missing actions", () => {
160
+ const yaml = `
161
+ version: "1"
162
+ name: "Test"
163
+ `;
164
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
165
+ expect(() => parseCampaignYaml(yaml)).toThrow("Missing required field: actions");
166
+ });
167
+ it("throws CampaignFormatError for non-array actions", () => {
168
+ const yaml = `
169
+ version: "1"
170
+ name: "Test"
171
+ actions: "visit"
172
+ `;
173
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
174
+ expect(() => parseCampaignYaml(yaml)).toThrow("Invalid field: actions must be an array");
175
+ });
176
+ it("throws CampaignFormatError for non-object settings", () => {
177
+ const yaml = `
178
+ version: "1"
179
+ name: "Test"
180
+ settings: "fast"
181
+ actions:
182
+ - type: VisitAndExtract
183
+ `;
184
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
185
+ expect(() => parseCampaignYaml(yaml)).toThrow("Invalid field: settings must be an object");
186
+ });
187
+ it("throws CampaignFormatError for array settings", () => {
188
+ const json = JSON.stringify({
189
+ version: "1",
190
+ name: "Test",
191
+ settings: [1, 2, 3],
192
+ actions: [{ type: "VisitAndExtract" }],
193
+ });
194
+ expect(() => parseCampaignJson(json)).toThrow(CampaignFormatError);
195
+ expect(() => parseCampaignJson(json)).toThrow("Invalid field: settings must be an object");
196
+ });
197
+ it("ignores non-numeric cooldownMs in settings", () => {
198
+ const json = JSON.stringify({
199
+ version: "1",
200
+ name: "Test",
201
+ settings: { cooldownMs: null, maxActionsPerRun: 5 },
202
+ actions: [{ type: "VisitAndExtract" }],
203
+ });
204
+ const config = parseCampaignJson(json);
205
+ expect(config.actions[0]?.coolDown).toBeUndefined();
206
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBe(5);
207
+ });
208
+ it("ignores NaN and Infinity in settings via YAML", () => {
209
+ const yaml = `
210
+ version: "1"
211
+ name: "Test"
212
+ settings:
213
+ cooldownMs: .nan
214
+ maxActionsPerRun: .inf
215
+ actions:
216
+ - type: VisitAndExtract
217
+ `;
218
+ const config = parseCampaignYaml(yaml);
219
+ expect(config.actions[0]?.coolDown).toBeUndefined();
220
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBeUndefined();
221
+ });
222
+ it("ignores array config in actions", () => {
223
+ const json = JSON.stringify({
224
+ version: "1",
225
+ name: "Test",
226
+ actions: [{ type: "VisitAndExtract", config: [1, 2, 3] }],
227
+ });
228
+ const config = parseCampaignJson(json);
229
+ expect(config.actions[0]?.actionSettings).toBeUndefined();
230
+ });
231
+ it("throws CampaignFormatError for empty actions array", () => {
232
+ const yaml = `
233
+ version: "1"
234
+ name: "Test"
235
+ actions: []
236
+ `;
237
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
238
+ expect(() => parseCampaignYaml(yaml)).toThrow("Actions array must not be empty");
239
+ });
240
+ it("throws CampaignFormatError for action without type", () => {
241
+ const yaml = `
242
+ version: "1"
243
+ name: "Test"
244
+ actions:
245
+ - config:
246
+ extractCurrentOrganizations: true
247
+ `;
248
+ expect(() => parseCampaignYaml(yaml)).toThrow(CampaignFormatError);
249
+ expect(() => parseCampaignYaml(yaml)).toThrow("Action at index 0 is missing required field: type");
250
+ });
251
+ it("throws CampaignFormatError for invalid YAML syntax", () => {
252
+ expect(() => parseCampaignYaml("{{invalid")).toThrow(CampaignFormatError);
253
+ expect(() => parseCampaignYaml("{{invalid")).toThrow("Invalid YAML");
254
+ });
255
+ it("throws CampaignFormatError for non-object document", () => {
256
+ expect(() => parseCampaignYaml("just a string")).toThrow(CampaignFormatError);
257
+ expect(() => parseCampaignYaml("just a string")).toThrow("Campaign document must be an object");
258
+ });
259
+ });
260
+ describe("parseCampaignJson", () => {
261
+ it("parses valid JSON", () => {
262
+ const json = JSON.stringify({
263
+ version: "1",
264
+ name: "Test Campaign",
265
+ actions: [{ type: "VisitAndExtract" }],
266
+ });
267
+ const config = parseCampaignJson(json);
268
+ expect(config.name).toBe("Test Campaign");
269
+ expect(config.actions).toHaveLength(1);
270
+ expect(config.actions[0]?.actionType).toBe("VisitAndExtract");
271
+ });
272
+ it("throws CampaignFormatError for invalid JSON syntax", () => {
273
+ expect(() => parseCampaignJson("{invalid}")).toThrow(CampaignFormatError);
274
+ expect(() => parseCampaignJson("{invalid}")).toThrow("Invalid JSON");
275
+ });
276
+ it("throws CampaignFormatError for invalid document structure", () => {
277
+ expect(() => parseCampaignJson('"just a string"')).toThrow(CampaignFormatError);
278
+ });
279
+ });
280
+ describe("serializeCampaignYaml", () => {
281
+ it("serializes campaign with uniform settings to campaign-level", () => {
282
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, MOCK_ACTIONS);
283
+ expect(yaml).toContain("version:");
284
+ expect(yaml).toContain('name: Test Campaign');
285
+ expect(yaml).toContain("description: Test description");
286
+ expect(yaml).toContain("cooldownMs: 60000");
287
+ expect(yaml).toContain("maxActionsPerRun: 10");
288
+ expect(yaml).toContain("type: VisitAndExtract");
289
+ expect(yaml).toContain("type: MessageToPerson");
290
+ });
291
+ it("serializes campaign with varied settings as per-action overrides", () => {
292
+ const action0 = MOCK_ACTIONS[0];
293
+ const action1 = MOCK_ACTIONS[1];
294
+ const variedActions = [
295
+ {
296
+ ...action0,
297
+ config: { ...action0.config, coolDown: 30000 },
298
+ },
299
+ {
300
+ ...action1,
301
+ config: { ...action1.config, coolDown: 60000 },
302
+ },
303
+ ];
304
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, variedActions);
305
+ // cooldownMs should NOT be at campaign-level settings since they differ
306
+ // but maxActionsPerRun is still uniform so should be in settings
307
+ expect(yaml).toContain("maxActionsPerRun: 10");
308
+ // per-action cooldownMs should be present
309
+ expect(yaml).toContain("cooldownMs: 30000");
310
+ expect(yaml).toContain("cooldownMs: 60000");
311
+ });
312
+ it("includes description when non-null", () => {
313
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, MOCK_ACTIONS);
314
+ expect(yaml).toContain("description: Test description");
315
+ });
316
+ it("omits description when null", () => {
317
+ const campaign = { ...MOCK_CAMPAIGN, description: null };
318
+ const yaml = serializeCampaignYaml(campaign, MOCK_ACTIONS);
319
+ expect(yaml).not.toContain("description:");
320
+ });
321
+ it("omits empty actionSettings from config", () => {
322
+ const action0 = MOCK_ACTIONS[0];
323
+ const actions = [
324
+ {
325
+ ...action0,
326
+ config: { ...action0.config, actionSettings: {} },
327
+ },
328
+ ];
329
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, actions);
330
+ expect(yaml).not.toContain("config:");
331
+ });
332
+ it("includes non-empty actionSettings as config", () => {
333
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, MOCK_ACTIONS);
334
+ expect(yaml).toContain("extractCurrentOrganizations: true");
335
+ expect(yaml).toContain("messageTemplate:");
336
+ });
337
+ });
338
+ describe("serializeCampaignJson", () => {
339
+ it("serializes to pretty-printed JSON", () => {
340
+ const json = serializeCampaignJson(MOCK_CAMPAIGN, MOCK_ACTIONS);
341
+ expect(() => JSON.parse(json)).not.toThrow();
342
+ const doc = JSON.parse(json);
343
+ expect(doc["version"]).toBe("1");
344
+ expect(doc["name"]).toBe("Test Campaign");
345
+ });
346
+ it("produces valid JSON that round-trips through parseCampaignJson", () => {
347
+ const json = serializeCampaignJson(MOCK_CAMPAIGN, MOCK_ACTIONS);
348
+ const config = parseCampaignJson(json);
349
+ expect(config.name).toBe("Test Campaign");
350
+ expect(config.description).toBe("Test description");
351
+ expect(config.actions).toHaveLength(2);
352
+ expect(config.actions[0]?.actionType).toBe("VisitAndExtract");
353
+ expect(config.actions[1]?.actionType).toBe("MessageToPerson");
354
+ });
355
+ });
356
+ describe("round-trip", () => {
357
+ it("YAML: serialize → parse preserves campaign data", () => {
358
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, MOCK_ACTIONS);
359
+ const config = parseCampaignYaml(yaml);
360
+ expect(config.name).toBe("Test Campaign");
361
+ expect(config.description).toBe("Test description");
362
+ expect(config.actions).toHaveLength(2);
363
+ expect(config.actions[0]?.actionType).toBe("VisitAndExtract");
364
+ expect(config.actions[0]?.actionSettings).toEqual({ extractCurrentOrganizations: true });
365
+ expect(config.actions[0]?.coolDown).toBe(60000);
366
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBe(10);
367
+ expect(config.actions[1]?.actionType).toBe("MessageToPerson");
368
+ expect(config.actions[1]?.actionSettings).toEqual({
369
+ messageTemplate: "Hi {firstName}",
370
+ });
371
+ });
372
+ it("JSON: serialize → parse preserves campaign data", () => {
373
+ const json = serializeCampaignJson(MOCK_CAMPAIGN, MOCK_ACTIONS);
374
+ const config = parseCampaignJson(json);
375
+ expect(config.name).toBe("Test Campaign");
376
+ expect(config.description).toBe("Test description");
377
+ expect(config.actions).toHaveLength(2);
378
+ expect(config.actions[0]?.actionType).toBe("VisitAndExtract");
379
+ expect(config.actions[0]?.actionSettings).toEqual({ extractCurrentOrganizations: true });
380
+ expect(config.actions[1]?.actionType).toBe("MessageToPerson");
381
+ });
382
+ it("YAML: serialize → parse preserves varied per-action settings", () => {
383
+ const action0 = MOCK_ACTIONS[0];
384
+ const action1 = MOCK_ACTIONS[1];
385
+ const variedActions = [
386
+ {
387
+ ...action0,
388
+ config: { ...action0.config, coolDown: 30000, maxActionResultsPerIteration: 5 },
389
+ },
390
+ {
391
+ ...action1,
392
+ config: { ...action1.config, coolDown: 60000, maxActionResultsPerIteration: 20 },
393
+ },
394
+ ];
395
+ const yaml = serializeCampaignYaml(MOCK_CAMPAIGN, variedActions);
396
+ const config = parseCampaignYaml(yaml);
397
+ expect(config.actions[0]?.coolDown).toBe(30000);
398
+ expect(config.actions[0]?.maxActionResultsPerIteration).toBe(5);
399
+ expect(config.actions[1]?.coolDown).toBe(60000);
400
+ expect(config.actions[1]?.maxActionResultsPerIteration).toBe(20);
401
+ });
402
+ it("parse → serialize → parse produces identical config", () => {
403
+ const config1 = parseCampaignYaml(FULL_YAML);
404
+ // Create a mock campaign and actions from parsed config to simulate DB state
405
+ const campaign = {
406
+ id: 1,
407
+ name: config1.name,
408
+ description: config1.description ?? null,
409
+ state: "active",
410
+ liAccountId: 1,
411
+ isPaused: false,
412
+ isArchived: false,
413
+ isValid: true,
414
+ createdAt: "2025-01-15T00:00:00Z",
415
+ };
416
+ const actions = config1.actions.map((a, i) => ({
417
+ id: i + 1,
418
+ campaignId: 1,
419
+ name: a.name,
420
+ description: null,
421
+ config: {
422
+ id: i + 100,
423
+ actionType: a.actionType,
424
+ actionSettings: a.actionSettings ?? {},
425
+ coolDown: a.coolDown ?? 60000,
426
+ maxActionResultsPerIteration: a.maxActionResultsPerIteration ?? 10,
427
+ isDraft: false,
428
+ },
429
+ versionId: i + 1000,
430
+ }));
431
+ const yaml = serializeCampaignYaml(campaign, actions);
432
+ const config2 = parseCampaignYaml(yaml);
433
+ expect(config2.name).toBe(config1.name);
434
+ expect(config2.description).toBe(config1.description);
435
+ expect(config2.actions).toHaveLength(config1.actions.length);
436
+ for (let i = 0; i < config1.actions.length; i++) {
437
+ expect(config2.actions[i]?.actionType).toBe(config1.actions[i]?.actionType);
438
+ expect(config2.actions[i]?.actionSettings).toEqual(config1.actions[i]?.actionSettings);
439
+ }
440
+ });
441
+ });
442
+ //# sourceMappingURL=campaign-format.test.js.map