diff --git a/.github/workflows/lint-client.yml b/.github/workflows/lint-client.yml new file mode 100644 index 00000000..81bf267e --- /dev/null +++ b/.github/workflows/lint-client.yml @@ -0,0 +1,45 @@ +name: Lint Client + +on: + push: + branches: + - main + - release/* + paths: + - "clients/js/**" + - ".github/workflows/lint-client.yml" + pull_request: + branches: + - main + paths: + - "clients/js/**" + - ".github/workflows/lint-client.yml" + types: [opened, reopened] + + workflow_dispatch: + +jobs: + starshipjs-tests: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: clients/js + + steps: + - name: Checkout Repository 🛎️ + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20.x' + + - name: Install Dependencies + run: yarn install + + - name: Build Project + run: yarn build + + - name: Run lint + run: yarn run lint diff --git a/clients/js/.prettierrc.json b/clients/js/.prettierrc.json index f0eb61e0..0a725205 100644 --- a/clients/js/.prettierrc.json +++ b/clients/js/.prettierrc.json @@ -2,5 +2,5 @@ "trailingComma": "es5", "tabWidth": 2, "semi": true, - "singleQuote": false + "singleQuote": true } diff --git a/clients/js/package.json b/clients/js/package.json index e2cb8cdb..6d0635b7 100644 --- a/clients/js/package.json +++ b/clients/js/package.json @@ -27,12 +27,15 @@ "devDependencies": { "@types/jest": "^29.5.11", "@types/node": "^20.12.7", - "@typescript-eslint/eslint-plugin": "^6.18.1", - "@typescript-eslint/parser": "^6.18.1", + "@typescript-eslint/eslint-plugin": "^7.17.0", + "@typescript-eslint/parser": "^7.17.0", + "babel-core": "7.0.0-bridge.0", + "babel-jest": "^29.3.1", "copyfiles": "^2.4.1", "del-cli": "^5.1.0", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.2.1", "eslint-plugin-simple-import-sort": "^10.0.0", "eslint-plugin-unused-imports": "^3.0.0", "jest": "^29.6.2", diff --git a/clients/js/packages/cli/.eslintrc.js b/clients/js/packages/cli/.eslintrc.js new file mode 100644 index 00000000..19060255 --- /dev/null +++ b/clients/js/packages/cli/.eslintrc.js @@ -0,0 +1,75 @@ +module.exports = { + parser: '@typescript-eslint/parser', // Specify the ESLint parser + plugins: ['@typescript-eslint', 'prettier'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'plugin:prettier/recommended' + ], + parserOptions: { + ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + ecmaFeatures: { + jsx: true // Allows for the parsing of JSX + } + }, + env: { + es6: true, + browser: true, + node: true, + jest: true + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', // Disable the rule entirely + 'no-debugger': 2, + 'no-alert': 2, + 'no-await-in-loop': 0, + 'no-prototype-builtins': 0, + 'no-return-assign': ['error', 'except-parens'], + 'no-restricted-syntax': [ + 2, + 'ForInStatement', + 'LabeledStatement', + 'WithStatement' + ], + 'no-unused-vars': [ + 0, + { + ignoreSiblings: true, + argsIgnorePattern: 'React|res|next|^_' + } + ], + 'prefer-const': [ + 'error', + { + destructuring: 'all' + } + ], + 'no-unused-expressions': [ + 2, + { + allowTaggedTemplates: true + } + ], + 'no-console': 'off', + 'comma-dangle': 2, + 'jsx-quotes': [2, 'prefer-double'], + 'linebreak-style': ['error', 'unix'], + quotes: [ + 2, + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true + } + ], + 'prettier/prettier': [ + 'error', + { + trailingComma: 'none', + singleQuote: true, + printWidth: 80 + } + ] + } +}; diff --git a/clients/js/packages/cli/jest.config.js b/clients/js/packages/cli/jest.config.js index 0aa3aaa4..eecd0733 100644 --- a/clients/js/packages/cli/jest.config.js +++ b/clients/js/packages/cli/jest.config.js @@ -1,18 +1,18 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { - preset: "ts-jest", - testEnvironment: "node", - transform: { - "^.+\\.tsx?$": [ - "ts-jest", - { - babelConfig: false, - tsconfig: "tsconfig.json", - }, - ], - }, - transformIgnorePatterns: [`/node_modules/*`], - testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - modulePathIgnorePatterns: ["dist/*"] + preset: 'ts-jest', + testEnvironment: 'node', + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + babelConfig: false, + tsconfig: 'tsconfig.json' + } + ] + }, + transformIgnorePatterns: [`/node_modules/*`], + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + modulePathIgnorePatterns: ['dist/*'] }; diff --git a/clients/js/packages/cli/src/index.ts b/clients/js/packages/cli/src/index.ts index 3e5920bb..0253a25a 100755 --- a/clients/js/packages/cli/src/index.ts +++ b/clients/js/packages/cli/src/index.ts @@ -3,7 +3,13 @@ import { StarshipClient, StarshipInstaller } from '@starship-ci/client'; // Adju import { Inquirerer, type Question } from 'inquirerer'; import minimist from 'minimist'; -import { displayUsage, displayVersion, loadConfig, params,usageText } from './utils'; +import { + displayUsage, + displayVersion, + loadConfig, + params, + usageText +} from './utils'; const argv = minimist(process.argv.slice(2), { alias: { @@ -24,11 +30,11 @@ const prompter = new Inquirerer({ noTty: !argv.tty }); -const questions: Question[] = params.map(name => ({ name, type: 'text' })); +const questions: Question[] = params.map((name) => ({ name, type: 'text' })); // Filter questions based on the command function getQuestionsForCommand(command: string): Question[] { - const commonQuestions = questions.filter(q => q.name !== 'config'); + const commonQuestions = questions.filter((q) => q.name !== 'config'); if (['start', 'deploy', 'start-ports', 'wait-for-pods'].includes(command)) { return questions; // Include all questions, including config } else { @@ -63,8 +69,8 @@ async function main() { switch (command) { case 'install': installer.checkAndInstallDependencies().catch((err: any) => { - console.error('An error occurred during start:', err); - process.exit(1); + console.error('An error occurred during start:', err); + process.exit(1); }); break; case 'start': @@ -112,7 +118,7 @@ async function main() { } // Improved error handling -main().catch(err => { +main().catch((err) => { console.error('An error occurred:', err); prompter.close(); process.exit(1); diff --git a/clients/js/packages/cli/src/package.ts b/clients/js/packages/cli/src/package.ts index 9463bca2..19ee2e36 100644 --- a/clients/js/packages/cli/src/package.ts +++ b/clients/js/packages/cli/src/package.ts @@ -1,7 +1,7 @@ -import { existsSync,readFileSync } from "fs"; -import { dirname,join } from "path"; +import { existsSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; -// need to search due to the dist/ folder and src/, etc. +// need to search due to the dist/ folder and src/, etc. function findPackageJson(currentDir: string): any { const filePath = join(currentDir, 'package.json'); @@ -30,4 +30,4 @@ export function readAndParsePackageJson() { const str = readFileSync(pkgPath, 'utf8'); const pkg = JSON.parse(str); return pkg; -} \ No newline at end of file +} diff --git a/clients/js/packages/cli/src/prompt.ts b/clients/js/packages/cli/src/prompt.ts index 05040e6f..3bbf9d6c 100644 --- a/clients/js/packages/cli/src/prompt.ts +++ b/clients/js/packages/cli/src/prompt.ts @@ -22,10 +22,18 @@ export class Inquirerer { } // Method to prompt for missing parameters - public async prompt(params: T, questions: Question[], usageText?: string): Promise { + public async prompt( + params: T, + questions: Question[], + usageText?: string + ): Promise { const obj: any = { ...params }; - if (usageText && Object.values(params).some(value => value === undefined) && !this.noTty) { + if ( + usageText && + Object.values(params).some((value) => value === undefined) && + !this.noTty + ) { console.log(usageText); } @@ -37,7 +45,9 @@ export class Inquirerer { this.rl.question(`Enter ${question.name}: `, resolve); }); } else { - throw new Error("No TTY available and a readline interface is missing."); + throw new Error( + 'No TTY available and a readline interface is missing.' + ); } } else { // Optionally handle noTty cases, e.g., set defaults or throw errors diff --git a/clients/js/packages/cli/src/utils.ts b/clients/js/packages/cli/src/utils.ts index c31ce62f..6c070bd1 100644 --- a/clients/js/packages/cli/src/utils.ts +++ b/clients/js/packages/cli/src/utils.ts @@ -1,32 +1,34 @@ -import {defaultStarshipContext, StarshipConfig, StarshipContext} from '@starship-ci/client'; // Adjust the import path as necessary +import { + defaultStarshipContext, + StarshipConfig, + StarshipContext +} from '@starship-ci/client'; // Adjust the import path as necessary import chalk from 'chalk'; -import {readFileSync} from 'fs'; +import { readFileSync } from 'fs'; import * as yaml from 'js-yaml'; -import { resolve} from 'path'; +import { resolve } from 'path'; -import {readAndParsePackageJson} from './package'; +import { readAndParsePackageJson } from './package'; // Function to display the version information export function displayVersion() { - const pkg = readAndParsePackageJson(); - console.log(chalk.green(`Name: ${pkg.name}`)); - console.log(chalk.blue(`Version: ${pkg.version}`)); + const pkg = readAndParsePackageJson(); + console.log(chalk.green(`Name: ${pkg.name}`)); + console.log(chalk.blue(`Version: ${pkg.version}`)); } - const resolvePath = (filename: string) => filename.startsWith('/') ? filename : resolve((process.cwd(), filename)); - const loadYaml = (filename: string): any => { const path = resolvePath(filename); const fileContents = readFileSync(path, 'utf8'); return yaml.load(fileContents); -} +}; export interface Config { - context: StarshipContext, - starship: StarshipConfig + context: StarshipContext; + starship: StarshipConfig; } export const params: string[] = [ @@ -36,36 +38,38 @@ export const params: string[] = [ 'repo', 'repoUrl', 'chart', - 'namespace', -] + 'namespace' +]; export const loadConfig = (argv: any): Config => { - console.log("argv: ", argv); - let context: StarshipContext = { ...defaultStarshipContext } as StarshipContext; + console.log('argv: ', argv); + const context: StarshipContext = { + ...defaultStarshipContext + } as StarshipContext; let starship: StarshipConfig = {} as StarshipConfig; - console.log("context", context); + console.log('context', context); // Override context with command-line arguments dynamically based on StarshipContext keys - params.forEach(key => { + params.forEach((key) => { if (argv[key] !== undefined) { - console.log("key: ", key, " argv[key]: ", argv[key]); - // @ts-ignore + console.log('key: ', key, ' argv[key]: ', argv[key]); + // @ts-expect-error - dynamic assignment context[key] = argv[key]; } }); if (context.config) { context.config = resolvePath(context.config); - starship = loadYaml(context.config) as StarshipConfig + starship = loadYaml(context.config) as StarshipConfig; } - console.log("starship: ", starship); + console.log('starship: ', starship); - return {context, starship}; -} + return { context, starship }; +}; -export const usageText =` +export const usageText = ` Usage: starship [options] Commands: @@ -106,4 +110,4 @@ Additional Help: export function displayUsage() { console.log(usageText); -}; \ No newline at end of file +} diff --git a/clients/js/packages/client/.eslintrc.js b/clients/js/packages/client/.eslintrc.js new file mode 100644 index 00000000..19060255 --- /dev/null +++ b/clients/js/packages/client/.eslintrc.js @@ -0,0 +1,75 @@ +module.exports = { + parser: '@typescript-eslint/parser', // Specify the ESLint parser + plugins: ['@typescript-eslint', 'prettier'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'plugin:prettier/recommended' + ], + parserOptions: { + ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + ecmaFeatures: { + jsx: true // Allows for the parsing of JSX + } + }, + env: { + es6: true, + browser: true, + node: true, + jest: true + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', // Disable the rule entirely + 'no-debugger': 2, + 'no-alert': 2, + 'no-await-in-loop': 0, + 'no-prototype-builtins': 0, + 'no-return-assign': ['error', 'except-parens'], + 'no-restricted-syntax': [ + 2, + 'ForInStatement', + 'LabeledStatement', + 'WithStatement' + ], + 'no-unused-vars': [ + 0, + { + ignoreSiblings: true, + argsIgnorePattern: 'React|res|next|^_' + } + ], + 'prefer-const': [ + 'error', + { + destructuring: 'all' + } + ], + 'no-unused-expressions': [ + 2, + { + allowTaggedTemplates: true + } + ], + 'no-console': 'off', + 'comma-dangle': 2, + 'jsx-quotes': [2, 'prefer-double'], + 'linebreak-style': ['error', 'unix'], + quotes: [ + 2, + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true + } + ], + 'prettier/prettier': [ + 'error', + { + trailingComma: 'none', + singleQuote: true, + printWidth: 80 + } + ] + } +}; diff --git a/clients/js/packages/client/__tests__/client.config.test.ts b/clients/js/packages/client/__tests__/client.config.test.ts index a2c12884..9343ab93 100644 --- a/clients/js/packages/client/__tests__/client.config.test.ts +++ b/clients/js/packages/client/__tests__/client.config.test.ts @@ -7,13 +7,13 @@ describe('StarshipClient', () => { it('setup', () => { const { client, ctx } = createClient(); - client.dependencies.forEach(dep => dep.installed = true); + client.dependencies.forEach((dep) => (dep.installed = true)); client.setConfig(config.config); const helmFile = client.ctx.config; client.ctx.config = join(outputDir, 'my-config.yaml'); - client.ctx.config = relative(process.cwd(), client.ctx.chart) - // @ts-ignore + client.ctx.config = relative(process.cwd(), client.ctx.chart); + // @ts-expect-error - Ignore lint error client.saveYaml = () => {}; client.saveConfig(); client.ctx.config = helmFile; @@ -25,11 +25,11 @@ describe('StarshipClient', () => { // helm client.setup(); client.deploy(); - + client.startPortForward(); client.stop(); expectClient(ctx, -1); }); -}); \ No newline at end of file +}); diff --git a/clients/js/packages/client/__tests__/client.deps.test.ts b/clients/js/packages/client/__tests__/client.deps.test.ts index 22be0655..4b04104b 100644 --- a/clients/js/packages/client/__tests__/client.deps.test.ts +++ b/clients/js/packages/client/__tests__/client.deps.test.ts @@ -4,7 +4,7 @@ describe('StarshipClient', () => { it('missing deps', () => { const { client, ctx } = createClient(); - client.dependencies = client.dependencies.map(dep=>{ + client.dependencies = client.dependencies.map((dep) => { if (['kubectl', 'docker'].includes(dep.name)) { return { ...dep, @@ -14,19 +14,19 @@ describe('StarshipClient', () => { return dep; }); - // @ts-ignore - client.exec(['something']) + // @ts-expect-error - Ignore lint error + client.exec(['something']); expectClient(ctx, 1); - }) + }); it('has all deps', () => { const { client, ctx } = createClient(); - client.dependencies.forEach(dep => dep.installed = true); + client.dependencies.forEach((dep) => (dep.installed = true)); - // @ts-ignore - client.exec(['something']) + // @ts-expect-error - Ignore lint error + client.exec(['something']); expectClient(ctx, -1); - }) -}); \ No newline at end of file + }); +}); diff --git a/clients/js/packages/client/__tests__/client.ports.test.ts b/clients/js/packages/client/__tests__/client.ports.test.ts index 59ef1c5a..42691c72 100644 --- a/clients/js/packages/client/__tests__/client.ports.test.ts +++ b/clients/js/packages/client/__tests__/client.ports.test.ts @@ -7,28 +7,27 @@ describe('StarshipClient', () => { it('setup', () => { const { client, ctx } = createClient(); - client.dependencies.forEach(dep => dep.installed = true); + client.dependencies.forEach((dep) => (dep.installed = true)); client.setConfig(config.config); client.setPodPorts({ - chains: { - osmosis: { - exposer: 98988, - faucet: 1000000, - grpc: 909090, - rest: 6767676 - } + chains: { + osmosis: { + exposer: 98988, + faucet: 1000000, + grpc: 909090, + rest: 6767676 } + } }); const portYaml = join(outputDir, 'custom-pod-ports.yaml'); const relativePortYaml = relative(process.cwd(), portYaml); client.savePodPorts(relativePortYaml); - // helm client.setup(); client.deploy(); - + client.startPortForward(); // remove helm chart @@ -36,4 +35,4 @@ describe('StarshipClient', () => { expectClient(ctx, -1); }); -}); \ No newline at end of file +}); diff --git a/clients/js/packages/client/__tests__/client.test.ts b/clients/js/packages/client/__tests__/client.test.ts index f5c5ff30..1299003b 100644 --- a/clients/js/packages/client/__tests__/client.test.ts +++ b/clients/js/packages/client/__tests__/client.test.ts @@ -5,14 +5,14 @@ describe('StarshipClient', () => { it('setup', () => { const { client, ctx } = createClient(); - client.dependencies.forEach(dep => dep.installed = true); + client.dependencies.forEach((dep) => (dep.installed = true)); client.setConfig(config.config); // helm client.setup(); client.deploy(); - + client.startPortForward(); // remove helm chart @@ -20,4 +20,4 @@ describe('StarshipClient', () => { expectClient(ctx, -1); }); -}); \ No newline at end of file +}); diff --git a/clients/js/packages/client/jest.config.js b/clients/js/packages/client/jest.config.js index 0aa3aaa4..eecd0733 100644 --- a/clients/js/packages/client/jest.config.js +++ b/clients/js/packages/client/jest.config.js @@ -1,18 +1,18 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { - preset: "ts-jest", - testEnvironment: "node", - transform: { - "^.+\\.tsx?$": [ - "ts-jest", - { - babelConfig: false, - tsconfig: "tsconfig.json", - }, - ], - }, - transformIgnorePatterns: [`/node_modules/*`], - testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - modulePathIgnorePatterns: ["dist/*"] + preset: 'ts-jest', + testEnvironment: 'node', + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + babelConfig: false, + tsconfig: 'tsconfig.json' + } + ] + }, + transformIgnorePatterns: [`/node_modules/*`], + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + modulePathIgnorePatterns: ['dist/*'] }; diff --git a/clients/js/packages/client/src/client.ts b/clients/js/packages/client/src/client.ts index fcdcdca6..2f84eff2 100644 --- a/clients/js/packages/client/src/client.ts +++ b/clients/js/packages/client/src/client.ts @@ -7,9 +7,9 @@ import * as os from 'os'; import { dirname, resolve } from 'path'; import * as shell from 'shelljs'; -import {Chain, Relayer, StarshipConfig} from './config'; +import { Chain, Relayer, StarshipConfig } from './config'; import { Ports } from './config'; -import { dependencies as defaultDependencies, Dependency } from "./deps"; +import { dependencies as defaultDependencies, Dependency } from './deps'; import { readAndParsePackageJson } from './package'; export interface StarshipContext { @@ -22,7 +22,7 @@ export interface StarshipContext { namespace?: string; verbose?: boolean; curdir?: string; -}; +} export const defaultStarshipContext: Partial = { name: '', @@ -30,24 +30,24 @@ export const defaultStarshipContext: Partial = { repoUrl: 'https://cosmology-tech.github.io/starship/', chart: 'starship/devnet', namespace: '', - version: '', + version: '' }; export interface PodPorts { - registry?: Ports, - explorer?: Ports, + registry?: Ports; + explorer?: Ports; chains?: { - defaultPorts?: Ports, - [chainName: string]: Ports - }, + defaultPorts?: Ports; + [chainName: string]: Ports; + }; relayers?: { - defaultPorts?: Ports, - [relayerName: string]: Ports - }, + defaultPorts?: Ports; + [relayerName: string]: Ports; + }; } -const defaultName: string = "starship" -const defaultVersion: string = "v0.2.10" +const defaultName: string = 'starship'; +const defaultVersion: string = 'v0.2.10'; // TODO talk to Anmol about moving these into yaml, if not already possible? const defaultPorts: PodPorts = { @@ -65,13 +65,13 @@ const defaultPorts: PodPorts = { rest: 1317, exposer: 8081, faucet: 8000, - cometmock: 22331, + cometmock: 22331 } }, relayers: { defaultPorts: { rest: 3000, - exposer: 8081, + exposer: 8081 } } }; @@ -81,8 +81,8 @@ export interface StarshipClientI { dependencies: Dependency[]; depsChecked: boolean; config: StarshipConfig; - podPorts: PodPorts -}; + podPorts: PodPorts; +} export interface PodStatus { phase: string; @@ -100,8 +100,8 @@ export interface ExecOptions { const defaultExecOptions: ExecOptions = { log: true, silent: false, - ignoreError: true, -} + ignoreError: true +}; export const formatChainID = (input: string): string => { // Replace underscores with hyphens @@ -134,8 +134,11 @@ export class StarshipClient implements StarshipClientI { this.version = readAndParsePackageJson().version; } - private exec(cmd: string[], options: Partial = {}): shell.ShellString { - const opts = {...defaultExecOptions, ...options}; + private exec( + cmd: string[], + options: Partial = {} + ): shell.ShellString { + const opts = { ...defaultExecOptions, ...options }; this.checkDependencies(); const str = cmd.join(' '); if (opts.log) this.log(str); @@ -166,15 +169,17 @@ export class StarshipClient implements StarshipClientI { const platform = process.env.NODE_ENV === 'test' ? 'linux' : os.platform(); const messages: string[] = []; const depMessages: string[] = []; - const missingDependencies = this.dependencies.filter(dep => !dep.installed); + const missingDependencies = this.dependencies.filter( + (dep) => !dep.installed + ); if (!missingDependencies.length) { this.depsChecked = true; return; } - this.dependencies.forEach(dep => { - if (missingDependencies.find(d => d.name === dep.name)) { + this.dependencies.forEach((dep) => { + if (missingDependencies.find((d) => d.name === dep.name)) { depMessages.push(`${chalk.red('x')}${dep.name}`); } else { depMessages.push(`${chalk.green('✓')}${dep.name}`); @@ -183,21 +188,35 @@ export class StarshipClient implements StarshipClientI { messages.push('\n'); // Adding a newline for better readability - missingDependencies.forEach(dep => { + missingDependencies.forEach((dep) => { messages.push(chalk.bold.white(dep.name + ': ') + chalk.cyan(dep.url)); if (dep.name === 'helm' && platform === 'darwin') { - messages.push(chalk.gray("Alternatively, you can install using brew: ") + chalk.white.bold("`brew install helm`")); + messages.push( + chalk.gray('Alternatively, you can install using brew: ') + + chalk.white.bold('`brew install helm`') + ); } if (dep.name === 'kubectl' && platform === 'darwin') { - messages.push(chalk.gray("Alternatively, you can install Docker for Mac which includes Kubernetes: ") + chalk.white.bold(dep.macUrl)); + messages.push( + chalk.gray( + 'Alternatively, you can install Docker for Mac which includes Kubernetes: ' + ) + chalk.white.bold(dep.macUrl) + ); } if (dep.name === 'docker' && platform === 'darwin') { - messages.push(chalk.gray("For macOS, you may also consider Docker for Mac: ") + chalk.white.bold(dep.macUrl)); + messages.push( + chalk.gray('For macOS, you may also consider Docker for Mac: ') + + chalk.white.bold(dep.macUrl) + ); } else if (dep.name === 'docker') { - messages.push(chalk.gray("For advanced Docker usage and installation on other platforms, see: ") + chalk.white.bold(dep.url)); + messages.push( + chalk.gray( + 'For advanced Docker usage and installation on other platforms, see: ' + ) + chalk.white.bold(dep.url) + ); } messages.push('\n'); // Adding a newline for separation between dependencies @@ -214,13 +233,17 @@ export class StarshipClient implements StarshipClientI { } private loadYaml(filename: string): any { - const path = filename.startsWith('/') ? filename : resolve((process.cwd(), filename)) + const path = filename.startsWith('/') + ? filename + : resolve((process.cwd(), filename)); const fileContents = readFileSync(path, 'utf8'); return yaml.load(fileContents); } private saveYaml(filename: string, obj: any): any { - const path = filename.startsWith('/') ? filename : resolve((process.cwd(), filename)) + const path = filename.startsWith('/') + ? filename + : resolve((process.cwd(), filename)); const yamlContent = yaml.dump(obj); mkdirp.sync(dirname(path)); writeFileSync(path, yamlContent, 'utf8'); @@ -273,11 +296,17 @@ export class StarshipClient implements StarshipClientI { // Use default name and version if not provided if (!this.config.name) { - this.log(chalk.yellow("No name specified, using default name: " + defaultName)); + this.log( + chalk.yellow('No name specified, using default name: ' + defaultName) + ); this.config.name = defaultName; } if (!this.config.version) { - this.log(chalk.yellow("No version specified, using default version: " + defaultVersion)); + this.log( + chalk.yellow( + 'No version specified, using default version: ' + defaultVersion + ) + ); this.config.version = defaultVersion; } @@ -326,26 +355,27 @@ export class StarshipClient implements StarshipClientI { } public setupHelm(): void { - this.exec([ - 'helm', - 'repo', - 'add', - this.ctx.repo, - this.ctx.repoUrl - ], { ignoreError: false }); + this.exec(['helm', 'repo', 'add', this.ctx.repo, this.ctx.repoUrl], { + ignoreError: false + }); this.exec(['helm', 'repo', 'update'], { ignoreError: false }); - this.exec([ - 'helm', - 'search', - 'repo', - this.ctx.chart, - '--version', - this.config.version - ], { ignoreError: false }); + this.exec( + [ + 'helm', + 'search', + 'repo', + this.ctx.chart, + '--version', + this.config.version + ], + { ignoreError: false } + ); } private ensureFileExists(filename: string): void { - const path = filename.startsWith('/') ? filename : resolve((process.cwd(), filename)) + const path = filename.startsWith('/') + ? filename + : resolve((process.cwd(), filename)); if (!existsSync(path)) { throw new Error(`Configuration file not found: ${filename}`); } @@ -353,7 +383,7 @@ export class StarshipClient implements StarshipClientI { public deploy(options: string[] = []): void { this.ensureFileExists(this.ctx.config); - this.log("Installing the helm chart. This is going to take a while....."); + this.log('Installing the helm chart. This is going to take a while.....'); const cmd: string[] = [ 'helm', @@ -365,7 +395,7 @@ export class StarshipClient implements StarshipClientI { '--version', this.config.version, ...this.getDeployArgs(), - ...options, + ...options ]; // Determine the data directory of the config file @@ -374,18 +404,20 @@ export class StarshipClient implements StarshipClientI { // Iterate through each chain to add script arguments this.config.chains.forEach((chain, chainIndex) => { if (chain.scripts) { - Object.keys(chain.scripts).forEach(scriptKey => { + Object.keys(chain.scripts).forEach((scriptKey) => { const script = chain.scripts?.[scriptKey as keyof Chain['scripts']]; if (script && script.file) { const scriptPath = resolve(datadir, script.file); - cmd.push(`--set-file chains[${chainIndex}].scripts.${scriptKey}.data=${scriptPath}`); + cmd.push( + `--set-file chains[${chainIndex}].scripts.${scriptKey}.data=${scriptPath}` + ); } }); } }); this.exec(cmd, { ignoreError: false }); - this.log("Run \"starship get-pods\" to check the status of the cluster"); + this.log('Run "starship get-pods" to check the status of the cluster'); } public debug(): void { @@ -399,39 +431,53 @@ export class StarshipClient implements StarshipClientI { public getPods(): void { this.exec([ - "kubectl", - "get pods", - ...this.getArgs(), + 'kubectl', + 'get pods', + ...this.getArgs() // "--all-namespaces" ]); } public checkConnection(): void { - const result = this.exec(['kubectl', 'get', 'nodes'], { log: false, silent: true }); + const result = this.exec(['kubectl', 'get', 'nodes'], { + log: false, + silent: true + }); if (result.code !== 0) { - this.log(chalk.red('Error: Unable to connect to the Kubernetes cluster.')); - this.log(chalk.red('Please ensure that the Kubernetes cluster is configured correctly.')); + this.log( + chalk.red('Error: Unable to connect to the Kubernetes cluster.') + ); + this.log( + chalk.red( + 'Please ensure that the Kubernetes cluster is configured correctly.' + ) + ); this.exit(1); } else { - this.log(chalk.green('Kubernetes cluster connection is working correctly.')); + this.log( + chalk.green('Kubernetes cluster connection is working correctly.') + ); } } private getPodNames(): string[] { - const result = this.exec([ - 'kubectl', - 'get', - 'pods', - '--no-headers', - '-o', - 'custom-columns=:metadata.name', - ...this.getArgs(), - ], { log: false, silent: true }) - + const result = this.exec( + [ + 'kubectl', + 'get', + 'pods', + '--no-headers', + '-o', + 'custom-columns=:metadata.name', + ...this.getArgs() + ], + { log: false, silent: true } + ); + // Split the output by new lines and filter out any empty lines - const podNames = result.split('\n').filter(name => name.trim() !== ''); - + const podNames = result.split('\n').filter((name) => name.trim() !== ''); + return podNames; } @@ -446,25 +492,37 @@ export class StarshipClient implements StarshipClientI { } private checkPodStatus(podName: string): void { - const result = this.exec([ - 'kubectl', - 'get', - 'pods', - podName, - '--no-headers', - '-o', - 'custom-columns=:status.phase,:status.containerStatuses[*].ready,:status.containerStatuses[*].restartCount,:status.containerStatuses[*].state.waiting.reason', - ...this.getArgs(), - ], { log: false, silent: true }).trim(); + const result = this.exec( + [ + 'kubectl', + 'get', + 'pods', + podName, + '--no-headers', + '-o', + 'custom-columns=:status.phase,:status.containerStatuses[*].ready,:status.containerStatuses[*].restartCount,:status.containerStatuses[*].state.waiting.reason', + ...this.getArgs() + ], + { log: false, silent: true } + ).trim(); const [phase, readyList, restartCountList, reason] = result.split(/\s+/); - const ready = readyList.split(',').every(state => state === 'true'); - const restarts = restartCountList.split(',').reduce((acc, count) => acc + parseInt(count, 10), 0); - - this.podStatuses.set(podName, { phase, ready, restartCount: restarts, reason }); + const ready = readyList.split(',').every((state) => state === 'true'); + const restarts = restartCountList + .split(',') + .reduce((acc, count) => acc + parseInt(count, 10), 0); + + this.podStatuses.set(podName, { + phase, + ready, + restartCount: restarts, + reason + }); if (restarts > this.RESTART_THRESHOLD) { - this.log(`${chalk.red('Error:')} Pod ${podName} has restarted more than ${this.RESTART_THRESHOLD} times.`); + this.log( + `${chalk.red('Error:')} Pod ${podName} has restarted more than ${this.RESTART_THRESHOLD} times.` + ); this.exit(1); } } @@ -473,19 +531,19 @@ export class StarshipClient implements StarshipClientI { const podNames = this.getPodNames(); // Check the status of each pod retrieved - podNames.forEach(podName => { + podNames.forEach((podName) => { this.checkPodStatus(podName); }); this.displayPodStatuses(); if (!this.areAllPodsRunning()) { - await new Promise(resolve => setTimeout(resolve, 2500)); + await new Promise((resolve) => setTimeout(resolve, 2500)); await this.waitForPods(); // Recursive call } else { this.log(chalk.green('All pods are running!')); // once the pods are in running state, wait for 10 more seconds - await new Promise(resolve => setTimeout(resolve, 5000)); + await new Promise((resolve) => setTimeout(resolve, 5000)); } } @@ -503,63 +561,107 @@ export class StarshipClient implements StarshipClientI { statusColor = chalk.red(status.phase); } - console.log(`[${chalk.blue(podName)}]: ${statusColor}, ${chalk.gray(`Ready: ${status.ready}, Restarts: ${status.restartCount}`)}`); + console.log( + `[${chalk.blue(podName)}]: ${statusColor}, ${chalk.gray(`Ready: ${status.ready}, Restarts: ${status.restartCount}`)}` + ); }); } - private forwardPort(chain: Chain, localPort: number, externalPort: number): void { + private forwardPort( + chain: Chain, + localPort: number, + externalPort: number + ): void { if (localPort !== undefined && externalPort !== undefined) { this.exec([ - "kubectl", "port-forward", + 'kubectl', + 'port-forward', `pods/${formatChainID(chain.id)}-genesis-0`, `${localPort}:${externalPort}`, ...this.getArgs(), - ">", "/dev/null", - "2>&1", "&" + '>', + '/dev/null', + '2>&1', + '&' ]); - this.log(chalk.yellow(`Forwarded ${formatChainID(chain.id)}: local ${localPort} -> target (host) ${externalPort}`)); + this.log( + chalk.yellow( + `Forwarded ${formatChainID(chain.id)}: local ${localPort} -> target (host) ${externalPort}` + ) + ); } } - private forwardPortCometmock(chain: Chain, localPort: number, externalPort: number): void { + private forwardPortCometmock( + chain: Chain, + localPort: number, + externalPort: number + ): void { if (localPort !== undefined && externalPort !== undefined) { this.exec([ - "kubectl", "port-forward", + 'kubectl', + 'port-forward', `pods/${formatChainID(chain.id)}-cometmock-0`, `${localPort}:${externalPort}`, ...this.getArgs(), - ">", "/dev/null", - "2>&1", "&" + '>', + '/dev/null', + '2>&1', + '&' ]); - this.log(chalk.yellow(`Forwarded ${formatChainID(chain.id)}: local ${localPort} -> target (host) ${externalPort}`)); + this.log( + chalk.yellow( + `Forwarded ${formatChainID(chain.id)}: local ${localPort} -> target (host) ${externalPort}` + ) + ); } } - private forwardPortRelayer(relayer: Relayer, localPort: number, externalPort: number): void { + private forwardPortRelayer( + relayer: Relayer, + localPort: number, + externalPort: number + ): void { if (localPort !== undefined && externalPort !== undefined) { this.exec([ - "kubectl", "port-forward", + 'kubectl', + 'port-forward', `pods/${relayer.type}-${relayer.name}-0`, `${localPort}:${externalPort}`, ...this.getArgs(), - ">", "/dev/null", - "2>&1", "&" + '>', + '/dev/null', + '2>&1', + '&' ]); - this.log(chalk.yellow(`Forwarded ${relayer.name}: local ${localPort} -> target (host) ${externalPort}`)); + this.log( + chalk.yellow( + `Forwarded ${relayer.name}: local ${localPort} -> target (host) ${externalPort}` + ) + ); } } - private forwardPortService(serviceName: string, localPort: number, externalPort: number): void { + private forwardPortService( + serviceName: string, + localPort: number, + externalPort: number + ): void { if (localPort !== undefined && externalPort !== undefined) { this.exec([ - "kubectl", "port-forward", + 'kubectl', + 'port-forward', `service/${serviceName}`, `${localPort}:${externalPort}`, ...this.getArgs(), - ">", "/dev/null", - "2>&1", "&" + '>', + '/dev/null', + '2>&1', + '&' ]); - this.log(`Forwarded ${serviceName} on port ${localPort} to target port ${externalPort}`); + this.log( + `Forwarded ${serviceName} on port ${localPort} to target port ${externalPort}` + ); } } @@ -567,65 +669,110 @@ export class StarshipClient implements StarshipClientI { if (!this.config) { throw new Error('no config!'); } - this.log("Attempting to stop any existing port-forwards..."); + this.log('Attempting to stop any existing port-forwards...'); this.stopPortForward(); - this.log("Starting new port forwarding..."); + this.log('Starting new port forwarding...'); - this.config.chains?.forEach(chain => { - const chainPodPorts = this.podPorts.chains[chain.name] || this.podPorts.chains.defaultPorts; + this.config.chains?.forEach((chain) => { + const chainPodPorts = + this.podPorts.chains[chain.name] || this.podPorts.chains.defaultPorts; if (chain.cometmock?.enabled) { - if (chain.ports?.rpc) this.forwardPortCometmock(chain, chain.ports.rpc, chainPodPorts.cometmock); + if (chain.ports?.rpc) + this.forwardPortCometmock( + chain, + chain.ports.rpc, + chainPodPorts.cometmock + ); } else { - if (chain.ports?.rpc) this.forwardPort(chain, chain.ports.rpc, chainPodPorts.rpc); + if (chain.ports?.rpc) + this.forwardPort(chain, chain.ports.rpc, chainPodPorts.rpc); } - if (chain.ports?.rest) this.forwardPort(chain, chain.ports.rest, chainPodPorts.rest); - if (chain.ports?.grpc) this.forwardPort(chain, chain.ports.grpc, chainPodPorts.grpc); - if (chain.ports?.exposer) this.forwardPort(chain, chain.ports.exposer, chainPodPorts.exposer); - if (chain.ports?.faucet) this.forwardPort(chain, chain.ports.faucet, chainPodPorts.faucet); + if (chain.ports?.rest) + this.forwardPort(chain, chain.ports.rest, chainPodPorts.rest); + if (chain.ports?.grpc) + this.forwardPort(chain, chain.ports.grpc, chainPodPorts.grpc); + if (chain.ports?.exposer) + this.forwardPort(chain, chain.ports.exposer, chainPodPorts.exposer); + if (chain.ports?.faucet) + this.forwardPort(chain, chain.ports.faucet, chainPodPorts.faucet); }); - this.config.relayers?.forEach(relayer => { - const relayerPodPorts = this.podPorts.relayers[relayer.name] || this.podPorts.relayers.defaultPorts; - if (relayer.ports?.rest) this.forwardPortRelayer(relayer, relayer.ports.rest, relayerPodPorts.rest); - if (relayer.ports?.exposer) this.forwardPortRelayer(relayer, relayer.ports.exposer, relayerPodPorts.exposer); + this.config.relayers?.forEach((relayer) => { + const relayerPodPorts = + this.podPorts.relayers[relayer.name] || + this.podPorts.relayers.defaultPorts; + if (relayer.ports?.rest) + this.forwardPortRelayer( + relayer, + relayer.ports.rest, + relayerPodPorts.rest + ); + if (relayer.ports?.exposer) + this.forwardPortRelayer( + relayer, + relayer.ports.exposer, + relayerPodPorts.exposer + ); }); if (this.config.registry?.enabled) { - this.forwardPortService("registry", this.config.registry.ports.rest, this.podPorts.registry.rest); - this.forwardPortService("registry", this.config.registry.ports.grpc, this.podPorts.registry.grpc); + this.forwardPortService( + 'registry', + this.config.registry.ports.rest, + this.podPorts.registry.rest + ); + this.forwardPortService( + 'registry', + this.config.registry.ports.grpc, + this.podPorts.registry.grpc + ); } if (this.config.explorer?.enabled) { - this.forwardPortService("explorer", this.config.explorer.ports.rest, this.podPorts.explorer.rest); + this.forwardPortService( + 'explorer', + this.config.explorer.ports.rest, + this.podPorts.explorer.rest + ); } } private getForwardPids(): string[] { const result = this.exec([ - "ps", "-ef", - "|", "grep", "-i", "'kubectl port-forward'", - "|", "grep", "-v", "'grep'", - "|", "awk", "'{print $2}'" + 'ps', + '-ef', + '|', + 'grep', + '-i', + "'kubectl port-forward'", + '|', + 'grep', + '-v', + "'grep'", + '|', + 'awk', + "'{print $2}'" ]); - const pids = (result || '').split('\n').map(pid => pid.trim()).filter(a => a !== '') + const pids = (result || '') + .split('\n') + .map((pid) => pid.trim()) + .filter((a) => a !== ''); return pids; } public stopPortForward(): void { - this.log(chalk.green("Trying to stop all port-forward, if any....")); + this.log(chalk.green('Trying to stop all port-forward, if any....')); const pids = this.getForwardPids(); - pids.forEach(pid => { - this.exec([ - "kill", "-15", pid - ]); + pids.forEach((pid) => { + this.exec(['kill', '-15', pid]); }); this.exec(['sleep', '2']); } public printForwardPids(): void { const pids = this.getForwardPids(); - pids.forEach(pid => { + pids.forEach((pid) => { console.log(pid); }); } diff --git a/clients/js/packages/client/src/config.ts b/clients/js/packages/client/src/config.ts index 9ea3e3f7..b1799b9b 100644 --- a/clients/js/packages/client/src/config.ts +++ b/clients/js/packages/client/src/config.ts @@ -81,7 +81,7 @@ export interface Chain { export interface Script { file?: string; data?: string; -}; +} export interface Relayer { name: string; @@ -145,8 +145,8 @@ export interface Images { } export interface StarshipConfig { - name: string, - version: string, + name: string; + version: string; chains: Chain[]; relayers?: Relayer[]; explorer?: Explorer; diff --git a/clients/js/packages/client/src/deps.ts b/clients/js/packages/client/src/deps.ts index e840e393..7cbfaebe 100644 --- a/clients/js/packages/client/src/deps.ts +++ b/clients/js/packages/client/src/deps.ts @@ -1,28 +1,28 @@ import * as shell from 'shelljs'; export type Dependency = { - name: string; - url: string; - macUrl?: string; // Optional property for macOS-specific URLs - installed: boolean + name: string; + url: string; + macUrl?: string; // Optional property for macOS-specific URLs + installed: boolean; }; export const dependencies: Dependency[] = [ - { - name: 'kubectl', - url: 'https://kubernetes.io/docs/tasks/tools/', - macUrl: 'https://docs.docker.com/desktop/install/mac-install/', - installed: !!shell.which('kubectl') - }, - { - name: 'docker', - url: 'https://docs.docker.com/get-docker/', - macUrl: 'https://docs.docker.com/desktop/install/mac-install/', - installed: !!shell.which('docker') - }, - { - name: 'helm', - url: 'https://helm.sh/docs/intro/install/', - installed: !!shell.which('helm') - } -]; \ No newline at end of file + { + name: 'kubectl', + url: 'https://kubernetes.io/docs/tasks/tools/', + macUrl: 'https://docs.docker.com/desktop/install/mac-install/', + installed: !!shell.which('kubectl') + }, + { + name: 'docker', + url: 'https://docs.docker.com/get-docker/', + macUrl: 'https://docs.docker.com/desktop/install/mac-install/', + installed: !!shell.which('docker') + }, + { + name: 'helm', + url: 'https://helm.sh/docs/intro/install/', + installed: !!shell.which('helm') + } +]; diff --git a/clients/js/packages/client/src/index.ts b/clients/js/packages/client/src/index.ts index 6b075fd5..91262af5 100644 --- a/clients/js/packages/client/src/index.ts +++ b/clients/js/packages/client/src/index.ts @@ -1,3 +1,3 @@ export * from './client'; export * from './config'; -export * from './installer'; \ No newline at end of file +export * from './installer'; diff --git a/clients/js/packages/client/src/installer.ts b/clients/js/packages/client/src/installer.ts index 93868651..cafc1186 100644 --- a/clients/js/packages/client/src/installer.ts +++ b/clients/js/packages/client/src/installer.ts @@ -3,57 +3,63 @@ import * as os from 'os'; import * as shell from 'shelljs'; type Installation = { - mac: string; - linux: string; + mac: string; + linux: string; }; export class StarshipInstaller { - private installations: Record = { - docker: { - mac: 'Please install Docker. Follow: https://docs.docker.com/desktop/install/mac-install/', - linux: 'Please install Docker. Follow: https://docs.docker.com/engine/install/ubuntu/' - }, - kubectl: { - mac: 'brew install kubectl', - linux: `curl -Lks "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" > ~/.local/bin/kubectl && chmod +x ~/.local/bin/kubectl` - }, - helm: { - mac: 'brew install helm', - linux: 'curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash' - }, - }; - - async checkAndInstallBinary(binaryName: string) { - if (!shell.which(binaryName)) { - console.log(`${binaryName} is not installed`); - await this.installBinary(binaryName); - if (!shell.which(binaryName)) { - console.log(chalk.red(`Installation of ${binaryName} failed. Please install ${binaryName} manually.`)); - process.exit(1); - } - } + private installations: Record = { + docker: { + mac: 'Please install Docker. Follow: https://docs.docker.com/desktop/install/mac-install/', + linux: + 'Please install Docker. Follow: https://docs.docker.com/engine/install/ubuntu/' + }, + kubectl: { + mac: 'brew install kubectl', + linux: `curl -Lks "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" > ~/.local/bin/kubectl && chmod +x ~/.local/bin/kubectl` + }, + helm: { + mac: 'brew install helm', + linux: + 'curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash' } + }; - async checkAndInstallDependencies() { - for (const dependency of Object.keys(this.installations)) { - console.log(`Checking ${dependency}...`); - await this.checkAndInstallBinary(dependency); - } + async checkAndInstallBinary(binaryName: string) { + if (!shell.which(binaryName)) { + console.log(`${binaryName} is not installed`); + await this.installBinary(binaryName); + if (!shell.which(binaryName)) { + console.log( + chalk.red( + `Installation of ${binaryName} failed. Please install ${binaryName} manually.` + ) + ); + process.exit(1); + } } + } - async installBinary(binaryName: string) { - const platform = os.platform(); - const installation = this.installations[binaryName]; - if (platform === 'darwin') { - await this.runInstallation(installation.mac); - } else if (platform === 'linux') { - await this.runInstallation(installation.linux); - } + async checkAndInstallDependencies() { + for (const dependency of Object.keys(this.installations)) { + console.log(`Checking ${dependency}...`); + await this.checkAndInstallBinary(dependency); } + } - private async runInstallation(command: string) { - shell.exec(command); + async installBinary(binaryName: string) { + const platform = os.platform(); + const installation = this.installations[binaryName]; + if (platform === 'darwin') { + await this.runInstallation(installation.mac); + } else if (platform === 'linux') { + await this.runInstallation(installation.linux); } + } + + private async runInstallation(command: string) { + shell.exec(command); + } } // Example usage: diff --git a/clients/js/packages/client/src/package.ts b/clients/js/packages/client/src/package.ts index 9463bca2..19ee2e36 100644 --- a/clients/js/packages/client/src/package.ts +++ b/clients/js/packages/client/src/package.ts @@ -1,7 +1,7 @@ -import { existsSync,readFileSync } from "fs"; -import { dirname,join } from "path"; +import { existsSync, readFileSync } from 'fs'; +import { dirname, join } from 'path'; -// need to search due to the dist/ folder and src/, etc. +// need to search due to the dist/ folder and src/, etc. function findPackageJson(currentDir: string): any { const filePath = join(currentDir, 'package.json'); @@ -30,4 +30,4 @@ export function readAndParsePackageJson() { const str = readFileSync(pkgPath, 'utf8'); const pkg = JSON.parse(str); return pkg; -} \ No newline at end of file +} diff --git a/clients/js/packages/client/test-utils/client.ts b/clients/js/packages/client/test-utils/client.ts index 18d84aba..8cc5c35d 100644 --- a/clients/js/packages/client/test-utils/client.ts +++ b/clients/js/packages/client/test-utils/client.ts @@ -1,7 +1,7 @@ import { relative } from 'path'; -import strip from 'strip-ansi' +import strip from 'strip-ansi'; -import { StarshipClient } from '../src' +import { StarshipClient } from '../src'; import { config } from './config'; interface TestClientCtx { @@ -19,15 +19,17 @@ export const createClient = () => { const client = new StarshipClient({ name: 'osmojs', - config: relative(process.cwd(), config.configPath), + config: relative(process.cwd(), config.configPath) }); const handler = { get(target: any, prop: string, _receiver: any) { const originalMethod = target[prop]; if (typeof originalMethod === 'function') { - return function(...args: any[]) { - const argsString = args.map(arg => strip(JSON.stringify(arg))).join(', '); + return function (...args: any[]) { + const argsString = args + .map((arg) => strip(JSON.stringify(arg))) + .join(', '); ctx.logs.push(`Call: ${prop}(${argsString})`); // if you want to see nested Call, replace target with this // I double checked both this and target, it does not call the exec in the methods when used internally @@ -41,20 +43,18 @@ export const createClient = () => { const proxiedClient: StarshipClient = new Proxy(client, handler); // Overriding the exit method - // @ts-ignore + // @ts-expect-error - Ignore lint error proxiedClient.exit = (code: number) => { ctx.code = code; }; - - // @ts-ignore - proxiedClient.ensureFileExists = (_filename: string) => { - - }; - + + // @ts-expect-error - Ignore lint error + proxiedClient.ensureFileExists = (_filename: string) => {}; + // Overriding the exec method - // @ts-ignore + // @ts-expect-error - Ignore lint error proxiedClient.exec = (cmd: string[]) => { - // @ts-ignore + // @ts-expect-error - Ignore lint error client.checkDependencies(); ctx.commands.push(cmd.join(' ')); ctx.logs.push(cmd.join(' ')); @@ -62,7 +62,7 @@ export const createClient = () => { }; // Overriding the log method - // @ts-ignore + // @ts-expect-error - Ignore lint error proxiedClient.log = (cmd: string) => { const str = strip(cmd); if (/\n/.test(str)) { @@ -75,12 +75,11 @@ export const createClient = () => { return { client: proxiedClient, ctx - } -} - + }; +}; export const expectClient = (ctx: TestClientCtx, code: number) => { expect(ctx.logs.join('\n')).toMatchSnapshot(); expect(ctx.commands.join('\n')).toMatchSnapshot(); expect(ctx.code).toBe(code); -} +}; diff --git a/clients/js/packages/client/test-utils/config.ts b/clients/js/packages/client/test-utils/config.ts index 28622179..9130fea3 100644 --- a/clients/js/packages/client/test-utils/config.ts +++ b/clients/js/packages/client/test-utils/config.ts @@ -8,17 +8,16 @@ export const fixtureDir = resolve(join(__dirname, '/../../../__fixtures__')); export const outputDir = resolve(join(__dirname, '/../../../__output__')); function loadConfig(filename: string) { - const configPath = join(fixtureDir, filename); - const configAsYaml = readFileSync(configPath, 'utf-8'); - const config: StarshipConfig = yaml.load(configAsYaml) as StarshipConfig; - return { - configPath, - configAsYaml, - config - }; + const configPath = join(fixtureDir, filename); + const configAsYaml = readFileSync(configPath, 'utf-8'); + const config: StarshipConfig = yaml.load(configAsYaml) as StarshipConfig; + return { + configPath, + configAsYaml, + config + }; } - const localConfig = loadConfig('local-config.yaml'); const config = loadConfig('config.yaml'); diff --git a/clients/js/packages/starshipjs/.eslintrc.js b/clients/js/packages/starshipjs/.eslintrc.js new file mode 100644 index 00000000..19060255 --- /dev/null +++ b/clients/js/packages/starshipjs/.eslintrc.js @@ -0,0 +1,75 @@ +module.exports = { + parser: '@typescript-eslint/parser', // Specify the ESLint parser + plugins: ['@typescript-eslint', 'prettier'], + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', // Uses the recommended rules from the @typescript-eslint/eslint-plugin + 'plugin:prettier/recommended' + ], + parserOptions: { + ecmaVersion: 2020, // Allows for the parsing of modern ECMAScript features + sourceType: 'module', // Allows for the use of imports + ecmaFeatures: { + jsx: true // Allows for the parsing of JSX + } + }, + env: { + es6: true, + browser: true, + node: true, + jest: true + }, + rules: { + '@typescript-eslint/no-explicit-any': 'off', // Disable the rule entirely + 'no-debugger': 2, + 'no-alert': 2, + 'no-await-in-loop': 0, + 'no-prototype-builtins': 0, + 'no-return-assign': ['error', 'except-parens'], + 'no-restricted-syntax': [ + 2, + 'ForInStatement', + 'LabeledStatement', + 'WithStatement' + ], + 'no-unused-vars': [ + 0, + { + ignoreSiblings: true, + argsIgnorePattern: 'React|res|next|^_' + } + ], + 'prefer-const': [ + 'error', + { + destructuring: 'all' + } + ], + 'no-unused-expressions': [ + 2, + { + allowTaggedTemplates: true + } + ], + 'no-console': 'off', + 'comma-dangle': 2, + 'jsx-quotes': [2, 'prefer-double'], + 'linebreak-style': ['error', 'unix'], + quotes: [ + 2, + 'single', + { + avoidEscape: true, + allowTemplateLiterals: true + } + ], + 'prettier/prettier': [ + 'error', + { + trailingComma: 'none', + singleQuote: true, + printWidth: 80 + } + ] + } +}; diff --git a/clients/js/packages/starshipjs/__tests__/config.test.ts b/clients/js/packages/starshipjs/__tests__/config.test.ts index 669b32a6..e7114220 100644 --- a/clients/js/packages/starshipjs/__tests__/config.test.ts +++ b/clients/js/packages/starshipjs/__tests__/config.test.ts @@ -1,14 +1,14 @@ -import { ChainRegistryFetcher } from "@chain-registry/client"; -import path from "path"; +import { ChainRegistryFetcher } from '@chain-registry/client'; +import path from 'path'; -import { Config, ConfigContext } from "../src/config"; +import { Config, ConfigContext } from '../src/config'; // it's more recommended to use ConfigContext.init to set the config file and registry. -it("1. throws without init;\n 2. init the setup and gets config;\n 3. throws when double init;\n", async () => { +it('1. throws without init;\n 2. init the setup and gets config;\n 3. throws when double init;\n', async () => { expect(() => ConfigContext.registry).toThrow(); expect(() => ConfigContext.configFile).toThrow(); - const file = path.join(__dirname, "../../../__fixtures__", "config.yaml"); + const file = path.join(__dirname, '../../../__fixtures__', 'config.yaml'); // for unit test, only setup a chain registry fetcher without fetching. await Config.init(file, new ChainRegistryFetcher()); diff --git a/clients/js/packages/starshipjs/__tests__/legacy.test.ts b/clients/js/packages/starshipjs/__tests__/legacy.test.ts index 6ce477f6..21e36350 100644 --- a/clients/js/packages/starshipjs/__tests__/legacy.test.ts +++ b/clients/js/packages/starshipjs/__tests__/legacy.test.ts @@ -1,14 +1,14 @@ -import { ChainRegistryFetcher } from "@chain-registry/client"; -import path from "path"; +import { ChainRegistryFetcher } from '@chain-registry/client'; +import path from 'path'; -import { ConfigContext } from "../src/config"; +import { ConfigContext } from '../src/config'; // people can still use legacy ConfigContext to set the config file and registry. -it("1. throws without init;\n 2. throws only init partially;\n 3. init the setup and gets config;\n 4. throws when double init;\n", async () => { +it('1. throws without init;\n 2. throws only init partially;\n 3. init the setup and gets config;\n 4. throws when double init;\n', async () => { expect(() => ConfigContext.registry).toThrow(); expect(() => ConfigContext.configFile).toThrow(); - const file = path.join(__dirname, "../../../__fixtures__", "config.yaml"); + const file = path.join(__dirname, '../../../__fixtures__', 'config.yaml'); ConfigContext.setConfigFile(file); diff --git a/clients/js/packages/starshipjs/jest.config.js b/clients/js/packages/starshipjs/jest.config.js index 0aa3aaa4..eecd0733 100644 --- a/clients/js/packages/starshipjs/jest.config.js +++ b/clients/js/packages/starshipjs/jest.config.js @@ -1,18 +1,18 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ module.exports = { - preset: "ts-jest", - testEnvironment: "node", - transform: { - "^.+\\.tsx?$": [ - "ts-jest", - { - babelConfig: false, - tsconfig: "tsconfig.json", - }, - ], - }, - transformIgnorePatterns: [`/node_modules/*`], - testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", - moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], - modulePathIgnorePatterns: ["dist/*"] + preset: 'ts-jest', + testEnvironment: 'node', + transform: { + '^.+\\.tsx?$': [ + 'ts-jest', + { + babelConfig: false, + tsconfig: 'tsconfig.json' + } + ] + }, + transformIgnorePatterns: [`/node_modules/*`], + testRegex: '(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$', + moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'], + modulePathIgnorePatterns: ['dist/*'] }; diff --git a/clients/js/packages/starshipjs/src/config.ts b/clients/js/packages/starshipjs/src/config.ts index d9e34b00..8330b8fc 100644 --- a/clients/js/packages/starshipjs/src/config.ts +++ b/clients/js/packages/starshipjs/src/config.ts @@ -1,6 +1,6 @@ -import { ChainRegistryFetcher } from "@chain-registry/client"; +import { ChainRegistryFetcher } from '@chain-registry/client'; -import { useRegistry } from "./hooks"; +import { useRegistry } from './hooks'; export class Config { // keep instantiation private to enforce singletone @@ -34,7 +34,7 @@ export class Config { registryFetcher?: ChainRegistryFetcher ) { if (Config.instance && Config.instance.isInitialized) { - throw new Error("Config is already initialized."); + throw new Error('Config is already initialized.'); } const fetcher = registryFetcher ?? (await useRegistry(configFile)); @@ -109,4 +109,4 @@ export interface ChainConfig { }>; } -export const ConfigContext = Config; \ No newline at end of file +export const ConfigContext = Config; diff --git a/clients/js/packages/starshipjs/src/hooks.ts b/clients/js/packages/starshipjs/src/hooks.ts index 32db443c..e8a1cedf 100644 --- a/clients/js/packages/starshipjs/src/hooks.ts +++ b/clients/js/packages/starshipjs/src/hooks.ts @@ -5,7 +5,9 @@ import fetch from 'node-fetch'; import { type ChainConfig, ConfigContext } from './config'; -export const useRegistry = async (configFile: string): Promise => { +export const useRegistry = async ( + configFile: string +): Promise => { const config = yaml.load(fs.readFileSync(configFile, 'utf8')) as ChainConfig; const registryUrl = `http://localhost:${config.registry.ports.rest}`; @@ -63,7 +65,10 @@ export const useChain = (chainName: string) => { return chainInfo.fetcher.getChainAssetList(chainName).assets[0]; }; - const creditFromFaucet = async (address: string, denom: string | null = null) => { + const creditFromFaucet = async ( + address: string, + denom: string | null = null + ) => { const faucetEndpoint = `http://localhost:${ config.chains.find((chain) => chain.id === chainID)!.ports.faucet }/credit`; diff --git a/clients/js/packages/starshipjs/src/index.ts b/clients/js/packages/starshipjs/src/index.ts index f7ee76f1..23e09c10 100644 --- a/clients/js/packages/starshipjs/src/index.ts +++ b/clients/js/packages/starshipjs/src/index.ts @@ -1,3 +1,3 @@ export * from './config'; export * from './hooks'; -export * from './utils'; \ No newline at end of file +export * from './utils'; diff --git a/clients/js/packages/starshipjs/src/utils.ts b/clients/js/packages/starshipjs/src/utils.ts index 8e9c385c..1f0f331b 100644 --- a/clients/js/packages/starshipjs/src/utils.ts +++ b/clients/js/packages/starshipjs/src/utils.ts @@ -1,3 +1,3 @@ -import { generateMnemonic } from 'bip39' +import { generateMnemonic } from 'bip39'; -export { generateMnemonic }; \ No newline at end of file +export { generateMnemonic }; diff --git a/clients/js/yarn.lock b/clients/js/yarn.lock index 69b6c82f..be65f0a1 100644 --- a/clients/js/yarn.lock +++ b/clients/js/yarn.lock @@ -2,11 +2,6 @@ # yarn lockfile v1 -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - "@ampproject/remapping@^2.2.0": version "2.3.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4" @@ -356,10 +351,10 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== +"@eslint-community/regexpp@^4.10.0", "@eslint-community/regexpp@^4.6.1": + version "4.11.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" + integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -1054,6 +1049,11 @@ resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== +"@pkgr/core@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.1.tgz#1ec17e2edbec25c8306d424ecfbf13c7de1aaa31" + integrity sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA== + "@sigstore/bundle@^1.1.0": version "1.1.0" resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" @@ -1279,11 +1279,6 @@ resolved "https://registry.yarnpkg.com/@types/js-yaml/-/js-yaml-4.0.9.tgz#cd82382c4f902fed9691a2ed79ec68c5898af4c2" integrity sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg== -"@types/json-schema@^7.0.12": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - "@types/minimatch@*": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" @@ -1319,11 +1314,6 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== -"@types/semver@^7.5.0": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - "@types/shelljs@^0.8.15": version "0.8.15" resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.8.15.tgz#22c6ab9dfe05cec57d8e6cb1a95ea173aee9fcac" @@ -1349,91 +1339,86 @@ dependencies: "@types/yargs-parser" "*" -"@typescript-eslint/eslint-plugin@^6.18.1": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" - integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== +"@typescript-eslint/eslint-plugin@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.17.0.tgz#c8ed1af1ad2928ede5cdd207f7e3090499e1f77b" + integrity sha512-pyiDhEuLM3PuANxH7uNYan1AaFs5XE0zw1hq69JBvGvE7gSuEoQl1ydtEe/XQeoC3GQxLXyOVa5kNOATgM638A== dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/type-utils" "6.21.0" - "@typescript-eslint/utils" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/type-utils" "7.17.0" + "@typescript-eslint/utils" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" graphemer "^1.4.0" - ignore "^5.2.4" + ignore "^5.3.1" natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" -"@typescript-eslint/parser@^6.18.1": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== +"@typescript-eslint/parser@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-7.17.0.tgz#be8e32c159190cd40a305a2121220eadea5a88e7" + integrity sha512-puiYfGeg5Ydop8eusb/Hy1k7QmOU6X3nvsqCgzrB2K4qMavK//21+PzNE8qeECgNOIoertJPUC1SpegHDI515A== dependencies: - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== +"@typescript-eslint/scope-manager@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-7.17.0.tgz#e072d0f914662a7bfd6c058165e3c2b35ea26b9d" + integrity sha512-0P2jTTqyxWp9HiKLu/Vemr2Rg1Xb5B7uHItdVZ6iAenXmPo4SZ86yOPCJwMqpCyaMiEHTNqizHfsbmCFT1x9SA== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" -"@typescript-eslint/type-utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" - integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== +"@typescript-eslint/type-utils@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-7.17.0.tgz#c5da78feb134c9c9978cbe89e2b1a589ed22091a" + integrity sha512-XD3aaBt+orgkM/7Cei0XNEm1vwUxQ958AOLALzPlbPqb8C1G8PZK85tND7Jpe69Wualri81PLU+Zc48GVKIMMA== dependencies: - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/typescript-estree" "7.17.0" + "@typescript-eslint/utils" "7.17.0" debug "^4.3.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== +"@typescript-eslint/types@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-7.17.0.tgz#7ce8185bdf06bc3494e73d143dbf3293111b9cff" + integrity sha512-a29Ir0EbyKTKHnZWbNsrc/gqfIBqYPwj3F2M+jWE/9bqfEHg0AMtXzkbUkOG6QgEScxh2+Pz9OXe11jHDnHR7A== -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== +"@typescript-eslint/typescript-estree@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-7.17.0.tgz#dcab3fea4c07482329dd6107d3c6480e228e4130" + integrity sha512-72I3TGq93t2GoSBWI093wmKo0n6/b7O4j9o8U+f65TVD0FS6bI2180X5eGEr8MA8PhKMvYe9myZJquUT2JkCZw== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/visitor-keys" "7.17.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" -"@typescript-eslint/utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" - integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== +"@typescript-eslint/utils@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-7.17.0.tgz#815cd85b9001845d41b699b0ce4f92d6dfb84902" + integrity sha512-r+JFlm5NdB+JXc7aWWZ3fKSm1gn0pkswEwIYsrGPdsT2GjsRATAKXiNtp3vgAAO1xZhX8alIOEQnNMl3kbTgJw== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - semver "^7.5.4" + "@typescript-eslint/scope-manager" "7.17.0" + "@typescript-eslint/types" "7.17.0" + "@typescript-eslint/typescript-estree" "7.17.0" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== +"@typescript-eslint/visitor-keys@7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-7.17.0.tgz#680465c734be30969e564b4647f38d6cdf49bfb0" + integrity sha512-RVGC9UhPOCsfCdI9pU++K4nD7to+jTcMIbXTSOcrLqUEW6gF2pU1UUbYJKc9cvcRSK1UDeMJ7pdMxf4bhMpV/A== dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" + "@typescript-eslint/types" "7.17.0" + eslint-visitor-keys "^3.4.3" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -1483,11 +1468,16 @@ acorn-walk@^8.1.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.2.tgz#7703af9415f1b6db9315d6895503862e231d34aa" integrity sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A== -acorn@^8.4.1, acorn@^8.9.0: +acorn@^8.4.1: version "8.11.3" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.3.tgz#71e0b14e13a4ec160724b38fb7b0f233b1b81d7a" integrity sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg== +acorn@^8.9.0: + version "8.12.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.12.1.tgz#71616bdccbe25e27a54439e0046e89ca76df2248" + integrity sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg== + add-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" @@ -1668,7 +1658,12 @@ axios@^1.6.0: form-data "^4.0.0" proxy-from-env "^1.1.0" -babel-jest@^29.7.0: +babel-core@7.0.0-bridge.0: + version "7.0.0-bridge.0" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-7.0.0-bridge.0.tgz#95a492ddd90f9b4e9a4a1da14eb335b87b634ece" + integrity sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg== + +babel-jest@^29.3.1, babel-jest@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== @@ -2273,13 +2268,20 @@ dateformat@^3.0.3: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== dependencies: ms "2.1.2" +debug@^4.3.1, debug@^4.3.2: + version "4.3.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" + integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + dependencies: + ms "2.1.2" + decamelize-keys@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" @@ -2528,15 +2530,23 @@ eslint-config-prettier@^9.1.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== +eslint-plugin-prettier@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.1.tgz#d1c8f972d8f60e414c25465c163d16f209411f95" + integrity sha512-gH3iR3g4JfF+yYPaJYkN7jEl9QbweL/YfkoRlNnuIEHEz1vHVlCmWOS+eGGiRuzHQXdJFCOTxRgvju9b8VUmrw== + dependencies: + prettier-linter-helpers "^1.0.0" + synckit "^0.9.1" + eslint-plugin-simple-import-sort@^10.0.0: version "10.0.0" resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-10.0.0.tgz#cc4ceaa81ba73252427062705b64321946f61351" integrity sha512-AeTvO9UCMSNzIHRkg8S6c3RPy5YEwKWSQPx3DYghLedo2ZQxowPFLGDN1AZ2evfg6r6mjBSZSLxLFsWSu3acsw== eslint-plugin-unused-imports@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.1.0.tgz#db015b569d3774e17a482388c95c17bd303bc602" - integrity sha512-9l1YFCzXKkw1qtAru1RWUtG2EVDZY0a0eChKXcL+EZ5jitG7qxdctu4RnvhOJHv4xfmUf7h+JJPINlVpGhZMrw== + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz#63a98c9ad5f622cd9f830f70bc77739f25ccfe0d" + integrity sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ== dependencies: eslint-rule-composer "^0.3.0" @@ -2617,9 +2627,9 @@ esprima@^4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + version "1.6.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.6.0.tgz#91419234f804d852a82dceec3e16cdc22cf9dae7" + integrity sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg== dependencies: estraverse "^5.1.0" @@ -2710,6 +2720,11 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + fast-glob@^3.2.9, fast-glob@^3.3.0: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" @@ -3262,7 +3277,7 @@ ignore-walk@^6.0.4: dependencies: minimatch "^9.0.0" -ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.1.tgz#5073e554cd42c5b33b394375f538b8593e34d4ef" integrity sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw== @@ -4974,16 +4989,16 @@ open@^8.4.0: is-wsl "^2.2.0" optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + version "0.9.4" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" + integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" + word-wrap "^1.2.5" ora@5.3.0: version "5.3.0" @@ -5290,6 +5305,13 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + prettier@^3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.1.tgz#e68935518dd90bb7ec4821ba970e68f8de16e1ac" @@ -5675,6 +5697,11 @@ semver@^7.0.0, semver@^7.1.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semve dependencies: lru-cache "^6.0.0" +semver@^7.6.0: + version "7.6.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" + integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== + set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" @@ -5894,7 +5921,16 @@ string-length@^4.0.1: char-regex "^1.0.2" strip-ansi "^6.0.0" -"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5931,7 +5967,14 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6, strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6, strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -6025,6 +6068,14 @@ symlink-workspace@^1.9.0: mkdirp "3.0.0" rimraf "5.0.0" +synckit@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.1.tgz#febbfbb6649979450131f64735aa3f6c14575c88" + integrity sha512-7gr8p9TQP6RAHusBOSLs46F4564ZrjV8xFmw5zCmgmhGUcw2hxsShhJ6CEiHQMgPDwAQ1fWHPM0ypc4RMAig4A== + dependencies: + "@pkgr/core" "^0.1.0" + tslib "^2.6.2" + tar-stream@~2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" @@ -6129,7 +6180,7 @@ trim-newlines@^4.0.2: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-4.1.1.tgz#28c88deb50ed10c7ba6dc2474421904a00139125" integrity sha512-jRKj0n0jXWo6kh62nA5TEh3+4igKDXLvzBJcPpiizP7oOolUrYIxmVBG9TOtHYFHoddUk6YvAkGeGoSVTXfQXQ== -ts-api-utils@^1.0.1: +ts-api-utils@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== @@ -6181,6 +6232,11 @@ tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== +tslib@^2.6.2: + version "2.6.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0" + integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ== + tuf-js@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" @@ -6409,12 +6465,17 @@ wide-align@^1.1.5: dependencies: string-width "^1.0.2 || 2 || 3 || 4" +word-wrap@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" + integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== + wordwrap@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -6432,6 +6493,15 @@ wrap-ansi@^6.0.1: string-width "^4.1.0" strip-ansi "^6.0.0" +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"