@skedulo/integration-sdk 0.2.4 → 0.3.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 (409) hide show
  1. package/CHANGELOG.md +43 -1
  2. package/README.md +9 -0
  3. package/dist/adapters/adapter-registry.d.ts +9 -0
  4. package/dist/adapters/adapter-registry.d.ts.map +1 -0
  5. package/dist/adapters/adapter-registry.js +34 -0
  6. package/dist/adapters/adapter-registry.js.map +1 -0
  7. package/dist/adapters/base-adapter-handler.d.ts +105 -0
  8. package/dist/adapters/base-adapter-handler.d.ts.map +1 -0
  9. package/dist/adapters/base-adapter-handler.js +379 -0
  10. package/dist/adapters/base-adapter-handler.js.map +1 -0
  11. package/dist/adapters/base.adapter.d.ts +38 -17
  12. package/dist/adapters/base.adapter.d.ts.map +1 -1
  13. package/dist/adapters/base.adapter.js +80 -22
  14. package/dist/adapters/base.adapter.js.map +1 -1
  15. package/dist/adapters/helpers.d.ts +15 -0
  16. package/dist/adapters/helpers.d.ts.map +1 -0
  17. package/dist/adapters/helpers.js +55 -0
  18. package/dist/adapters/helpers.js.map +1 -0
  19. package/dist/adapters/skedulo-metadata-adapter.d.ts +3 -0
  20. package/dist/adapters/skedulo-metadata-adapter.d.ts.map +1 -0
  21. package/dist/adapters/skedulo-metadata-adapter.js +57 -0
  22. package/dist/adapters/skedulo-metadata-adapter.js.map +1 -0
  23. package/dist/adapters/skedulo-metadata.adapter.d.ts +3 -0
  24. package/dist/adapters/skedulo-metadata.adapter.d.ts.map +1 -0
  25. package/dist/adapters/skedulo-metadata.adapter.js +57 -0
  26. package/dist/adapters/skedulo-metadata.adapter.js.map +1 -0
  27. package/dist/adapters/skedulo.adapter.d.ts +11 -0
  28. package/dist/adapters/skedulo.adapter.d.ts.map +1 -1
  29. package/dist/adapters/skedulo.adapter.js +31 -7
  30. package/dist/adapters/skedulo.adapter.js.map +1 -1
  31. package/dist/adapters/upsert-harness.d.ts +15 -0
  32. package/dist/adapters/upsert-harness.d.ts.map +1 -0
  33. package/dist/adapters/upsert-harness.js +55 -0
  34. package/dist/adapters/upsert-harness.js.map +1 -0
  35. package/dist/clients/dataflow-client.d.ts +18 -0
  36. package/dist/clients/dataflow-client.d.ts.map +1 -0
  37. package/dist/clients/dataflow-client.js +43 -0
  38. package/dist/clients/dataflow-client.js.map +1 -0
  39. package/dist/clients/dataflow.client.js +2 -2
  40. package/dist/clients/dataflow.client.js.map +1 -1
  41. package/dist/clients/proxy-client.d.ts +13 -0
  42. package/dist/clients/proxy-client.d.ts.map +1 -0
  43. package/dist/clients/proxy-client.js +20 -0
  44. package/dist/clients/proxy-client.js.map +1 -0
  45. package/dist/clients/proxy.client.d.ts +11 -1
  46. package/dist/clients/proxy.client.d.ts.map +1 -1
  47. package/dist/clients/proxy.client.js.map +1 -1
  48. package/dist/constants.d.ts +7 -0
  49. package/dist/constants.d.ts.map +1 -1
  50. package/dist/constants.js +7 -1
  51. package/dist/constants.js.map +1 -1
  52. package/dist/context.d.ts +5 -0
  53. package/dist/context.d.ts.map +1 -1
  54. package/dist/context.js +9 -0
  55. package/dist/context.js.map +1 -1
  56. package/dist/dist/adapters/skedulo-metadata-adapter.d.ts +3 -0
  57. package/dist/dist/adapters/skedulo-metadata-adapter.d.ts.map +1 -0
  58. package/dist/dist/adapters/skedulo-metadata-adapter.js +57 -0
  59. package/dist/dist/adapters/skedulo-metadata-adapter.js.map +1 -0
  60. package/dist/dist/adapters/skedulo-metadata.adapter.d.ts +3 -0
  61. package/dist/dist/adapters/skedulo-metadata.adapter.d.ts.map +1 -0
  62. package/dist/dist/adapters/skedulo-metadata.adapter.js +57 -0
  63. package/dist/dist/adapters/skedulo-metadata.adapter.js.map +1 -0
  64. package/dist/dist/adapters/skedulo.adapter.d.ts +15 -0
  65. package/dist/dist/adapters/skedulo.adapter.d.ts.map +1 -0
  66. package/dist/dist/adapters/skedulo.adapter.js +213 -0
  67. package/dist/dist/adapters/skedulo.adapter.js.map +1 -0
  68. package/dist/dist/browser.d.ts +12 -0
  69. package/dist/dist/browser.d.ts.map +1 -0
  70. package/dist/dist/browser.js +9 -0
  71. package/dist/dist/browser.js.map +1 -0
  72. package/dist/dist/clients/dataflow-client.d.ts +18 -0
  73. package/dist/dist/clients/dataflow-client.d.ts.map +1 -0
  74. package/dist/dist/clients/dataflow-client.js +43 -0
  75. package/dist/dist/clients/dataflow-client.js.map +1 -0
  76. package/dist/dist/clients/dataflow.client.d.ts +19 -0
  77. package/dist/dist/clients/dataflow.client.d.ts.map +1 -0
  78. package/dist/dist/clients/dataflow.client.js +28 -0
  79. package/dist/dist/clients/dataflow.client.js.map +1 -0
  80. package/dist/dist/clients/proxy-client.d.ts +13 -0
  81. package/dist/dist/clients/proxy-client.d.ts.map +1 -0
  82. package/dist/dist/clients/proxy-client.js +20 -0
  83. package/dist/dist/clients/proxy-client.js.map +1 -0
  84. package/dist/dist/clients/proxy.client.d.ts +13 -0
  85. package/dist/dist/clients/proxy.client.d.ts.map +1 -0
  86. package/dist/dist/clients/proxy.client.js +21 -0
  87. package/dist/dist/clients/proxy.client.js.map +1 -0
  88. package/dist/dist/constants.d.ts +17 -0
  89. package/dist/dist/constants.d.ts.map +1 -0
  90. package/dist/dist/constants.js +20 -0
  91. package/dist/dist/constants.js.map +1 -0
  92. package/dist/dist/context.d.ts +19 -0
  93. package/dist/dist/context.d.ts.map +1 -0
  94. package/dist/dist/context.js +40 -0
  95. package/dist/dist/context.js.map +1 -0
  96. package/dist/dist/handlers/metadata.handler.d.ts +17 -0
  97. package/dist/dist/handlers/metadata.handler.d.ts.map +1 -0
  98. package/dist/dist/handlers/metadata.handler.js +50 -0
  99. package/dist/dist/handlers/metadata.handler.js.map +1 -0
  100. package/dist/dist/index.d.ts +18 -0
  101. package/dist/dist/index.d.ts.map +1 -0
  102. package/dist/dist/index.js +48 -0
  103. package/dist/dist/index.js.map +1 -0
  104. package/dist/dist/interfaces/adapter.interface.d.ts +122 -0
  105. package/dist/dist/interfaces/adapter.interface.d.ts.map +1 -0
  106. package/dist/dist/interfaces/adapter.interface.js +3 -0
  107. package/dist/dist/interfaces/adapter.interface.js.map +1 -0
  108. package/dist/dist/interfaces/data-flow-spec.interface.d.ts +22 -0
  109. package/dist/dist/interfaces/data-flow-spec.interface.d.ts.map +1 -0
  110. package/dist/dist/interfaces/data-flow-spec.interface.js +3 -0
  111. package/dist/dist/interfaces/data-flow-spec.interface.js.map +1 -0
  112. package/dist/dist/interfaces/field-mapping.interface.d.ts +26 -0
  113. package/dist/dist/interfaces/field-mapping.interface.d.ts.map +1 -0
  114. package/dist/dist/interfaces/field-mapping.interface.js +3 -0
  115. package/dist/dist/interfaces/field-mapping.interface.js.map +1 -0
  116. package/dist/dist/interfaces/filter.interface.d.ts +19 -0
  117. package/dist/dist/interfaces/filter.interface.d.ts.map +1 -0
  118. package/dist/dist/interfaces/filter.interface.js +20 -0
  119. package/dist/dist/interfaces/filter.interface.js.map +1 -0
  120. package/dist/dist/interfaces/integration-capabilities.interface.d.ts +13 -0
  121. package/dist/dist/interfaces/integration-capabilities.interface.d.ts.map +1 -0
  122. package/dist/dist/interfaces/integration-capabilities.interface.js +3 -0
  123. package/dist/dist/interfaces/integration-capabilities.interface.js.map +1 -0
  124. package/dist/dist/interfaces/lookup-rule.interface.d.ts +14 -0
  125. package/dist/dist/interfaces/lookup-rule.interface.d.ts.map +1 -0
  126. package/dist/dist/interfaces/lookup-rule.interface.js +3 -0
  127. package/dist/dist/interfaces/lookup-rule.interface.js.map +1 -0
  128. package/dist/dist/interfaces/mapped-event.interface.d.ts +9 -0
  129. package/dist/dist/interfaces/mapped-event.interface.d.ts.map +1 -0
  130. package/dist/dist/interfaces/mapped-event.interface.js +3 -0
  131. package/dist/dist/interfaces/mapped-event.interface.js.map +1 -0
  132. package/dist/dist/interfaces/mapping-config.interface.d.ts +26 -0
  133. package/dist/dist/interfaces/mapping-config.interface.d.ts.map +1 -0
  134. package/dist/dist/interfaces/mapping-config.interface.js +3 -0
  135. package/dist/dist/interfaces/mapping-config.interface.js.map +1 -0
  136. package/dist/dist/interfaces/metadata-adapter.interface.d.ts +26 -0
  137. package/dist/dist/interfaces/metadata-adapter.interface.d.ts.map +1 -0
  138. package/dist/dist/interfaces/metadata-adapter.interface.js +3 -0
  139. package/dist/dist/interfaces/metadata-adapter.interface.js.map +1 -0
  140. package/dist/dist/interfaces/pull-adapter.interface.d.ts +50 -0
  141. package/dist/dist/interfaces/pull-adapter.interface.d.ts.map +1 -0
  142. package/dist/dist/interfaces/pull-adapter.interface.js +3 -0
  143. package/dist/dist/interfaces/pull-adapter.interface.js.map +1 -0
  144. package/dist/dist/interfaces/push-adapter.interface.d.ts +28 -0
  145. package/dist/dist/interfaces/push-adapter.interface.d.ts.map +1 -0
  146. package/dist/dist/interfaces/push-adapter.interface.js +3 -0
  147. package/dist/dist/interfaces/push-adapter.interface.js.map +1 -0
  148. package/dist/dist/interfaces/sample-fetcher.interface.d.ts +4 -0
  149. package/dist/dist/interfaces/sample-fetcher.interface.d.ts.map +1 -0
  150. package/dist/dist/interfaces/sample-fetcher.interface.js +3 -0
  151. package/dist/dist/interfaces/sample-fetcher.interface.js.map +1 -0
  152. package/dist/dist/interfaces/sync-result.interface.d.ts +19 -0
  153. package/dist/dist/interfaces/sync-result.interface.d.ts.map +1 -0
  154. package/dist/dist/interfaces/sync-result.interface.js +3 -0
  155. package/dist/dist/interfaces/sync-result.interface.js.map +1 -0
  156. package/dist/dist/interfaces/target-adapter.interface.d.ts +10 -0
  157. package/dist/dist/interfaces/target-adapter.interface.d.ts.map +1 -0
  158. package/dist/dist/interfaces/target-adapter.interface.js +3 -0
  159. package/dist/dist/interfaces/target-adapter.interface.js.map +1 -0
  160. package/dist/dist/mocks/hubspot.d.ts +4 -0
  161. package/dist/dist/mocks/hubspot.d.ts.map +1 -0
  162. package/dist/dist/mocks/hubspot.js +61 -0
  163. package/dist/dist/mocks/hubspot.js.map +1 -0
  164. package/dist/dist/provenance.d.ts +3 -0
  165. package/dist/dist/provenance.d.ts.map +1 -0
  166. package/dist/dist/provenance.js +12 -0
  167. package/dist/dist/provenance.js.map +1 -0
  168. package/dist/dist/services/dataflow-service.d.ts +21 -0
  169. package/dist/dist/services/dataflow-service.d.ts.map +1 -0
  170. package/dist/dist/services/dataflow-service.js +47 -0
  171. package/dist/dist/services/dataflow-service.js.map +1 -0
  172. package/dist/dist/services/dataflow.service.d.ts +20 -0
  173. package/dist/dist/services/dataflow.service.d.ts.map +1 -0
  174. package/dist/dist/services/dataflow.service.js +52 -0
  175. package/dist/dist/services/dataflow.service.js.map +1 -0
  176. package/dist/dist/services/eql.d.ts +2 -0
  177. package/dist/dist/services/eql.d.ts.map +1 -0
  178. package/dist/dist/services/eql.js +10 -0
  179. package/dist/dist/services/eql.js.map +1 -0
  180. package/dist/dist/services/mapping-service.d.ts +14 -0
  181. package/dist/dist/services/mapping-service.d.ts.map +1 -0
  182. package/dist/dist/services/mapping-service.js +88 -0
  183. package/dist/dist/services/mapping-service.js.map +1 -0
  184. package/dist/dist/services/mapping.service.d.ts +14 -0
  185. package/dist/dist/services/mapping.service.d.ts.map +1 -0
  186. package/dist/dist/services/mapping.service.js +89 -0
  187. package/dist/dist/services/mapping.service.js.map +1 -0
  188. package/dist/dist/services/outbound-service.d.ts +14 -0
  189. package/dist/dist/services/outbound-service.d.ts.map +1 -0
  190. package/dist/dist/services/outbound-service.js +65 -0
  191. package/dist/dist/services/outbound-service.js.map +1 -0
  192. package/dist/dist/services/paragon-workflow-service.d.ts +7 -0
  193. package/dist/dist/services/paragon-workflow-service.d.ts.map +1 -0
  194. package/dist/dist/services/paragon-workflow-service.js +68 -0
  195. package/dist/dist/services/paragon-workflow-service.js.map +1 -0
  196. package/dist/dist/services/paragon-workflow.service.d.ts +8 -0
  197. package/dist/dist/services/paragon-workflow.service.d.ts.map +1 -0
  198. package/dist/dist/services/paragon-workflow.service.js +31 -0
  199. package/dist/dist/services/paragon-workflow.service.js.map +1 -0
  200. package/dist/dist/services/preview-service.d.ts +11 -0
  201. package/dist/dist/services/preview-service.d.ts.map +1 -0
  202. package/dist/dist/services/preview-service.js +66 -0
  203. package/dist/dist/services/preview-service.js.map +1 -0
  204. package/dist/dist/services/preview.service.d.ts +11 -0
  205. package/dist/dist/services/preview.service.d.ts.map +1 -0
  206. package/dist/dist/services/preview.service.js +74 -0
  207. package/dist/dist/services/preview.service.js.map +1 -0
  208. package/dist/dist/services/pull-service.d.ts +9 -0
  209. package/dist/dist/services/pull-service.d.ts.map +1 -0
  210. package/dist/dist/services/pull-service.js +207 -0
  211. package/dist/dist/services/pull-service.js.map +1 -0
  212. package/dist/dist/services/pull.service.d.ts +11 -0
  213. package/dist/dist/services/pull.service.d.ts.map +1 -0
  214. package/dist/dist/services/pull.service.js +200 -0
  215. package/dist/dist/services/pull.service.js.map +1 -0
  216. package/dist/dist/services/push-service.d.ts +16 -0
  217. package/dist/dist/services/push-service.d.ts.map +1 -0
  218. package/dist/dist/services/push-service.js +76 -0
  219. package/dist/dist/services/push-service.js.map +1 -0
  220. package/dist/dist/services/push.service.d.ts +19 -0
  221. package/dist/dist/services/push.service.d.ts.map +1 -0
  222. package/dist/dist/services/push.service.js +186 -0
  223. package/dist/dist/services/push.service.js.map +1 -0
  224. package/dist/dist/services/scheduled-pull-service.d.ts +7 -0
  225. package/dist/dist/services/scheduled-pull-service.d.ts.map +1 -0
  226. package/dist/dist/services/scheduled-pull-service.js +58 -0
  227. package/dist/dist/services/scheduled-pull-service.js.map +1 -0
  228. package/dist/dist/services/split-filter.d.ts +3 -0
  229. package/dist/dist/services/split-filter.d.ts.map +1 -0
  230. package/dist/dist/services/split-filter.js +50 -0
  231. package/dist/dist/services/split-filter.js.map +1 -0
  232. package/dist/dist/services/sync-runner.d.ts +22 -0
  233. package/dist/dist/services/sync-runner.d.ts.map +1 -0
  234. package/dist/dist/services/sync-runner.js +110 -0
  235. package/dist/dist/services/sync-runner.js.map +1 -0
  236. package/dist/dist/services/sync.service.d.ts +21 -0
  237. package/dist/dist/services/sync.service.d.ts.map +1 -0
  238. package/dist/dist/services/sync.service.js +166 -0
  239. package/dist/dist/services/sync.service.js.map +1 -0
  240. package/dist/dist/types.d.ts +11 -0
  241. package/dist/dist/types.d.ts.map +1 -0
  242. package/dist/dist/types.js +6 -0
  243. package/dist/dist/types.js.map +1 -0
  244. package/dist/dist/utils/compileFilter.d.ts +3 -0
  245. package/dist/dist/utils/compileFilter.d.ts.map +1 -0
  246. package/dist/dist/utils/compileFilter.js +73 -0
  247. package/dist/dist/utils/compileFilter.js.map +1 -0
  248. package/dist/dist/utils/normalizeDataFlow.d.ts +3 -0
  249. package/dist/dist/utils/normalizeDataFlow.d.ts.map +1 -0
  250. package/dist/dist/utils/normalizeDataFlow.js +30 -0
  251. package/dist/dist/utils/normalizeDataFlow.js.map +1 -0
  252. package/dist/dist/utils.d.ts +2 -0
  253. package/dist/dist/utils.d.ts.map +1 -0
  254. package/dist/dist/utils.js +10 -0
  255. package/dist/dist/utils.js.map +1 -0
  256. package/dist/handlers/metadata.handler.d.ts +0 -4
  257. package/dist/handlers/metadata.handler.d.ts.map +1 -1
  258. package/dist/handlers/metadata.handler.js +8 -12
  259. package/dist/handlers/metadata.handler.js.map +1 -1
  260. package/dist/index.d.ts +15 -7
  261. package/dist/index.d.ts.map +1 -1
  262. package/dist/index.js +22 -4
  263. package/dist/index.js.map +1 -1
  264. package/dist/interfaces/adapter.interface.d.ts +62 -0
  265. package/dist/interfaces/adapter.interface.d.ts.map +1 -1
  266. package/dist/interfaces/integration-capabilities.interface.d.ts +4 -9
  267. package/dist/interfaces/integration-capabilities.interface.d.ts.map +1 -1
  268. package/dist/interfaces/mapping-config.interface.d.ts +26 -0
  269. package/dist/interfaces/mapping-config.interface.d.ts.map +1 -0
  270. package/dist/interfaces/mapping-config.interface.js +3 -0
  271. package/dist/interfaces/mapping-config.interface.js.map +1 -0
  272. package/dist/interfaces/metadata-adapter.interface.d.ts +26 -0
  273. package/dist/interfaces/metadata-adapter.interface.d.ts.map +1 -0
  274. package/dist/interfaces/metadata-adapter.interface.js +3 -0
  275. package/dist/interfaces/metadata-adapter.interface.js.map +1 -0
  276. package/dist/interfaces/pull-adapter.interface.d.ts +50 -0
  277. package/dist/interfaces/pull-adapter.interface.d.ts.map +1 -0
  278. package/dist/interfaces/pull-adapter.interface.js +3 -0
  279. package/dist/interfaces/pull-adapter.interface.js.map +1 -0
  280. package/dist/interfaces/push-adapter.interface.d.ts +28 -0
  281. package/dist/interfaces/push-adapter.interface.d.ts.map +1 -0
  282. package/dist/interfaces/push-adapter.interface.js +3 -0
  283. package/dist/interfaces/push-adapter.interface.js.map +1 -0
  284. package/dist/interfaces/sync-flow-strategy.interface.d.ts +2 -1
  285. package/dist/interfaces/sync-flow-strategy.interface.d.ts.map +1 -1
  286. package/dist/interfaces/target-adapter.interface.d.ts +10 -0
  287. package/dist/interfaces/target-adapter.interface.d.ts.map +1 -0
  288. package/dist/interfaces/target-adapter.interface.js +3 -0
  289. package/dist/interfaces/target-adapter.interface.js.map +1 -0
  290. package/dist/mocks/hubspot.d.ts +4 -0
  291. package/dist/mocks/hubspot.d.ts.map +1 -0
  292. package/dist/mocks/hubspot.js +61 -0
  293. package/dist/mocks/hubspot.js.map +1 -0
  294. package/dist/provenance.d.ts +3 -0
  295. package/dist/provenance.d.ts.map +1 -0
  296. package/dist/provenance.js +12 -0
  297. package/dist/provenance.js.map +1 -0
  298. package/dist/services/dataflow-service.d.ts +21 -0
  299. package/dist/services/dataflow-service.d.ts.map +1 -0
  300. package/dist/services/dataflow-service.js +47 -0
  301. package/dist/services/dataflow-service.js.map +1 -0
  302. package/dist/services/eql.d.ts +2 -0
  303. package/dist/services/eql.d.ts.map +1 -0
  304. package/dist/services/eql.js +10 -0
  305. package/dist/services/eql.js.map +1 -0
  306. package/dist/services/external-id-sync.strategy.d.ts +1 -1
  307. package/dist/services/external-id-sync.strategy.d.ts.map +1 -1
  308. package/dist/services/external-id-sync.strategy.js +18 -9
  309. package/dist/services/external-id-sync.strategy.js.map +1 -1
  310. package/dist/services/id-mapping-sync.strategy.d.ts.map +1 -1
  311. package/dist/services/id-mapping-sync.strategy.js +86 -22
  312. package/dist/services/id-mapping-sync.strategy.js.map +1 -1
  313. package/dist/services/id-mapping.service.js +11 -11
  314. package/dist/services/id-mapping.service.js.map +1 -1
  315. package/dist/services/mapping-service.d.ts +14 -0
  316. package/dist/services/mapping-service.d.ts.map +1 -0
  317. package/dist/services/mapping-service.js +88 -0
  318. package/dist/services/mapping-service.js.map +1 -0
  319. package/dist/services/mapping.service.d.ts +14 -0
  320. package/dist/services/mapping.service.d.ts.map +1 -0
  321. package/dist/services/mapping.service.js +89 -0
  322. package/dist/services/mapping.service.js.map +1 -0
  323. package/dist/services/outbound-service.d.ts +14 -0
  324. package/dist/services/outbound-service.d.ts.map +1 -0
  325. package/dist/services/outbound-service.js +65 -0
  326. package/dist/services/outbound-service.js.map +1 -0
  327. package/dist/services/paragon-workflow-service.d.ts +7 -0
  328. package/dist/services/paragon-workflow-service.d.ts.map +1 -0
  329. package/dist/services/paragon-workflow-service.js +68 -0
  330. package/dist/services/paragon-workflow-service.js.map +1 -0
  331. package/dist/services/paragon-workflow.service.d.ts +8 -0
  332. package/dist/services/paragon-workflow.service.d.ts.map +1 -0
  333. package/dist/services/paragon-workflow.service.js +31 -0
  334. package/dist/services/paragon-workflow.service.js.map +1 -0
  335. package/dist/services/preview-service.d.ts +11 -0
  336. package/dist/services/preview-service.d.ts.map +1 -0
  337. package/dist/services/preview-service.js +66 -0
  338. package/dist/services/preview-service.js.map +1 -0
  339. package/dist/services/pull-service.d.ts +9 -0
  340. package/dist/services/pull-service.d.ts.map +1 -0
  341. package/dist/services/pull-service.js +207 -0
  342. package/dist/services/pull-service.js.map +1 -0
  343. package/dist/services/pull.service.d.ts +11 -0
  344. package/dist/services/pull.service.d.ts.map +1 -0
  345. package/dist/services/pull.service.js +200 -0
  346. package/dist/services/pull.service.js.map +1 -0
  347. package/dist/services/push-service.d.ts +16 -0
  348. package/dist/services/push-service.d.ts.map +1 -0
  349. package/dist/services/push-service.js +76 -0
  350. package/dist/services/push-service.js.map +1 -0
  351. package/dist/services/push.service.d.ts +19 -0
  352. package/dist/services/push.service.d.ts.map +1 -0
  353. package/dist/services/push.service.js +186 -0
  354. package/dist/services/push.service.js.map +1 -0
  355. package/dist/services/routes.factory.d.ts +19 -0
  356. package/dist/services/routes.factory.d.ts.map +1 -0
  357. package/dist/services/routes.factory.js +352 -0
  358. package/dist/services/routes.factory.js.map +1 -0
  359. package/dist/services/scheduled-pull-service.d.ts +7 -0
  360. package/dist/services/scheduled-pull-service.d.ts.map +1 -0
  361. package/dist/services/scheduled-pull-service.js +58 -0
  362. package/dist/services/scheduled-pull-service.js.map +1 -0
  363. package/dist/services/split-filter.d.ts +3 -0
  364. package/dist/services/split-filter.d.ts.map +1 -0
  365. package/dist/services/split-filter.js +50 -0
  366. package/dist/services/split-filter.js.map +1 -0
  367. package/dist/services/sync-runner.d.ts +6 -0
  368. package/dist/services/sync-runner.d.ts.map +1 -1
  369. package/dist/services/sync-runner.js +46 -20
  370. package/dist/services/sync-runner.js.map +1 -1
  371. package/dist/testing/adapter-contract.d.ts +24 -0
  372. package/dist/testing/adapter-contract.d.ts.map +1 -0
  373. package/dist/testing/adapter-contract.js +82 -0
  374. package/dist/testing/adapter-contract.js.map +1 -0
  375. package/dist/utils/auth.d.ts +6 -0
  376. package/dist/utils/auth.d.ts.map +1 -0
  377. package/dist/utils/auth.js +18 -0
  378. package/dist/utils/auth.js.map +1 -0
  379. package/dist/utils/helpers.d.ts +23 -0
  380. package/dist/utils/helpers.d.ts.map +1 -0
  381. package/dist/utils/helpers.js +118 -0
  382. package/dist/utils/helpers.js.map +1 -0
  383. package/dist/utils/http-response.d.ts +16 -0
  384. package/dist/utils/http-response.d.ts.map +1 -0
  385. package/dist/utils/http-response.js +36 -0
  386. package/dist/utils/http-response.js.map +1 -0
  387. package/dist/utils/query-string.d.ts +2 -0
  388. package/dist/utils/query-string.d.ts.map +1 -0
  389. package/dist/utils/query-string.js +13 -0
  390. package/dist/utils/query-string.js.map +1 -0
  391. package/dist/utils/sked-handler.d.ts +22 -0
  392. package/dist/utils/sked-handler.d.ts.map +1 -0
  393. package/dist/utils/sked-handler.js +41 -0
  394. package/dist/utils/sked-handler.js.map +1 -0
  395. package/dist/utils/strings.d.ts +2 -0
  396. package/dist/utils/strings.d.ts.map +1 -0
  397. package/dist/utils/strings.js +14 -0
  398. package/dist/utils/strings.js.map +1 -0
  399. package/dist/utils/unwrap-proxy.d.ts +2 -0
  400. package/dist/utils/unwrap-proxy.d.ts.map +1 -0
  401. package/dist/utils/unwrap-proxy.js +12 -0
  402. package/dist/utils/unwrap-proxy.js.map +1 -0
  403. package/package.json +1 -1
  404. package/yarn.lock +5 -0
  405. package/.claude/worktrees/agent-a16acadaf5412dffd/jest.config.js +0 -12
  406. package/.claude/worktrees/agent-a33c3e4636d488e49/jest.config.js +0 -12
  407. package/.claude/worktrees/agent-a5b1d2ffa4ceef4a6/jest.config.js +0 -12
  408. package/.claude/worktrees/agent-aa1db4c22eabbde8e/jest.config.js +0 -12
  409. package/.claude/worktrees/agent-ac197ae8c69d7061c/jest.config.js +0 -12
package/CHANGELOG.md CHANGED
@@ -1,5 +1,44 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.3.0] - 2026-05-21
4
+
5
+ - **`BaseAdapterHandler`** — 12 standard route handlers (capabilities, setup, metadata, scheduled-pull, run-flow, run-all-flows, on-skedulo-event, on-vendor-event). Subclassing is now optional — `new BaseAdapterHandler({ adapter })` is enough for the common case.
6
+ - **`AdapterRegistry`** auto-built from `adapter.integrationType` — no more hand-wired registries in consumers. `SyncRunner` accepts a registry; `SyncRunner.create()` removed.
7
+ - **Adapter declares its own identity** — required `integrationType` + optional `capabilities` (`roles`, `lookupStrategy`, `allowNewDataFlows`, `hasDataFlows`). Handler derives userAgent and request-source labels from it.
8
+ - **`Adapter.parseChangeEvent(body)`** — vendor change-event envelope parser lives on the adapter; `onVendorEvent` route dispatches via it. No handler subclass needed.
9
+ - **Symmetric event endpoints** — `onSkeduloEvent` (Skedulo→vendor) and `onVendorEvent` (vendor→Skedulo) replace the directional `push`/`onChangeEvent` pair.
10
+ - **`ProxyResult<T> { status, headers, output }`** — `ProxyClient.request<T>()` returns the envelope directly, replacing `unwrapProxy` boilerplate. Adapters can read `status` for stale-mapping detection without try/catch.
11
+ - **`LookupStrategy` enum** (`IdMapping` / `ExternalId`) — replaces hardcoded `"idMapping"` strings.
12
+ - **Upsert harness on `BaseAdapter`** — `runUpsertBatch`, `classifyHttpStatus`, `handleStaleMapping`, default `buildMappingEntries` replace duplicated upsert + stale-mapping logic in every adapter.
13
+ - **`AdapterCapabilities` with `roles`** + `AdapterRoleError` — declarative source/target support so source-only adapters (e.g. Workday) can be modelled cleanly. Defaults to `[SOURCE, TARGET]` for back-compat.
14
+ - **`source.beforeMap` now runs on the event path** in both strategies — payload normalisation lives in the adapter once, not duplicated in route handlers.
15
+ - **`IdMappingSyncStrategy` dispatches `insert`/`update`** when adapters define them (falls back to `upsert` for legacy adapters); strips internal `__targetUID` marker on inserts.
16
+ - **`skeduloAdapter` singleton** with `bootstrap()` / `checkBootstrap()` — no more direct `IdMappingService` usage in consumers.
17
+ - **Testing harness** — `runAdapterContractTests({ createAdapter })` covers `integrationType`, capabilities, default `buildMappingEntries`. `mockProxyResult<T>()` builds `ProxyResult` mocks.
18
+ - Lifted utilities: `unwrapProxy`, `okResponse`, `errorResponse`, `getQueryParam`, `isAdminRequest`, `requireAdmin`, `humanizeFieldName`.
19
+ - New `docs/IMPLEMENTING-AN-INTEGRATION.md` — discovery + implementation guide for new adapters.
20
+
21
+ ## [0.2.4] - 2026-05-14
22
+
23
+ ### Added
24
+
25
+ - **Delta sync / change detection** — `SyncRunner.run()` now manages the incremental cursor automatically. After each successful run it writes `lastRunAt` back to the integration service via `DataFlowService.updateCursor()`. On the next run, `flow.lastRunAt` is used as the cursor source (overrides `args.since`), with a configurable overlap window (`SyncRunOptions.cursorOverlapMs`, default 60 s) to cover records modified at the tail of the previous run.
26
+ - **`Adapter.isChanged(raw, cursor)`** — optional per-record change gate. Return `false` to skip a record before it enters the pipeline. Takes precedence over `getRecordTimestamp` if both are implemented.
27
+ - **`Adapter.getRecordTimestamp(raw)`** — alternative timestamp-based change gate. Return the record's modification timestamp; the SDK compares it against the effective cursor. Return `null` to treat the record as changed (safe fallback).
28
+ - **`BatchResult.skipped`** — new counter for records excluded by the change detection gate (distinct from `filtered`, which covers `FilterSpec`-based exclusions).
29
+ - **`UpsertOutcome.status: 'precondition'`** — new status for insert pre-condition failures (e.g. a required relation doesn't exist yet in the target system).
30
+ - **`SyncResult.status: 'precondition_failed'`** — corresponding event-driven result status that surfaces a silent insert failure.
31
+ - **`DataFlowClient.updateCursor()` / `DataFlowService.updateCursor()`** — new methods to persist the run cursor to the integration service.
32
+ - **`DataFlow.lastRunAt`** — new field on `DataFlow`: the persisted cursor written by `SyncRunner` after each successful run. `null` means no prior run (full sync).
33
+ - **`SyncRunOptions.cursorOverlapMs`** — configurable overlap buffer (default: `60_000` ms).
34
+ - **`yarn typecheck`** — new script that type-checks both `src/` and `test/` without emitting output.
35
+
36
+ ---
37
+
38
+ > **⚠️ v0.2.3 is deprecated.** It contains bugs in cursor accumulation and change detection. Upgrade directly to v0.2.4.
39
+
40
+ ---
41
+
3
42
  ## [0.2.2] - 2026-05-13
4
43
 
5
44
  - Add `hasDataFlows` to `IntegrationCapabilities` and `IdMappingService.checkSchema()` for setup status checks
@@ -14,12 +53,14 @@
14
53
 
15
54
  ### Added
16
55
 
17
- - **`IdMappingSyncStrategy`** — new sync strategy that resolves cross-system identity via the `IntegrationIdMapping` Skedulo custom object instead of ExternalId fields.
56
+ - **`IdMappingSyncStrategy`** — new sync strategy that resolves cross-system identity via the `IntegrationIdMapping` Skedulo custom object instead of ExternalId fields.
18
57
 
19
58
  ## [0.1.2] - 2026-05-08
59
+
20
60
  - Harden `compileFilter` against backtick and expr injection; guard `LOCAL_INTEGRATION_SERVICE` to localhost only; pre-validate filter spec in `_processBatch` to fail fast
21
61
 
22
62
  ## [0.1.1] - 2026-05-08
63
+
23
64
  - Make SampleRecord generic — each adapter returns native fields
24
65
 
25
66
  ### Updated
@@ -27,6 +68,7 @@
27
68
  ## [0.1.0] - 2026-05-07
28
69
 
29
70
  ### Added
71
+
30
72
  - Initial package scaffold with TypeScript config, Jest config, and build setup
31
73
  - `SyncService` and `SyncRunner` — batch and event-driven sync execution
32
74
  - `Adapter` interface — source, target, and metadata roles
package/README.md CHANGED
@@ -67,6 +67,14 @@ export class MyAdapter extends BaseAdapter {
67
67
  const outcomes = ctx.pipeline?.outcomes ?? [];
68
68
  }
69
69
  }
70
+
71
+ // Optional delta sync — implement one of these to enable per-record change detection
72
+ getRecordTimestamp(raw: Record<string, unknown>): Date | null {
73
+ const ts = raw['updatedAt'];
74
+ if (!ts) return null;
75
+ const d = new Date(String(ts));
76
+ return isNaN(d.getTime()) ? null : d;
77
+ }
70
78
  }
71
79
  ```
72
80
 
@@ -76,6 +84,7 @@ See [docs/ADAPTERS.md](./docs/ADAPTERS.md) for the full method reference and lif
76
84
 
77
85
  ```bash
78
86
  yarn build # Compile TypeScript → dist/
87
+ yarn typecheck # Type-check src/ and test/ without emitting output
79
88
  yarn test # Run all tests
80
89
  yarn test:coverage # Run tests with coverage
81
90
  yarn format # Format all src/ and test/ files with Prettier
@@ -0,0 +1,9 @@
1
+ import type { Adapter } from '../interfaces/adapter.interface';
2
+ export declare class AdapterRegistry {
3
+ private readonly adapters;
4
+ constructor(adapters: Record<string, Adapter>);
5
+ register(systemName: string, adapter: Adapter): void;
6
+ entries(): Array<[string, Adapter]>;
7
+ resolve(system: string | undefined): Adapter;
8
+ }
9
+ //# sourceMappingURL=adapter-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../src/adapters/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAM/D,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA0B;gBAEvC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAI7C,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpD,OAAO,IAAI,KAAK,CAAC,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAInC,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO;CAW7C"}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AdapterRegistry = void 0;
4
+ // Resolves a system name to its registered Adapter. Consumers register every
5
+ // adapter they want addressable — including the built-in `skeduloAdapter` when
6
+ // needed. Throws an Error with a top-level numeric `.status = 400` for missing
7
+ // or unknown systems — errorResponse() turns that into a 400 response body.
8
+ class AdapterRegistry {
9
+ constructor(adapters) {
10
+ this.adapters = Object.assign({}, adapters);
11
+ }
12
+ register(systemName, adapter) {
13
+ this.adapters[systemName] = adapter;
14
+ }
15
+ entries() {
16
+ return Object.entries(this.adapters);
17
+ }
18
+ resolve(system) {
19
+ if (!system)
20
+ throw httpError(400, 'system is required');
21
+ const adapter = this.adapters[system];
22
+ if (!adapter) {
23
+ throw httpError(400, `Unsupported system: "${system}". Must be one of: ${Object.keys(this.adapters).join(', ')}`);
24
+ }
25
+ return adapter;
26
+ }
27
+ }
28
+ exports.AdapterRegistry = AdapterRegistry;
29
+ function httpError(status, message) {
30
+ const err = new Error(message);
31
+ err.status = status;
32
+ return err;
33
+ }
34
+ //# sourceMappingURL=adapter-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-registry.js","sourceRoot":"","sources":["../../src/adapters/adapter-registry.ts"],"names":[],"mappings":";;;AAEA,6EAA6E;AAC7E,+EAA+E;AAC/E,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAa,eAAe;IAG1B,YAAY,QAAiC;QAC3C,IAAI,CAAC,QAAQ,qBAAQ,QAAQ,CAAE,CAAC;IAClC,CAAC;IAED,QAAQ,CAAC,UAAkB,EAAE,OAAgB;QAC3C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC;IACtC,CAAC;IAED,OAAO;QACL,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED,OAAO,CAAC,MAA0B;QAChC,IAAI,CAAC,MAAM;YAAE,MAAM,SAAS,CAAC,GAAG,EAAE,oBAAoB,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACtC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,SAAS,CACb,GAAG,EACH,wBAAwB,MAAM,sBAAsB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC5F,CAAC;QACJ,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA1BD,0CA0BC;AAED,SAAS,SAAS,CAAC,MAAc,EAAE,OAAe;IAChD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,OAAO,CAA+B,CAAC;IAC7D,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC;IACpB,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { LookupStrategy } from '../constants';
2
+ import { type IntegrationContext } from '../context';
3
+ import type { Adapter } from '../interfaces/adapter.interface';
4
+ import { SyncRunner } from '../services/sync-runner';
5
+ import { AdapterRegistry } from './adapter-registry';
6
+ export type RouteHandler = (body: any, headers: any, method: string, path: string, skedContext: any, querystring?: string | Record<string, string> | null) => Promise<{
7
+ status: number;
8
+ body?: unknown;
9
+ }>;
10
+ export interface BaseAdapterHandlerConfig {
11
+ /** The vendor adapter. Its `integrationType` seeds the auto-built registry, userAgent and request sources. */
12
+ adapter: Adapter;
13
+ /**
14
+ * Optional. When omitted the handler builds
15
+ * `{ [adapter.integrationType]: adapter, skedulo: skeduloAdapter }`.
16
+ * Provide one only for multi-vendor functions that expose extra adapters.
17
+ */
18
+ registry?: AdapterRegistry;
19
+ /** Default record limit for /sample-records when callers don't specify one. Defaults to 5. */
20
+ sampleDefaultLimit?: number;
21
+ }
22
+ /**
23
+ * Base class implementing the 12 standard handler routes every integration
24
+ * function exposes (capabilities, setup, metadata, scheduled pull, etc.).
25
+ * Subclass and add the vendor-specific inbound webhook handler — the rest
26
+ * just works.
27
+ *
28
+ * Handlers are arrow-function properties so they can be passed as values
29
+ * (e.g. into a routes table) without rebinding `this`.
30
+ *
31
+ * Override any handler or the protected helpers (`createContext`,
32
+ * `createRunner`) when a vendor needs different behaviour.
33
+ */
34
+ export declare class BaseAdapterHandler {
35
+ protected readonly config: BaseAdapterHandlerConfig;
36
+ protected readonly requestSources: {
37
+ admin: string;
38
+ scheduledPull: string;
39
+ runFlow: string;
40
+ skeduloEvent: string;
41
+ vendorEvent: string;
42
+ };
43
+ protected readonly userAgent: string;
44
+ protected readonly sampleDefaultLimit: number;
45
+ protected readonly integrationType: string;
46
+ protected readonly registry: AdapterRegistry;
47
+ protected readonly lookupStrategy: LookupStrategy;
48
+ constructor(config: BaseAdapterHandlerConfig);
49
+ protected createContext(skedContext: unknown, requestSource: string): IntegrationContext;
50
+ protected createRunner(): SyncRunner;
51
+ /** GET /capabilities */
52
+ getCapabilities: RouteHandler;
53
+ /** GET /setup — reports whether the Skedulo-side schema is bootstrapped. */
54
+ getSetupStatus: RouteHandler;
55
+ /** POST /setup — bootstraps the IntegrationIdMapping custom object. Idempotent. */
56
+ setup: RouteHandler;
57
+ /** GET /objects?system=<name> */
58
+ getObjects: RouteHandler;
59
+ /** GET /fields?system=<name>&object=<objectName> */
60
+ getFields: RouteHandler;
61
+ /** GET /templates?system=<name> */
62
+ getTemplates: RouteHandler;
63
+ /** GET /sample-apis?system=<name> */
64
+ getSampleAPIs: RouteHandler;
65
+ /** GET /sample-records?system=<name>&objectType=<obj>&limit=<n> */
66
+ getSampleRecords: RouteHandler;
67
+ /**
68
+ * POST /scheduled-pull — incremental sync of inbound flows on a schedule.
69
+ * Runs every active flow with triggerConfig.incremental, in executionOrder.
70
+ * SDK reads each flow's lastRunAt for the cursor.
71
+ */
72
+ scheduledPull: RouteHandler;
73
+ /**
74
+ * POST /run-all-flows — runs every active flow from scratch (since=null).
75
+ * Requires admin. Resets each flow's cursor so a full sync happens regardless
76
+ * of any previous lastRunAt.
77
+ */
78
+ runAllFlows: RouteHandler;
79
+ /**
80
+ * POST /run-flow — runs a single flow by ID from scratch. Used by the
81
+ * "Run now" UI button. Body: { flowId }.
82
+ */
83
+ runFlow: RouteHandler;
84
+ /**
85
+ * POST /on-skedulo-event — Skedulo triggered-action callback for
86
+ * OUTBOUND_TRIGGERED flows. Fires when a Skedulo record changes and that
87
+ * record is the source of a flow that targets the vendor.
88
+ * Body: { skeduloObject, recordId, operation, payload? }
89
+ *
90
+ * Pair: `onVendorEvent` handles the opposite direction (vendor → Skedulo).
91
+ */
92
+ onSkeduloEvent: RouteHandler;
93
+ /**
94
+ * POST /on-vendor-event — inbound real-time webhook from the vendor system.
95
+ *
96
+ * Dispatches via `adapter.parseChangeEvent(body)` — implement that on the
97
+ * adapter to opt in. Returns 501 if the adapter doesn't implement parsing.
98
+ *
99
+ * Envelope shape is vendor-specific, hence the parser lives on the adapter.
100
+ *
101
+ * Pair: `onSkeduloEvent` handles the opposite direction (Skedulo → vendor).
102
+ */
103
+ onVendorEvent: RouteHandler;
104
+ }
105
+ //# sourceMappingURL=base-adapter-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-adapter-handler.d.ts","sourceRoot":"","sources":["../../src/adapters/base-adapter-handler.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAA4B,KAAK,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iCAAiC,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAKrD,MAAM,MAAM,YAAY,GAAG,CACzB,IAAI,EAAE,GAAG,EACT,OAAO,EAAE,GAAG,EACZ,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,GAAG,EAChB,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,KACjD,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAEjD,MAAM,WAAW,wBAAwB;IACvC,8GAA8G;IAC9G,OAAO,EAAE,OAAO,CAAC;IACjB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAC;IAC3B,8FAA8F;IAC9F,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAID;;;;;;;;;;;GAWG;AACH,qBAAa,kBAAkB;IAejB,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,wBAAwB;IAb/D,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE;QACjC,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,OAAO,EAAE,MAAM,CAAC;QAChB,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,SAAS,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IACrC,SAAS,CAAC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IAC3C,SAAS,CAAC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;gBAEnB,MAAM,EAAE,wBAAwB;IAmB/D,SAAS,CAAC,aAAa,CAAC,WAAW,EAAE,OAAO,EAAE,aAAa,EAAE,MAAM,GAAG,kBAAkB;IAOxF,SAAS,CAAC,YAAY,IAAI,UAAU;IAMpC,wBAAwB;IACxB,eAAe,EAAE,YAAY,CAE3B;IAEF,4EAA4E;IAC5E,cAAc,EAAE,YAAY,CAQ1B;IAEF,mFAAmF;IACnF,KAAK,EAAE,YAAY,CAQjB;IAIF,iCAAiC;IACjC,UAAU,EAAE,YAAY,CAWtB;IAEF,oDAAoD;IACpD,SAAS,EAAE,YAAY,CAgBrB;IAEF,mCAAmC;IACnC,YAAY,EAAE,YAAY,CAQxB;IAEF,qCAAqC;IACrC,aAAa,EAAE,YAAY,CAQzB;IAEF,mEAAmE;IACnE,gBAAgB,EAAE,YAAY,CAsB5B;IAIF;;;;OAIG;IACH,aAAa,EAAE,YAAY,CAiDzB;IAEF;;;;OAIG;IACH,WAAW,EAAE,YAAY,CAqEvB;IAEF;;;OAGG;IACH,OAAO,EAAE,YAAY,CA6BnB;IAEF;;;;;;;OAOG;IACH,cAAc,EAAE,YAAY,CAuC1B;IAEF;;;;;;;;;OASG;IACH,aAAa,EAAE,YAAY,CAsCzB;CACH"}
@@ -0,0 +1,379 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BaseAdapterHandler = void 0;
4
+ const crypto_1 = require("crypto");
5
+ const constants_1 = require("../constants");
6
+ const context_1 = require("../context");
7
+ const sync_runner_1 = require("../services/sync-runner");
8
+ const helpers_1 = require("../utils/helpers");
9
+ const adapter_registry_1 = require("./adapter-registry");
10
+ const skedulo_adapter_1 = require("./skedulo.adapter");
11
+ const DEFAULT_SAMPLE_LIMIT = 5;
12
+ /**
13
+ * Base class implementing the 12 standard handler routes every integration
14
+ * function exposes (capabilities, setup, metadata, scheduled pull, etc.).
15
+ * Subclass and add the vendor-specific inbound webhook handler — the rest
16
+ * just works.
17
+ *
18
+ * Handlers are arrow-function properties so they can be passed as values
19
+ * (e.g. into a routes table) without rebinding `this`.
20
+ *
21
+ * Override any handler or the protected helpers (`createContext`,
22
+ * `createRunner`) when a vendor needs different behaviour.
23
+ */
24
+ class BaseAdapterHandler {
25
+ constructor(config) {
26
+ var _a, _c, _d, _e;
27
+ this.config = config;
28
+ // ── Admin ──────────────────────────────────────────────────────────────────
29
+ /** GET /capabilities */
30
+ this.getCapabilities = async () => {
31
+ return { status: 200, body: this.config.adapter.capabilities };
32
+ };
33
+ /** GET /setup — reports whether the Skedulo-side schema is bootstrapped. */
34
+ this.getSetupStatus = async (_b, _h, _m, _p, skedContext) => {
35
+ try {
36
+ const ctx = this.createContext(skedContext, this.requestSources.admin);
37
+ const status = await skedulo_adapter_1.skeduloAdapter.checkBootstrap(ctx);
38
+ return { status: 200, body: status };
39
+ }
40
+ catch (err) {
41
+ return (0, helpers_1.errorResponse)(err);
42
+ }
43
+ };
44
+ /** POST /setup — bootstraps the IntegrationIdMapping custom object. Idempotent. */
45
+ this.setup = async (_b, _h, _m, _p, skedContext) => {
46
+ try {
47
+ const ctx = this.createContext(skedContext, this.requestSources.admin);
48
+ await skedulo_adapter_1.skeduloAdapter.bootstrap(ctx);
49
+ return (0, helpers_1.okResponse)('Setup complete', { schema: this.integrationType });
50
+ }
51
+ catch (err) {
52
+ return (0, helpers_1.errorResponse)(err);
53
+ }
54
+ };
55
+ // ── Metadata (drives the mapping editor UI) ────────────────────────────────
56
+ /** GET /objects?system=<name> */
57
+ this.getObjects = async (_b, _h, _m, _p, skedContext, querystring) => {
58
+ var _a;
59
+ try {
60
+ const system = (_a = (0, helpers_1.getQueryParam)(querystring, 'system')) !== null && _a !== void 0 ? _a : this.integrationType;
61
+ const adapter = this.registry.resolve(system);
62
+ const objects = await adapter.getObjects(this.createContext(skedContext, this.requestSources.admin));
63
+ return { status: 200, body: { system, objects } };
64
+ }
65
+ catch (err) {
66
+ return (0, helpers_1.errorResponse)(err);
67
+ }
68
+ };
69
+ /** GET /fields?system=<name>&object=<objectName> */
70
+ this.getFields = async (_b, _h, _m, _p, skedContext, querystring) => {
71
+ var _a;
72
+ try {
73
+ const system = (_a = (0, helpers_1.getQueryParam)(querystring, 'system')) !== null && _a !== void 0 ? _a : this.integrationType;
74
+ const objectName = (0, helpers_1.getQueryParam)(querystring, 'object');
75
+ if (!objectName)
76
+ return { status: 400, body: { message: 'object query parameter is required' } };
77
+ const adapter = this.registry.resolve(system);
78
+ const fields = await adapter.getFields(this.createContext(skedContext, this.requestSources.admin), objectName);
79
+ return { status: 200, body: { system, object: objectName, fields } };
80
+ }
81
+ catch (err) {
82
+ return (0, helpers_1.errorResponse)(err);
83
+ }
84
+ };
85
+ /** GET /templates?system=<name> */
86
+ this.getTemplates = async (_b, _h, _m, _p, _ctx, querystring) => {
87
+ var _a, _c, _d, _e;
88
+ try {
89
+ const system = (_a = (0, helpers_1.getQueryParam)(querystring, 'system')) !== null && _a !== void 0 ? _a : this.integrationType;
90
+ const templates = (_e = (await ((_d = (_c = this.registry.resolve(system)).getTemplates) === null || _d === void 0 ? void 0 : _d.call(_c)))) !== null && _e !== void 0 ? _e : [];
91
+ return { status: 200, body: { templates } };
92
+ }
93
+ catch (err) {
94
+ return (0, helpers_1.errorResponse)(err);
95
+ }
96
+ };
97
+ /** GET /sample-apis?system=<name> */
98
+ this.getSampleAPIs = async (_b, _h, _m, _p, _ctx, querystring) => {
99
+ var _a, _c, _d, _e;
100
+ try {
101
+ const system = (_a = (0, helpers_1.getQueryParam)(querystring, 'system')) !== null && _a !== void 0 ? _a : this.integrationType;
102
+ const apis = (_e = (_d = (_c = this.registry.resolve(system)).getSampleAPIs) === null || _d === void 0 ? void 0 : _d.call(_c)) !== null && _e !== void 0 ? _e : [];
103
+ return { status: 200, body: { apis } };
104
+ }
105
+ catch (err) {
106
+ return (0, helpers_1.errorResponse)(err);
107
+ }
108
+ };
109
+ /** GET /sample-records?system=<name>&objectType=<obj>&limit=<n> */
110
+ this.getSampleRecords = async (_b, _h, _m, _p, skedContext, querystring) => {
111
+ var _a, _c;
112
+ try {
113
+ const system = (_a = (0, helpers_1.getQueryParam)(querystring, 'system')) !== null && _a !== void 0 ? _a : this.integrationType;
114
+ const objectType = (0, helpers_1.getQueryParam)(querystring, 'objectType');
115
+ if (!objectType)
116
+ return { status: 400, body: { message: 'objectType query parameter is required' } };
117
+ const limit = Number((_c = (0, helpers_1.getQueryParam)(querystring, 'limit')) !== null && _c !== void 0 ? _c : this.sampleDefaultLimit);
118
+ if (!Number.isInteger(limit) || limit <= 0) {
119
+ return { status: 400, body: { message: 'limit must be a positive integer' } };
120
+ }
121
+ const adapter = this.registry.resolve(system);
122
+ const records = await adapter.fetchSampleRecords(this.createContext(skedContext, this.requestSources.runFlow), objectType, [], limit);
123
+ return { status: 200, body: { records } };
124
+ }
125
+ catch (err) {
126
+ return (0, helpers_1.errorResponse)(err);
127
+ }
128
+ };
129
+ // ── Sync ───────────────────────────────────────────────────────────────────
130
+ /**
131
+ * POST /scheduled-pull — incremental sync of inbound flows on a schedule.
132
+ * Runs every active flow with triggerConfig.incremental, in executionOrder.
133
+ * SDK reads each flow's lastRunAt for the cursor.
134
+ */
135
+ this.scheduledPull = async (_b, _h, _m, _p, skedContext) => {
136
+ try {
137
+ const ctx = this.createContext(skedContext, this.requestSources.scheduledPull);
138
+ const allInbound = await ctx.dataFlowService.listActive({
139
+ integrationType: this.integrationType,
140
+ targetSystem: 'skedulo',
141
+ });
142
+ const flows = allInbound
143
+ .filter((f) => { var _a; return (_a = f.triggerConfig) === null || _a === void 0 ? void 0 : _a.incremental; })
144
+ .sort((a, b) => { var _a, _c; return ((_a = a.executionOrder) !== null && _a !== void 0 ? _a : Infinity) - ((_c = b.executionOrder) !== null && _c !== void 0 ? _c : Infinity); });
145
+ if (flows.length === 0) {
146
+ ctx.logger.info(`[scheduled-pull] no active incremental flows for ${this.integrationType}`);
147
+ return (0, helpers_1.okResponse)('No active flows', { processed: 0 });
148
+ }
149
+ const runner = this.createRunner();
150
+ const results = {};
151
+ for (const flow of flows) {
152
+ const startedAt = Date.now();
153
+ try {
154
+ const stats = await runner.run({
155
+ flowId: flow.id,
156
+ since: null,
157
+ sourceSystem: this.integrationType,
158
+ targetSystem: 'skedulo',
159
+ options: { lookupStrategy: this.lookupStrategy },
160
+ }, ctx);
161
+ const durationMs = Date.now() - startedAt;
162
+ ctx.logger.info(`[scheduled-pull] flow=${flow.id} ${flow.sourceObject}→${flow.targetObject} ` +
163
+ `${JSON.stringify(stats)} took=${durationMs}ms`);
164
+ results[flow.id] = Object.assign(Object.assign({}, stats), { durationMs });
165
+ }
166
+ catch (err) {
167
+ const msg = err instanceof Error ? err.message : String(err);
168
+ ctx.logger.error(`[scheduled-pull] flow=${flow.id} failed: ${msg}`);
169
+ results[flow.id] = { error: msg };
170
+ }
171
+ }
172
+ return (0, helpers_1.okResponse)('Scheduled pull tick complete', { processed: flows.length, results });
173
+ }
174
+ catch (err) {
175
+ return (0, helpers_1.errorResponse)(err);
176
+ }
177
+ };
178
+ /**
179
+ * POST /run-all-flows — runs every active flow from scratch (since=null).
180
+ * Requires admin. Resets each flow's cursor so a full sync happens regardless
181
+ * of any previous lastRunAt.
182
+ */
183
+ this.runAllFlows = async (_b, _h, _m, _p, skedContext) => {
184
+ var _a, _c, _d, _e;
185
+ try {
186
+ const denied = (0, helpers_1.requireAdmin)(skedContext, 'runAllFlows');
187
+ if (denied)
188
+ return denied;
189
+ const ctx = this.createContext(skedContext, this.requestSources.admin);
190
+ const flows = await ctx.dataFlowService.listActive({
191
+ integrationType: this.integrationType,
192
+ });
193
+ if (flows.length === 0) {
194
+ return {
195
+ status: 503,
196
+ body: {
197
+ message: `No active data flows found for ${this.integrationType}. Create flows first.`,
198
+ },
199
+ };
200
+ }
201
+ ctx.logger.info(`[run-all-flows] found ${flows.length} active flow(s): ` +
202
+ flows.map((f) => `${f.sourceObject}→${f.targetObject}`).join(', '));
203
+ const sorted = [...flows].sort((a, b) => { var _a, _c; return ((_a = a.executionOrder) !== null && _a !== void 0 ? _a : Infinity) - ((_c = b.executionOrder) !== null && _c !== void 0 ? _c : Infinity); });
204
+ const runner = this.createRunner();
205
+ const results = {};
206
+ for (const flow of sorted) {
207
+ if (!((_c = (_a = flow.mappingConfig) === null || _a === void 0 ? void 0 : _a.mappings) === null || _c === void 0 ? void 0 : _c.length)) {
208
+ ctx.logger.warn(`[run-all-flows] skipping flow ${flow.id} (${flow.sourceObject}) — no mappingConfig`);
209
+ results[String(flow.id)] = {
210
+ flowId: flow.id,
211
+ sourceObject: flow.sourceObject,
212
+ targetObject: flow.targetObject,
213
+ skipped: true,
214
+ reason: 'no mappingConfig',
215
+ };
216
+ continue;
217
+ }
218
+ // Reset cursor so the SDK treats this as a full sync regardless of any prior lastRunAt.
219
+ await ctx.dataFlowService.updateCursor(flow.id, null);
220
+ ctx.logger.info(`[run-all-flows] syncing ${flow.sourceObject} → ${flow.targetObject}`);
221
+ const stats = await runner.run({
222
+ flowId: flow.id,
223
+ since: null,
224
+ sourceSystem: (_d = flow.sourceSystem) !== null && _d !== void 0 ? _d : this.integrationType,
225
+ targetSystem: (_e = flow.targetSystem) !== null && _e !== void 0 ? _e : 'skedulo',
226
+ options: { lookupStrategy: this.lookupStrategy },
227
+ }, ctx);
228
+ results[String(flow.id)] = Object.assign({ flowId: flow.id, sourceObject: flow.sourceObject, targetObject: flow.targetObject }, stats);
229
+ }
230
+ return (0, helpers_1.okResponse)('All flows completed successfully', { results });
231
+ }
232
+ catch (err) {
233
+ return (0, helpers_1.errorResponse)(err);
234
+ }
235
+ };
236
+ /**
237
+ * POST /run-flow — runs a single flow by ID from scratch. Used by the
238
+ * "Run now" UI button. Body: { flowId }.
239
+ */
240
+ this.runFlow = async (body, _h, _m, _p, skedContext) => {
241
+ var _a, _c;
242
+ try {
243
+ const denied = (0, helpers_1.requireAdmin)(skedContext, 'runFlow');
244
+ if (denied)
245
+ return denied;
246
+ const { flowId } = (body !== null && body !== void 0 ? body : {});
247
+ if (!flowId)
248
+ return { status: 400, body: { message: 'flowId is required' } };
249
+ const runId = (0, crypto_1.randomUUID)();
250
+ const ctx = this.createContext(skedContext, this.requestSources.runFlow);
251
+ const flow = await ctx.dataFlowService.getFlowById(flowId);
252
+ if (!flow)
253
+ return { status: 404, body: { message: `Flow ${flowId} not found` } };
254
+ ctx.logger.info(`[run-flow] flowId=${flowId} runId=${runId} starting`);
255
+ const stats = await this.createRunner().run({
256
+ flowId,
257
+ since: null,
258
+ sourceSystem: (_a = flow.sourceSystem) !== null && _a !== void 0 ? _a : this.integrationType,
259
+ targetSystem: (_c = flow.targetSystem) !== null && _c !== void 0 ? _c : 'skedulo',
260
+ options: { lookupStrategy: this.lookupStrategy },
261
+ }, ctx);
262
+ ctx.logger.info(`[run-flow] done: ${JSON.stringify(stats)}`);
263
+ return { status: 200, body: Object.assign({ runId, flowId }, stats) };
264
+ }
265
+ catch (err) {
266
+ return (0, helpers_1.errorResponse)(err);
267
+ }
268
+ };
269
+ /**
270
+ * POST /on-skedulo-event — Skedulo triggered-action callback for
271
+ * OUTBOUND_TRIGGERED flows. Fires when a Skedulo record changes and that
272
+ * record is the source of a flow that targets the vendor.
273
+ * Body: { skeduloObject, recordId, operation, payload? }
274
+ *
275
+ * Pair: `onVendorEvent` handles the opposite direction (vendor → Skedulo).
276
+ */
277
+ this.onSkeduloEvent = async (body, _h, _m, _p, skedContext) => {
278
+ var _a;
279
+ try {
280
+ const { skeduloObject, recordId, operation } = (body !== null && body !== void 0 ? body : {});
281
+ if (!skeduloObject || !recordId || !operation) {
282
+ return {
283
+ status: 400,
284
+ body: { message: 'Missing required fields: skeduloObject, recordId, operation' },
285
+ };
286
+ }
287
+ if (operation !== 'INSERT' && operation !== 'UPDATE' && operation !== 'DELETE') {
288
+ return { status: 400, body: { message: `Unsupported operation: ${operation}` } };
289
+ }
290
+ const ctx = this.createContext(skedContext, this.requestSources.skeduloEvent);
291
+ const results = await this.createRunner().handleEvent({
292
+ event: {
293
+ integrationType: this.integrationType,
294
+ objectType: skeduloObject,
295
+ operation,
296
+ recordId,
297
+ payload: (_a = body === null || body === void 0 ? void 0 : body.payload) !== null && _a !== void 0 ? _a : {},
298
+ },
299
+ options: { lookupStrategy: this.lookupStrategy },
300
+ }, ctx);
301
+ if (results.some((r) => r.status === 'failed')) {
302
+ return { status: 502, body: { message: 'Skedulo event processing failed', results } };
303
+ }
304
+ return (0, helpers_1.okResponse)('Skedulo event processed', { results });
305
+ }
306
+ catch (err) {
307
+ return (0, helpers_1.errorResponse)(err);
308
+ }
309
+ };
310
+ /**
311
+ * POST /on-vendor-event — inbound real-time webhook from the vendor system.
312
+ *
313
+ * Dispatches via `adapter.parseChangeEvent(body)` — implement that on the
314
+ * adapter to opt in. Returns 501 if the adapter doesn't implement parsing.
315
+ *
316
+ * Envelope shape is vendor-specific, hence the parser lives on the adapter.
317
+ *
318
+ * Pair: `onSkeduloEvent` handles the opposite direction (Skedulo → vendor).
319
+ */
320
+ this.onVendorEvent = async (body, _h, _m, _p, skedContext) => {
321
+ try {
322
+ const adapter = this.config.adapter;
323
+ if (!adapter.parseChangeEvent) {
324
+ return {
325
+ status: 501,
326
+ body: { message: `${this.integrationType} adapter does not implement parseChangeEvent` },
327
+ };
328
+ }
329
+ const parsed = adapter.parseChangeEvent(body);
330
+ if ('error' in parsed)
331
+ return { status: 400, body: { message: parsed.error } };
332
+ const ctx = this.createContext(skedContext, this.requestSources.vendorEvent);
333
+ const results = await this.createRunner().handleEvent({ event: parsed.event, options: { lookupStrategy: this.lookupStrategy } }, ctx);
334
+ if (results.some((r) => r.status === 'precondition_failed')) {
335
+ return {
336
+ status: 412,
337
+ body: {
338
+ message: 'Integration not bootstrapped — run /setup then /run-all-flows',
339
+ results,
340
+ },
341
+ };
342
+ }
343
+ if (results.some((r) => r.status === 'failed')) {
344
+ return { status: 502, body: { message: 'Event processing failed', results } };
345
+ }
346
+ return (0, helpers_1.okResponse)(`${parsed.event.objectType} ${parsed.event.operation.toLowerCase()} processed`, { results });
347
+ }
348
+ catch (err) {
349
+ return (0, helpers_1.errorResponse)(err);
350
+ }
351
+ };
352
+ this.integrationType = config.adapter.integrationType;
353
+ const t = this.integrationType;
354
+ this.requestSources = {
355
+ admin: `${t}-admin`,
356
+ scheduledPull: `${t}-scheduled-pull`,
357
+ runFlow: `${t}-run-flow`,
358
+ skeduloEvent: `${t}-skedulo-event`,
359
+ vendorEvent: `${t}-vendor-event`,
360
+ };
361
+ this.userAgent = `${t}-function`;
362
+ this.sampleDefaultLimit = (_a = config.sampleDefaultLimit) !== null && _a !== void 0 ? _a : DEFAULT_SAMPLE_LIMIT;
363
+ this.registry =
364
+ (_c = config.registry) !== null && _c !== void 0 ? _c : new adapter_registry_1.AdapterRegistry({ [t]: config.adapter, skedulo: skedulo_adapter_1.skeduloAdapter });
365
+ this.lookupStrategy = (_e = (_d = config.adapter.capabilities) === null || _d === void 0 ? void 0 : _d.lookupStrategy) !== null && _e !== void 0 ? _e : constants_1.LookupStrategy.ExternalId;
366
+ }
367
+ // ── Protected helpers (override to customize) ──────────────────────────────
368
+ createContext(skedContext, requestSource) {
369
+ return (0, context_1.createIntegrationContext)(skedContext, this.integrationType, {
370
+ requestSource,
371
+ userAgent: this.userAgent,
372
+ });
373
+ }
374
+ createRunner() {
375
+ return new sync_runner_1.SyncRunner(this.registry);
376
+ }
377
+ }
378
+ exports.BaseAdapterHandler = BaseAdapterHandler;
379
+ //# sourceMappingURL=base-adapter-handler.js.map