Skip to content

Commit fdb90ad

Browse files
Roma-Kyrnistovbinm
andauthored
Add Asana converters for Faros Destination (#116)
* asana begin * identity file error * add asana destination * FAI-441 - Implement Phabricator check connection + streams (#105) * Cache repostories in Phabricator streams (#106) * Add Jenkins converters (#95) * FAI-441 - Added revisions & users streams to Phabricator source + bump version (#113) * FA-441 - Added projects stream to Phabricator + cleanup (#114) * add tests; fix story creator; update task stream * remove github comment * don't create user on tasks and stories * fix wroting records quantity * add tags; save TMS TaskBords on Task * use null to undefined values; rename interfaces * Fix Jenkins converter's url (#115) * update jenkins url; remove lodash * not update job's url Co-authored-by: Matthew Tovbin <tovbinm@users.noreply.github.com>
1 parent 531275c commit fdb90ad

File tree

16 files changed

+818
-0
lines changed

16 files changed

+818
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import {AirbyteRecord} from 'faros-airbyte-cdk/src/protocol';
2+
3+
import {Converter, DestinationRecord} from '../converter';
4+
5+
export interface AsanaProject {
6+
gid: string;
7+
}
8+
9+
export interface AsanaSection {
10+
gid: string;
11+
name: string;
12+
project?: AsanaProject;
13+
}
14+
15+
export interface AsanaUser {
16+
gid: string;
17+
name?: string;
18+
email?: string;
19+
}
20+
21+
interface TmsTaskType {
22+
category: TmsTaskCategory;
23+
detail: string;
24+
}
25+
26+
enum TmsTaskCategory {
27+
Bug = 'Bug',
28+
Custom = 'Custom',
29+
Story = 'Story',
30+
Task = 'Task',
31+
}
32+
33+
/** Common functions shares across Asana converters */
34+
export class AsanaCommon {
35+
// Max length for free-form description text fields such as issue body
36+
static readonly MAX_DESCRIPTION_LENGTH = 1000;
37+
38+
static toTmsTaskType(type: string): TmsTaskType {
39+
const detail = type.toLowerCase();
40+
switch (detail) {
41+
case 'bug':
42+
return {category: TmsTaskCategory.Bug, detail};
43+
case 'story':
44+
return {category: TmsTaskCategory.Story, detail};
45+
case 'task':
46+
return {category: TmsTaskCategory.Task, detail};
47+
default:
48+
return {category: TmsTaskCategory.Custom, detail};
49+
}
50+
}
51+
52+
static tms_User(user: AsanaUser, source: string): DestinationRecord {
53+
return {
54+
model: 'tms_User',
55+
record: {
56+
uid: user.gid,
57+
name: user.name || null,
58+
emailAddress: user.email || null,
59+
source,
60+
},
61+
};
62+
}
63+
64+
static tms_TaskBoard(section: AsanaSection, source: string): DestinationRecord {
65+
return {
66+
model: 'tms_TaskBoard',
67+
record: {
68+
uid: section.gid,
69+
name: section.name,
70+
source,
71+
},
72+
};
73+
}
74+
}
75+
76+
/** Asana converter base */
77+
export abstract class AsanaConverter extends Converter {
78+
/** All Asana records should have id property */
79+
id(record: AirbyteRecord): any {
80+
return record?.record?.data?.gid;
81+
}
82+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {AirbyteRecord} from 'faros-airbyte-cdk';
2+
import {Utils} from 'faros-feeds-sdk'
3+
4+
import {DestinationModel, DestinationRecord, StreamContext} from '../converter';
5+
import {AsanaCommon, AsanaConverter} from './common';
6+
7+
export class AsanaProjects extends AsanaConverter {
8+
readonly destinationModels: ReadonlyArray<DestinationModel> = ['tms_Project'];
9+
10+
convert(
11+
record: AirbyteRecord,
12+
ctx: StreamContext
13+
): ReadonlyArray<DestinationRecord> {
14+
const source = this.streamName.source;
15+
const project = record.record.data;
16+
17+
const tmsProject: DestinationRecord = {
18+
model: 'tms_Project',
19+
record: {
20+
uid: project.gid,
21+
name: project.name,
22+
description: project.notes?.substring(
23+
0,
24+
AsanaCommon.MAX_DESCRIPTION_LENGTH
25+
),
26+
createdAt: Utils.toDate(project.created_at),
27+
updatedAt: Utils.toDate(project.modified_at),
28+
source,
29+
}
30+
}
31+
32+
return [tmsProject];
33+
}
34+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import {AirbyteRecord} from 'faros-airbyte-cdk';
2+
3+
import {DestinationModel, DestinationRecord, StreamContext} from '../converter';
4+
import {AsanaCommon, AsanaConverter, AsanaSection} from './common';
5+
6+
export class AsanaSections extends AsanaConverter {
7+
readonly destinationModels: ReadonlyArray<DestinationModel> = [
8+
'tms_TaskBoard',
9+
'tms_TaskBoardProjectRelationship',
10+
];
11+
12+
convert(
13+
record: AirbyteRecord,
14+
ctx: StreamContext
15+
): ReadonlyArray<DestinationRecord> {
16+
const res: DestinationRecord[] = [];
17+
const source = this.streamName.source;
18+
const section = record.record.data as AsanaSection;
19+
20+
res.push(AsanaCommon.tms_TaskBoard(section, source));
21+
res.push({
22+
model: 'tms_TaskBoardProjectRelationship',
23+
record: {
24+
board: {uid: section.gid, source},
25+
project: section.project ? {uid: section.project.gid, source} : null,
26+
},
27+
});
28+
29+
return res;
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import {AirbyteRecord} from 'faros-airbyte-cdk';
2+
import {Utils} from 'faros-feeds-sdk';
3+
4+
import {DestinationModel, DestinationRecord, StreamContext} from '../converter';
5+
import {AsanaCommon, AsanaConverter} from './common';
6+
7+
export class AsanaStories extends AsanaConverter {
8+
readonly destinationModels: ReadonlyArray<DestinationModel> = [
9+
'tms_Task',
10+
];
11+
12+
convert(
13+
record: AirbyteRecord,
14+
ctx: StreamContext
15+
): ReadonlyArray<DestinationRecord> {
16+
const res: DestinationRecord[] = [];
17+
const source = this.streamName.source;
18+
const story = record.record.data;
19+
20+
res.push({
21+
model: 'tms_Task',
22+
record: {
23+
uid: story.gid,
24+
name: story.source || null,
25+
description: story.text?.substring(
26+
0,
27+
AsanaCommon.MAX_DESCRIPTION_LENGTH
28+
),
29+
type: AsanaCommon.toTmsTaskType(story.resource_type),
30+
createdAt: Utils.toDate(story.created_at),
31+
updatedAt: Utils.toDate(story.created_at),
32+
creator: {uid: story.created_by.gid, source},
33+
source,
34+
},
35+
});
36+
37+
return res;
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import {AirbyteRecord} from 'faros-airbyte-cdk';
2+
3+
import {DestinationModel, DestinationRecord, StreamContext} from '../converter';
4+
import {AsanaConverter} from './common';
5+
6+
export class AsanaTags extends AsanaConverter {
7+
readonly destinationModels: ReadonlyArray<DestinationModel> = ['tms_Label'];
8+
9+
convert(
10+
record: AirbyteRecord,
11+
ctx: StreamContext
12+
): ReadonlyArray<DestinationRecord> {
13+
const tag = record.record.data;
14+
15+
return [
16+
{
17+
model: 'tms_Label',
18+
record: {
19+
name: tag.name,
20+
},
21+
},
22+
];
23+
}
24+
}

0 commit comments

Comments
 (0)