| 262 | } |
| 263 | |
| 264 | function credential(http: HttpClient.HttpClient, server: string, token: typeof Token.Type) { |
| 265 | return Effect.gen(function* () { |
| 266 | const [user, orgs] = yield* Effect.all( |
| 267 | [ |
| 268 | get(http, `${server}/api/user`, token.access_token, User), |
| 269 | get(http, `${server}/api/orgs`, token.access_token, Schema.Array(Org)), |
| 270 | ], |
| 271 | { concurrency: 2 }, |
| 272 | ) |
| 273 | const org = orgs.toSorted((a, b) => a.name.localeCompare(b.name) || a.id.localeCompare(b.id))[0] |
| 274 | return Credential.OAuth.make({ |
| 275 | type: "oauth" as const, |
| 276 | methodID, |
| 277 | access: token.access_token, |
| 278 | refresh: token.refresh_token, |
| 279 | expires: Date.now() + token.expires_in * 1000, |
| 280 | metadata: { |
| 281 | server, |
| 282 | accountID: user.id, |
| 283 | email: user.email, |
| 284 | orgID: org?.id, |
| 285 | orgName: org?.name, |
| 286 | }, |
| 287 | }) |
| 288 | }) |
| 289 | } |
| 290 | |
| 291 | function get<S extends Schema.Top>(http: HttpClient.HttpClient, url: string, token: string, schema: S) { |
| 292 | return HttpClient.filterStatusOk(http) |