From c0ad00bd6b5d23c8d2d58671b081307268bf1bc8 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:40:10 +0000 Subject: [PATCH 1/6] Initial plan From f61b4acfd3d0da618df00aa2d61ee6527b42de37 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:43:50 +0000 Subject: [PATCH 2/6] Initial analysis and plan for enterprise type support in TEAMS tab Co-authored-by: liguori <8238828+liguori@users.noreply.github.com> --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index bef656e1..6c33ef92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,7 @@ "nuxt-auth-utils": "^0.5.7", "roboto-fontface": "^0.10.0", "undici": ">=7.5.0", - "vue": "*", + "vue": "latest", "vue-chartjs": "^5.3.2", "vuetify": "^3.7.3", "webfontloader": "^1.6.28" From 45be598bc0986889924cc398018228af576a060a Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:52:04 +0000 Subject: [PATCH 3/6] Implement enterprise type support for TEAMS tab Co-authored-by: liguori <8238828+liguori@users.noreply.github.com> --- .env | 5 ++ app/model/Options.ts | 53 ++++++++++++- nuxt.config.ts | 1 + server/api/teams.ts | 93 ++++++++++++++++++----- tests/enterprise-type.spec.ts | 136 ++++++++++++++++++++++++++++++++++ 5 files changed, 267 insertions(+), 21 deletions(-) create mode 100644 tests/enterprise-type.spec.ts diff --git a/.env b/.env index ac0c1a85..fdbf2a3d 100644 --- a/.env +++ b/.env @@ -10,6 +10,11 @@ NUXT_PUBLIC_GITHUB_ORG=octodemo NUXT_PUBLIC_GITHUB_ENT= +# Determines the GitHub Enterprise type for enterprise-scoped deployments. +# Can be 'full' (GitHub Enterprise with full features) or 'copilot-only' (Copilot Business Only). +# This affects how teams are retrieved and team metrics are accessed. +NUXT_PUBLIC_ENTERPRISE_TYPE=copilot-only + # Determines the team name if exists to target API calls. NUXT_PUBLIC_GITHUB_TEAM= diff --git a/app/model/Options.ts b/app/model/Options.ts index 9d64face..e356ac81 100644 --- a/app/model/Options.ts +++ b/app/model/Options.ts @@ -6,6 +6,7 @@ import type { QueryObject } from 'ufo'; import type { RouteLocationNormalizedLoadedGeneric } from 'vue-router'; export type Scope = 'organization' | 'enterprise' | 'team-organization' | 'team-enterprise'; +export type EnterpriseType = 'full' | 'copilot-only'; export interface OptionsData { since?: string; @@ -15,6 +16,7 @@ export interface OptionsData { githubEnt?: string; githubTeam?: string; scope?: Scope; + enterpriseType?: EnterpriseType; excludeHolidays?: boolean; locale?: string; } @@ -25,6 +27,7 @@ export interface RuntimeConfig { githubOrg?: string; githubEnt?: string; githubTeam?: string; + enterpriseType?: string; isDataMocked?: boolean; }; } @@ -54,6 +57,7 @@ export class Options { public githubEnt?: string; public githubTeam?: string; public scope?: Scope; + public enterpriseType?: EnterpriseType; public excludeHolidays?: boolean; public locale?: string; @@ -65,6 +69,7 @@ export class Options { this.githubEnt = data.githubEnt; this.githubTeam = data.githubTeam; this.scope = data.scope; + this.enterpriseType = data.enterpriseType; this.excludeHolidays = data.excludeHolidays; this.locale = data.locale; } @@ -109,6 +114,7 @@ export class Options { if (config.public.githubOrg) options.githubOrg = config.public.githubOrg; if (config.public.githubEnt) options.githubEnt = config.public.githubEnt; if (config.public.githubTeam) options.githubTeam = config.public.githubTeam; + if (config.public.enterpriseType) options.enterpriseType = config.public.enterpriseType as EnterpriseType; } return options; @@ -126,6 +132,7 @@ export class Options { githubEnt: params.get('githubEnt') || undefined, githubTeam: params.get('githubTeam') || undefined, scope: (params.get('scope') as Scope) || undefined, + enterpriseType: (params.get('enterpriseType') as EnterpriseType) || undefined, locale: params.get('locale') || undefined }); @@ -149,6 +156,7 @@ export class Options { githubEnt: query.githubEnt as string | undefined, githubTeam: query.githubTeam as string | undefined, scope: (query.scope as Scope) || undefined, + enterpriseType: (query.enterpriseType as EnterpriseType) || undefined, locale: query.locale as string | undefined }); @@ -184,6 +192,7 @@ export class Options { if (this.githubEnt) params.set('githubEnt', this.githubEnt); if (this.githubTeam) params.set('githubTeam', this.githubTeam); if (this.scope) params.set('scope', this.scope); + if (this.enterpriseType) params.set('enterpriseType', this.enterpriseType); if (this.excludeHolidays) params.set('excludeHolidays', 'true'); if (this.locale) params.set('locale', this.locale); @@ -199,6 +208,7 @@ export class Options { if (this.githubEnt) params.githubEnt = this.githubEnt; if (this.githubTeam) params.githubTeam = this.githubTeam; if (this.scope) params.scope = this.scope; + if (this.enterpriseType) params.enterpriseType = this.enterpriseType; if (this.excludeHolidays) params.excludeHolidays = String(this.excludeHolidays); if (this.locale) params.locale = this.locale; return params; @@ -217,6 +227,7 @@ export class Options { if (this.githubEnt !== undefined) result.githubEnt = this.githubEnt; if (this.githubTeam !== undefined) result.githubTeam = this.githubTeam; if (this.scope !== undefined) result.scope = this.scope; + if (this.enterpriseType !== undefined) result.enterpriseType = this.enterpriseType; if (this.excludeHolidays !== undefined) result.excludeHolidays = this.excludeHolidays; if (this.locale !== undefined) result.locale = this.locale; @@ -242,6 +253,7 @@ export class Options { githubEnt: other.githubEnt ?? this.githubEnt, githubTeam: other.githubTeam ?? this.githubTeam, scope: other.scope ?? this.scope, + enterpriseType: other.enterpriseType ?? this.enterpriseType, excludeHolidays: other.excludeHolidays ?? this.excludeHolidays, locale: other.locale ?? this.locale }); @@ -287,7 +299,23 @@ export class Options { if (!this.githubEnt || !this.githubTeam) { throw new Error('GitHub enterprise and team must be set for team-enterprise scope'); } - url = `${baseUrl}/enterprises/${this.githubEnt}/team/${this.githubTeam}/copilot/metrics`; + // For full enterprises, teams are organization-based, so we need to use org API + // For copilot-only enterprises, we use the enterprise team API + if (this.enterpriseType === 'full') { + // We need to determine which organization the team belongs to + // This will be handled by extracting org name from team slug format "org-name - team-name" + const teamParts = this.githubTeam.split(' - '); + if (teamParts.length >= 2) { + const orgName = teamParts[0]; + const teamName = teamParts[1]; + url = `${baseUrl}/orgs/${orgName}/team/${teamName}/copilot/metrics`; + } else { + throw new Error('Team slug must be in format "org-name - team-name" for full enterprise scope'); + } + } else { + // Default to copilot-only behavior + url = `${baseUrl}/enterprises/${this.githubEnt}/team/${this.githubTeam}/copilot/metrics`; + } break; case 'enterprise': @@ -355,13 +383,34 @@ export class Options { if (!this.githubEnt) { throw new Error('GitHub enterprise must be set for enterprise scope'); } - return `${baseUrl}/enterprises/${this.githubEnt}/teams`; + // For full enterprises, we need to get teams from organizations within the enterprise + // For copilot-only enterprises, we use the enterprise teams API + if (this.enterpriseType === 'full') { + // This will be handled by the teams API to enumerate organizations first + return `${baseUrl}/enterprises/${this.githubEnt}/organizations`; + } else { + // Default to copilot-only behavior (enterprise teams API) + return `${baseUrl}/enterprises/${this.githubEnt}/teams`; + } default: throw new Error(`Invalid scope: ${this.scope}`); } } + /** + * Get the Enterprise Organizations API URL + */ + getEnterpriseOrganizationsApiUrl(): string { + const baseUrl = 'https://api.github.com'; + + if (!this.githubEnt) { + throw new Error('GitHub enterprise must be set'); + } + + return `${baseUrl}/enterprises/${this.githubEnt}/organizations`; + } + /** * Get the Teams API URL based on scope and configuration */ diff --git a/nuxt.config.ts b/nuxt.config.ts index ec5dff8f..60a4f834 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -94,6 +94,7 @@ export default defineNuxtConfig({ githubOrg: '', githubEnt: '', githubTeam: '', + enterpriseType: 'copilot-only', // can be overridden by NUXT_PUBLIC_ENTERPRISE_TYPE environment variable usingGithubAuth: false, version, isPublicApp: false diff --git a/server/api/teams.ts b/server/api/teams.ts index 31591c43..28773aa7 100644 --- a/server/api/teams.ts +++ b/server/api/teams.ts @@ -1,8 +1,9 @@ -import { Options, type Scope } from '@/model/Options' +import { Options, type Scope, type EnterpriseType } from '@/model/Options' import type { H3Event, EventHandlerRequest } from 'h3' interface Team { name: string; slug: string; description: string } interface GitHubTeam { name: string; slug: string; description?: string } +interface GitHubOrganization { login: string; id: number } class TeamsError extends Error { statusCode: number @@ -53,6 +54,7 @@ export async function getTeams(event: H3Event): Promise): Promise { + describe('Options class enterprise type handling', () => { + it('should handle copilot-only enterprise type', () => { + const options = new Options({ + scope: 'enterprise', + githubEnt: 'test-enterprise', + enterpriseType: 'copilot-only' + }) + + expect(options.enterpriseType).toBe('copilot-only') + expect(options.getTeamsApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/teams') + }) + + it('should handle full enterprise type', () => { + const options = new Options({ + scope: 'enterprise', + githubEnt: 'test-enterprise', + enterpriseType: 'full' + }) + + expect(options.enterpriseType).toBe('full') + expect(options.getTeamsApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/organizations') + }) + + it('should default to copilot-only behavior when enterprise type not specified', () => { + const options = new Options({ + scope: 'enterprise', + githubEnt: 'test-enterprise' + }) + + expect(options.getTeamsApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/teams') + }) + + it('should handle team-enterprise scope with copilot-only type', () => { + const options = new Options({ + scope: 'team-enterprise', + githubEnt: 'test-enterprise', + githubTeam: 'test-team', + enterpriseType: 'copilot-only' + }) + + expect(options.getApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/team/test-team/copilot/metrics') + }) + + it('should handle team-enterprise scope with full type', () => { + const options = new Options({ + scope: 'team-enterprise', + githubEnt: 'test-enterprise', + githubTeam: 'org-name - team-name', + enterpriseType: 'full' + }) + + expect(options.getApiUrl()).toBe('https://api.github.com/orgs/org-name/team/team-name/copilot/metrics') + }) + + it('should throw error for invalid team slug format in full enterprise', () => { + const options = new Options({ + scope: 'team-enterprise', + githubEnt: 'test-enterprise', + githubTeam: 'invalid-team-slug', + enterpriseType: 'full' + }) + + expect(() => options.getApiUrl()).toThrow('Team slug must be in format "org-name - team-name" for full enterprise scope') + }) + + it('should include enterprise type in serialization methods', () => { + const options = new Options({ + scope: 'enterprise', + githubEnt: 'test-enterprise', + enterpriseType: 'full' + }) + + const params = options.toParams() + expect(params.enterpriseType).toBe('full') + + const urlParams = options.toURLSearchParams() + expect(urlParams.get('enterpriseType')).toBe('full') + + const obj = options.toObject() + expect(obj.enterpriseType).toBe('full') + }) + + it('should handle enterprise type in fromQuery method', () => { + const options = Options.fromQuery({ + scope: 'enterprise', + githubEnt: 'test-enterprise', + enterpriseType: 'full' + }) + + expect(options.enterpriseType).toBe('full') + }) + + it('should handle enterprise type in fromURLSearchParams method', () => { + const params = new URLSearchParams() + params.set('scope', 'enterprise') + params.set('githubEnt', 'test-enterprise') + params.set('enterpriseType', 'full') + + const options = Options.fromURLSearchParams(params) + expect(options.enterpriseType).toBe('full') + }) + + it('should handle enterprise type in merge method', () => { + const options1 = new Options({ + scope: 'enterprise', + githubEnt: 'test-enterprise', + enterpriseType: 'copilot-only' + }) + + const options2 = new Options({ + enterpriseType: 'full' + }) + + const merged = options1.merge(options2) + expect(merged.enterpriseType).toBe('full') + }) + + it('should handle enterprise organizations API URL', () => { + const options = new Options({ + githubEnt: 'test-enterprise' + }) + + expect(options.getEnterpriseOrganizationsApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/organizations') + }) + + it('should throw error for enterprise organizations API without enterprise', () => { + const options = new Options() + + expect(() => options.getEnterpriseOrganizationsApiUrl()).toThrow('GitHub enterprise must be set') + }) + }) +}) \ No newline at end of file From 3197fd77b54408dc05d1edf6178e2ea8728f4815 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 21:55:23 +0000 Subject: [PATCH 4/6] Add documentation for enterprise type configuration Co-authored-by: liguori <8238828+liguori@users.noreply.github.com> --- DEPLOYMENT.md | 33 +++++++++++++++++++++++++++++++++ README.md | 8 +++++++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 670ab3a7..8fdbf583 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -132,6 +132,39 @@ docker run -it --rm -p 3000:80 \ ghcr.io/github-copilot-resources/copilot-metrics-viewer ``` +### Enterprise Type Configuration + +For enterprise deployments, you can specify the enterprise type to control how teams are retrieved and managed: + +**For Full GitHub Enterprises** (with repos, actions, copilot, etc): +```bash +docker run -it --rm -p 3000:80 \ +-e NUXT_PUBLIC_SCOPE=enterprise \ +-e NUXT_PUBLIC_GITHUB_ENT= \ +-e NUXT_PUBLIC_ENTERPRISE_TYPE=full \ +-e NUXT_GITHUB_TOKEN= \ +-e NUXT_SESSION_PASSWORD= \ +ghcr.io/github-copilot-resources/copilot-metrics-viewer +``` + +**For Copilot Business Only Enterprises** (default behavior): +```bash +docker run -it --rm -p 3000:80 \ +-e NUXT_PUBLIC_SCOPE=enterprise \ +-e NUXT_PUBLIC_GITHUB_ENT= \ +-e NUXT_PUBLIC_ENTERPRISE_TYPE=copilot-only \ +-e NUXT_GITHUB_TOKEN= \ +-e NUXT_SESSION_PASSWORD= \ +ghcr.io/github-copilot-resources/copilot-metrics-viewer +``` + +**Environment Variable Details:** +- `NUXT_PUBLIC_ENTERPRISE_TYPE`: Set to `full` for Full GitHub Enterprises or `copilot-only` for Copilot Business Only enterprises +- Default value: `copilot-only` (maintains backward compatibility) +- This affects how teams are retrieved in the TEAMS tab: + - `full`: Enumerates organizations within the enterprise and fetches teams from each organization + - `copilot-only`: Uses enterprise-level teams API (existing behavior) + ## Health Check Endpoints for Kubernetes The application provides dedicated health check endpoints for Kubernetes deployments that avoid triggering GitHub API calls: diff --git a/README.md b/README.md index 2e2044eb..19687dec 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,13 @@ Users can now filter metrics for custom date ranges up to 100 days, with an intu

### Teams Comparison -Compare Copilot metrics across multiple teams within your organization to understand adoption patterns and identify high-performing teams. +Compare Copilot metrics across multiple teams within your organization or enterprise to understand adoption patterns and identify high-performing teams. + +**Enterprise Support**: The application now supports both Full GitHub Enterprises and Copilot Business Only enterprises: +- **Full Enterprises**: Teams are retrieved from all organizations within the enterprise +- **Copilot Business Only**: Teams are retrieved using enterprise-level APIs + +Configure enterprise type using the `NUXT_PUBLIC_ENTERPRISE_TYPE` environment variable (`full` or `copilot-only`).

Teams Comparison From e5a6a7a56f48a4c6a98b810ce7f89cfd615a41c5 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 22:33:00 +0000 Subject: [PATCH 5/6] Fix organization retrieval for full enterprises to use GraphQL instead of REST API Co-authored-by: liguori <8238828+liguori@users.noreply.github.com> --- app/model/Options.ts | 19 ++------ server/api/teams.ts | 89 +++++++++++++++++++---------------- tests/enterprise-type.spec.ts | 16 +------ 3 files changed, 52 insertions(+), 72 deletions(-) diff --git a/app/model/Options.ts b/app/model/Options.ts index e356ac81..0bf5abab 100644 --- a/app/model/Options.ts +++ b/app/model/Options.ts @@ -383,11 +383,11 @@ export class Options { if (!this.githubEnt) { throw new Error('GitHub enterprise must be set for enterprise scope'); } - // For full enterprises, we need to get teams from organizations within the enterprise + // For full enterprises, teams are fetched via GraphQL + organization teams APIs // For copilot-only enterprises, we use the enterprise teams API if (this.enterpriseType === 'full') { - // This will be handled by the teams API to enumerate organizations first - return `${baseUrl}/enterprises/${this.githubEnt}/organizations`; + // GraphQL will be used to get organizations, then org teams APIs + return `${baseUrl}/graphql`; } else { // Default to copilot-only behavior (enterprise teams API) return `${baseUrl}/enterprises/${this.githubEnt}/teams`; @@ -398,19 +398,6 @@ export class Options { } } - /** - * Get the Enterprise Organizations API URL - */ - getEnterpriseOrganizationsApiUrl(): string { - const baseUrl = 'https://api.github.com'; - - if (!this.githubEnt) { - throw new Error('GitHub enterprise must be set'); - } - - return `${baseUrl}/enterprises/${this.githubEnt}/organizations`; - } - /** * Get the Teams API URL based on scope and configuration */ diff --git a/server/api/teams.ts b/server/api/teams.ts index 28773aa7..6a21fce4 100644 --- a/server/api/teams.ts +++ b/server/api/teams.ts @@ -3,7 +3,16 @@ import type { H3Event, EventHandlerRequest } from 'h3' interface Team { name: string; slug: string; description: string } interface GitHubTeam { name: string; slug: string; description?: string } -interface GitHubOrganization { login: string; id: number } +interface GraphQLOrganization { login: string; name: string; url: string } +interface GraphQLResponse { + data: { + enterprise: { + organizations: { + nodes: GraphQLOrganization[] + } + } + } +} class TeamsError extends Error { statusCode: number @@ -80,52 +89,50 @@ export async function getTeams(event: H3Event): Promise('https://api.github.com/graphql', { + method: 'POST', + headers: { + ...event.context.headers, + 'Content-Type': 'application/json' + }, + body: JSON.stringify(graphqlQuery) + }) + + const organizations = graphqlResponse.data.enterprise.organizations.nodes + logger.info(`Found ${organizations.length} organizations in enterprise`) + + // For each organization, fetch its teams + for (const org of organizations) { + const orgTeamsUrl = `https://api.github.com/orgs/${org.login}/teams` + let nextTeamsUrl: string | null = `${orgTeamsUrl}?per_page=100` + let teamsPage = 1 - // For each organization, fetch its teams - for (const org of orgsData) { - const orgTeamsUrl = `https://api.github.com/orgs/${org.login}/teams` - let nextTeamsUrl: string | null = `${orgTeamsUrl}?per_page=100` - let teamsPage = 1 + while (nextTeamsUrl) { + logger.info(`Fetching teams page ${teamsPage} from ${nextTeamsUrl} for org ${org.login}`) + const teamsRes = await $fetch.raw(nextTeamsUrl, { + headers: event.context.headers + }) - while (nextTeamsUrl) { - logger.info(`Fetching teams page ${teamsPage} from ${nextTeamsUrl} for org ${org.login}`) - const teamsRes = await $fetch.raw(nextTeamsUrl, { - headers: event.context.headers - }) - - const teamsData = teamsRes._data as GitHubTeam[] - for (const t of teamsData) { - const name: string = `${org.login} - ${t.name}` - const slug: string = `${org.login} - ${t.slug}` - const description: string = t.description || `Team ${t.name} from organization ${org.login}` - if (t.name && t.slug) allTeams.push({ name, slug, description }) - } - - const teamsLinkHeader = teamsRes.headers.get('link') || teamsRes.headers.get('Link') - const teamsLinks = parseLinkHeader(teamsLinkHeader) - nextTeamsUrl = teamsLinks['next'] || null - teamsPage += 1 + const teamsData = teamsRes._data as GitHubTeam[] + for (const t of teamsData) { + const name: string = `${org.login} - ${t.name}` + const slug: string = `${org.login} - ${t.slug}` + const description: string = t.description || `Team ${t.name} from organization ${org.login}` + if (t.name && t.slug) allTeams.push({ name, slug, description }) } + + const teamsLinkHeader = teamsRes.headers.get('link') || teamsRes.headers.get('Link') + const teamsLinks = parseLinkHeader(teamsLinkHeader) + nextTeamsUrl = teamsLinks['next'] || null + teamsPage += 1 } - - const orgsLinkHeader = orgsRes.headers.get('link') || orgsRes.headers.get('Link') - const orgsLinks = parseLinkHeader(orgsLinkHeader) - nextOrgsUrl = orgsLinks['next'] || null - orgsPage += 1 } } else { // Handle organization scope or copilot-only enterprise scope (original logic) diff --git a/tests/enterprise-type.spec.ts b/tests/enterprise-type.spec.ts index fdccda30..bc058d7a 100644 --- a/tests/enterprise-type.spec.ts +++ b/tests/enterprise-type.spec.ts @@ -22,7 +22,7 @@ describe('Enterprise Type Support', () => { }) expect(options.enterpriseType).toBe('full') - expect(options.getTeamsApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/organizations') + expect(options.getTeamsApiUrl()).toBe('https://api.github.com/graphql') }) it('should default to copilot-only behavior when enterprise type not specified', () => { @@ -118,19 +118,5 @@ describe('Enterprise Type Support', () => { const merged = options1.merge(options2) expect(merged.enterpriseType).toBe('full') }) - - it('should handle enterprise organizations API URL', () => { - const options = new Options({ - githubEnt: 'test-enterprise' - }) - - expect(options.getEnterpriseOrganizationsApiUrl()).toBe('https://api.github.com/enterprises/test-enterprise/organizations') - }) - - it('should throw error for enterprise organizations API without enterprise', () => { - const options = new Options() - - expect(() => options.getEnterpriseOrganizationsApiUrl()).toThrow('GitHub enterprise must be set') - }) }) }) \ No newline at end of file From 02e5fe36e3138e1a1616010c643ef5ec0825cb15 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 19 Sep 2025 23:09:43 +0000 Subject: [PATCH 6/6] Fix Authorization header forwarding in GraphQL requests for full enterprises Co-authored-by: liguori <8238828+liguori@users.noreply.github.com> --- server/api/teams.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/server/api/teams.ts b/server/api/teams.ts index 6a21fce4..3911ad5a 100644 --- a/server/api/teams.ts +++ b/server/api/teams.ts @@ -98,10 +98,7 @@ export async function getTeams(event: H3Event): Promise('https://api.github.com/graphql', { method: 'POST', - headers: { - ...event.context.headers, - 'Content-Type': 'application/json' - }, + headers: event.context.headers, body: JSON.stringify(graphqlQuery) })