Skip to content

Commit

Permalink
feat: add nextui list command (#5)
Browse files Browse the repository at this point in the history
* feat: add nextui list command

* fix: add error catch and optimize output
  • Loading branch information
winchesHe committed Mar 29, 2024
1 parent d58dc42 commit 773dc07
Show file tree
Hide file tree
Showing 7 changed files with 406 additions and 95 deletions.
2 changes: 1 addition & 1 deletion src/actions/init-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function initAction(projectName: string, options: InitActionOptions
]);
}
if (!packageName) {
/** ======================== Temporary use npm with default value ======================== */
/** ======================== TODO:(winches)Temporary use npm with default value ======================== */
packageName = 'npm';
// packageName = await getSelect('Select a package manager', [
// {
Expand Down
143 changes: 143 additions & 0 deletions src/actions/list-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
import { resolve } from 'path';

import chalk from 'chalk';

import { Logger } from '@helpers/logger';
import { PasCalCase } from '@helpers/utils';

import {
type NextUIComponents,
colorNextUIComponentKeys,
nextUIComponents,
orderNextUIComponentKeys
} from '../../src/constants/component';
import { ROOT } from '../../src/constants/path';

interface ListActionOptions {
current?: boolean;
packagePath?: string;
}

const rounded = {
bl: '╰',
br: '╯',
h: '─',
tl: '╭',
tr: '╮',
v: '│'
} as const;
const space = ' ';
const padStart = `${rounded.v}${space}`;
const padEnd = `${space}${rounded.v}${space}`;

export async function listAction(options: ListActionOptions) {
const { current, packagePath = resolve(ROOT, 'package.json') } = options;

let components = nextUIComponents as NextUIComponents;

try {
/** ======================== Get the installed components ======================== */
if (current) {
const pkg = await import(packagePath);
const devDependencies = pkg.devDependencies || {};
const dependencies = pkg.dependencies || {};
const allDependencies = { ...devDependencies, ...dependencies };
const dependenciesKeys = new Set(Object.keys(allDependencies));

components = components.filter((component) => dependenciesKeys.has(component.name));
}

if (!components.length) {
Logger.warn(
`No installed NextUI components found, reference package.json path: ${packagePath}`
);

return;
}

/** ======================== Output the components ======================== */
outputComponents(components);
} catch (error) {
Logger.error(`NextUI CLI Error occurred while listing the components: ${error}`);
}
}

function outputComponents(components: NextUIComponents) {
const componentKeyLengthMap: Record<keyof NextUIComponents[0], number> = {
description: 0,
docs: 0,
name: 0,
package: 0,
status: 0,
version: 0
};

for (const component of components) {
for (const key in component) {
// Align the length of the version
componentKeyLengthMap[key] = Math.max(
componentKeyLengthMap[key],
key === 'version' ? 'version'.length : String(component[key]).length
);
}
}

let transformComponentsOutput = components.reduce((acc, component) => {
let outputData = padStart;

for (const key of orderNextUIComponentKeys) {
let value = component[key].padEnd(componentKeyLengthMap[key]);

if (component.status === 'stable' && colorNextUIComponentKeys.includes(key)) {
value = chalk.greenBright(value);
} else if (component.status === 'newPost') {
value = chalk.magentaBright(value);
} else if (component.status === 'updated') {
value = chalk.blueBright(value);
}

outputData += value + padEnd;
}

outputData;

acc.push(outputData);

return acc;
}, [] as string[]);

/** ======================== Generate box header ======================== */
let boxHeader = rounded.tl + padStart.replace(/.*/g, rounded.h).slice(1);
let boxHeaderSec = padStart;
let boxHeaderTrd = rounded.v + padStart.replace(/.*/g, rounded.h).slice(1);

for (const key of orderNextUIComponentKeys) {
boxHeader += `${rounded.h.padEnd(componentKeyLengthMap[key] + 7, rounded.h)}`;
boxHeaderSec += chalk.redBright(PasCalCase(key).padEnd(componentKeyLengthMap[key])) + padEnd;
boxHeaderTrd += `${rounded.h.padEnd(componentKeyLengthMap[key] + 7, rounded.h)}`;
}

boxHeader = boxHeader.slice(0, -2) + rounded.tr;
boxHeaderTrd = boxHeaderTrd.slice(0, -2) + rounded.v;

/** ======================== Generate box footer ======================== */
let boxFooter = rounded.bl + padStart.replace(/.*/g, rounded.h).slice(1);

for (const key of orderNextUIComponentKeys) {
boxFooter += `${rounded.h.padEnd(componentKeyLengthMap[key] + 7, rounded.h)}`;
}

boxFooter = boxFooter.slice(0, -2) + rounded.br;

transformComponentsOutput = [
boxHeader,
boxHeaderSec,
boxHeaderTrd,
...transformComponentsOutput,
boxFooter
];

Logger.info('Current NextUI Components:\n');

Logger.log(transformComponentsOutput.join('\n'));
}
Loading

0 comments on commit 773dc07

Please sign in to comment.