(
accessToken: string,
tierId: string,
projectId?: string,
attempts = 10,
delayMs = 5000,
)
| 572 | } |
| 573 | |
| 574 | async function onboardManagedProject( |
| 575 | accessToken: string, |
| 576 | tierId: string, |
| 577 | projectId?: string, |
| 578 | attempts = 10, |
| 579 | delayMs = 5000, |
| 580 | ): Promise<string | undefined> { |
| 581 | const metadata: Record<string, string> = { |
| 582 | ideType: "IDE_UNSPECIFIED", |
| 583 | platform: "PLATFORM_UNSPECIFIED", |
| 584 | pluginType: "GEMINI", |
| 585 | } |
| 586 | if (projectId) { |
| 587 | metadata.duetProject = projectId |
| 588 | } |
| 589 | |
| 590 | const requestBody: Record<string, unknown> = { |
| 591 | tierId, |
| 592 | metadata, |
| 593 | } |
| 594 | |
| 595 | if (tierId !== "FREE" && !projectId) { |
| 596 | throw new Error( |
| 597 | "Gemini requires a Google Cloud project for non-free tiers. Set GOOGLE_CLOUD_PROJECT.", |
| 598 | ) |
| 599 | } |
| 600 | |
| 601 | if (projectId) { |
| 602 | requestBody.cloudaicompanionProject = projectId |
| 603 | } |
| 604 | |
| 605 | for (let attempt = 0; attempt < attempts; attempt += 1) { |
| 606 | try { |
| 607 | const response = await fetch("https://cloudcode-pa.googleapis.com/v1internal:onboardUser", { |
| 608 | method: "POST", |
| 609 | headers: { |
| 610 | "Content-Type": "application/json", |
| 611 | Authorization: `Bearer ${accessToken}`, |
| 612 | ...codeAssistHeaders, |
| 613 | }, |
| 614 | body: JSON.stringify(requestBody), |
| 615 | }) |
| 616 | |
| 617 | if (!response.ok) { |
| 618 | return undefined |
| 619 | } |
| 620 | |
| 621 | const payload = await response.json() |
| 622 | const managedProjectId = payload?.response?.cloudaicompanionProject?.id |
| 623 | if (payload?.done && managedProjectId) { |
| 624 | return managedProjectId |
| 625 | } |
| 626 | if (payload?.done && projectId) { |
| 627 | return projectId |
| 628 | } |
| 629 | } catch (error) { |
| 630 | log.error("google oauth onboard managed project failed", { error }) |
| 631 | return undefined |
no test coverage detected