diff --git a/src/cmds/categories/create.ts b/src/cmds/categories/create.ts index fcda65a62..f452e2166 100644 --- a/src/cmds/categories/create.ts +++ b/src/cmds/categories/create.ts @@ -102,7 +102,7 @@ export default class CategoriesCreateCommand extends Command { type: categoryType, }), }) - .then(res => handleRes(res)) + .then(handleRes) .then(res => `🌱 successfully created '${res.title}' with a type of '${res.type}' and an id of '${res.id}'`); } diff --git a/src/cmds/docs/edit.ts b/src/cmds/docs/edit.ts index 783d69033..e8629db07 100644 --- a/src/cmds/docs/edit.ts +++ b/src/cmds/docs/edit.ts @@ -70,7 +70,7 @@ export default class DocsEditCommand extends Command { Accept: 'application/json', }) ), - }).then(res => handleRes(res)); + }).then(handleRes); await writeFile(filename, existingDoc.body); @@ -99,11 +99,9 @@ export default class DocsEditCommand extends Command { }) ), }) - .then(res => res.json()) + .then(res => handleRes(res, false)) .then(async res => { - Command.debug(`response from PUT request: ${res}`); - // The reason we aren't using our handleRes() function here is - // because we need to use the `reject` function from + // We need to use the `reject` function from // the Promise that's wrapping this function. if (res.error) { return reject(new APIError(res)); diff --git a/src/cmds/openapi/index.ts b/src/cmds/openapi/index.ts index 6ff60be1c..ec2ac7c11 100644 --- a/src/cmds/openapi/index.ts +++ b/src/cmds/openapi/index.ts @@ -153,9 +153,7 @@ export default class OpenAPICommand extends Command { ? `You've successfully uploaded a new ${specType} file to your ReadMe project!` : `You've successfully updated an existing ${specType} file on your ReadMe project!`; - Command.debug(`successful ${data.status} response`); - const body = await data.json(); - Command.debug(`successful response payload: ${JSON.stringify(body)}`); + const body = await handleRes(data, false); const output = { commandType: isUpdate ? 'update' : 'create', @@ -300,8 +298,7 @@ export default class OpenAPICommand extends Command { Command.debug(`total pages: ${totalPages}`); Command.debug(`pagination result: ${JSON.stringify(parsedDocs)}`); - const apiSettingsBody = await apiSettings.json(); - Command.debug(`api settings list response payload: ${JSON.stringify(apiSettingsBody)}`); + const apiSettingsBody = await handleRes(apiSettings); if (!apiSettingsBody.length) return createSpec(); if (update) { diff --git a/src/cmds/versions/create.ts b/src/cmds/versions/create.ts index ca3f3eb91..a09a2f86a 100644 --- a/src/cmds/versions/create.ts +++ b/src/cmds/versions/create.ts @@ -63,7 +63,7 @@ export default class CreateVersionCommand extends Command { versionList = await fetch(`${config.get('host')}/api/v1/version`, { method: 'get', headers: cleanHeaders(key), - }).then(res => handleRes(res)); + }).then(handleRes); } const versionPrompt = promptHandler.createVersionPrompt(versionList || [], { diff --git a/src/cmds/versions/update.ts b/src/cmds/versions/update.ts index b574c17be..6ca7aac2d 100644 --- a/src/cmds/versions/update.ts +++ b/src/cmds/versions/update.ts @@ -59,7 +59,7 @@ export default class UpdateVersionCommand extends Command { const foundVersion = await fetch(`${config.get('host')}/api/v1/version/${selectedVersion}`, { method: 'get', headers: cleanHeaders(key), - }).then(res => handleRes(res)); + }).then(handleRes); const promptResponse = await promptTerminal(promptHandler.createVersionPrompt([], opts, foundVersion)); diff --git a/src/lib/fetch.ts b/src/lib/fetch.ts index a95707771..324235e7f 100644 --- a/src/lib/fetch.ts +++ b/src/lib/fetch.ts @@ -136,14 +136,18 @@ export default function fetch(url: string, options: RequestInit = { headers: new * * If we receive non-JSON responses, we consider them errors and throw them. * + * @param rejectOnJsonError if omitted (or set to true), the function will return + * an `APIError` if the JSON body contains an `error` property. If set to false, + * the function will return a resolved promise containing the JSON object. + * */ -async function handleRes(res: Response) { +async function handleRes(res: Response, rejectOnJsonError = true) { const contentType = res.headers.get('content-type'); const extension = mime.extension(contentType); if (extension === 'json') { const body = await res.json(); debug(`received status code ${res.status} from ${res.url} with JSON response: ${JSON.stringify(body)}`); - if (body.error) { + if (body.error && rejectOnJsonError) { return Promise.reject(new APIError(body)); } return body; diff --git a/src/lib/getCategories.ts b/src/lib/getCategories.ts index 8eaac2c3b..61b3f9841 100644 --- a/src/lib/getCategories.ts +++ b/src/lib/getCategories.ts @@ -47,7 +47,7 @@ export default async function getCategories(key: string, selectedVersion: string Accept: 'application/json', }) ), - }).then(res => handleRes(res)); + }).then(handleRes); }) )) ); diff --git a/src/lib/prompts.ts b/src/lib/prompts.ts index 58ae2ef36..0303f2876 100644 --- a/src/lib/prompts.ts +++ b/src/lib/prompts.ts @@ -7,6 +7,7 @@ import type { Choice, PromptObject } from 'prompts'; import parse from 'parse-link-header'; import semver from 'semver'; +import { handleRes } from './fetch'; import promptTerminal from './promptWrapper'; interface Spec { @@ -69,7 +70,7 @@ const updateOasPrompt = ( try { const newSpecs = await getSpecs(`${parsedDocs.prev.url}`); const newParsedDocs = parse(newSpecs.headers.get('link')); - const newSpecList = await newSpecs.json(); + const newSpecList = await handleRes(newSpecs); // @todo: figure out how to add a stricter type here, see: // https://github.com/readmeio/rdme/pull/570#discussion_r949715913 const { specId } = await promptTerminal( @@ -83,7 +84,7 @@ const updateOasPrompt = ( try { const newSpecs = await getSpecs(`${parsedDocs.next.url}`); const newParsedDocs = parse(newSpecs.headers.get('link')); - const newSpecList = await newSpecs.json(); + const newSpecList = await handleRes(newSpecs); // @todo: figure out how to add a stricter type here, see: // https://github.com/readmeio/rdme/pull/570#discussion_r949715913 const { specId } = await promptTerminal( diff --git a/src/lib/streamSpecToRegistry.ts b/src/lib/streamSpecToRegistry.ts index caadc83f3..d791a8bce 100644 --- a/src/lib/streamSpecToRegistry.ts +++ b/src/lib/streamSpecToRegistry.ts @@ -36,7 +36,7 @@ export default async function streamSpecToRegistry(spec: string) { }; return fetch(`${config.get('host')}/api/v1/api-registry`, options) - .then(res => handleRes(res)) + .then(handleRes) .then(body => { spinner.stop(); return body.registryUUID; diff --git a/src/lib/syncDocsPath.ts b/src/lib/syncDocsPath.ts index 30d0d1110..1517ce05c 100644 --- a/src/lib/syncDocsPath.ts +++ b/src/lib/syncDocsPath.ts @@ -76,7 +76,7 @@ async function pushDoc( ...payload, }), }) - .then(res => handleRes(res)) + .then(handleRes) // eslint-disable-next-line no-underscore-dangle .then(res => `🌱 successfully created '${res.slug}' (ID: ${res._id}) with contents from ${filepath}`) ); @@ -110,7 +110,7 @@ async function pushDoc( }) ), }) - .then(res => handleRes(res)) + .then(handleRes) .then(res => `✏️ successfully updated '${res.slug}' with contents from ${filepath}`); } @@ -125,8 +125,7 @@ async function pushDoc( ), }) .then(async res => { - const body = await res.json(); - debug(`GET /${type}/:slug API response for ${slug}: ${JSON.stringify(body)}`); + const body = await handleRes(res, false); if (!res.ok) { if (res.status !== 404) return Promise.reject(new APIError(body)); debug(`error retrieving data for ${slug}, creating doc`); diff --git a/src/lib/versionSelect.ts b/src/lib/versionSelect.ts index 5b825d5c9..d6eb579e7 100644 --- a/src/lib/versionSelect.ts +++ b/src/lib/versionSelect.ts @@ -22,7 +22,7 @@ export async function getProjectVersion(versionFlag: string, key: string, return method: 'get', headers: cleanHeaders(key), }) - .then(res => handleRes(res)) + .then(handleRes) .then((res: Version) => res.version); } @@ -34,7 +34,7 @@ export async function getProjectVersion(versionFlag: string, key: string, return const versionList: Version[] = await fetch(`${config.get('host')}/api/v1/version`, { method: 'get', headers: cleanHeaders(key), - }).then(res => handleRes(res)); + }).then(handleRes); if (versionList.length === 1) { return versionList[0].version;