diff --git a/.eslintrc b/.eslintrc index ff5bea0b1..8fceff89e 100644 --- a/.eslintrc +++ b/.eslintrc @@ -30,15 +30,6 @@ */ "class-methods-use-this": ["error", { "exceptMethods": ["run"] }], - "import/order": ["error", { - "alphabetize": { - "order": "asc", - "caseInsensitive": true - }, - "groups": ["type", "builtin", "external", "internal", "parent", "sibling", "index", "object"], - "newlines-between": "always" - }], - /** * This is a small rule to prevent us from using console.log() statements in our commands. * diff --git a/package-lock.json b/package-lock.json index c5e2a3560..a520efcdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "rdme": "bin/rdme" }, "devDependencies": { - "@readme/eslint-config": "^9.0.0", + "@readme/eslint-config": "^10.0.0", "@readme/oas-examples": "^5.3.0", "@types/cli-table": "^0.3.0", "@types/command-line-args": "^5.2.0", @@ -1361,9 +1361,9 @@ } }, "node_modules/@readme/eslint-config": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@readme/eslint-config/-/eslint-config-9.0.0.tgz", - "integrity": "sha512-r11j5+y2h8zbF+icsQCcjrTTfpzyFD9pybgyQWrm8/Qq+dklmcfnV84fusfyuQxX7czXi6w3GnsQhUorXv8LIg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@readme/eslint-config/-/eslint-config-10.0.0.tgz", + "integrity": "sha512-jrRFj/rzj4sl5BiXvxJ4d9KBywjTTHv0Pd0FnfRnLzDGjKgcHfM8E6uoJjKxnFxJAq/w8LxzYdq/fWAGnf+nwA==", "dev": true, "dependencies": { "@typescript-eslint/eslint-plugin": "^5.30.5", @@ -13810,9 +13810,9 @@ } }, "@readme/eslint-config": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@readme/eslint-config/-/eslint-config-9.0.0.tgz", - "integrity": "sha512-r11j5+y2h8zbF+icsQCcjrTTfpzyFD9pybgyQWrm8/Qq+dklmcfnV84fusfyuQxX7czXi6w3GnsQhUorXv8LIg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@readme/eslint-config/-/eslint-config-10.0.0.tgz", + "integrity": "sha512-jrRFj/rzj4sl5BiXvxJ4d9KBywjTTHv0Pd0FnfRnLzDGjKgcHfM8E6uoJjKxnFxJAq/w8LxzYdq/fWAGnf+nwA==", "dev": true, "requires": { "@typescript-eslint/eslint-plugin": "^5.30.5", diff --git a/package.json b/package.json index 17d7a217d..b15c9e149 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,7 @@ "update-notifier": "^5.1.0" }, "devDependencies": { - "@readme/eslint-config": "^9.0.0", + "@readme/eslint-config": "^10.0.0", "@readme/oas-examples": "^5.3.0", "@types/cli-table": "^0.3.0", "@types/command-line-args": "^5.2.0", diff --git a/src/cmds/categories/create.ts b/src/cmds/categories/create.ts index 735ee463a..b395fabc7 100644 --- a/src/cmds/categories/create.ts +++ b/src/cmds/categories/create.ts @@ -7,7 +7,6 @@ import { Headers } from 'node-fetch'; import Command, { CommandCategories } from '../../lib/baseCommand'; import fetch, { cleanHeaders, handleRes } from '../../lib/fetch'; import getCategories from '../../lib/getCategories'; -import { debug } from '../../lib/logger'; import { getProjectVersion } from '../../lib/versionSelect'; interface Category { @@ -73,7 +72,7 @@ export default class CategoriesCreateCommand extends Command { const selectedVersion = await getProjectVersion(version, key, false); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); async function matchCategory() { const allCategories = await getCategories(key, selectedVersion); diff --git a/src/cmds/categories/index.ts b/src/cmds/categories/index.ts index c2acde7b2..d4e78cdce 100644 --- a/src/cmds/categories/index.ts +++ b/src/cmds/categories/index.ts @@ -2,7 +2,6 @@ import type { CommandOptions } from '../../lib/baseCommand'; import Command, { CommandCategories } from '../../lib/baseCommand'; import getCategories from '../../lib/getCategories'; -import { debug } from '../../lib/logger'; import { getProjectVersion } from '../../lib/versionSelect'; export default class CategoriesCommand extends Command { @@ -32,7 +31,7 @@ export default class CategoriesCommand extends Command { const selectedVersion = await getProjectVersion(version, key, true); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); const allCategories = await getCategories(key, selectedVersion); diff --git a/src/cmds/changelogs/index.ts b/src/cmds/changelogs/index.ts index 4d835d41f..0453f3855 100644 --- a/src/cmds/changelogs/index.ts +++ b/src/cmds/changelogs/index.ts @@ -4,7 +4,6 @@ import chalk from 'chalk'; import config from 'config'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { debug } from '../../lib/logger'; import pushDoc, { readdirRecursive } from '../../lib/pushDoc'; export type Options = { @@ -56,7 +55,7 @@ export default class ChangelogsCommand extends Command { file => file.toLowerCase().endsWith('.md') || file.toLowerCase().endsWith('.markdown') ); - debug(`number of files: ${files.length}`); + Command.debug(`number of files: ${files.length}`); if (!files.length) { return Promise.reject(new Error(`We were unable to locate Markdown files in ${folder}.`)); diff --git a/src/cmds/custompages/index.ts b/src/cmds/custompages/index.ts index 4855ebc3a..9ae45089a 100644 --- a/src/cmds/custompages/index.ts +++ b/src/cmds/custompages/index.ts @@ -4,7 +4,6 @@ import chalk from 'chalk'; import config from 'config'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { debug } from '../../lib/logger'; import pushDoc, { readdirRecursive } from '../../lib/pushDoc'; export type Options = { @@ -59,7 +58,7 @@ export default class CustomPagesCommand extends Command { file.toLowerCase().endsWith('.markdown') ); - debug(`number of files: ${files.length}`); + Command.debug(`number of files: ${files.length}`); if (!files.length) { return Promise.reject(new Error(`We were unable to locate Markdown or HTML files in ${folder}.`)); diff --git a/src/cmds/docs/edit.ts b/src/cmds/docs/edit.ts index 33b6eb308..8a85ea826 100644 --- a/src/cmds/docs/edit.ts +++ b/src/cmds/docs/edit.ts @@ -11,7 +11,6 @@ import editor from 'editor'; import APIError from '../../lib/apiError'; import Command, { CommandCategories } from '../../lib/baseCommand'; import fetch, { cleanHeaders, handleRes } from '../../lib/fetch'; -import { debug, info } from '../../lib/logger'; import { getProjectVersion } from '../../lib/versionSelect'; const writeFile = promisify(fs.writeFile); @@ -60,7 +59,7 @@ export default class EditDocsCommand extends Command { const selectedVersion = await getProjectVersion(version, key, true); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); const filename = `${slug}.md`; @@ -77,15 +76,15 @@ export default class EditDocsCommand extends Command { await writeFile(filename, existingDoc.body); - debug(`wrote to local file: ${filename}, opening editor`); + Command.debug(`wrote to local file: ${filename}, opening editor`); return new Promise((resolve, reject) => { (opts.mockEditor || editor)(filename, async (code: number) => { - debug(`editor closed with code ${code}`); + Command.debug(`editor closed with code ${code}`); if (code !== 0) return reject(new Error('Non zero exit code from $EDITOR')); const updatedDoc = await readFile(filename, 'utf8'); - debug(`read edited contents of ${filename}, sending to ReadMe`); + Command.debug(`read edited contents of ${filename}, sending to ReadMe`); return fetch(`${config.get('host')}/api/v1/docs/${slug}`, { method: 'put', @@ -104,16 +103,19 @@ export default class EditDocsCommand extends Command { }) .then(res => res.json()) .then(async res => { - debug(`response from PUT request: ${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 // the Promise that's wrapping this function. if (res.error) { return reject(new APIError(res)); } - info('Doc successfully updated. Cleaning up local file.'); + + Command.info('Doc successfully updated. Cleaning up local file.'); + await unlink(filename); - debug('file unlinked'); + Command.debug('file unlinked'); + // Normally we should resolve with a value that is logged to the console, // but since we need to wait for the temporary file to be removed, // it's okay to resolve the promise with no value. diff --git a/src/cmds/docs/index.ts b/src/cmds/docs/index.ts index 40fca8b51..1bc649e85 100644 --- a/src/cmds/docs/index.ts +++ b/src/cmds/docs/index.ts @@ -4,7 +4,6 @@ import chalk from 'chalk'; import config from 'config'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { debug } from '../../lib/logger'; import pushDoc, { readdirRecursive } from '../../lib/pushDoc'; import { getProjectVersion } from '../../lib/versionSelect'; @@ -58,14 +57,14 @@ export default class DocsCommand extends Command { // Ideally we should ignore this parameter entirely if the category is included. const selectedVersion = await getProjectVersion(version, key, false); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); // Strip out non-markdown files const files = readdirRecursive(folder).filter( file => file.toLowerCase().endsWith('.md') || file.toLowerCase().endsWith('.markdown') ); - debug(`number of files: ${files.length}`); + Command.debug(`number of files: ${files.length}`); if (!files.length) { return Promise.reject(new Error(`We were unable to locate Markdown files in ${folder}.`)); diff --git a/src/cmds/docs/single.ts b/src/cmds/docs/single.ts index eb80c5cb8..722a5a00a 100644 --- a/src/cmds/docs/single.ts +++ b/src/cmds/docs/single.ts @@ -4,7 +4,6 @@ import chalk from 'chalk'; import config from 'config'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { debug } from '../../lib/logger'; import pushDoc from '../../lib/pushDoc'; import { getProjectVersion } from '../../lib/versionSelect'; @@ -62,7 +61,7 @@ export default class SingleDocCommand extends Command { // Ideally we should ignore this parameter entirely if the category is included. const selectedVersion = await getProjectVersion(version, key, false); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); const createdDoc = await pushDoc(key, selectedVersion, dryRun, filePath, this.cmdCategory); diff --git a/src/cmds/open.ts b/src/cmds/open.ts index 048fc99fe..04314c07f 100644 --- a/src/cmds/open.ts +++ b/src/cmds/open.ts @@ -6,7 +6,6 @@ import open from 'open'; import Command, { CommandCategories } from '../lib/baseCommand'; import configStore from '../lib/configstore'; -import { debug } from '../lib/logger'; export type Options = { mockOpen?: (url: string) => Promise; @@ -29,7 +28,7 @@ export default class OpenCommand extends Command { super.run(opts); const project = configStore.get('project'); - debug(`project: ${project}`); + Command.debug(`project: ${project}`); if (!project) { return Promise.reject(new Error(`Please login using \`${config.get('cli')} login\`.`)); diff --git a/src/cmds/openapi.ts b/src/cmds/openapi.ts index 2a65f56d3..b43cd4642 100644 --- a/src/cmds/openapi.ts +++ b/src/cmds/openapi.ts @@ -10,7 +10,7 @@ import parse from 'parse-link-header'; import Command, { CommandCategories } from '../lib/baseCommand'; import fetch, { cleanHeaders, handleRes } from '../lib/fetch'; -import { debug, info, warn, oraOptions } from '../lib/logger'; +import { oraOptions } from '../lib/logger'; import prepareOas from '../lib/prepareOas'; import * as promptHandler from '../lib/prompts'; import streamSpecToRegistry from '../lib/streamSpecToRegistry'; @@ -81,7 +81,9 @@ export default class OpenAPICommand extends Command { } if (version && id) { - warn("We'll be using the version associated with the `--id` option, so the `--version` option will be ignored."); + Command.warn( + "We'll be using the version associated with the `--id` option, so the `--version` option will be ignored." + ); } // Reason we're hardcoding in command here is because `swagger` command @@ -89,7 +91,9 @@ export default class OpenAPICommand extends Command { const { bundledSpec, specPath, specType, specVersion } = await prepareOas(spec, 'openapi'); if (useSpecVersion) { - info(`Using the version specified in your API definition for your ReadMe project version (${specVersion})`); + Command.info( + `Using the version specified in your API definition for your ReadMe project version (${specVersion})` + ); selectedVersion = specVersion; } @@ -97,16 +101,16 @@ export default class OpenAPICommand extends Command { selectedVersion = await getProjectVersion(selectedVersion, key, true); } - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); async function success(data: Response) { const message = !isUpdate ? `You've successfully uploaded a new ${specType} file to your ReadMe project!` : `You've successfully updated an existing ${specType} file on your ReadMe project!`; - debug(`successful ${data.status} response`); + Command.debug(`successful ${data.status} response`); const body = await data.json(); - debug(`successful response payload: ${JSON.stringify(body)}`); + Command.debug(`successful response payload: ${JSON.stringify(body)}`); return Promise.resolve( [ @@ -211,23 +215,23 @@ export default class OpenAPICommand extends Command { } if (!id) { - debug('no id parameter, retrieving list of API specs'); + Command.debug('no id parameter, retrieving list of API specs'); const apiSettings = await getSpecs('/api/v1/api-specification'); const totalPages = Math.ceil(parseInt(apiSettings.headers.get('x-total-count'), 10) / 10); const parsedDocs = parse(apiSettings.headers.get('link')); - debug(`total pages: ${totalPages}`); - debug(`pagination result: ${JSON.stringify(parsedDocs)}`); + Command.debug(`total pages: ${totalPages}`); + Command.debug(`pagination result: ${JSON.stringify(parsedDocs)}`); const apiSettingsBody = await apiSettings.json(); - debug(`api settings list response payload: ${JSON.stringify(apiSettingsBody)}`); + Command.debug(`api settings list response payload: ${JSON.stringify(apiSettingsBody)}`); if (!apiSettingsBody.length) return createSpec(); const { option }: { option: 'create' | 'update' } = await prompt( promptHandler.createOasPrompt(apiSettingsBody, parsedDocs, totalPages, getSpecs) ); - debug(`selection result: ${option}`); + Command.debug(`selection result: ${option}`); if (!option) return null; return option === 'create' ? createSpec() : updateSpec(option); } diff --git a/src/cmds/swagger.ts b/src/cmds/swagger.ts index 01379fc66..1d5785956 100644 --- a/src/cmds/swagger.ts +++ b/src/cmds/swagger.ts @@ -1,7 +1,7 @@ import type { CommandOptions } from '../lib/baseCommand'; import type { Options } from './openapi'; -import { warn } from '../lib/logger'; +import Command from '../lib/baseCommand'; import OpenAPICommand from './openapi'; @@ -16,7 +16,7 @@ export default class SwaggerCommand extends OpenAPICommand { } async run(opts: CommandOptions) { - warn('`rdme swagger` has been deprecated. Please use `rdme openapi` instead.'); + Command.warn('`rdme swagger` has been deprecated. Please use `rdme openapi` instead.'); return super.run(opts); } } diff --git a/src/cmds/versions/delete.ts b/src/cmds/versions/delete.ts index 77416cc7b..7d2d0bf4d 100644 --- a/src/cmds/versions/delete.ts +++ b/src/cmds/versions/delete.ts @@ -4,7 +4,6 @@ import config from 'config'; import Command, { CommandCategories } from '../../lib/baseCommand'; import fetch, { cleanHeaders, handleRes } from '../../lib/fetch'; -import { debug } from '../../lib/logger'; import { getProjectVersion } from '../../lib/versionSelect'; export default class DeleteVersionCommand extends Command { @@ -41,7 +40,7 @@ export default class DeleteVersionCommand extends Command { return Promise.reject(e); }); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); return fetch(`${config.get('host')}/api/v1/version/${selectedVersion}`, { method: 'delete', diff --git a/src/cmds/versions/update.ts b/src/cmds/versions/update.ts index 6848563ba..892935d6a 100644 --- a/src/cmds/versions/update.ts +++ b/src/cmds/versions/update.ts @@ -6,7 +6,6 @@ import { Headers } from 'node-fetch'; import Command, { CommandCategories } from '../../lib/baseCommand'; import fetch, { cleanHeaders, handleRes } from '../../lib/fetch'; -import { debug } from '../../lib/logger'; import * as promptHandler from '../../lib/prompts'; import { getProjectVersion } from '../../lib/versionSelect'; @@ -68,7 +67,7 @@ export default class UpdateVersionCommand extends Command { return Promise.reject(e); }); - debug(`selectedVersion: ${selectedVersion}`); + Command.debug(`selectedVersion: ${selectedVersion}`); const foundVersion = await fetch(`${config.get('host')}/api/v1/version/${selectedVersion}`, { method: 'get', diff --git a/src/lib/baseCommand.ts b/src/lib/baseCommand.ts index 7c27b7ce9..0b74deef8 100644 --- a/src/lib/baseCommand.ts +++ b/src/lib/baseCommand.ts @@ -1,6 +1,7 @@ +/* eslint-disable class-methods-use-this */ import type { OptionDefinition } from 'command-line-usage'; -import { debug } from './logger'; +import { debug, info, warn } from './logger'; export type CommandOptions = T & { key?: string; @@ -34,8 +35,8 @@ export default class Command { args: OptionDefinition[]; run(opts: CommandOptions<{}>, requiresAuth?: boolean): void | Promise { - debug(`command: ${this.command}`); - debug(`opts: ${JSON.stringify(opts)}`); + Command.debug(`command: ${this.command}`); + Command.debug(`opts: ${JSON.stringify(opts)}`); if (requiresAuth) { if (!opts.key) { @@ -44,7 +45,6 @@ export default class Command { } } - // eslint-disable-next-line class-methods-use-this getVersionArg() { return { name: 'version', @@ -53,4 +53,16 @@ export default class Command { 'Project version. If running command in a CI environment and this option is not passed, the main project version will be used.', }; } + + static debug(msg: string) { + debug(msg); + } + + static info(msg: string) { + info(msg); + } + + static warn(msg: string) { + warn(msg); + } }