From c07764f9df2d87c81aa545f48b0e84620013c4ab Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 10:33:40 -0300 Subject: [PATCH 1/9] chore: remove unused imports --- src/commands/syncConfig.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/commands/syncConfig.ts b/src/commands/syncConfig.ts index 1995463..944a618 100644 --- a/src/commands/syncConfig.ts +++ b/src/commands/syncConfig.ts @@ -1,14 +1,10 @@ import { Command } from 'commander'; import { uploadConfiguration, - login, updateCloudConfiguration, - hasGithubCli, - isGithubLogged, getConfiguration, basicGithubVerifications, } from '../lib/github'; -import { confirm } from '@inquirer/prompts'; import { changeGistUrl, createConfig, getConfig } from '../lib/utils'; const syncConfig = new Command('sync') From 08a45a05e83bd766caae1ced24ec4134db1d4cd9 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:12:44 -0300 Subject: [PATCH 2/9] chore(deps): add `fast-levenshtein` --- package-lock.json | 29 ++++++++++++++++++++++++++++- package.json | 4 +++- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18c4702..b4b88d6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,13 +10,15 @@ "license": "MIT", "dependencies": { "@inquirer/prompts": "^5.4.0", - "commander": "^12.1.0" + "commander": "^12.1.0", + "fast-levenshtein": "^3.0.0" }, "bin": { "fj": "bin/index.js", "foji": "bin/index.js" }, "devDependencies": { + "@types/fast-levenshtein": "^0.0.4", "@types/inquirer": "^9.0.7", "@types/node": "^22.5.1", "semantic-release": "^24.1.1", @@ -761,6 +763,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@types/fast-levenshtein": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@types/fast-levenshtein/-/fast-levenshtein-0.0.4.tgz", + "integrity": "sha512-tkDveuitddQCxut1Db8eEFfMahTjOumTJGPHmT9E7KUH+DkVq9WTpVvlfenf3S+uCBeu8j5FP2xik/KfxOEjeA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/inquirer": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-9.0.7.tgz", @@ -1658,6 +1667,24 @@ "node": ">=8.6.0" } }, + "node_modules/fast-levenshtein": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", + "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", + "license": "MIT", + "dependencies": { + "fastest-levenshtein": "^1.0.7" + } + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", diff --git a/package.json b/package.json index 068df61..4f9d729 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "license": "MIT", "description": "Forge your code in a new way.", "devDependencies": { + "@types/fast-levenshtein": "^0.0.4", "@types/inquirer": "^9.0.7", "@types/node": "^22.5.1", "semantic-release": "^24.1.1", @@ -34,6 +35,7 @@ }, "dependencies": { "@inquirer/prompts": "^5.4.0", - "commander": "^12.1.0" + "commander": "^12.1.0", + "fast-levenshtein": "^3.0.0" } } From 56b4741ca66645d7e1161c168bf536950bde1fcc Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:13:01 -0300 Subject: [PATCH 3/9] feat: add suggestion to command not found --- src/commands/index.ts | 22 ++++++++++++++++++++-- src/lib/utils.ts | 17 +++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/commands/index.ts b/src/commands/index.ts index bbb078c..d9d7e3a 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -6,7 +6,12 @@ import removeCommand from './removeCommand'; import openConfig from './openConfig'; import uploadConfig from './uploadConfig'; import downloadConfig from './downloadConfig'; -import { getConfig, logList, runUserCommand } from '../lib/utils'; +import { + getClosestWord, + getConfig, + logList, + runUserCommand, +} from '../lib/utils'; import syncConfig from './syncConfig'; import renameCommand from './renameCommand'; @@ -51,7 +56,20 @@ const program = new Command() const command = configCommands[commandName]; if (!command) { - console.error(`command "${commandName}" not found`); + const closestWord = getClosestWord( + commandName, + Object.keys(configCommands) + ); + + let suggestion: string; + + if (isFinite(closestWord.distance)) + suggestion = `\nDid you mean: "${closestWord.word}"?`; + + console.error( + `command "${commandName}" not found.${suggestion ? suggestion : ''}` + ); + process.exit(1); } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 53f1674..d1f28cf 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,5 +1,6 @@ import { confirm } from '@inquirer/prompts'; import { spawn, exec } from 'node:child_process'; +import levenshtein from 'fast-levenshtein'; import * as fs from 'node:fs'; import * as os from 'node:os'; import * as path from 'node:path'; @@ -205,3 +206,19 @@ export function openDirectory(path: string) { exec(`${command} "${path}"`); } + +export function getClosestWord( + searchWord: string, + words: string[], + defaultWord?: '' +): { distance: number; word: string } { + return words.reduce( + (data, word) => { + const distance = levenshtein.get(searchWord, word); + + if (distance < data.distance) return { distance, word }; + return data; + }, + { distance: Infinity, word: defaultWord } + ); +} From 07145f1c253cb3652d42940cbabdf7df7283a892 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:21:56 -0300 Subject: [PATCH 4/9] chore: change suggestion formatting --- src/commands/index.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/index.ts b/src/commands/index.ts index d9d7e3a..5ceec2d 100644 --- a/src/commands/index.ts +++ b/src/commands/index.ts @@ -64,11 +64,11 @@ const program = new Command() let suggestion: string; if (isFinite(closestWord.distance)) - suggestion = `\nDid you mean: "${closestWord.word}"?`; + suggestion = `Did you mean: "${closestWord.word}"?`; - console.error( - `command "${commandName}" not found.${suggestion ? suggestion : ''}` - ); + console.error(`command "${commandName}" not found.`); + + if (suggestion) console.log(suggestion); process.exit(1); } From 58af596c3cf368c98d9510c9210087445b0f81c2 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:35:42 -0300 Subject: [PATCH 5/9] refactor: enhance debug mode output --- src/lib/utils.ts | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index d1f28cf..2042707 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -151,12 +151,6 @@ export function formatCommand( args = args.map((arg) => (arg === '_' ? undefined : arg)); - if (debug) { - console.log('Command:', command); - console.log('Command arguments:', commandArguments); - console.log('Received arguments:', args); - } - for (let index = 0; index < commandArguments.length; index++) { const arg = commandArguments[index]; let argValue = arg.alternativeValue @@ -168,6 +162,16 @@ export function formatCommand( splitCommand[index * 2 + 1] = argValue; } + if (debug) { + console.log('Command:', command); + console.log('Command arguments:', commandArguments); + console.log('Received arguments:', args); + console.log(`Formatted command: ${splitCommand.join('')}`); + console.log(); + console.log('Running command...'); + console.log(); + } + return splitCommand.join(''); } From b612ee3725a4b7142783c61490a22519740a5587 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:53:19 -0300 Subject: [PATCH 6/9] refactor: set `next` branch as `prerelease` --- release.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.config.mjs b/release.config.mjs index 1632787..c47377c 100644 --- a/release.config.mjs +++ b/release.config.mjs @@ -2,5 +2,5 @@ * @type {import('semantic-release').GlobalConfig} */ export default { - branches: ['master', 'next'], + branches: ['master', { name: 'next', prerelease: true }], }; From b3c4a3db367536cd6d61d6e5dac0cb61c65f7667 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:56:21 -0300 Subject: [PATCH 7/9] refactor: change `next` prerelease to `beta` --- release.config.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release.config.mjs b/release.config.mjs index c47377c..f902b49 100644 --- a/release.config.mjs +++ b/release.config.mjs @@ -2,5 +2,5 @@ * @type {import('semantic-release').GlobalConfig} */ export default { - branches: ['master', { name: 'next', prerelease: true }], + branches: ['master', 'next', { name: 'beta', prerelease: true }], }; From ffc74d38399c604e64b7de88c06b2f2bc9555a43 Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 11:59:51 -0300 Subject: [PATCH 8/9] chore: change `package.json` version to `0.0.0-development` --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4f9d729..3fc58d1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "foji", - "version": "0.4.1", + "version": "0.0.0-development", "main": "src/index.ts", "bin": { "foji": "./bin/index.js", From 690d71e88ec654e5217cd57c06ecd528c3a6a4eb Mon Sep 17 00:00:00 2001 From: Felipe Cardoso Date: Mon, 16 Sep 2024 13:42:42 -0300 Subject: [PATCH 9/9] chore: update `package-lock.json` versions --- package-lock.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index b4b88d6..c4c395d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "foji", - "version": "0.4.1", + "version": "0.0.0-development", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "foji", - "version": "0.4.1", + "version": "0.0.0-development", "license": "MIT", "dependencies": { "@inquirer/prompts": "^5.4.0",