From c87aaf2e110953317fa8a129812c2ed57d4f36ed Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 3 Jan 2023 13:02:44 -0600 Subject: [PATCH 1/6] fix(login): better indicators to input project subdomain --- src/lib/loginFlow.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/loginFlow.ts b/src/lib/loginFlow.ts index 3626e3003..4950b4ad4 100644 --- a/src/lib/loginFlow.ts +++ b/src/lib/loginFlow.ts @@ -51,8 +51,12 @@ export default async function loginFlow(otp?: string) { { type: 'text', name: 'project', - message: 'What project are you logging into?', + message: 'What project subdomain are you logging into?', initial: storedConfig.project, + validate: value => + // eslint-disable-next-line unicorn/no-unsafe-regex + /^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/.test(value) || + 'Project subdomain must contain only letters, numbers and dashes.', }, ]); From a92eae88a050dd1edde33d24b8bed12dfd1aa759 Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 3 Jan 2023 13:10:46 -0600 Subject: [PATCH 2/6] refactor: rename helper function/file --- __tests__/lib/checkFile.test.ts | 10 +++++----- src/cmds/openapi/convert.ts | 4 ++-- src/cmds/openapi/reduce.ts | 4 ++-- src/lib/createGHA/index.ts | 4 ++-- src/lib/{checkFile.ts => validatePromptInput.ts} | 2 +- 5 files changed, 12 insertions(+), 12 deletions(-) rename src/lib/{checkFile.ts => validatePromptInput.ts} (88%) diff --git a/__tests__/lib/checkFile.test.ts b/__tests__/lib/checkFile.test.ts index 3188af19f..d81af2f98 100644 --- a/__tests__/lib/checkFile.test.ts +++ b/__tests__/lib/checkFile.test.ts @@ -1,14 +1,14 @@ import fs from 'fs'; -import { checkFilePath } from '../../src/lib/checkFile'; +import { validateFilePath } from '../../src/lib/validatePromptInput'; -describe('#checkFilePath', () => { +describe('#validateFilePath', () => { afterEach(() => { jest.clearAllMocks(); }); it('should return error for empty path value', () => { - return expect(checkFilePath('')).toBe('An output path must be supplied.'); + return expect(validateFilePath('')).toBe('An output path must be supplied.'); }); it('should return error if path already exists', () => { @@ -17,7 +17,7 @@ describe('#checkFilePath', () => { fs.existsSync = jest.fn(() => true); - expect(checkFilePath(testPath)).toBe('Specified output path already exists.'); + expect(validateFilePath(testPath)).toBe('Specified output path already exists.'); expect(fs.existsSync).toHaveBeenCalledWith(testPath); }); @@ -27,7 +27,7 @@ describe('#checkFilePath', () => { fs.existsSync = jest.fn(() => false); - expect(checkFilePath(testPath)).toBe(true); + expect(validateFilePath(testPath)).toBe(true); expect(fs.existsSync).toHaveBeenCalledWith(testPath); }); }); diff --git a/src/cmds/openapi/convert.ts b/src/cmds/openapi/convert.ts index c1d4ba14d..a24262a4b 100644 --- a/src/cmds/openapi/convert.ts +++ b/src/cmds/openapi/convert.ts @@ -8,7 +8,7 @@ import chalk from 'chalk'; import prompts from 'prompts'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { checkFilePath } from '../../lib/checkFile'; +import { validateFilePath } from '../../lib/validatePromptInput'; import prepareOas from '../../lib/prepareOas'; import promptTerminal from '../../lib/promptWrapper'; @@ -72,7 +72,7 @@ export default class OpenAPIConvertCommand extends Command { const extension = path.extname(specPath); return `${path.basename(specPath).split(extension)[0]}.openapi${extension}`; }, - validate: value => checkFilePath(value), + validate: value => validateFilePath(value), }, ]); diff --git a/src/cmds/openapi/reduce.ts b/src/cmds/openapi/reduce.ts index c53f1e6fe..5b8d93bf4 100644 --- a/src/cmds/openapi/reduce.ts +++ b/src/cmds/openapi/reduce.ts @@ -11,7 +11,7 @@ import ora from 'ora'; import prompts from 'prompts'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { checkFilePath } from '../../lib/checkFile'; +import { validateFilePath } from '../../lib/validatePromptInput'; import { oraOptions } from '../../lib/logger'; import prepareOas from '../../lib/prepareOas'; import promptTerminal from '../../lib/promptWrapper'; @@ -170,7 +170,7 @@ export default class OpenAPIReduceCommand extends Command { const extension = path.extname(specPath); return `${path.basename(specPath).split(extension)[0]}.reduced${extension}`; }, - validate: value => checkFilePath(value), + validate: value => validateFilePath(value), }, ]); diff --git a/src/lib/createGHA/index.ts b/src/lib/createGHA/index.ts index e9472eaa8..613fe351e 100644 --- a/src/lib/createGHA/index.ts +++ b/src/lib/createGHA/index.ts @@ -9,7 +9,7 @@ import chalk from 'chalk'; import prompts from 'prompts'; import simpleGit from 'simple-git'; -import { checkFilePath, cleanFileName } from '../checkFile'; +import { validateFilePath, cleanFileName } from '../validatePromptInput'; import configstore from '../configstore'; import { getMajorPkgVersion } from '../getPkgVersion'; import isCI, { isNpmScript, isTest } from '../isCI'; @@ -234,7 +234,7 @@ export default async function createGHA( type: 'text', initial: cleanFileName(`rdme-${command}`), format: prev => getGHAFileName(prev), - validate: value => checkFilePath(value, getGHAFileName), + validate: value => validateFilePath(value, getGHAFileName), }, ], { diff --git a/src/lib/checkFile.ts b/src/lib/validatePromptInput.ts similarity index 88% rename from src/lib/checkFile.ts rename to src/lib/validatePromptInput.ts index aec4e5f73..badc50a24 100644 --- a/src/lib/checkFile.ts +++ b/src/lib/validatePromptInput.ts @@ -16,7 +16,7 @@ export const cleanFileName = (input: string) => input.replace(/[^a-z0-9]/gi, '-' * @returns true if path is valid (i.e. is non-empty and doesn't already exist), * otherwise a string containing the error message */ -export function checkFilePath(value: string, getFullPath: (file: string) => string = file => file) { +export function validateFilePath(value: string, getFullPath: (file: string) => string = file => file) { if (value.length) { const fullPath = getFullPath(value); if (!fs.existsSync(fullPath)) { From 5fcfab3fe51ae5c4dbefe48365d918b53b48f2b5 Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 3 Jan 2023 13:16:01 -0600 Subject: [PATCH 3/6] refactor: separate validator function, add tests --- __tests__/lib/checkFile.test.ts | 24 +++++++++++++++++++++++- src/lib/loginFlow.ts | 6 ++---- src/lib/validatePromptInput.ts | 13 +++++++++++++ 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/__tests__/lib/checkFile.test.ts b/__tests__/lib/checkFile.test.ts index d81af2f98..30c7ce2d5 100644 --- a/__tests__/lib/checkFile.test.ts +++ b/__tests__/lib/checkFile.test.ts @@ -1,6 +1,6 @@ import fs from 'fs'; -import { validateFilePath } from '../../src/lib/validatePromptInput'; +import { validateFilePath, validateSubdomain } from '../../src/lib/validatePromptInput'; describe('#validateFilePath', () => { afterEach(() => { @@ -31,3 +31,25 @@ describe('#validateFilePath', () => { expect(fs.existsSync).toHaveBeenCalledWith(testPath); }); }); + +describe('#validateSubdomain', () => { + it('should validate basic subdomain', () => { + expect(validateSubdomain('subdomain')).toBe(true); + }); + + it('should validate subdomain with other characters', () => { + expect(validateSubdomain('test-Subdomain123')).toBe(true); + }); + + it('should reject subdomain with spaces', () => { + expect(validateSubdomain('test subdomain')).toBe( + 'Project subdomain must contain only letters, numbers and dashes.' + ); + }); + + it('should reject subdomain with special characters', () => { + expect(validateSubdomain('test-subdomain!')).toBe( + 'Project subdomain must contain only letters, numbers and dashes.' + ); + }); +}); diff --git a/src/lib/loginFlow.ts b/src/lib/loginFlow.ts index 4950b4ad4..d4e7b7511 100644 --- a/src/lib/loginFlow.ts +++ b/src/lib/loginFlow.ts @@ -7,6 +7,7 @@ import fetch, { handleRes } from './fetch'; import getCurrentConfig from './getCurrentConfig'; import { debug } from './logger'; import promptTerminal from './promptWrapper'; +import { validateSubdomain } from './validatePromptInput'; interface LoginBody { email?: string; @@ -53,10 +54,7 @@ export default async function loginFlow(otp?: string) { name: 'project', message: 'What project subdomain are you logging into?', initial: storedConfig.project, - validate: value => - // eslint-disable-next-line unicorn/no-unsafe-regex - /^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/.test(value) || - 'Project subdomain must contain only letters, numbers and dashes.', + validate: validateSubdomain, }, ]); diff --git a/src/lib/validatePromptInput.ts b/src/lib/validatePromptInput.ts index badc50a24..9f32f20e6 100644 --- a/src/lib/validatePromptInput.ts +++ b/src/lib/validatePromptInput.ts @@ -28,3 +28,16 @@ export function validateFilePath(value: string, getFullPath: (file: string) => s return 'An output path must be supplied.'; } + +/** + * Validates that a project subdomain value is valid. + * + * @param value the terminal input + * @returns true if the subdomain value is valid, else an error message + */ +export function validateSubdomain(value: string) { + return ( + // eslint-disable-next-line unicorn/no-unsafe-regex + /^[a-zA-Z0-9]+(-[a-zA-Z0-9]+)*$/.test(value) || 'Project subdomain must contain only letters, numbers and dashes.' + ); +} From f44a477e9cd36f5940fb383987b7f3c25e3bab21 Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 3 Jan 2023 13:21:11 -0600 Subject: [PATCH 4/6] chore: rename another file --- __tests__/lib/{checkFile.test.ts => validatePromptInput.test.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename __tests__/lib/{checkFile.test.ts => validatePromptInput.test.ts} (100%) diff --git a/__tests__/lib/checkFile.test.ts b/__tests__/lib/validatePromptInput.test.ts similarity index 100% rename from __tests__/lib/checkFile.test.ts rename to __tests__/lib/validatePromptInput.test.ts From a9872f75c2f130fef2163b96c8e517ba91835c05 Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 3 Jan 2023 13:21:58 -0600 Subject: [PATCH 5/6] fix: lint --- src/cmds/openapi/convert.ts | 2 +- src/cmds/openapi/reduce.ts | 2 +- src/lib/createGHA/index.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cmds/openapi/convert.ts b/src/cmds/openapi/convert.ts index a24262a4b..011dda2b6 100644 --- a/src/cmds/openapi/convert.ts +++ b/src/cmds/openapi/convert.ts @@ -8,9 +8,9 @@ import chalk from 'chalk'; import prompts from 'prompts'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { validateFilePath } from '../../lib/validatePromptInput'; import prepareOas from '../../lib/prepareOas'; import promptTerminal from '../../lib/promptWrapper'; +import { validateFilePath } from '../../lib/validatePromptInput'; export interface Options { spec?: string; diff --git a/src/cmds/openapi/reduce.ts b/src/cmds/openapi/reduce.ts index 5b8d93bf4..7e18dbbc3 100644 --- a/src/cmds/openapi/reduce.ts +++ b/src/cmds/openapi/reduce.ts @@ -11,10 +11,10 @@ import ora from 'ora'; import prompts from 'prompts'; import Command, { CommandCategories } from '../../lib/baseCommand'; -import { validateFilePath } from '../../lib/validatePromptInput'; import { oraOptions } from '../../lib/logger'; import prepareOas from '../../lib/prepareOas'; import promptTerminal from '../../lib/promptWrapper'; +import { validateFilePath } from '../../lib/validatePromptInput'; export interface Options { spec?: string; diff --git a/src/lib/createGHA/index.ts b/src/lib/createGHA/index.ts index 613fe351e..f8d556c93 100644 --- a/src/lib/createGHA/index.ts +++ b/src/lib/createGHA/index.ts @@ -9,12 +9,12 @@ import chalk from 'chalk'; import prompts from 'prompts'; import simpleGit from 'simple-git'; -import { validateFilePath, cleanFileName } from '../validatePromptInput'; import configstore from '../configstore'; import { getMajorPkgVersion } from '../getPkgVersion'; import isCI, { isNpmScript, isTest } from '../isCI'; import { debug, info } from '../logger'; import promptTerminal from '../promptWrapper'; +import { validateFilePath, cleanFileName } from '../validatePromptInput'; import yamlBase from './baseFile'; From 4383d815052136e33911c613ba4000022587004a Mon Sep 17 00:00:00 2001 From: Kanad Gupta Date: Tue, 3 Jan 2023 13:23:29 -0600 Subject: [PATCH 6/6] chore: this was bugging me --- src/lib/createGHA/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/createGHA/index.ts b/src/lib/createGHA/index.ts index f8d556c93..2f7a3c01c 100644 --- a/src/lib/createGHA/index.ts +++ b/src/lib/createGHA/index.ts @@ -14,7 +14,7 @@ import { getMajorPkgVersion } from '../getPkgVersion'; import isCI, { isNpmScript, isTest } from '../isCI'; import { debug, info } from '../logger'; import promptTerminal from '../promptWrapper'; -import { validateFilePath, cleanFileName } from '../validatePromptInput'; +import { cleanFileName, validateFilePath } from '../validatePromptInput'; import yamlBase from './baseFile';