-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathteam-member.ts
More file actions
130 lines (124 loc) · 3.77 KB
/
team-member.ts
File metadata and controls
130 lines (124 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import {GitHub} from '../github.js'
import {Id, StateSchema} from '../terraform/schema.js'
import {Path, ConfigSchema} from '../yaml/schema.js'
import {Resource} from './resource.js'
import {Team} from './team.js'
export enum Role {
Maintainer = 'maintainer',
Member = 'member'
}
export class TeamMember extends String implements Resource {
static StateType = 'github_team_membership' as const
static async FromGitHub(_members: TeamMember[]): Promise<[Id, TeamMember][]> {
const github = await GitHub.getGitHub()
const invitations = await github.listTeamInvitations()
const members = await github.listTeamMembers()
const result: [Id, TeamMember][] = []
for (const invitation of invitations) {
if (invitation.invitation.login === null) {
throw new Error(`Invitation ${invitation.invitation.id} has no login`)
}
const member = _members.find(
m =>
m.team === invitation.team.name &&
m.username === invitation.invitation.login
)
result.push([
`${invitation.team.id}:${invitation.invitation.login}`,
new TeamMember(
invitation.team.name,
invitation.invitation.login,
member?.role || Role.Member
)
])
}
for (const member of members) {
result.push([
`${member.team.id}:${member.member.login}`,
new TeamMember(
member.team.name,
member.member.login,
member.membership.role as Role
)
])
}
return result
}
static FromState(state: StateSchema): TeamMember[] {
const members: TeamMember[] = []
if (state.values?.root_module?.resources !== undefined) {
for (const resource of state.values.root_module.resources) {
if (
resource.type === TeamMember.StateType &&
resource.mode === 'managed'
) {
const teamIndex = resource.index.split(`:`).slice(0, -1).join(`:`)
const team = state.values.root_module.resources.find(
r =>
r.mode === 'managed' &&
r.type === Team.StateType &&
r.index === teamIndex
)
console.log(teamIndex, team)
members.push(
new TeamMember(
team !== undefined && team.type === Team.StateType
? team.values.name
: teamIndex,
resource.values.username,
resource.values.role as Role
)
)
}
}
}
return members
}
static FromConfig(config: ConfigSchema): TeamMember[] {
const members: TeamMember[] = []
if (config.teams !== undefined) {
for (const [team_name, team] of Object.entries(config.teams)) {
if (team.members !== undefined) {
for (const [role, usernames] of Object.entries(team.members)) {
for (const username of usernames ?? []) {
members.push(new TeamMember(team_name, username, role as Role))
}
}
}
}
}
return members
}
constructor(team: string, username: string, role: Role) {
super(username)
this._team = team
this._username = username
this._role = role
}
private _team: string
get team(): string {
return this._team
}
private _username: string
get username(): string {
return this._username
}
private _role: Role
get role(): Role {
return this._role
}
getSchemaPath(schema: ConfigSchema): Path {
const members = schema.teams?.[this.team]?.members?.[this.role] || []
const index = members.indexOf(this.username)
return [
'teams',
this.team,
'members',
this.role,
index === -1 ? members.length : index
]
}
getStateAddress(): string {
return `${TeamMember.StateType}.this["${this.team}:${this.username}"]`
}
}