-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
141 lines (138 loc) · 4.79 KB
/
index.js
File metadata and controls
141 lines (138 loc) · 4.79 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
131
132
133
134
135
136
137
138
139
140
141
const configDefaults = {
apiHost: 'app.rightbrain.ai',
authHost: 'oauth.rightbrain.ai',
clientID: null,
clientSecret: null,
}
function NewTasksClient(userConfig) {
config = {...configDefaults, ...userConfig}
authClient = new AuthClient(config.authHost, config.clientID, config.clientSecret)
return new TasksClient(authClient, config.apiHost)
}
class AuthClient {
constructor(authHost, clientID, clientSecret) {
this.authHost = authHost
this.clientID = clientID
this.clientSecret = clientSecret
}
async CreateToken() {
const res = await fetch(`https://${this.authHost}/oauth2/token`, {
method: 'POST',
headers: {
Authorization: `Basic ${this.GetBasicAuthorizationHeader(this.clientID, this.clientSecret)}`
},
body: this.GetFormDataWithGrantType('client_credentials')
})
if (res.status !== 200) {
throw new Error(
`cannot create token, expected 200 but got ${res.status}: ${res.statusText}`
)
}
const data = await res.json()
if (!data.access_token) {
throw new Error(
`cannot create token, expected response to contain access token`
)
}
return data.access_token
}
GetBasicAuthorizationHeader(clientID, clientSecret) {
return btoa(`${clientID}:${clientSecret}`)
}
GetFormDataWithGrantType(grantType) {
const formData = new FormData()
formData.append('grant_type', grantType)
return formData
}
}
class TasksClient {
constructor(authClient, apiHost) {
this.authClient = authClient
this.apiHost = apiHost
}
async Create(definition) {
const accessToken = await this.authClient.CreateToken()
const response = await fetch(await this.getTaskCreateURL(accessToken), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${accessToken}`
},
body: JSON.stringify(definition)
})
if (response.status !== 200) {
throw new Error(
`Error creating Task, expected status code of 200, but got ${response.status}: ${response.statusText}`
)
}
return await response.json()
}
async Run(taskID, taskInput, taskRevision) {
const data = JSON.stringify(taskInput)
this.assertTaskInputSize(data)
const accessToken = await this.authClient.CreateToken()
const response = await fetch(await this.getTaskRunURL(accessToken, taskID, taskRevision), {
method: 'POST',
headers: {
Authorization: `Bearer ${accessToken}`
},
body: this.getTaskInputFormData(data)
})
if (response.status !== 200) {
throw new Error(
`Error running Task, expected status code of 200, but got ${response.status}: ${response.statusText}`
)
}
return await response.json()
}
async getTaskCreateURL(accessToken) {
const clientDetails = await this.getClientDetails(accessToken)
return `https://${this.apiHost}/api/v1/org/${clientDetails.org_id}/project/${clientDetails.project_id}/task`
}
async getTaskRunURL(accessToken, taskID, taskRevision) {
const clientDetails = await this.getClientDetails(accessToken)
let url = `https://${this.apiHost}/api/v1/org/${clientDetails.org_id}/project/${clientDetails.project_id}/task/${taskID}/run`
if (taskRevision) {
url += `?revision=${taskRevision}`
}
return url
}
assertTaskInputSize(taskInput) {
if (taskInput.length > 128000) {
throw new Error(`Error running task, max task input is 128,000 but input was ${taskInput.length}`)
}
}
getTaskInputFormData(taskInput) {
const formData = new FormData()
formData.append('task_input', taskInput)
return formData
}
async getClientDetails(accessToken) {
if (!accessToken) {
throw new Error(
`Error running task, cannot get client details, expected access token to not be empty`
)
}
const res = await fetch(`https://${this.apiHost}/api/v1/whoami`, {
method: 'GET',
headers: {
Authorization: `Bearer ${accessToken}`
}
})
if (res.status !== 200) {
throw new Error(
`Error running task, cannot get client details, expected 200 but got ${res.status}: ${res.statusText}`
)
}
const details = await res.json()
if (!details.client) {
throw new Error(
`Error running task, cannot get client details, expected response to contain client details`
)
}
return details.client
}
}
module.exports = {
NewTasksClient,
}