airbyte-faros-destination 0.1.56 → 0.1.59

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.
package/README.md CHANGED
@@ -57,8 +57,8 @@ import {AirbyteRecord} from 'faros-airbyte-cdk';
57
57
  import {Converter, DestinationModel, DestinationRecord,FarosDestinationRunner,StreamContext} from 'airbyte-faros-destination'
58
58
 
59
59
  class Builds extends Converter {
60
- source: string = 'CustomSource'
61
- destinationModels: ReadonlyArray<DestinationModel> = ['cicd_Build'];
60
+ source = 'CustomSource'
61
+ destinationModels = ['cicd_Build'];
62
62
 
63
63
  id(record: AirbyteRecord): string {
64
64
  return record.record.data.id;
@@ -66,7 +66,7 @@ class Builds extends Converter {
66
66
 
67
67
  async convert(
68
68
  record: AirbyteRecord,
69
- _ctx: StreamContext
69
+ ctx: StreamContext
70
70
  ): Promise<ReadonlyArray<DestinationRecord>> {
71
71
  const build = record.record.data
72
72
  return [
@@ -83,12 +83,13 @@ class Builds extends Converter {
83
83
  ];
84
84
  }
85
85
  }
86
+
86
87
  class Pipelines extends Converter {
87
88
  // similar to the Builds in the example above
88
89
  ...
89
90
  }
90
91
 
91
- // main entry point
92
+ // Main entry point
92
93
  export function mainCommand(): Command {
93
94
  const destinationRunner = new FarosDestinationRunner();
94
95
 
@@ -97,7 +98,6 @@ export function mainCommand(): Command {
97
98
  new Builds(),
98
99
  new Pipelines()
99
100
  );
100
-
101
101
  return destinationRunner.program;
102
102
  }
103
103
  ```
@@ -157,5 +157,10 @@ Example `catalog.json`
157
157
  }
158
158
  ```
159
159
 
160
+ **Tip**: you can even pipe data directly from your custom source into your custom destination without Airbyte server while prefixing your streams (as expected by Faros Destination):
161
+ ```shell
162
+ <my-source-command> | jq -c -R 'fromjson? | select(.type == "RECORD") | .record.stream = "mydatasource__CustomSource__\(.record.stream)"' | <my-destination-command>
163
+ ```
164
+
160
165
  ### Additional Commands
161
166
  Run `./bin/main --help` for detailed information on available commands.
@@ -8,7 +8,7 @@ export declare class HasuraClient {
8
8
  private readonly references;
9
9
  private readonly backReferences;
10
10
  private sortedModelDependencies;
11
- constructor(url: string);
11
+ constructor(url: string, adminSecret?: string);
12
12
  healthCheck(): Promise<void>;
13
13
  private fetchDbSource;
14
14
  loadSchema(): Promise<void>;
@@ -16,7 +16,7 @@ const traverse_1 = __importDefault(require("traverse"));
16
16
  const verror_1 = require("verror");
17
17
  const types_1 = require("./types");
18
18
  class HasuraClient {
19
- constructor(url) {
19
+ constructor(url, adminSecret) {
20
20
  this.logger = new faros_airbyte_cdk_1.AirbyteLogger();
21
21
  this.primaryKeys = {};
22
22
  this.scalars = {};
@@ -24,7 +24,10 @@ class HasuraClient {
24
24
  this.backReferences = {};
25
25
  this.api = axios_1.default.create({
26
26
  baseURL: url,
27
- headers: { 'X-Hasura-Role': 'admin' },
27
+ headers: {
28
+ 'X-Hasura-Role': 'admin',
29
+ ...(adminSecret && { 'X-Hasura-Admin-Secret': adminSecret }),
30
+ },
28
31
  });
29
32
  }
30
33
  async healthCheck() {
@@ -12,10 +12,15 @@ export interface CategoryRef {
12
12
  readonly category: string;
13
13
  readonly detail: string;
14
14
  }
15
+ export interface ProjectKey {
16
+ uid: string;
17
+ source: string;
18
+ }
15
19
  /** Common functions shares across Bitbucket converters */
16
20
  export declare class BitbucketCommon {
17
21
  static MAX_DESCRIPTION_LENGTH: number;
18
22
  static vcsUser(user: User, source: string): DestinationRecord | undefined;
23
+ static tms_ProjectBoard_with_TaskBoard(projectKey: ProjectKey, name: string, description: string | null, createdAt: string | null | undefined, updatedAt: string | null | undefined): DestinationRecord[];
19
24
  }
20
25
  /** Bitbucket converter base */
21
26
  export declare abstract class BitbucketConverter extends Converter {
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.BitbucketConverter = exports.BitbucketCommon = void 0;
4
+ const faros_feeds_sdk_1 = require("faros-feeds-sdk");
4
5
  const converter_1 = require("../converter");
5
6
  var UserTypeCategory;
6
7
  (function (UserTypeCategory) {
@@ -29,6 +30,34 @@ class BitbucketCommon {
29
30
  },
30
31
  };
31
32
  }
33
+ static tms_ProjectBoard_with_TaskBoard(projectKey, name, description, createdAt, updatedAt) {
34
+ return [
35
+ {
36
+ model: 'tms_Project',
37
+ record: {
38
+ ...projectKey,
39
+ name: name,
40
+ description: description === null || description === void 0 ? void 0 : description.substring(0, BitbucketCommon.MAX_DESCRIPTION_LENGTH),
41
+ createdAt: faros_feeds_sdk_1.Utils.toDate(createdAt),
42
+ updatedAt: faros_feeds_sdk_1.Utils.toDate(updatedAt),
43
+ },
44
+ },
45
+ {
46
+ model: 'tms_TaskBoard',
47
+ record: {
48
+ ...projectKey,
49
+ name,
50
+ },
51
+ },
52
+ {
53
+ model: 'tms_TaskBoardProjectRelationship',
54
+ record: {
55
+ board: projectKey,
56
+ project: projectKey,
57
+ },
58
+ },
59
+ ];
60
+ }
32
61
  }
33
62
  exports.BitbucketCommon = BitbucketCommon;
34
63
  // max length for free-form description text field
@@ -1,9 +1,7 @@
1
1
  import { AirbyteRecord } from 'faros-airbyte-cdk';
2
- import { DestinationModel, DestinationRecord, StreamContext, StreamName } from '../converter';
2
+ import { DestinationModel, DestinationRecord, StreamContext } from '../converter';
3
3
  import { BitbucketConverter } from './common';
4
4
  export declare class Repositories extends BitbucketConverter {
5
5
  readonly destinationModels: ReadonlyArray<DestinationModel>;
6
- private readonly workspacesStream;
7
- get dependencies(): ReadonlyArray<StreamName>;
8
6
  convert(record: AirbyteRecord, ctx: StreamContext): Promise<ReadonlyArray<DestinationRecord>>;
9
7
  }
@@ -1,41 +1,55 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Repositories = void 0;
4
- const converter_1 = require("../converter");
4
+ const faros_feeds_sdk_1 = require("faros-feeds-sdk");
5
5
  const common_1 = require("./common");
6
6
  class Repositories extends common_1.BitbucketConverter {
7
7
  constructor() {
8
8
  super(...arguments);
9
9
  this.destinationModels = [
10
10
  'cicd_Repository',
11
+ 'vcs_Repository',
12
+ 'tms_Project',
13
+ 'tms_TaskBoard',
14
+ 'tms_TaskBoardProjectRelationship',
11
15
  ];
12
- this.workspacesStream = new converter_1.StreamName('bitbucket', 'workspace');
13
- }
14
- get dependencies() {
15
- return [this.workspacesStream];
16
16
  }
17
17
  async convert(record, ctx) {
18
- var _a, _b;
18
+ var _a, _b, _c, _d, _e;
19
19
  const source = this.streamName.source;
20
20
  const repository = record.record.data;
21
- const workspacesStream = this.workspacesStream.asString;
22
- const workspacesRecord = ctx.get(workspacesStream, repository.workspace.uuid);
23
- const workspace = (_a = workspacesRecord === null || workspacesRecord === void 0 ? void 0 : workspacesRecord.record) === null || _a === void 0 ? void 0 : _a.data;
24
- if (!workspace) {
25
- return [];
26
- }
27
- return [
28
- {
29
- model: 'cicd_Repository',
30
- record: {
31
- uid: repository.slug.toLowerCase(),
32
- name: repository.name,
33
- description: (_b = repository.description) === null || _b === void 0 ? void 0 : _b.substring(0, common_1.BitbucketCommon.MAX_DESCRIPTION_LENGTH),
34
- url: repository.links.htmlUrl,
35
- organization: { uid: workspace === null || workspace === void 0 ? void 0 : workspace.uuid, source },
36
- },
21
+ const workspace = repository.workspace;
22
+ const res = [];
23
+ const description = (_a = repository.description) === null || _a === void 0 ? void 0 : _a.substring(0, common_1.BitbucketCommon.MAX_DESCRIPTION_LENGTH);
24
+ // Create a TMS Project/Board per repo that we sync
25
+ res.push(...common_1.BitbucketCommon.tms_ProjectBoard_with_TaskBoard({ uid: repository.name, source }, repository.name, repository.description, repository.createdOn, repository.updatedOn));
26
+ res.push({
27
+ model: 'cicd_Repository',
28
+ record: {
29
+ uid: repository.slug.toLowerCase(),
30
+ name: repository.fullName,
31
+ description,
32
+ url: (_b = repository === null || repository === void 0 ? void 0 : repository.links) === null || _b === void 0 ? void 0 : _b.htmlUrl,
33
+ organization: { uid: workspace.uuid, source },
37
34
  },
38
- ];
35
+ });
36
+ res.push({
37
+ model: 'vcs_Repository',
38
+ record: {
39
+ name: repository.slug.toLowerCase(),
40
+ fullName: repository.fullName,
41
+ description,
42
+ private: repository.isPrivate,
43
+ language: (_c = repository.language) !== null && _c !== void 0 ? _c : null,
44
+ size: BigInt(repository.size),
45
+ htmlUrl: (_d = repository === null || repository === void 0 ? void 0 : repository.links) === null || _d === void 0 ? void 0 : _d.htmlUrl,
46
+ createdAt: faros_feeds_sdk_1.Utils.toDate(repository.createdOn),
47
+ updatedAt: faros_feeds_sdk_1.Utils.toDate(repository.updatedOn),
48
+ mainBranch: (_e = repository.mainBranch) === null || _e === void 0 ? void 0 : _e.name,
49
+ organization: { uid: workspace.uuid, source },
50
+ },
51
+ });
52
+ return res;
39
53
  }
40
54
  }
41
55
  exports.Repositories = Repositories;
@@ -19,7 +19,7 @@ export declare class ConverterRegistry {
19
19
  */
20
20
  static getConverter(streamName: StreamName, onLoadError?: (err: Error) => void): Converter | undefined;
21
21
  /**
22
- * Add a convertor to the registory.
22
+ * Add a convertor to the registry.
23
23
  */
24
24
  static addConverter(converter: Converter): void;
25
25
  }
@@ -53,7 +53,7 @@ class ConverterRegistry {
53
53
  }
54
54
  }
55
55
  /**
56
- * Add a convertor to the registory.
56
+ * Add a convertor to the registry.
57
57
  */
58
58
  static addConverter(converter) {
59
59
  const name = converter.streamName.asString;
@@ -1,8 +1,8 @@
1
- import { AirbyteConfig, AirbyteRecord } from 'faros-airbyte-cdk';
1
+ import { AirbyteConfig, AirbyteLogger, AirbyteRecord } from 'faros-airbyte-cdk';
2
2
  import { FarosClient } from 'faros-feeds-sdk';
3
3
  import { Dictionary } from 'ts-essentials';
4
4
  /** Airbyte -> Faros record converter */
5
- export declare abstract class Converter {
5
+ export declare abstract class ConverterTyped<R> {
6
6
  private stream;
7
7
  /** Name of the source system that records were fetched from (e.g. GitHub) **/
8
8
  abstract readonly source: string;
@@ -14,14 +14,17 @@ export declare abstract class Converter {
14
14
  /** All the record models produced by converter */
15
15
  abstract get destinationModels(): ReadonlyArray<DestinationModel>;
16
16
  /** Function converts an input Airbyte record to Faros destination canonical record */
17
- abstract convert(record: AirbyteRecord, ctx: StreamContext): Promise<ReadonlyArray<DestinationRecord>>;
17
+ abstract convert(record: AirbyteRecord, ctx: StreamContext): Promise<ReadonlyArray<DestinationRecordTyped<R>>>;
18
+ }
19
+ export declare abstract class Converter extends ConverterTyped<Dictionary<any>> {
18
20
  }
19
21
  export declare function parseObjectConfig<T>(obj: any, name: string): T | undefined;
20
22
  /** Stream context to store records by stream and other helpers */
21
23
  export declare class StreamContext {
24
+ readonly logger: AirbyteLogger;
22
25
  readonly config: AirbyteConfig;
23
26
  readonly farosClient?: FarosClient;
24
- constructor(config: AirbyteConfig, farosClient?: FarosClient);
27
+ constructor(logger: AirbyteLogger, config: AirbyteConfig, farosClient?: FarosClient);
25
28
  private readonly recordsByStreamName;
26
29
  getAll(streamName: string): Dictionary<AirbyteRecord>;
27
30
  get(streamName: string, id: string): AirbyteRecord | undefined;
@@ -55,9 +58,10 @@ export declare class StreamName {
55
58
  * }
56
59
  * }
57
60
  */
58
- export declare type DestinationRecord = {
61
+ export declare type DestinationRecordTyped<R extends Dictionary<any>> = {
59
62
  readonly model: DestinationModel;
60
- readonly record: Dictionary<any>;
63
+ readonly record: R;
61
64
  };
65
+ export declare type DestinationRecord = DestinationRecordTyped<Dictionary<any>>;
62
66
  /** Faros destination model name, e.g identity_Identity, vcs_Commit */
63
67
  export declare type DestinationModel = string;
@@ -3,12 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.StreamName = exports.StreamNameSeparator = exports.StreamContext = exports.parseObjectConfig = exports.Converter = void 0;
6
+ exports.StreamName = exports.StreamNameSeparator = exports.StreamContext = exports.parseObjectConfig = exports.Converter = exports.ConverterTyped = void 0;
7
7
  const lodash_1 = require("lodash");
8
8
  const object_sizeof_1 = __importDefault(require("object-sizeof"));
9
9
  const verror_1 = require("verror");
10
10
  /** Airbyte -> Faros record converter */
11
- class Converter {
11
+ class ConverterTyped {
12
12
  /** Input stream supported by converter */
13
13
  get streamName() {
14
14
  if (this.stream)
@@ -23,6 +23,9 @@ class Converter {
23
23
  return [];
24
24
  }
25
25
  }
26
+ exports.ConverterTyped = ConverterTyped;
27
+ class Converter extends ConverterTyped {
28
+ }
26
29
  exports.Converter = Converter;
27
30
  // Helper function for reading object type configurations that
28
31
  // may be inputted as proper JSON via API or stringified JSON via Airbyte UI
@@ -44,7 +47,8 @@ function parseObjectConfig(obj, name) {
44
47
  exports.parseObjectConfig = parseObjectConfig;
45
48
  /** Stream context to store records by stream and other helpers */
46
49
  class StreamContext {
47
- constructor(config, farosClient) {
50
+ constructor(logger, config, farosClient) {
51
+ this.logger = logger;
48
52
  this.config = config;
49
53
  this.farosClient = farosClient;
50
54
  this.recordsByStreamName = {};
@@ -0,0 +1,20 @@
1
+ import { AirbyteRecord } from 'faros-airbyte-cdk';
2
+ import { Converter, StreamContext } from '../converter';
3
+ declare type ApplicationMapping = Record<string, {
4
+ name: string;
5
+ platform?: string;
6
+ }>;
7
+ interface FirehHydrantConfig {
8
+ application_mapping?: ApplicationMapping;
9
+ max_description_length?: number;
10
+ }
11
+ /** Firehydrant converter base */
12
+ export declare abstract class FireHydrantConverter extends Converter {
13
+ source: string;
14
+ /** Almost every Firehydrant record have id property */
15
+ id(record: AirbyteRecord): any;
16
+ protected firehydrantConfig(ctx: StreamContext): FirehHydrantConfig;
17
+ protected maxDescriptionLength(ctx: StreamContext): number;
18
+ protected applicationMapping(ctx: StreamContext): ApplicationMapping;
19
+ }
20
+ export {};
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FireHydrantConverter = void 0;
4
+ const converter_1 = require("../converter");
5
+ const MAX_DESCRIPTION_LENGTH = 1000;
6
+ /** Firehydrant converter base */
7
+ class FireHydrantConverter extends converter_1.Converter {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.source = 'FireHydrant';
11
+ }
12
+ /** Almost every Firehydrant record have id property */
13
+ id(record) {
14
+ var _a, _b;
15
+ return (_b = (_a = record === null || record === void 0 ? void 0 : record.record) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.id;
16
+ }
17
+ firehydrantConfig(ctx) {
18
+ var _a, _b;
19
+ return (_b = (_a = ctx.config.source_specific_configs) === null || _a === void 0 ? void 0 : _a.firehydrant) !== null && _b !== void 0 ? _b : {};
20
+ }
21
+ maxDescriptionLength(ctx) {
22
+ var _a;
23
+ return ((_a = this.firehydrantConfig(ctx).max_description_length) !== null && _a !== void 0 ? _a : MAX_DESCRIPTION_LENGTH);
24
+ }
25
+ applicationMapping(ctx) {
26
+ var _a, _b;
27
+ return ((_b = (0, converter_1.parseObjectConfig)((_a = this.firehydrantConfig(ctx)) === null || _a === void 0 ? void 0 : _a.application_mapping, 'Application Mapping')) !== null && _b !== void 0 ? _b : {});
28
+ }
29
+ }
30
+ exports.FireHydrantConverter = FireHydrantConverter;
@@ -0,0 +1,13 @@
1
+ import { AirbyteRecord } from 'faros-airbyte-cdk';
2
+ import { DestinationModel, DestinationRecord, StreamContext } from '../converter';
3
+ import { FireHydrantConverter } from './common';
4
+ export declare class Incidents extends FireHydrantConverter {
5
+ readonly destinationModels: ReadonlyArray<DestinationModel>;
6
+ private seenTags;
7
+ convert(record: AirbyteRecord, ctx: StreamContext): Promise<ReadonlyArray<DestinationRecord>>;
8
+ private getTaskDestinationRecord;
9
+ private getPriority;
10
+ private getSeverity;
11
+ private getIncidentStatus;
12
+ private getTaskStatus;
13
+ }
@@ -0,0 +1,235 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Incidents = void 0;
4
+ const faros_feeds_sdk_1 = require("faros-feeds-sdk");
5
+ const common_1 = require("./common");
6
+ const models_1 = require("./models");
7
+ class Incidents extends common_1.FireHydrantConverter {
8
+ constructor() {
9
+ super(...arguments);
10
+ this.destinationModels = [
11
+ 'compute_Application',
12
+ 'ims_Incident',
13
+ 'ims_IncidentApplicationImpact',
14
+ 'ims_IncidentAssignment',
15
+ 'ims_IncidentEvent',
16
+ 'ims_IncidentTag',
17
+ 'ims_IncidentTasks',
18
+ 'ims_Label',
19
+ 'tms_Task',
20
+ ];
21
+ this.seenTags = new Set();
22
+ }
23
+ async convert(record, ctx) {
24
+ var _a, _b;
25
+ const source = this.streamName.source;
26
+ const incident = record.record.data;
27
+ const res = [];
28
+ const maxDescriptionLength = this.maxDescriptionLength(ctx);
29
+ const applicationMapping = this.applicationMapping(ctx);
30
+ const incidentRef = { uid: incident.id, source };
31
+ const createdAt = faros_feeds_sdk_1.Utils.toDate(incident.created_at);
32
+ const updatedAt = incident.events
33
+ ? faros_feeds_sdk_1.Utils.toDate(incident.events[incident.events.length - 1].occurred_at)
34
+ : createdAt;
35
+ let acknowledgedAt = undefined;
36
+ let resolvedAt = undefined;
37
+ for (const event of incident.events) {
38
+ const eventType = {
39
+ category: models_1.IncidentEventTypeCategory.Created,
40
+ detail: event.type,
41
+ };
42
+ const occurredAt = faros_feeds_sdk_1.Utils.toDate(event.occurred_at);
43
+ if (!resolvedAt &&
44
+ event.data.current_milestone === models_1.FirehydrantIncidentMilestone.resolved) {
45
+ resolvedAt = occurredAt;
46
+ eventType.category = models_1.IncidentEventTypeCategory.Resolved;
47
+ }
48
+ if (!acknowledgedAt &&
49
+ event.data.current_milestone ===
50
+ models_1.FirehydrantIncidentMilestone.acknowledged) {
51
+ acknowledgedAt = occurredAt;
52
+ eventType.category = models_1.IncidentEventTypeCategory.Acknowledged;
53
+ }
54
+ res.push({
55
+ model: 'ims_IncidentEvent',
56
+ record: {
57
+ uid: event.id,
58
+ type: eventType,
59
+ incident: incidentRef,
60
+ detail: JSON.stringify(event.data),
61
+ createdAt: occurredAt,
62
+ },
63
+ });
64
+ if (event.data.operation === 'created' && event.data.ticket) {
65
+ const ticket = event.data.ticket;
66
+ // TODO
67
+ res.push(this.getTaskDestinationRecord(ticket, source, maxDescriptionLength, occurredAt));
68
+ const task = { uid: ticket.id, source };
69
+ res.push({
70
+ model: 'ims_IncidentTasks',
71
+ record: {
72
+ task,
73
+ incident: incidentRef,
74
+ },
75
+ });
76
+ }
77
+ }
78
+ res.push({
79
+ model: 'ims_Incident',
80
+ record: {
81
+ ...incidentRef,
82
+ title: incident.name,
83
+ description: (_a = incident.description) === null || _a === void 0 ? void 0 : _a.substring(0, maxDescriptionLength),
84
+ url: incident.incident_url,
85
+ createdAt,
86
+ updatedAt,
87
+ acknowledgedAt,
88
+ resolvedAt,
89
+ priority: this.getPriority(incident.priority),
90
+ severity: this.getSeverity(incident.severity),
91
+ status: this.getIncidentStatus(incident.current_milestone),
92
+ },
93
+ });
94
+ for (const service of incident.services) {
95
+ if (service.name in applicationMapping &&
96
+ applicationMapping[service.name].name) {
97
+ const mappedApp = applicationMapping[service.name];
98
+ const application = {
99
+ name: mappedApp.name,
100
+ platform: (_b = mappedApp.platform) !== null && _b !== void 0 ? _b : '',
101
+ };
102
+ res.push({ model: 'compute_Application', record: application });
103
+ res.push({
104
+ model: 'ims_IncidentApplicationImpact',
105
+ record: {
106
+ incident: incidentRef,
107
+ application,
108
+ },
109
+ });
110
+ }
111
+ }
112
+ for (const assignment of incident.role_assignments) {
113
+ const assignee = { uid: assignment.user.id, source };
114
+ res.push({
115
+ model: 'ims_IncidentAssignment',
116
+ record: {
117
+ assignee,
118
+ incident: incidentRef,
119
+ },
120
+ });
121
+ }
122
+ for (const tag of incident.tag_list) {
123
+ if (!this.seenTags.has(tag)) {
124
+ this.seenTags.add(tag);
125
+ res.push({
126
+ model: 'ims_Label',
127
+ record: {
128
+ name: tag,
129
+ },
130
+ });
131
+ }
132
+ res.push({
133
+ model: 'ims_IncidentTag',
134
+ record: {
135
+ label: { name: tag },
136
+ incident: incidentRef,
137
+ },
138
+ });
139
+ }
140
+ return res;
141
+ }
142
+ getTaskDestinationRecord(ticket, source, maxDescriptionLength, occurredAt) {
143
+ var _a;
144
+ return {
145
+ model: 'tms_Task',
146
+ record: {
147
+ uid: ticket.id,
148
+ name: ticket.summary,
149
+ description: (_a = ticket.description) === null || _a === void 0 ? void 0 : _a.substring(0, maxDescriptionLength),
150
+ source,
151
+ url: undefined,
152
+ type: {
153
+ detail: ticket.type,
154
+ category: 'Task',
155
+ },
156
+ priority: undefined,
157
+ status: this.getTaskStatus(ticket.state),
158
+ points: 0,
159
+ additionalFields: [],
160
+ createdAt: occurredAt,
161
+ updatedAt: occurredAt,
162
+ statusChangedAt: undefined,
163
+ statusChangelog: undefined,
164
+ parent: undefined,
165
+ creator: { uid: ticket.created_by.id, source },
166
+ epic: undefined,
167
+ sprint: undefined,
168
+ },
169
+ };
170
+ }
171
+ getPriority(priority) {
172
+ const detail = priority;
173
+ switch (priority) {
174
+ case models_1.FirehydrantIncidentPriority.P1:
175
+ return { category: models_1.IncidentPriorityCategory.Critical, detail };
176
+ case models_1.FirehydrantIncidentPriority.P2:
177
+ return { category: models_1.IncidentPriorityCategory.High, detail };
178
+ case models_1.FirehydrantIncidentPriority.P3:
179
+ return { category: models_1.IncidentPriorityCategory.Medium, detail };
180
+ case models_1.FirehydrantIncidentPriority.P4:
181
+ return { category: models_1.IncidentPriorityCategory.Low, detail };
182
+ default:
183
+ return { category: models_1.IncidentPriorityCategory.Custom, detail };
184
+ }
185
+ }
186
+ getSeverity(severity) {
187
+ const detail = severity;
188
+ switch (severity) {
189
+ case models_1.FirehydrantIncidentSeverity.SEV1:
190
+ return { category: models_1.IncidentSeverityCategory.Sev1, detail };
191
+ case models_1.FirehydrantIncidentSeverity.SEV2:
192
+ return { category: models_1.IncidentSeverityCategory.Sev2, detail };
193
+ case models_1.FirehydrantIncidentSeverity.SEV3:
194
+ return { category: models_1.IncidentSeverityCategory.Sev3, detail };
195
+ case models_1.FirehydrantIncidentSeverity.SEV4:
196
+ return { category: models_1.IncidentSeverityCategory.Sev4, detail };
197
+ case models_1.FirehydrantIncidentSeverity.SEV5:
198
+ return { category: models_1.IncidentSeverityCategory.Sev5, detail };
199
+ default:
200
+ return { category: models_1.IncidentSeverityCategory.Custom, detail };
201
+ }
202
+ }
203
+ //https://support.firehydrant.io/hc/en-us/articles/4403969187604-Incident-Milestones
204
+ getIncidentStatus(milestone) {
205
+ const detail = milestone;
206
+ switch (milestone) {
207
+ case models_1.FirehydrantIncidentMilestone.started:
208
+ return { category: models_1.IncidentStatusCategory.Investigating, detail };
209
+ case models_1.FirehydrantIncidentMilestone.detected:
210
+ return { category: models_1.IncidentStatusCategory.Identified, detail };
211
+ case models_1.FirehydrantIncidentMilestone.acknowledged:
212
+ case models_1.FirehydrantIncidentMilestone.firstaction:
213
+ return { category: models_1.IncidentStatusCategory.Monitoring, detail };
214
+ case models_1.FirehydrantIncidentMilestone.mitigated:
215
+ case models_1.FirehydrantIncidentMilestone.resolved:
216
+ return { category: models_1.IncidentStatusCategory.Resolved, detail };
217
+ default:
218
+ return { category: models_1.IncidentStatusCategory.Custom, detail };
219
+ }
220
+ }
221
+ getTaskStatus(status) {
222
+ const detail = status;
223
+ switch (status) {
224
+ case models_1.IncidentTicketState.open:
225
+ return { category: models_1.TaskStatusCategory.Todo, detail };
226
+ case models_1.IncidentTicketState.in_progress:
227
+ return { category: models_1.TaskStatusCategory.InProgress, detail };
228
+ case models_1.IncidentTicketState.done:
229
+ return { category: models_1.TaskStatusCategory.Done, detail };
230
+ default:
231
+ return { category: models_1.TaskStatusCategory.Custom, detail };
232
+ }
233
+ }
234
+ }
235
+ exports.Incidents = Incidents;