airbyte-faros-destination 0.1.53

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 (280) hide show
  1. package/README.md +161 -0
  2. package/lib/common/write-stats.d.ts +16 -0
  3. package/lib/common/write-stats.js +48 -0
  4. package/lib/community/hasura-client.d.ts +27 -0
  5. package/lib/community/hasura-client.js +278 -0
  6. package/lib/community/hasura-writer.d.ts +12 -0
  7. package/lib/community/hasura-writer.js +44 -0
  8. package/lib/community/types.d.ts +26 -0
  9. package/lib/community/types.js +9 -0
  10. package/lib/converters/agileaccelerator/agileaccelerator_types.d.ts +315 -0
  11. package/lib/converters/agileaccelerator/agileaccelerator_types.js +81 -0
  12. package/lib/converters/agileaccelerator/common.d.ts +64 -0
  13. package/lib/converters/agileaccelerator/common.js +167 -0
  14. package/lib/converters/agileaccelerator/works.d.ts +7 -0
  15. package/lib/converters/agileaccelerator/works.js +105 -0
  16. package/lib/converters/asana/common.d.ts +39 -0
  17. package/lib/converters/asana/common.js +64 -0
  18. package/lib/converters/asana/projects.d.ts +7 -0
  19. package/lib/converters/asana/projects.js +29 -0
  20. package/lib/converters/asana/sections.d.ts +7 -0
  21. package/lib/converters/asana/sections.js +28 -0
  22. package/lib/converters/asana/stories.d.ts +7 -0
  23. package/lib/converters/asana/stories.js +32 -0
  24. package/lib/converters/asana/tags.d.ts +7 -0
  25. package/lib/converters/asana/tags.js +22 -0
  26. package/lib/converters/asana/tasks.d.ts +11 -0
  27. package/lib/converters/asana/tasks.js +160 -0
  28. package/lib/converters/asana/users.d.ts +7 -0
  29. package/lib/converters/asana/users.js +16 -0
  30. package/lib/converters/backlog/common.d.ts +20 -0
  31. package/lib/converters/backlog/common.js +59 -0
  32. package/lib/converters/backlog/issues.d.ts +7 -0
  33. package/lib/converters/backlog/issues.js +119 -0
  34. package/lib/converters/backlog/models.d.ts +156 -0
  35. package/lib/converters/backlog/models.js +23 -0
  36. package/lib/converters/backlog/projects.d.ts +7 -0
  37. package/lib/converters/backlog/projects.js +78 -0
  38. package/lib/converters/backlog/users.d.ts +7 -0
  39. package/lib/converters/backlog/users.js +26 -0
  40. package/lib/converters/bitbucket/branches.d.ts +7 -0
  41. package/lib/converters/bitbucket/branches.js +31 -0
  42. package/lib/converters/bitbucket/commits.d.ts +7 -0
  43. package/lib/converters/bitbucket/commits.js +50 -0
  44. package/lib/converters/bitbucket/common.d.ts +28 -0
  45. package/lib/converters/bitbucket/common.js +56 -0
  46. package/lib/converters/bitbucket/deployments.d.ts +11 -0
  47. package/lib/converters/bitbucket/deployments.js +100 -0
  48. package/lib/converters/bitbucket/issues.d.ts +12 -0
  49. package/lib/converters/bitbucket/issues.js +111 -0
  50. package/lib/converters/bitbucket/pipeline_steps.d.ts +10 -0
  51. package/lib/converters/bitbucket/pipeline_steps.js +83 -0
  52. package/lib/converters/bitbucket/pipelines.d.ts +8 -0
  53. package/lib/converters/bitbucket/pipelines.js +90 -0
  54. package/lib/converters/bitbucket/pull_request_activities.d.ts +13 -0
  55. package/lib/converters/bitbucket/pull_request_activities.js +112 -0
  56. package/lib/converters/bitbucket/pull_requests.d.ts +10 -0
  57. package/lib/converters/bitbucket/pull_requests.js +95 -0
  58. package/lib/converters/bitbucket/repositories.d.ts +9 -0
  59. package/lib/converters/bitbucket/repositories.js +41 -0
  60. package/lib/converters/bitbucket/types.d.ts +667 -0
  61. package/lib/converters/bitbucket/types.js +2 -0
  62. package/lib/converters/bitbucket/workspace_users.d.ts +7 -0
  63. package/lib/converters/bitbucket/workspace_users.js +31 -0
  64. package/lib/converters/bitbucket/workspaces.d.ts +8 -0
  65. package/lib/converters/bitbucket/workspaces.js +61 -0
  66. package/lib/converters/converter-registry.d.ts +25 -0
  67. package/lib/converters/converter-registry.js +64 -0
  68. package/lib/converters/converter.d.ts +63 -0
  69. package/lib/converters/converter.js +122 -0
  70. package/lib/converters/datadog/common.d.ts +27 -0
  71. package/lib/converters/datadog/common.js +34 -0
  72. package/lib/converters/datadog/incidents.d.ts +9 -0
  73. package/lib/converters/datadog/incidents.js +128 -0
  74. package/lib/converters/datadog/users.d.ts +7 -0
  75. package/lib/converters/datadog/users.js +27 -0
  76. package/lib/converters/docker/common.d.ts +87 -0
  77. package/lib/converters/docker/common.js +76 -0
  78. package/lib/converters/docker/tags.d.ts +8 -0
  79. package/lib/converters/docker/tags.js +98 -0
  80. package/lib/converters/github/assignees.d.ts +7 -0
  81. package/lib/converters/github/assignees.js +16 -0
  82. package/lib/converters/github/branches.d.ts +7 -0
  83. package/lib/converters/github/branches.js +28 -0
  84. package/lib/converters/github/collaborators.d.ts +7 -0
  85. package/lib/converters/github/collaborators.js +19 -0
  86. package/lib/converters/github/commits.d.ts +7 -0
  87. package/lib/converters/github/commits.js +48 -0
  88. package/lib/converters/github/common.d.ts +37 -0
  89. package/lib/converters/github/common.js +130 -0
  90. package/lib/converters/github/issue_labels.d.ts +7 -0
  91. package/lib/converters/github/issue_labels.js +20 -0
  92. package/lib/converters/github/issue_milestones.d.ts +8 -0
  93. package/lib/converters/github/issue_milestones.js +42 -0
  94. package/lib/converters/github/issues.d.ts +9 -0
  95. package/lib/converters/github/issues.js +90 -0
  96. package/lib/converters/github/organizations.d.ts +7 -0
  97. package/lib/converters/github/organizations.js +37 -0
  98. package/lib/converters/github/projects.d.ts +7 -0
  99. package/lib/converters/github/projects.js +21 -0
  100. package/lib/converters/github/pull_request_stats.d.ts +7 -0
  101. package/lib/converters/github/pull_request_stats.js +43 -0
  102. package/lib/converters/github/pull_requests.d.ts +7 -0
  103. package/lib/converters/github/pull_requests.js +63 -0
  104. package/lib/converters/github/releases.d.ts +7 -0
  105. package/lib/converters/github/releases.js +51 -0
  106. package/lib/converters/github/repositories.d.ts +7 -0
  107. package/lib/converters/github/repositories.js +44 -0
  108. package/lib/converters/github/review_comments.d.ts +7 -0
  109. package/lib/converters/github/review_comments.js +39 -0
  110. package/lib/converters/github/reviews.d.ts +7 -0
  111. package/lib/converters/github/reviews.js +58 -0
  112. package/lib/converters/github/tags.d.ts +7 -0
  113. package/lib/converters/github/tags.js +31 -0
  114. package/lib/converters/github/users.d.ts +7 -0
  115. package/lib/converters/github/users.js +19 -0
  116. package/lib/converters/gitlab/branches.d.ts +8 -0
  117. package/lib/converters/gitlab/branches.js +44 -0
  118. package/lib/converters/gitlab/commits.d.ts +7 -0
  119. package/lib/converters/gitlab/commits.js +33 -0
  120. package/lib/converters/gitlab/common.d.ts +30 -0
  121. package/lib/converters/gitlab/common.js +70 -0
  122. package/lib/converters/gitlab/group_labels.d.ts +7 -0
  123. package/lib/converters/gitlab/group_labels.js +15 -0
  124. package/lib/converters/gitlab/group_milestones.d.ts +8 -0
  125. package/lib/converters/gitlab/group_milestones.js +41 -0
  126. package/lib/converters/gitlab/groups.d.ts +7 -0
  127. package/lib/converters/gitlab/groups.js +43 -0
  128. package/lib/converters/gitlab/issues.d.ts +10 -0
  129. package/lib/converters/gitlab/issues.js +79 -0
  130. package/lib/converters/gitlab/jobs.d.ts +11 -0
  131. package/lib/converters/gitlab/jobs.js +75 -0
  132. package/lib/converters/gitlab/merge_request_commits.d.ts +7 -0
  133. package/lib/converters/gitlab/merge_request_commits.js +34 -0
  134. package/lib/converters/gitlab/merge_requests.d.ts +10 -0
  135. package/lib/converters/gitlab/merge_requests.js +65 -0
  136. package/lib/converters/gitlab/pipelines.d.ts +7 -0
  137. package/lib/converters/gitlab/pipelines.js +41 -0
  138. package/lib/converters/gitlab/project_labels.d.ts +7 -0
  139. package/lib/converters/gitlab/project_labels.js +15 -0
  140. package/lib/converters/gitlab/project_milestones.d.ts +8 -0
  141. package/lib/converters/gitlab/project_milestones.js +41 -0
  142. package/lib/converters/gitlab/projects.d.ts +7 -0
  143. package/lib/converters/gitlab/projects.js +51 -0
  144. package/lib/converters/gitlab/releases.d.ts +10 -0
  145. package/lib/converters/gitlab/releases.js +68 -0
  146. package/lib/converters/gitlab/tags.d.ts +10 -0
  147. package/lib/converters/gitlab/tags.js +41 -0
  148. package/lib/converters/gitlab/users.d.ts +7 -0
  149. package/lib/converters/gitlab/users.js +33 -0
  150. package/lib/converters/googlecalendar/calendar_models.d.ts +618 -0
  151. package/lib/converters/googlecalendar/calendar_models.js +2 -0
  152. package/lib/converters/googlecalendar/calendars.d.ts +7 -0
  153. package/lib/converters/googlecalendar/calendars.js +29 -0
  154. package/lib/converters/googlecalendar/common.d.ts +52 -0
  155. package/lib/converters/googlecalendar/common.js +130 -0
  156. package/lib/converters/googlecalendar/events.d.ts +8 -0
  157. package/lib/converters/googlecalendar/events.js +117 -0
  158. package/lib/converters/harness/common.d.ts +105 -0
  159. package/lib/converters/harness/common.js +16 -0
  160. package/lib/converters/harness/executions.d.ts +15 -0
  161. package/lib/converters/harness/executions.js +245 -0
  162. package/lib/converters/jenkins/builds.d.ts +9 -0
  163. package/lib/converters/jenkins/builds.js +74 -0
  164. package/lib/converters/jenkins/common.d.ts +25 -0
  165. package/lib/converters/jenkins/common.js +54 -0
  166. package/lib/converters/jenkins/jobs.d.ts +8 -0
  167. package/lib/converters/jenkins/jobs.js +29 -0
  168. package/lib/converters/jira/board_issues.d.ts +7 -0
  169. package/lib/converters/jira/board_issues.js +28 -0
  170. package/lib/converters/jira/boards.d.ts +7 -0
  171. package/lib/converters/jira/boards.js +34 -0
  172. package/lib/converters/jira/common.d.ts +61 -0
  173. package/lib/converters/jira/common.js +64 -0
  174. package/lib/converters/jira/epics.d.ts +8 -0
  175. package/lib/converters/jira/epics.js +45 -0
  176. package/lib/converters/jira/issue_fields.d.ts +7 -0
  177. package/lib/converters/jira/issue_fields.js +15 -0
  178. package/lib/converters/jira/issues.d.ts +52 -0
  179. package/lib/converters/jira/issues.js +545 -0
  180. package/lib/converters/jira/project_versions.d.ts +9 -0
  181. package/lib/converters/jira/project_versions.js +48 -0
  182. package/lib/converters/jira/projects.d.ts +7 -0
  183. package/lib/converters/jira/projects.js +40 -0
  184. package/lib/converters/jira/pull_requests.d.ts +7 -0
  185. package/lib/converters/jira/pull_requests.js +15 -0
  186. package/lib/converters/jira/sprint_issues.d.ts +7 -0
  187. package/lib/converters/jira/sprint_issues.js +15 -0
  188. package/lib/converters/jira/sprints.d.ts +16 -0
  189. package/lib/converters/jira/sprints.js +80 -0
  190. package/lib/converters/jira/users.d.ts +8 -0
  191. package/lib/converters/jira/users.js +33 -0
  192. package/lib/converters/jira/workflow_statuses.d.ts +7 -0
  193. package/lib/converters/jira/workflow_statuses.js +15 -0
  194. package/lib/converters/jsonata.d.ts +17 -0
  195. package/lib/converters/jsonata.js +47 -0
  196. package/lib/converters/okta/common.d.ts +8 -0
  197. package/lib/converters/okta/common.js +17 -0
  198. package/lib/converters/okta/groups.d.ts +7 -0
  199. package/lib/converters/okta/groups.js +47 -0
  200. package/lib/converters/okta/models.d.ts +102 -0
  201. package/lib/converters/okta/models.js +2 -0
  202. package/lib/converters/okta/users.d.ts +8 -0
  203. package/lib/converters/okta/users.js +73 -0
  204. package/lib/converters/okta_faros/common.d.ts +4 -0
  205. package/lib/converters/okta_faros/common.js +11 -0
  206. package/lib/converters/okta_faros/groups.d.ts +13 -0
  207. package/lib/converters/okta_faros/groups.js +23 -0
  208. package/lib/converters/okta_faros/users.d.ts +13 -0
  209. package/lib/converters/okta_faros/users.js +23 -0
  210. package/lib/converters/pagerduty/common.d.ts +37 -0
  211. package/lib/converters/pagerduty/common.js +40 -0
  212. package/lib/converters/pagerduty/incident_log_entries.d.ts +8 -0
  213. package/lib/converters/pagerduty/incident_log_entries.js +56 -0
  214. package/lib/converters/pagerduty/incidents.d.ts +10 -0
  215. package/lib/converters/pagerduty/incidents.js +127 -0
  216. package/lib/converters/pagerduty/priorities_resource.d.ts +11 -0
  217. package/lib/converters/pagerduty/priorities_resource.js +64 -0
  218. package/lib/converters/pagerduty/users.d.ts +7 -0
  219. package/lib/converters/pagerduty/users.js +26 -0
  220. package/lib/converters/phabricator/commits.d.ts +8 -0
  221. package/lib/converters/phabricator/commits.js +75 -0
  222. package/lib/converters/phabricator/common.d.ts +40 -0
  223. package/lib/converters/phabricator/common.js +107 -0
  224. package/lib/converters/phabricator/repositories.d.ts +7 -0
  225. package/lib/converters/phabricator/repositories.js +56 -0
  226. package/lib/converters/phabricator/revisions.d.ts +7 -0
  227. package/lib/converters/phabricator/revisions.js +83 -0
  228. package/lib/converters/phabricator/users.d.ts +7 -0
  229. package/lib/converters/phabricator/users.js +39 -0
  230. package/lib/converters/shortcut/common.d.ts +16 -0
  231. package/lib/converters/shortcut/common.js +68 -0
  232. package/lib/converters/shortcut/epics.d.ts +7 -0
  233. package/lib/converters/shortcut/epics.js +29 -0
  234. package/lib/converters/shortcut/iterations.d.ts +7 -0
  235. package/lib/converters/shortcut/iterations.js +29 -0
  236. package/lib/converters/shortcut/members.d.ts +7 -0
  237. package/lib/converters/shortcut/members.js +26 -0
  238. package/lib/converters/shortcut/models.d.ts +392 -0
  239. package/lib/converters/shortcut/models.js +30 -0
  240. package/lib/converters/shortcut/projects.d.ts +7 -0
  241. package/lib/converters/shortcut/projects.js +46 -0
  242. package/lib/converters/shortcut/stories.d.ts +7 -0
  243. package/lib/converters/shortcut/stories.js +127 -0
  244. package/lib/converters/squadcast/common.d.ts +169 -0
  245. package/lib/converters/squadcast/common.js +62 -0
  246. package/lib/converters/squadcast/events.d.ts +9 -0
  247. package/lib/converters/squadcast/events.js +53 -0
  248. package/lib/converters/squadcast/incidents.d.ts +10 -0
  249. package/lib/converters/squadcast/incidents.js +141 -0
  250. package/lib/converters/squadcast/services.d.ts +7 -0
  251. package/lib/converters/squadcast/services.js +28 -0
  252. package/lib/converters/squadcast/users.d.ts +7 -0
  253. package/lib/converters/squadcast/users.js +27 -0
  254. package/lib/converters/statuspage/common.d.ts +93 -0
  255. package/lib/converters/statuspage/common.js +80 -0
  256. package/lib/converters/statuspage/incident_updates.d.ts +8 -0
  257. package/lib/converters/statuspage/incident_updates.js +45 -0
  258. package/lib/converters/statuspage/incidents.d.ts +10 -0
  259. package/lib/converters/statuspage/incidents.js +128 -0
  260. package/lib/converters/statuspage/users.d.ts +7 -0
  261. package/lib/converters/statuspage/users.js +26 -0
  262. package/lib/converters/victorops/common.d.ts +16 -0
  263. package/lib/converters/victorops/common.js +24 -0
  264. package/lib/converters/victorops/incidents.d.ts +12 -0
  265. package/lib/converters/victorops/incidents.js +209 -0
  266. package/lib/converters/victorops/teams.d.ts +8 -0
  267. package/lib/converters/victorops/teams.js +30 -0
  268. package/lib/converters/victorops/users.d.ts +8 -0
  269. package/lib/converters/victorops/users.js +33 -0
  270. package/lib/destination-runner.d.ts +12 -0
  271. package/lib/destination-runner.js +22 -0
  272. package/lib/destination.d.ts +42 -0
  273. package/lib/destination.js +508 -0
  274. package/lib/index.d.ts +16 -0
  275. package/lib/index.js +39 -0
  276. package/lib/tsconfig.tsbuildinfo +1 -0
  277. package/package.json +71 -0
  278. package/resources/fetch-primary-keys.sql +16 -0
  279. package/resources/introspection-query.gql +61 -0
  280. package/resources/spec.json +468 -0
@@ -0,0 +1,12 @@
1
+ import { Command } from 'commander';
2
+ import { AirbyteDestinationRunner } from 'faros-airbyte-cdk';
3
+ import { Converter } from './converters/converter';
4
+ /** Faros destination runner. */
5
+ export declare class FarosDestinationRunner extends AirbyteDestinationRunner {
6
+ readonly program: Command;
7
+ constructor();
8
+ /**
9
+ * Register converters for custom streams
10
+ */
11
+ registerConverters(...converters: ReadonlyArray<Converter>): void;
12
+ }
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FarosDestinationRunner = void 0;
4
+ const faros_airbyte_cdk_1 = require("faros-airbyte-cdk");
5
+ const converter_registry_1 = require("./converters/converter-registry");
6
+ const destination_1 = require("./destination");
7
+ /** Faros destination runner. */
8
+ class FarosDestinationRunner extends faros_airbyte_cdk_1.AirbyteDestinationRunner {
9
+ constructor() {
10
+ const logger = new faros_airbyte_cdk_1.AirbyteLogger();
11
+ const destination = new destination_1.FarosDestination(logger);
12
+ super(logger, destination);
13
+ this.program = super.mainCommand();
14
+ }
15
+ /**
16
+ * Register converters for custom streams
17
+ */
18
+ registerConverters(...converters) {
19
+ converters.forEach(converter_registry_1.ConverterRegistry.addConverter);
20
+ }
21
+ }
22
+ exports.FarosDestinationRunner = FarosDestinationRunner;
@@ -0,0 +1,42 @@
1
+ /// <reference types="node" />
2
+ import Analytics from 'analytics-node';
3
+ import { AirbyteConfig, AirbyteConfiguredCatalog, AirbyteConnectionStatusMessage, AirbyteDestination, AirbyteLogger, AirbyteSpec, AirbyteStateMessage } from 'faros-airbyte-cdk';
4
+ import { FarosClient } from 'faros-feeds-sdk';
5
+ import { HasuraClient } from './community/hasura-client';
6
+ import { Converter } from './converters/converter';
7
+ import { JSONataApplyMode } from './converters/jsonata';
8
+ export declare enum InvalidRecordStrategy {
9
+ FAIL = "FAIL",
10
+ SKIP = "SKIP"
11
+ }
12
+ export declare enum Edition {
13
+ COMMUNITY = "community",
14
+ CLOUD = "cloud"
15
+ }
16
+ /** Faros destination implementation. */
17
+ export declare class FarosDestination extends AirbyteDestination {
18
+ private readonly logger;
19
+ private edition;
20
+ private farosClient;
21
+ private jsonataConverter;
22
+ private jsonataMode;
23
+ private invalidRecordStrategy;
24
+ private hasuraClient;
25
+ private analytics;
26
+ constructor(logger: AirbyteLogger, edition?: Edition, farosClient?: FarosClient, jsonataConverter?: Converter | undefined, jsonataMode?: JSONataApplyMode, invalidRecordStrategy?: InvalidRecordStrategy, hasuraClient?: HasuraClient, analytics?: Analytics);
27
+ getFarosClient(): FarosClient;
28
+ getHasuraClient(): HasuraClient;
29
+ spec(): Promise<AirbyteSpec>;
30
+ check(config: AirbyteConfig): Promise<AirbyteConnectionStatusMessage>;
31
+ private initCommunity;
32
+ private initCloud;
33
+ private initGlobal;
34
+ private init;
35
+ private getOrigin;
36
+ write(config: AirbyteConfig, catalog: AirbyteConfiguredCatalog, stdin: NodeJS.ReadStream, dryRun: boolean): AsyncGenerator<AirbyteStateMessage>;
37
+ private writeEntries;
38
+ private handleRecordProcessingError;
39
+ private initStreamsCheckConverters;
40
+ private getConverter;
41
+ private writeRecord;
42
+ }
@@ -0,0 +1,508 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.FarosDestination = exports.Edition = exports.InvalidRecordStrategy = void 0;
7
+ const analytics_node_1 = __importDefault(require("analytics-node"));
8
+ const faros_airbyte_cdk_1 = require("faros-airbyte-cdk");
9
+ const faros_feeds_sdk_1 = require("faros-feeds-sdk");
10
+ const lodash_1 = require("lodash");
11
+ const readline_1 = __importDefault(require("readline"));
12
+ const util_1 = __importDefault(require("util"));
13
+ const uuid_1 = require("uuid");
14
+ const verror_1 = require("verror");
15
+ const write_stats_1 = require("./common/write-stats");
16
+ const hasura_client_1 = require("./community/hasura-client");
17
+ const hasura_writer_1 = require("./community/hasura-writer");
18
+ const converter_1 = require("./converters/converter");
19
+ const converter_registry_1 = require("./converters/converter-registry");
20
+ const jsonata_1 = require("./converters/jsonata");
21
+ var InvalidRecordStrategy;
22
+ (function (InvalidRecordStrategy) {
23
+ InvalidRecordStrategy["FAIL"] = "FAIL";
24
+ InvalidRecordStrategy["SKIP"] = "SKIP";
25
+ })(InvalidRecordStrategy = exports.InvalidRecordStrategy || (exports.InvalidRecordStrategy = {}));
26
+ var Edition;
27
+ (function (Edition) {
28
+ Edition["COMMUNITY"] = "community";
29
+ Edition["CLOUD"] = "cloud";
30
+ })(Edition = exports.Edition || (exports.Edition = {}));
31
+ /** Faros destination implementation. */
32
+ class FarosDestination extends faros_airbyte_cdk_1.AirbyteDestination {
33
+ constructor(logger, edition = undefined, farosClient = undefined, jsonataConverter = undefined, jsonataMode = jsonata_1.JSONataApplyMode.FALLBACK, invalidRecordStrategy = InvalidRecordStrategy.SKIP, hasuraClient = undefined, analytics = undefined) {
34
+ super();
35
+ this.logger = logger;
36
+ this.edition = edition;
37
+ this.farosClient = farosClient;
38
+ this.jsonataConverter = jsonataConverter;
39
+ this.jsonataMode = jsonataMode;
40
+ this.invalidRecordStrategy = invalidRecordStrategy;
41
+ this.hasuraClient = hasuraClient;
42
+ this.analytics = analytics;
43
+ }
44
+ getFarosClient() {
45
+ if (this.farosClient)
46
+ return this.farosClient;
47
+ throw new verror_1.VError('Faros client is not initialized');
48
+ }
49
+ getHasuraClient() {
50
+ if (this.hasuraClient)
51
+ return this.hasuraClient;
52
+ throw new verror_1.VError('Hasura client is not initialized');
53
+ }
54
+ async spec() {
55
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
56
+ return new faros_airbyte_cdk_1.AirbyteSpec(require('../resources/spec.json'));
57
+ }
58
+ async check(config) {
59
+ try {
60
+ await this.init(config);
61
+ }
62
+ catch (e) {
63
+ return new faros_airbyte_cdk_1.AirbyteConnectionStatusMessage({
64
+ status: faros_airbyte_cdk_1.AirbyteConnectionStatus.FAILED,
65
+ message: e.message,
66
+ });
67
+ }
68
+ return new faros_airbyte_cdk_1.AirbyteConnectionStatusMessage({
69
+ status: faros_airbyte_cdk_1.AirbyteConnectionStatus.SUCCEEDED,
70
+ });
71
+ }
72
+ async initCommunity(config) {
73
+ var _a;
74
+ if (!config.edition_configs.hasura_url) {
75
+ throw new verror_1.VError('Community Edition Hasura URL is not set');
76
+ }
77
+ try {
78
+ this.hasuraClient = new hasura_client_1.HasuraClient(config.edition_configs.hasura_url);
79
+ }
80
+ catch (e) {
81
+ throw new verror_1.VError(`Failed to initialize Hasura Client. Error: ${e}`);
82
+ }
83
+ try {
84
+ if (config.dry_run !== true) {
85
+ await this.getHasuraClient().healthCheck();
86
+ }
87
+ }
88
+ catch (e) {
89
+ throw new verror_1.VError(`Invalid Hasura url. Error: ${e}`);
90
+ }
91
+ const segmentUserId = config.edition_configs.segment_user_id;
92
+ if (segmentUserId) {
93
+ if (!(0, uuid_1.validate)(segmentUserId)) {
94
+ throw new verror_1.VError(`Segment User Id ${segmentUserId} is not a valid UUID. Example: ${(0, uuid_1.v4)()}`);
95
+ }
96
+ // Segment host is used for testing purposes only
97
+ const host = (_a = config.edition_configs) === null || _a === void 0 ? void 0 : _a.segment_test_host;
98
+ // Only create the client if there's a user id specified
99
+ this.analytics = new analytics_node_1.default('YEu7VC65n9dIR85pQ1tgV2RHQHjo2bwn', {
100
+ host,
101
+ });
102
+ }
103
+ }
104
+ async initCloud(config) {
105
+ if (!config.edition_configs.api_url) {
106
+ throw new verror_1.VError('API URL is not set');
107
+ }
108
+ if (!config.edition_configs.api_key) {
109
+ throw new verror_1.VError('API key is not set');
110
+ }
111
+ try {
112
+ this.farosClient = new faros_feeds_sdk_1.FarosClient({
113
+ url: config.edition_configs.api_url,
114
+ apiKey: config.edition_configs.api_key,
115
+ });
116
+ }
117
+ catch (e) {
118
+ throw new verror_1.VError(`Failed to initialize Faros Client. Error: ${e}`);
119
+ }
120
+ try {
121
+ if (config.dry_run !== true) {
122
+ await this.getFarosClient().tenant();
123
+ }
124
+ }
125
+ catch (e) {
126
+ throw new verror_1.VError(`Invalid Faros API url or API key. Error: ${e}`);
127
+ }
128
+ const graph = config.edition_configs.graph;
129
+ try {
130
+ const exists = await this.getFarosClient().graphExists(graph);
131
+ if (!exists) {
132
+ throw new verror_1.VError(`Faros graph ${graph} does not exist`);
133
+ }
134
+ }
135
+ catch (e) {
136
+ throw new verror_1.VError(`Invalid Faros graph ${graph}. Error: ${e}`);
137
+ }
138
+ }
139
+ initGlobal(config) {
140
+ var _a, _b;
141
+ try {
142
+ this.jsonataConverter = config.jsonata_expression
143
+ ? jsonata_1.JSONataConverter.make(config.jsonata_expression, config.jsonata_destination_models)
144
+ : undefined;
145
+ }
146
+ catch (e) {
147
+ throw new verror_1.VError(`Failed to initialize JSONata converter. Error: ${e}`);
148
+ }
149
+ if (config.invalid_record_strategy &&
150
+ !Object.values(InvalidRecordStrategy).includes(config.invalid_record_strategy)) {
151
+ throw new verror_1.VError(`Invalid strategy ${config.invalid_record_strategy}. ` +
152
+ `Possible values are ${Object.values(InvalidRecordStrategy).join(',')}`);
153
+ }
154
+ if (config.invalid_record_strategy) {
155
+ this.invalidRecordStrategy = config.invalid_record_strategy;
156
+ }
157
+ if (config.jsonata_mode &&
158
+ !Object.values(jsonata_1.JSONataApplyMode).includes(config.jsonata_mode)) {
159
+ throw new verror_1.VError(`Invalid JSONata mode ${config.jsonata_mode}. ` +
160
+ `Possible values are ${Object.values(jsonata_1.JSONataApplyMode).join(',')}`);
161
+ }
162
+ if (config.jsonata_mode) {
163
+ this.jsonataMode = config.jsonata_mode;
164
+ }
165
+ if (config.jsonata_expression &&
166
+ (!Array.isArray(config.jsonata_destination_models) ||
167
+ !config.jsonata_destination_models.length)) {
168
+ throw new verror_1.VError('JSONata destination models must be set when using JSONata expression');
169
+ }
170
+ const jira_configs = (_b = (_a = config.source_specific_configs) === null || _a === void 0 ? void 0 : _a.jira) !== null && _b !== void 0 ? _b : {};
171
+ if (typeof jira_configs.truncate_limit === 'number' &&
172
+ jira_configs.truncate_limit < 0) {
173
+ throw new verror_1.VError('Jira Truncate Limit must be a non-negative number');
174
+ }
175
+ if (typeof jira_configs.additional_fields_array_limit === 'number' &&
176
+ jira_configs.additional_fields_array_limit < 0) {
177
+ throw new verror_1.VError('Jira Additional Fields Array Limit must be a non-negative number');
178
+ }
179
+ const objectTypeConfigKeys = [
180
+ ['bitbucket', 'application_mapping'],
181
+ ['pagerduty', 'application_mapping'],
182
+ ['squadcast', 'application_mapping'],
183
+ ['statuspage', 'application_mapping'],
184
+ ['victorops', 'application_mapping'],
185
+ ];
186
+ objectTypeConfigKeys.forEach((k) => {
187
+ var _a, _b;
188
+ return (0, converter_1.parseObjectConfig)((_b = (_a = config.source_specific_configs) === null || _a === void 0 ? void 0 : _a[k[0]]) === null || _b === void 0 ? void 0 : _b[k[1]], k.join('.'));
189
+ });
190
+ }
191
+ async init(config) {
192
+ var _a;
193
+ const edition = (_a = config.edition_configs) === null || _a === void 0 ? void 0 : _a.edition;
194
+ if (!edition) {
195
+ throw new verror_1.VError('Faros Edition is not set');
196
+ }
197
+ this.edition = edition;
198
+ if (edition === Edition.COMMUNITY) {
199
+ await this.initCommunity(config);
200
+ }
201
+ else if (edition === Edition.CLOUD) {
202
+ await this.initCloud(config);
203
+ }
204
+ else {
205
+ throw new verror_1.VError(`Invalid run mode ${edition}. ` +
206
+ `Possible values are ${Object.values(Edition).join(',')}`);
207
+ }
208
+ this.initGlobal(config);
209
+ }
210
+ getOrigin(config, catalog) {
211
+ if (config.origin) {
212
+ this.logger.info(`Using origin ${config.origin} found in config`);
213
+ return config.origin;
214
+ }
215
+ // Determine origin from stream prefixes
216
+ const origins = (0, lodash_1.uniq)(catalog.streams.map((s) => s.stream.name.split(converter_1.StreamNameSeparator, 1)[0]));
217
+ if (origins.length === 0) {
218
+ throw new verror_1.VError('Could not determine origin from catalog');
219
+ }
220
+ else if (origins.length > 1) {
221
+ throw new verror_1.VError(`Found multiple possible origins from catalog: ${origins.join(',')}`);
222
+ }
223
+ this.logger.info(`Determined origin ${origins[0]} from stream prefixes`);
224
+ return origins[0];
225
+ }
226
+ async *write(config, catalog, stdin, dryRun) {
227
+ await this.init(config);
228
+ const origin = this.getOrigin(config, catalog);
229
+ const { streams, deleteModelEntries, converterDependencies } = this.initStreamsCheckConverters(catalog);
230
+ const stateMessages = [];
231
+ const stats = new write_stats_1.WriteStats();
232
+ const dryRunEnabled = config.dry_run === true || dryRun;
233
+ // Avoid creating a new revision and writer when dry run or community edition is enabled
234
+ try {
235
+ if (dryRunEnabled) {
236
+ this.logger.info("Dry run is ENABLED. Won't write any records");
237
+ await this.writeEntries(config, stdin, streams, stateMessages, converterDependencies, stats);
238
+ }
239
+ else if (this.edition === Edition.COMMUNITY) {
240
+ const hasura = this.getHasuraClient();
241
+ await hasura.loadSchema();
242
+ await hasura.resetData(origin, deleteModelEntries);
243
+ const writer = new hasura_writer_1.HasuraWriter(hasura, origin, stats, this.handleRecordProcessingError);
244
+ await this.writeEntries(config, stdin, streams, stateMessages, converterDependencies, stats, writer);
245
+ }
246
+ else {
247
+ this.logger.info(`Opening a new revision on graph ${config.edition_configs.graph} ` +
248
+ `with expiration of ${config.edition_configs.expiration}`);
249
+ // Log all models to be deleted (if any)
250
+ if (deleteModelEntries.length > 0) {
251
+ const modelsToDelete = (0, lodash_1.sortBy)(deleteModelEntries).join(',');
252
+ this.logger.info(`Deleting records in destination graph ${config.edition_configs.graph} for models: ${modelsToDelete}`);
253
+ }
254
+ // Create an entry uploader for the destination graph
255
+ const entryUploaderConfig = {
256
+ name: origin,
257
+ url: config.edition_configs.api_url,
258
+ authHeader: config.edition_configs.api_key,
259
+ expiration: config.edition_configs.expiration,
260
+ graphName: config.edition_configs.graph,
261
+ deleteModelEntries,
262
+ logger: this.logger.asPino('debug'),
263
+ };
264
+ await (0, faros_feeds_sdk_1.withEntryUploader)(entryUploaderConfig, async (writer, state) => {
265
+ try {
266
+ // Log last synced time
267
+ const lastSynced = (state === null || state === void 0 ? void 0 : state.lastSynced)
268
+ ? `last synced at ${state.lastSynced}`
269
+ : 'not synced yet';
270
+ this.logger.info(`Destination graph ${config.edition_configs.graph} was ${lastSynced}`);
271
+ // Process input and write entries
272
+ await this.writeEntries(config, stdin, streams, stateMessages, converterDependencies, stats, writer);
273
+ // Return the current time
274
+ return { lastSynced: new Date().toISOString() };
275
+ }
276
+ finally {
277
+ // Don't forget to close the writer
278
+ if (!writer.writableEnded)
279
+ writer.end();
280
+ }
281
+ });
282
+ }
283
+ if (this.analytics) {
284
+ this.logger.info('Sending write stats to Segment.');
285
+ const fn = (callback) => {
286
+ this.analytics
287
+ .track({
288
+ event: 'Write Stats',
289
+ userId: config.edition_configs.segment_user_id,
290
+ properties: stats,
291
+ }, callback)
292
+ .flush(callback);
293
+ };
294
+ await util_1.default
295
+ .promisify(fn)()
296
+ .catch((err) => this.logger.error(`Failed to send write stats to Segment: ${err.message}`));
297
+ }
298
+ // Since we are writing all records in a single revision,
299
+ // we should be ok to return all the state messages at the end,
300
+ // once the revision has been closed.
301
+ for (const state of stateMessages)
302
+ yield state;
303
+ }
304
+ finally {
305
+ // Log collected statistics
306
+ stats.log(this.logger, dryRunEnabled ? 'Would write' : 'Wrote');
307
+ }
308
+ }
309
+ async writeEntries(config, stdin, streams, stateMessages, converterDependencies, stats, writer) {
310
+ const ctx = new converter_1.StreamContext(config, this.edition === Edition.COMMUNITY ? undefined : this.getFarosClient());
311
+ const recordsToBeProcessedLast = [];
312
+ // NOTE: readline.createInterface() will start to consume the input stream once invoked.
313
+ // Having asynchronous operations between interface creation and asynchronous iteration may
314
+ // result in missed lines.
315
+ const input = readline_1.default.createInterface({
316
+ input: stdin,
317
+ terminal: stdin.isTTY,
318
+ });
319
+ try {
320
+ // Process input & write records
321
+ for await (const line of input) {
322
+ await this.handleRecordProcessingError(stats, async () => {
323
+ const msg = (0, faros_airbyte_cdk_1.parseAirbyteMessage)(line);
324
+ stats.messagesRead++;
325
+ if (msg.type === faros_airbyte_cdk_1.AirbyteMessageType.STATE) {
326
+ stateMessages.push(msg);
327
+ }
328
+ else if (msg.type === faros_airbyte_cdk_1.AirbyteMessageType.RECORD) {
329
+ stats.recordsRead++;
330
+ const recordMessage = msg;
331
+ if (!recordMessage.record) {
332
+ throw new verror_1.VError('Empty record');
333
+ }
334
+ if (!streams[recordMessage.record.stream]) {
335
+ throw new verror_1.VError(`Undefined stream ${recordMessage.record.stream}`);
336
+ }
337
+ const unpacked = recordMessage.unpackRaw();
338
+ if (!unpacked.record) {
339
+ throw new verror_1.VError('Empty unpacked record');
340
+ }
341
+ const stream = unpacked.record.stream;
342
+ stats.incrementProcessedByStream(stream);
343
+ const converter = this.getConverter(stream);
344
+ // No need to fail on records we don't have a converter yet
345
+ if (!converter) {
346
+ stats.recordsSkipped++;
347
+ return;
348
+ }
349
+ const writeRecord = async (context) => {
350
+ stats.recordsWritten += await this.writeRecord(converter, unpacked, stats, context, writer);
351
+ stats.recordsProcessed++;
352
+ };
353
+ // Check if any converters depend on this record stream.
354
+ // If yes, keep the record in the stream context for other converters to get.
355
+ const streamName = converter_1.StreamName.fromString(stream).asString;
356
+ const recordId = converter.id(unpacked);
357
+ if (converterDependencies.has(streamName) && recordId) {
358
+ ctx.set(streamName, String(recordId), unpacked);
359
+ // Print stream context stats every so often
360
+ if (stats.recordsProcessed % 1000 == 0) {
361
+ this.logger.info(`Stream context stats: ${ctx.stats(false)}`);
362
+ }
363
+ }
364
+ // Process the record immediately if converter has no dependencies,
365
+ // otherwise process it later once all streams are processed.
366
+ if (converter.dependencies.length === 0) {
367
+ await writeRecord(ctx);
368
+ }
369
+ else {
370
+ recordsToBeProcessedLast.push(writeRecord);
371
+ }
372
+ }
373
+ });
374
+ }
375
+ // Process all the remaining records
376
+ if (recordsToBeProcessedLast.length > 0) {
377
+ this.logger.info(`Stdin processing completed, but still have ${recordsToBeProcessedLast.length} records to process`);
378
+ this.logger.info(`Stream context stats: ${ctx.stats(true)}`);
379
+ for await (const process of recordsToBeProcessedLast) {
380
+ await this.handleRecordProcessingError(stats, () => process(ctx));
381
+ }
382
+ }
383
+ // Don't forget to close the writer
384
+ await (writer === null || writer === void 0 ? void 0 : writer.end());
385
+ }
386
+ finally {
387
+ input.close();
388
+ }
389
+ }
390
+ async handleRecordProcessingError(stats, processRecord) {
391
+ var _a;
392
+ try {
393
+ await processRecord();
394
+ }
395
+ catch (e) {
396
+ stats.recordsErrored++;
397
+ this.logger.error(`Error processing input: ${(_a = e.message) !== null && _a !== void 0 ? _a : JSON.stringify(e)}`);
398
+ switch (this.invalidRecordStrategy) {
399
+ case InvalidRecordStrategy.SKIP:
400
+ stats.recordsSkipped++;
401
+ break;
402
+ case InvalidRecordStrategy.FAIL:
403
+ throw e;
404
+ }
405
+ }
406
+ }
407
+ initStreamsCheckConverters(catalog) {
408
+ const streams = (0, lodash_1.keyBy)(catalog.streams, (s) => s.stream.name);
409
+ const streamKeys = Object.keys(streams);
410
+ const deleteModelEntries = [];
411
+ const dependenciesByStream = {};
412
+ // Check input streams & initialize record converters
413
+ for (const stream of streamKeys) {
414
+ const destinationSyncMode = streams[stream].destination_sync_mode;
415
+ if (!destinationSyncMode) {
416
+ throw new verror_1.VError(`Undefined destination sync mode for stream ${stream}`);
417
+ }
418
+ const converter = this.getConverter(stream, (err) => {
419
+ if (err.message.includes('Cannot find module ')) {
420
+ this.logger.info(`No converter found for ${stream}`);
421
+ }
422
+ else {
423
+ this.logger.error(err.message);
424
+ }
425
+ });
426
+ if (converter) {
427
+ this.logger.info(`Using ${converter.constructor.name} converter to convert ${stream} stream records`);
428
+ // Collect all converter dependencies
429
+ if (converter.dependencies.length > 0) {
430
+ const streamName = converter.streamName.asString;
431
+ if (!dependenciesByStream[streamName]) {
432
+ dependenciesByStream[streamName] = new Set();
433
+ }
434
+ const deps = dependenciesByStream[streamName];
435
+ converter.dependencies.forEach((d) => deps.add(d.asString));
436
+ }
437
+ // Prepare destination models to delete if any
438
+ if (destinationSyncMode === faros_airbyte_cdk_1.DestinationSyncMode.OVERWRITE) {
439
+ deleteModelEntries.push(...converter.destinationModels);
440
+ }
441
+ }
442
+ }
443
+ // Check for circular dependencies and error early if any
444
+ const deps = Object.keys(dependenciesByStream);
445
+ for (const d of deps) {
446
+ const dd = [...dependenciesByStream[d].values()];
447
+ this.logger.info(`Records of stream ${d} will be accumulated and processed last, ` +
448
+ `since their converter has dependencies on streams: ${dd.join(',')}`);
449
+ const res = (0, lodash_1.intersection)(deps, dd);
450
+ if (res.length > 0) {
451
+ throw new verror_1.VError(`Circular converter dependency detected: ${res.join(',')}`);
452
+ }
453
+ }
454
+ // Collect all converter dependencies
455
+ const converterDependencies = new Set();
456
+ Object.keys(dependenciesByStream).forEach((k) => dependenciesByStream[k].forEach((v) => converterDependencies.add(v)));
457
+ return {
458
+ streams,
459
+ deleteModelEntries: (0, lodash_1.uniq)(deleteModelEntries),
460
+ converterDependencies,
461
+ };
462
+ }
463
+ getConverter(stream, onLoadError) {
464
+ var _a;
465
+ const converter = converter_registry_1.ConverterRegistry.getConverter(converter_1.StreamName.fromString(stream), onLoadError);
466
+ return this.jsonataMode === jsonata_1.JSONataApplyMode.OVERRIDE
467
+ ? (_a = this.jsonataConverter) !== null && _a !== void 0 ? _a : converter
468
+ : converter !== null && converter !== void 0 ? converter : this.jsonataConverter;
469
+ }
470
+ async writeRecord(converter, recordMessage, stats, ctx, writer) {
471
+ // Apply conversion on the input record
472
+ const results = await converter.convert(recordMessage, ctx);
473
+ if (!Array.isArray(results)) {
474
+ throw new verror_1.VError('Invalid results: not an array');
475
+ }
476
+ let recordsWritten = 0;
477
+ // Write out the results to the output stream
478
+ for (const result of results) {
479
+ if (!result.model)
480
+ throw new verror_1.VError('Invalid result: undefined model');
481
+ if (!result.record)
482
+ throw new verror_1.VError('Invalid result: undefined record');
483
+ if (typeof result.record !== 'object')
484
+ throw new verror_1.VError('Invalid result: record is not an object');
485
+ // Set the source if missing
486
+ if (!result.record['source']) {
487
+ result.record['source'] = converter.streamName.source;
488
+ }
489
+ let isTimestamped = false;
490
+ if (writer) {
491
+ if (writer instanceof hasura_writer_1.HasuraWriter) {
492
+ isTimestamped = await writer.write(result);
493
+ }
494
+ else {
495
+ const obj = {};
496
+ obj[result.model] = result.record;
497
+ writer.write(obj);
498
+ }
499
+ }
500
+ if (!isTimestamped) {
501
+ recordsWritten++;
502
+ stats.incrementWrittenByModel(result.model);
503
+ }
504
+ }
505
+ return recordsWritten;
506
+ }
507
+ }
508
+ exports.FarosDestination = FarosDestination;
package/lib/index.d.ts ADDED
@@ -0,0 +1,16 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * The main entry point
4
+ *
5
+ * You can optionally provide options `exitOverride` and `configureOutput` to
6
+ * override default behavior of the CLI when it detects an error and where it
7
+ * writes to respectively. See https://github.com/tj/commander.js#override-exit-and-output-handling
8
+ * for detailed info on how these options work.
9
+ */
10
+ export declare function mainCommand(options?: {
11
+ exitOverride?: boolean;
12
+ suppressOutput?: boolean;
13
+ }): Command;
14
+ export { Converter, DestinationRecord, DestinationModel, StreamContext, StreamName, StreamNameSeparator, } from './converters/converter';
15
+ export { Edition, InvalidRecordStrategy } from './destination';
16
+ export { FarosDestinationRunner } from './destination-runner';
package/lib/index.js ADDED
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FarosDestinationRunner = exports.InvalidRecordStrategy = exports.Edition = exports.StreamNameSeparator = exports.StreamName = exports.StreamContext = exports.Converter = exports.mainCommand = void 0;
4
+ const destination_runner_1 = require("./destination-runner");
5
+ /**
6
+ * The main entry point
7
+ *
8
+ * You can optionally provide options `exitOverride` and `configureOutput` to
9
+ * override default behavior of the CLI when it detects an error and where it
10
+ * writes to respectively. See https://github.com/tj/commander.js#override-exit-and-output-handling
11
+ * for detailed info on how these options work.
12
+ */
13
+ function mainCommand(options) {
14
+ const destinationRunner = new destination_runner_1.FarosDestinationRunner();
15
+ const program = destinationRunner.mainCommand();
16
+ if (options === null || options === void 0 ? void 0 : options.exitOverride) {
17
+ program.exitOverride();
18
+ }
19
+ if (options === null || options === void 0 ? void 0 : options.suppressOutput) {
20
+ program.configureOutput({
21
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
22
+ writeOut: () => { },
23
+ // eslint-disable-next-line @typescript-eslint/no-empty-function
24
+ writeErr: () => { },
25
+ });
26
+ }
27
+ return program;
28
+ }
29
+ exports.mainCommand = mainCommand;
30
+ var converter_1 = require("./converters/converter");
31
+ Object.defineProperty(exports, "Converter", { enumerable: true, get: function () { return converter_1.Converter; } });
32
+ Object.defineProperty(exports, "StreamContext", { enumerable: true, get: function () { return converter_1.StreamContext; } });
33
+ Object.defineProperty(exports, "StreamName", { enumerable: true, get: function () { return converter_1.StreamName; } });
34
+ Object.defineProperty(exports, "StreamNameSeparator", { enumerable: true, get: function () { return converter_1.StreamNameSeparator; } });
35
+ var destination_1 = require("./destination");
36
+ Object.defineProperty(exports, "Edition", { enumerable: true, get: function () { return destination_1.Edition; } });
37
+ Object.defineProperty(exports, "InvalidRecordStrategy", { enumerable: true, get: function () { return destination_1.InvalidRecordStrategy; } });
38
+ var destination_runner_2 = require("./destination-runner");
39
+ Object.defineProperty(exports, "FarosDestinationRunner", { enumerable: true, get: function () { return destination_runner_2.FarosDestinationRunner; } });