From 00bf316136acf001344a5bacff906f1748e6c368 Mon Sep 17 00:00:00 2001 From: Tim Rogers Date: Thu, 16 Jan 2025 16:53:42 +0000 Subject: [PATCH] feat: correctly parse response bodies as JSON where the Content-Type is `application/scim+json` (#731) GitHub has APIs that return `application/scim+json` response bodies. Currently, these responses are not parsed as JSON, and instead, an `ArrayBuffer` is returned in `response.data`. This adds handling for `application/scim+json` so they are parsed as JSON as normal. --- src/fetch-wrapper.ts | 11 ++++++++++- test/request.test.ts | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/fetch-wrapper.ts b/src/fetch-wrapper.ts index a1596716e..2313cccbc 100644 --- a/src/fetch-wrapper.ts +++ b/src/fetch-wrapper.ts @@ -3,6 +3,8 @@ import { isPlainObject } from "./is-plain-object.js"; import { RequestError } from "@octokit/request-error"; import type { EndpointInterface, OctokitResponse } from "@octokit/types"; +type ContentType = ReturnType; + export default async function fetchWrapper( requestOptions: ReturnType, ): Promise> { @@ -155,7 +157,7 @@ async function getResponseData(response: Response): Promise { const mimetype = safeParse(contentType); - if (mimetype.type === "application/json") { + if (isJSONResponse(mimetype)) { let text = ""; try { text = await response.text(); @@ -173,6 +175,13 @@ async function getResponseData(response: Response): Promise { } } +function isJSONResponse(mimetype: ContentType): boolean { + return ( + mimetype.type === "application/json" || + mimetype.type === "application/scim+json" + ); +} + function toErrorMessage(data: string | ArrayBuffer | Record) { if (typeof data === "string") { return data; diff --git a/test/request.test.ts b/test/request.test.ts index e4bee928e..ce8d73279 100644 --- a/test/request.test.ts +++ b/test/request.test.ts @@ -1263,4 +1263,41 @@ x//0u+zd/R/QRUzLOw4N72/Hu+UG6MNt5iDZFCtapRaKt6OvSBwy8w== }), ).rejects.toHaveProperty("message", "Unknown error: {}"); }); + + it("parses response bodies as JSON when Content-Type is application/scim+json", async () => { + expect.assertions(1); + + const mock = fetchMock.createInstance(); + mock.get("https://api.github.com/scim/v2/Users", { + status: 200, + body: { + totalResults: 1, + Resources: [ + { + id: "123", + userName: "octocat", + }, + ], + }, + headers: { + "Content-Type": "application/scim+json", + }, + }); + + const response = await request("GET /scim/v2/Users", { + request: { + fetch: mock.fetchHandler, + }, + }); + + expect(response.data).toEqual({ + totalResults: 1, + Resources: [ + { + id: "123", + userName: "octocat", + }, + ], + }); + }); });