From e864491699e5134ff67444f54db9d65738d14ec3 Mon Sep 17 00:00:00 2001 From: Kanad Gupta <8854718+kanadgupta@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:25:32 -0600 Subject: [PATCH] refactor: rename a few more fetch functions (#1077) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit | 🚥 Resolves ISSUE_ID | | :------------------- | ## 🧰 Changes Describe in detail what this PR is for. ## 🧬 QA & Testing Provide as much information as you can on how to test what you've done. --- __tests__/lib/fetch.test.ts | 72 +++++++++++++++---------------- src/commands/categories/create.ts | 8 ++-- src/commands/openapi/index.ts | 18 ++++---- src/commands/versions/create.ts | 14 +++--- src/commands/versions/delete.ts | 8 ++-- src/commands/versions/index.ts | 8 ++-- src/commands/versions/update.ts | 14 +++--- src/lib/deleteDoc.ts | 8 ++-- src/lib/getCategories.ts | 14 +++--- src/lib/getDocs.ts | 8 ++-- src/lib/loginFlow.ts | 8 ++-- src/lib/prompts.ts | 6 +-- src/lib/readmeAPIFetch.ts | 18 ++++---- src/lib/streamSpecToRegistry.ts | 6 +-- src/lib/syncDocsPath.ts | 20 ++++----- src/lib/versionSelect.ts | 14 +++--- 16 files changed, 121 insertions(+), 123 deletions(-) diff --git a/__tests__/lib/fetch.test.ts b/__tests__/lib/fetch.test.ts index d65370296..356e15938 100644 --- a/__tests__/lib/fetch.test.ts +++ b/__tests__/lib/fetch.test.ts @@ -3,11 +3,11 @@ import nock from 'nock'; import { describe, beforeEach, afterEach, it, expect, vi, beforeAll, type MockInstance } from 'vitest'; import pkg from '../../package.json' with { type: 'json' }; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../src/lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../src/lib/readmeAPIFetch.js'; import { getAPIV1Mock } from '../helpers/get-api-mock.js'; import { after, before } from '../helpers/setup-gha-env.js'; -describe('#readmeAPIV1Fetch()', () => { +describe('#readmeAPIv1Fetch()', () => { beforeAll(() => { nock.disableNetConnect(); }); @@ -29,10 +29,10 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch('/api/v1', { + const headers = await readmeAPIv1Fetch('/api/v1', { method: 'get', - headers: cleanHeaders(key), - }).then(handleRes); + headers: cleanAPIv1Headers(key), + }).then(handleAPIv1Res); expect(headers['user-agent']).toBe(`rdme-github/${pkg.version}`); expect(headers['x-readme-source']).toBe('cli-gh'); @@ -56,14 +56,14 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch( + const headers = await readmeAPIv1Fetch( '/api/v1', { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }, { filePath: 'openapi.json', fileType: 'path' }, - ).then(handleRes); + ).then(handleAPIv1Res); expect(headers['x-readme-source-url']).toBe( 'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/openapi.json', @@ -81,14 +81,14 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch( + const headers = await readmeAPIv1Fetch( '/api/v1', { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }, { filePath: './📈 Dashboard & Metrics/openapi.json', fileType: 'path' }, - ).then(handleRes); + ).then(handleAPIv1Res); expect(headers['x-readme-source-url']).toBe( 'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/%F0%9F%93%88%20Dashboard%20&%20Metrics/openapi.json', @@ -107,14 +107,14 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch( + const headers = await readmeAPIv1Fetch( '/api/v1', { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }, { filePath: './📈 Dashboard & Metrics/openapi.json', fileType: 'path' }, - ).then(handleRes); + ).then(handleAPIv1Res); expect(headers['x-readme-source-url']).toBeUndefined(); mock.done(); @@ -130,14 +130,14 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch( + const headers = await readmeAPIv1Fetch( '/api/v1', { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }, { filePath: './openapi.json', fileType: 'path' }, - ).then(handleRes); + ).then(handleAPIv1Res); expect(headers['x-readme-source-url']).toBe( 'https://github.com/octocat/Hello-World/blob/ffac537e6cbbf934b08745a378932722df287a53/openapi.json', @@ -156,14 +156,14 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch( + const headers = await readmeAPIv1Fetch( '/api/v1', { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }, { filePath, fileType: 'url' }, - ).then(handleRes); + ).then(handleAPIv1Res); expect(headers['x-readme-source-url']).toBe(filePath); mock.done(); @@ -181,10 +181,10 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch('/api/v1', { + const headers = await readmeAPIv1Fetch('/api/v1', { method: 'get', - headers: cleanHeaders(key), - }).then(handleRes); + headers: cleanAPIv1Headers(key), + }).then(handleAPIv1Res); expect(headers['user-agent']).toBe(`rdme/${pkg.version}`); expect(headers['x-readme-source']).toBe('cli'); @@ -203,7 +203,7 @@ describe('#readmeAPIV1Fetch()', () => { return this.req.headers; }); - const headers = await readmeAPIV1Fetch('/api/v1/doesnt-need-auth').then(handleRes); + const headers = await readmeAPIv1Fetch('/api/v1/doesnt-need-auth').then(handleAPIv1Res); expect(headers['user-agent']).toBe(`rdme/${pkg.version}`); expect(headers['x-readme-source']).toBe('cli'); @@ -235,7 +235,7 @@ describe('#readmeAPIV1Fetch()', () => { Warning: '', }); - await readmeAPIV1Fetch('/api/v1/some-warning'); + await readmeAPIv1Fetch('/api/v1/some-warning'); expect(console.warn).toHaveBeenCalledTimes(0); expect(getWarningCommandOutput()).toBe(''); @@ -248,7 +248,7 @@ describe('#readmeAPIV1Fetch()', () => { Warning: '199 - "some error"', }); - await readmeAPIV1Fetch('/api/v1/some-warning'); + await readmeAPIv1Fetch('/api/v1/some-warning'); expect(console.warn).toHaveBeenCalledTimes(1); expect(getWarningCommandOutput()).toBe('⚠️ ReadMe API Warning: some error'); @@ -261,7 +261,7 @@ describe('#readmeAPIV1Fetch()', () => { Warning: '199 - "some error" 199 - "another error"', }); - await readmeAPIV1Fetch('/api/v1/some-warning'); + await readmeAPIv1Fetch('/api/v1/some-warning'); expect(console.warn).toHaveBeenCalledTimes(2); expect(getWarningCommandOutput()).toBe( @@ -276,7 +276,7 @@ describe('#readmeAPIV1Fetch()', () => { Warning: 'some garbage error', }); - await readmeAPIV1Fetch('/api/v1/some-warning'); + await readmeAPIv1Fetch('/api/v1/some-warning'); expect(console.warn).toHaveBeenCalledTimes(1); expect(getWarningCommandOutput()).toBe('⚠️ ReadMe API Warning: some garbage error'); @@ -302,7 +302,7 @@ describe('#readmeAPIV1Fetch()', () => { const mock = getAPIV1Mock({}).get('/api/v1/proxy').reply(200); - await readmeAPIV1Fetch('/api/v1/proxy'); + await readmeAPIv1Fetch('/api/v1/proxy'); mock.done(); }); @@ -314,7 +314,7 @@ describe('#readmeAPIV1Fetch()', () => { const mock = getAPIV1Mock({}).get('/api/v1/proxy').reply(200); - await readmeAPIV1Fetch('/api/v1/proxy'); + await readmeAPIv1Fetch('/api/v1/proxy'); mock.done(); }); @@ -326,27 +326,27 @@ describe('#readmeAPIV1Fetch()', () => { const mock = getAPIV1Mock({}).get('/api/v1/proxy').reply(200); - await readmeAPIV1Fetch('/api/v1/proxy'); + await readmeAPIv1Fetch('/api/v1/proxy'); mock.done(); }); }); }); -describe('#cleanHeaders()', () => { +describe('#cleanAPIv1Headers()', () => { it('should base64-encode key in ReadMe-friendly format', () => { - expect(Array.from(cleanHeaders('test'))).toStrictEqual([['authorization', 'Basic dGVzdDo=']]); + expect(Array.from(cleanAPIv1Headers('test'))).toStrictEqual([['authorization', 'Basic dGVzdDo=']]); }); it('should filter out undefined headers', () => { - expect(Array.from(cleanHeaders('test', undefined, new Headers({ 'x-something': undefined })))).toStrictEqual([ + expect(Array.from(cleanAPIv1Headers('test', undefined, new Headers({ 'x-something': undefined })))).toStrictEqual([ ['authorization', 'Basic dGVzdDo='], ]); }); it('should filter out null headers', () => { expect( - Array.from(cleanHeaders('test', undefined, new Headers({ 'x-something': '1234', Accept: null }))), + Array.from(cleanAPIv1Headers('test', undefined, new Headers({ 'x-something': '1234', Accept: null }))), ).toStrictEqual([ ['authorization', 'Basic dGVzdDo='], ['x-something', '1234'], @@ -360,7 +360,7 @@ describe('#cleanHeaders()', () => { 'Content-Type': 'application/json', }); - expect(Array.from(cleanHeaders('test', undefined, headers))).toStrictEqual([ + expect(Array.from(cleanAPIv1Headers('test', undefined, headers))).toStrictEqual([ ['accept', 'text/plain'], ['authorization', 'Basic dGVzdDo='], ['content-type', 'application/json'], diff --git a/src/commands/categories/create.ts b/src/commands/categories/create.ts index 798e10d33..c03504bb2 100644 --- a/src/commands/categories/create.ts +++ b/src/commands/categories/create.ts @@ -4,7 +4,7 @@ import chalk from 'chalk'; import BaseCommand from '../../lib/baseCommand.js'; import { keyFlag, versionFlag } from '../../lib/flags.js'; import getCategories from '../../lib/getCategories.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../lib/readmeAPIFetch.js'; import { getProjectVersion } from '../../lib/versionSelect.js'; interface Category { @@ -57,15 +57,15 @@ export default class CategoriesCreateCommand extends BaseCommand `🌱 successfully created '${res.title}' with a type of '${res.type}' and an id of '${res.id}'`); return Promise.resolve(chalk.green(createdCategory)); diff --git a/src/commands/openapi/index.ts b/src/commands/openapi/index.ts index 97de0b13f..cecdb83cc 100644 --- a/src/commands/openapi/index.ts +++ b/src/commands/openapi/index.ts @@ -11,7 +11,7 @@ import { info, oraOptions, warn } from '../../lib/logger.js'; import prepareOas from '../../lib/prepareOas.js'; import * as promptHandler from '../../lib/prompts.js'; import promptTerminal from '../../lib/promptWrapper.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../lib/readmeAPIFetch.js'; import streamSpecToRegistry from '../../lib/streamSpecToRegistry.js'; import { getProjectVersion } from '../../lib/versionSelect.js'; @@ -111,7 +111,7 @@ export default class OpenAPICommand extends BaseCommand { ? `You've successfully uploaded a new ${specType} file to your ReadMe project!` : `You've successfully updated an existing ${specType} file on your ReadMe project!`; - const body = await handleRes(data, false); + const body = await handleAPIv1Res(data, false); const output = { commandType: isUpdate ? 'update' : 'create', @@ -147,7 +147,7 @@ export default class OpenAPICommand extends BaseCommand { }; const error = (res: Response) => { - return handleRes(res).catch(err => { + return handleAPIv1Res(res).catch(err => { // If we receive an APIError, no changes needed! Throw it as is. if (err.name === 'APIError') { throw err; @@ -176,7 +176,7 @@ export default class OpenAPICommand extends BaseCommand { const registryUUID = await streamSpecToRegistry(preparedSpec); const options: RequestInit = { - headers: cleanHeaders( + headers: cleanAPIv1Headers( key, selectedVersion, new Headers({ Accept: 'application/json', 'Content-Type': 'application/json' }), @@ -191,7 +191,7 @@ export default class OpenAPICommand extends BaseCommand { options.method = 'post'; spinner.start('Creating your API docs in ReadMe...'); - return readmeAPIV1Fetch('/api/v1/api-specification', options, { + return readmeAPIv1Fetch('/api/v1/api-specification', options, { filePath: specPath, fileType: specFileType, }).then(res => { @@ -212,7 +212,7 @@ export default class OpenAPICommand extends BaseCommand { isUpdate = true; options.method = 'put'; spinner.start('Updating your API docs in ReadMe...'); - return readmeAPIV1Fetch(`/api/v1/api-specification/${specId}`, options, { + return readmeAPIv1Fetch(`/api/v1/api-specification/${specId}`, options, { filePath: specPath, fileType: specFileType, }).then(res => { @@ -235,9 +235,9 @@ export default class OpenAPICommand extends BaseCommand { function getSpecs(url: string) { if (url) { - return readmeAPIV1Fetch(url, { + return readmeAPIv1Fetch(url, { method: 'get', - headers: cleanHeaders(key, selectedVersion), + headers: cleanAPIv1Headers(key, selectedVersion), }); } @@ -261,7 +261,7 @@ export default class OpenAPICommand extends BaseCommand { this.debug(`total pages: ${totalPages}`); this.debug(`pagination result: ${JSON.stringify(parsedDocs)}`); - const apiSettingsBody = await handleRes(apiSettings); + const apiSettingsBody = await handleAPIv1Res(apiSettings); if (!apiSettingsBody.length) return createSpec(); if (update) { diff --git a/src/commands/versions/create.ts b/src/commands/versions/create.ts index a95f50181..c58be4f41 100644 --- a/src/commands/versions/create.ts +++ b/src/commands/versions/create.ts @@ -9,7 +9,7 @@ import castStringOptToBool from '../../lib/castStringOptToBool.js'; import { baseVersionFlags, keyFlag } from '../../lib/flags.js'; import * as promptHandler from '../../lib/prompts.js'; import promptTerminal from '../../lib/promptWrapper.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../lib/readmeAPIFetch.js'; export default class CreateVersionCommand extends BaseCommand { static description = 'Create a new version for your project.'; @@ -42,10 +42,10 @@ export default class CreateVersionCommand extends BaseCommand { return Promise.resolve(`Version ${version} created successfully.`); }); diff --git a/src/commands/versions/delete.ts b/src/commands/versions/delete.ts index c4a4f9054..aef0a7cd6 100644 --- a/src/commands/versions/delete.ts +++ b/src/commands/versions/delete.ts @@ -2,7 +2,7 @@ import { Args } from '@oclif/core'; import BaseCommand from '../../lib/baseCommand.js'; import { keyFlag } from '../../lib/flags.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../lib/readmeAPIFetch.js'; import { getProjectVersion } from '../../lib/versionSelect.js'; export default class DeleteVersionCommand extends BaseCommand { @@ -26,11 +26,11 @@ export default class DeleteVersionCommand extends BaseCommand { return Promise.resolve(`Version ${selectedVersion} deleted successfully.`); }); diff --git a/src/commands/versions/index.ts b/src/commands/versions/index.ts index 9341a31a4..6609edf5e 100644 --- a/src/commands/versions/index.ts +++ b/src/commands/versions/index.ts @@ -2,7 +2,7 @@ import { Flags } from '@oclif/core'; import BaseCommand from '../../lib/baseCommand.js'; import { keyFlag } from '../../lib/flags.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../lib/readmeAPIFetch.js'; export interface Version { codename?: string; @@ -28,11 +28,11 @@ export default class VersionsCommand extends BaseCommand const uri = version ? `/api/v1/version/${version}` : '/api/v1/version'; - return readmeAPIV1Fetch(uri, { + return readmeAPIv1Fetch(uri, { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }) - .then(handleRes) + .then(handleAPIv1Res) .then(data => Promise.resolve(JSON.stringify(data, null, 2))); } } diff --git a/src/commands/versions/update.ts b/src/commands/versions/update.ts index bc78be8b5..8f6dae80c 100644 --- a/src/commands/versions/update.ts +++ b/src/commands/versions/update.ts @@ -8,7 +8,7 @@ import castStringOptToBool from '../../lib/castStringOptToBool.js'; import { baseVersionFlags, keyFlag } from '../../lib/flags.js'; import * as promptHandler from '../../lib/prompts.js'; import promptTerminal from '../../lib/promptWrapper.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from '../../lib/readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from '../../lib/readmeAPIFetch.js'; import { getProjectVersion } from '../../lib/versionSelect.js'; export default class UpdateVersionCommand extends BaseCommand { @@ -34,10 +34,10 @@ export default class UpdateVersionCommand extends BaseCommand { return Promise.resolve(`Version ${selectedVersion} updated successfully.`); }); diff --git a/src/lib/deleteDoc.ts b/src/lib/deleteDoc.ts index 1616cdfc6..0723876ec 100644 --- a/src/lib/deleteDoc.ts +++ b/src/lib/deleteDoc.ts @@ -1,4 +1,4 @@ -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; /** * Delete a document from ReadMe @@ -19,10 +19,10 @@ export default async function deleteDoc( if (dryRun) { return Promise.resolve(`🎭 dry run! This will delete \`${slug}\`.`); } - return readmeAPIV1Fetch(`/api/v1/docs/${slug}`, { + return readmeAPIv1Fetch(`/api/v1/docs/${slug}`, { method: 'delete', - headers: cleanHeaders(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), }) - .then(handleRes) + .then(handleAPIv1Res) .then(() => `🗑️ successfully deleted \`${slug}\`.`); } diff --git a/src/lib/getCategories.ts b/src/lib/getCategories.ts index 98f6ff648..4ad5ee87a 100644 --- a/src/lib/getCategories.ts +++ b/src/lib/getCategories.ts @@ -1,4 +1,4 @@ -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; /** * Returns all categories for a given project and version @@ -10,13 +10,13 @@ import { cleanHeaders, handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; export default async function getCategories(key: string, selectedVersion: string | undefined) { async function getNumberOfPages() { let totalCount = 0; - return readmeAPIV1Fetch('/api/v1/categories?perPage=20&page=1', { + return readmeAPIv1Fetch('/api/v1/categories?perPage=20&page=1', { method: 'get', - headers: cleanHeaders(key, selectedVersion, new Headers({ Accept: 'application/json' })), + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ Accept: 'application/json' })), }) .then(res => { totalCount = Math.ceil(parseInt(res.headers.get('x-total-count') || '0', 10) / 20); - return handleRes(res); + return handleAPIv1Res(res); }) .then(res => { return { firstPage: res, totalCount }; @@ -29,10 +29,10 @@ export default async function getCategories(key: string, selectedVersion: string ...(await Promise.all( // retrieves all categories beyond first page [...new Array(totalCount + 1).keys()].slice(2).map(async page => { - return readmeAPIV1Fetch(`/api/v1/categories?perPage=20&page=${page}`, { + return readmeAPIv1Fetch(`/api/v1/categories?perPage=20&page=${page}`, { method: 'get', - headers: cleanHeaders(key, selectedVersion, new Headers({ Accept: 'application/json' })), - }).then(handleRes); + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ Accept: 'application/json' })), + }).then(handleAPIv1Res); }), )), ); diff --git a/src/lib/getDocs.ts b/src/lib/getDocs.ts index b675bfa17..aa3cd1ea0 100644 --- a/src/lib/getDocs.ts +++ b/src/lib/getDocs.ts @@ -1,5 +1,5 @@ import getCategories from './getCategories.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; interface Document { _id: string; @@ -34,10 +34,10 @@ async function getCategoryDocs( selectedVersion: string | undefined, category: string, ): Promise { - return readmeAPIV1Fetch(`/api/v1/categories/${category}/docs`, { + return readmeAPIv1Fetch(`/api/v1/categories/${category}/docs`, { method: 'get', - headers: cleanHeaders(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), - }).then(handleRes); + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), + }).then(handleAPIv1Res); } /** diff --git a/src/lib/loginFlow.ts b/src/lib/loginFlow.ts index 091cd0d26..8d474d79b 100644 --- a/src/lib/loginFlow.ts +++ b/src/lib/loginFlow.ts @@ -5,7 +5,7 @@ import configStore from './configstore.js'; import getCurrentConfig from './getCurrentConfig.js'; import { debug } from './logger.js'; import promptTerminal from './promptWrapper.js'; -import { handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; import { validateSubdomain } from './validatePromptInput.js'; interface LoginBody { @@ -16,7 +16,7 @@ interface LoginBody { } function loginFetch(body: LoginBody) { - return readmeAPIV1Fetch('/api/v1/login', { + return readmeAPIv1Fetch('/api/v1/login', { method: 'post', headers: { Accept: 'application/json', 'Content-Type': 'application/json' }, body: JSON.stringify(body), @@ -71,7 +71,7 @@ export default async function loginFlow(otp?: string) { if (otp) payload.token = otp; return loginFetch(payload) - .then(handleRes) + .then(handleAPIv1Res) .catch(async err => { // if the user's login requires 2FA, let's prompt them for the token! if (err.code === 'LOGIN_TWOFACTOR') { @@ -82,7 +82,7 @@ export default async function loginFlow(otp?: string) { message: 'What is your 2FA token?', }); - return loginFetch({ email, password, project, token: otpPrompt.otp }).then(handleRes); + return loginFetch({ email, password, project, token: otpPrompt.otp }).then(handleAPIv1Res); } throw err; }) diff --git a/src/lib/prompts.ts b/src/lib/prompts.ts index b0c92a956..ecc964cc0 100644 --- a/src/lib/prompts.ts +++ b/src/lib/prompts.ts @@ -6,7 +6,7 @@ import semver from 'semver'; import { debug } from './logger.js'; import promptTerminal from './promptWrapper.js'; -import { handleRes } from './readmeAPIFetch.js'; +import { handleAPIv1Res } from './readmeAPIFetch.js'; interface Spec { _id: string; @@ -75,7 +75,7 @@ const updateOasPrompt = ( try { const newSpecs = await getSpecs(`${parsedDocs?.prev?.url || ''}`); const newParsedDocs = parse(newSpecs.headers.get('link')); - const newSpecList = await handleRes(newSpecs); + const newSpecList = await handleAPIv1Res(newSpecs); const { specId }: { specId: string } = await promptTerminal( updateOasPrompt(newSpecList, newParsedDocs, currPage - 1, totalPages, getSpecs), ); @@ -88,7 +88,7 @@ const updateOasPrompt = ( try { const newSpecs = await getSpecs(`${parsedDocs?.next?.url || ''}`); const newParsedDocs = parse(newSpecs.headers.get('link')); - const newSpecList = await handleRes(newSpecs); + const newSpecList = await handleAPIv1Res(newSpecs); const { specId }: { specId: string } = await promptTerminal( updateOasPrompt(newSpecList, newParsedDocs, currPage + 1, totalPages, getSpecs), ); diff --git a/src/lib/readmeAPIFetch.ts b/src/lib/readmeAPIFetch.ts index 207f1a9a4..99d8f10a3 100644 --- a/src/lib/readmeAPIFetch.ts +++ b/src/lib/readmeAPIFetch.ts @@ -88,7 +88,7 @@ function parseWarningHeader(header: string): WarningHeader[] { * environment. * */ -function getUserAgent() { +export function getUserAgent() { const gh = isGHA() ? '-github' : ''; return `rdme${gh}/${pkg.version}`; } @@ -128,7 +128,7 @@ function sanitizeHeaders(headers: Headers) { * @param fileOpts optional object containing information about the file being sent. * We use this to construct a full source URL for the file. */ -export async function readmeAPIV1Fetch( +export async function readmeAPIv1Fetch( pathname: string, options: RequestInit = { headers: new Headers() }, fileOpts: FilePathDetails = { filePath: '', fileType: false }, @@ -210,7 +210,7 @@ export async function readmeAPIV1Fetch( } /** - * Small handler for handling responses from our API. + * Small handler for handling responses from API v1. * * If we receive JSON errors, we throw an APIError exception. * @@ -221,7 +221,7 @@ export async function readmeAPIV1Fetch( * the function will return a resolved promise containing the JSON object. * */ -async function handleRes(res: Response, rejectOnJsonError = true) { +export async function handleAPIv1Res(res: Response, rejectOnJsonError = true) { const contentType = res.headers.get('content-type') || ''; const extension = mime.extension(contentType); if (extension === 'json') { @@ -246,10 +246,10 @@ async function handleRes(res: Response, rejectOnJsonError = true) { } /** - * Returns the basic auth header and any other defined headers for use in `fetch` API calls. + * Returns the basic auth header and any other defined headers for use in `fetch` calls against API v1. * */ -function cleanHeaders( +export function cleanAPIv1Headers( key: string, /** used for `x-readme-header` */ version?: string, @@ -265,8 +265,8 @@ function cleanHeaders( } for (const header of inputHeaders.entries()) { - // If you supply `undefined` or `null` to the `Headers` API it'll convert that those to a - // string. + // If you supply `undefined` or `null` to the `Headers` API it'll convert those to a string by default, + // so we instead filter those out here. if (header[1] !== 'null' && header[1] !== 'undefined' && header[1].length > 0) { headers.set(header[0], header[1]); } @@ -274,5 +274,3 @@ function cleanHeaders( return headers; } - -export { cleanHeaders, getUserAgent, handleRes }; diff --git a/src/lib/streamSpecToRegistry.ts b/src/lib/streamSpecToRegistry.ts index 422740b5c..e494d4c9f 100644 --- a/src/lib/streamSpecToRegistry.ts +++ b/src/lib/streamSpecToRegistry.ts @@ -4,7 +4,7 @@ import ora from 'ora'; import { file as tmpFile } from 'tmp-promise'; import { debug, oraOptions } from './logger.js'; -import { handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; /** * Uploads a spec to the API registry for usage in ReadMe @@ -44,8 +44,8 @@ export default async function streamSpecToRegistry( method: 'POST', }; - return readmeAPIV1Fetch('/api/v1/api-registry', options) - .then(handleRes) + return readmeAPIv1Fetch('/api/v1/api-registry', options) + .then(handleAPIv1Res) .then(body => { spinner.stop(); return body.registryUUID; diff --git a/src/lib/syncDocsPath.ts b/src/lib/syncDocsPath.ts index 8fd7f32e8..8c80737bc 100644 --- a/src/lib/syncDocsPath.ts +++ b/src/lib/syncDocsPath.ts @@ -12,7 +12,7 @@ import toposort from 'toposort'; import APIError from './apiError.js'; import readdirRecursive from './readdirRecursive.js'; import readDoc from './readDoc.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; /** API path within ReadMe to update (e.g. `docs`, `changelogs`, etc.) */ type PageType = 'changelogs' | 'custompages' | 'docs'; @@ -65,11 +65,11 @@ async function pushDoc( } return ( - readmeAPIV1Fetch( + readmeAPIv1Fetch( `/api/v1/${type}`, { method: 'post', - headers: cleanHeaders(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), body: JSON.stringify({ slug, ...payload, @@ -77,7 +77,7 @@ async function pushDoc( }, { filePath, fileType: 'path' }, ) - .then(handleRes) + .then(handleAPIv1Res) // eslint-disable-next-line no-underscore-dangle .then(res => `🌱 successfully created '${res.slug}' (ID: ${res._id}) with contents from ${filePath}`) ); @@ -96,25 +96,25 @@ async function pushDoc( )}`; } - return readmeAPIV1Fetch( + return readmeAPIv1Fetch( `/api/v1/${type}/${slug}`, { method: 'put', - headers: cleanHeaders(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ 'Content-Type': 'application/json' })), body: JSON.stringify(payload), }, { filePath, fileType: 'path' }, ) - .then(handleRes) + .then(handleAPIv1Res) .then(res => `✏️ successfully updated '${res.slug}' with contents from ${filePath}`); } - return readmeAPIV1Fetch(`/api/v1/${type}/${slug}`, { + return readmeAPIv1Fetch(`/api/v1/${type}/${slug}`, { method: 'get', - headers: cleanHeaders(key, selectedVersion, new Headers({ Accept: 'application/json' })), + headers: cleanAPIv1Headers(key, selectedVersion, new Headers({ Accept: 'application/json' })), }) .then(async res => { - const body = await handleRes(res, false); + const body = await handleAPIv1Res(res, false); if (!res.ok) { if (res.status !== 404) return Promise.reject(new APIError(body)); this.debug(`error retrieving data for ${slug}, creating doc`); diff --git a/src/lib/versionSelect.ts b/src/lib/versionSelect.ts index 5ee79cb9f..2516239aa 100644 --- a/src/lib/versionSelect.ts +++ b/src/lib/versionSelect.ts @@ -5,7 +5,7 @@ import APIError from './apiError.js'; import isCI from './isCI.js'; import { warn } from './logger.js'; import promptTerminal from './promptWrapper.js'; -import { cleanHeaders, handleRes, readmeAPIV1Fetch } from './readmeAPIFetch.js'; +import { cleanAPIv1Headers, handleAPIv1Res, readmeAPIv1Fetch } from './readmeAPIFetch.js'; /** * Validates and returns a project version. @@ -21,11 +21,11 @@ export async function getProjectVersion( ): Promise { try { if (versionFlag) { - return await readmeAPIV1Fetch(`/api/v1/version/${versionFlag}`, { + return await readmeAPIv1Fetch(`/api/v1/version/${versionFlag}`, { method: 'get', - headers: cleanHeaders(key), + headers: cleanAPIv1Headers(key), }) - .then(handleRes) + .then(handleAPIv1Res) .then((res: Version) => res.version); } @@ -34,10 +34,10 @@ export async function getProjectVersion( return undefined; } - const versionList: Version[] = await readmeAPIV1Fetch('/api/v1/version', { + const versionList: Version[] = await readmeAPIv1Fetch('/api/v1/version', { method: 'get', - headers: cleanHeaders(key), - }).then(handleRes); + headers: cleanAPIv1Headers(key), + }).then(handleAPIv1Res); if (versionList.length === 1) { return versionList[0].version;