Skip to content

Commit

Permalink
feat: doctor add core tailwind and app check
Browse files Browse the repository at this point in the history
  • Loading branch information
winchesHe committed Mar 31, 2024
1 parent ca06979 commit 107034c
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 36 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"async-retry": "1.3.3",
"chalk": "5.3.0",
"commander": "11.0.0",
"fast-glob": "3.3.2",
"gradient-string": "2.0.2",
"ora": "8.0.1",
"prompts": "2.4.2",
Expand Down
31 changes: 8 additions & 23 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

109 changes: 106 additions & 3 deletions src/actions/doctor-action.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import chalk from 'chalk';

import { checkRequiredContentInstalled } from '@helpers/check';
import { checkApp, checkRequiredContentInstalled, checkTailwind } from '@helpers/check';
import { Logger, type PrefixLogType } from '@helpers/logger';
import { getPackageInfo } from '@helpers/package';
import { findFiles } from '@helpers/utils';
import { resolver } from 'src/constants/path';
import { DOCS_APP_SETUP, DOCS_INSTALLED, DOCS_TAILWINDCSS_SETUP } from 'src/constants/required';

interface DoctorActionOptions {
packagePath?: string;
tailwindPath?: string;
appPath?: string;
}

interface ProblemRecord {
Expand All @@ -16,11 +20,28 @@ interface ProblemRecord {
}

export async function doctorAction(options: DoctorActionOptions) {
const { packagePath = resolver('package.json') } = options;
const {
appPath = findFiles('**/app.tsx')[0],
packagePath = resolver('package.json'),
tailwindPath = findFiles('**/tailwind.config.js')
} = options;
const tailwindPaths = [tailwindPath].flat();

const { allDependenciesKeys, currentComponents, isAllComponents } =
await getPackageInfo(packagePath);

/** ======================== Output when there is no components installed ======================== */
if (!currentComponents.length && !isAllComponents) {
Logger.prefix(
'error',
`❌Sorry there are no ${chalk.underline(
'NextUI components'
)} in your project\nPlace check the NextUI document: https://nextui.org/docs/guide/installation#global-installation`
);

return;
}

/** ======================== Problem record ======================== */
const problemRecord: ProblemRecord[] = [];

Expand All @@ -33,7 +54,6 @@ export async function doctorAction(options: DoctorActionOptions) {
Logger.warn('you have installed redundant dependencies, please remove them');
Logger.newLine();
Logger.info('The redundant dependencies are:');
Logger.newLine();
currentComponents.forEach((component) => {
Logger.info(`- ${component.package}`);
});
Expand All @@ -49,6 +69,89 @@ export async function doctorAction(options: DoctorActionOptions) {
allDependenciesKeys
);

if (!isCorrectInstalled) {
problemRecord.push({
level: 'error',
name: 'missingDependencies',
outputFn: () => {
Logger.error('you have not installed the required dependencies');
Logger.newLine();
Logger.info('The required dependencies are:');
missingDependencies.forEach((dependency) => {
Logger.info(`- ${dependency}`);
});
Logger.newLine();
Logger.info(`Please check the detail in the NextUI document: ${DOCS_INSTALLED}`);
}
});
}

// Check whether tailwind.config.js is correct
if (!tailwindPaths.length) {
problemRecord.push({
level: 'error',
name: 'missingTailwind',
outputFn: () => {
Logger.error('you have not created the tailwind.config.js');
Logger.error(`Please check the detail in the NextUI document: ${DOCS_TAILWINDCSS_SETUP}`);
}
});
} else {
for (const tailwindPath of tailwindPaths) {
const [isCorrectTailwind, ...errorInfo] = checkTailwind('all', tailwindPath);

if (!isCorrectTailwind) {
problemRecord.push({
level: 'error',
name: 'incorrectTailwind',
outputFn: () => {
Logger.error('your tailwind.config.js is incorrect');
Logger.info('The missing part is:');
errorInfo.forEach((info) => {
Logger.info(`- need added ${info}`);
});
Logger.error(`Please check the detail in the NextUI document: ${DOCS_APP_SETUP}`);
}
});
}
}
}

// Check whether the app.tsx is correct
if (!appPath) {
problemRecord.push({
level: 'error',
name: 'missingApp',
outputFn: () => {
Logger.error('Cannot find the app.tsx file');
Logger.error("You should specify appPath through 'doctor --appPath=yourAppPath'");
}
});
} else {
const [isAppCorrect, ...errorInfo] = checkApp('all', appPath);

if (!isAppCorrect) {
problemRecord.push({
level: 'error',
name: 'incorrectApp',
outputFn: () => {
Logger.error('your app.tsx is incorrect');
Logger.info('The missing part is:');
errorInfo.forEach((info) => {
Logger.info(`- need added ${info}`);
});
Logger.error(`Please check the detail in the NextUI document: ${DOCS_INSTALLED}`);
}
});
}
}
} else if (currentComponents.length) {
// Individual components check
const [isCorrectInstalled, ...missingDependencies] = checkRequiredContentInstalled(
'partial',
allDependenciesKeys
);

if (!isCorrectInstalled) {
problemRecord.push({
level: 'error',
Expand Down
23 changes: 21 additions & 2 deletions src/constants/required.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
export const ALL_COMPONENTS = '@nextui-org/react';
export const FRAMER_MOTION = 'framer-motion';
export const ALL_COMPONENTS_REQUIRED = [ALL_COMPONENTS, FRAMER_MOTION] as const;
export const TAILWINDCSS = 'tailwindcss';
export const NEXT_UI = '@nextui-org/react';
export const THEME_UI = '@nextui-org/theme';
export const SYSTEM_UI = '@nextui-org/system';
export const ALL_COMPONENTS_REQUIRED = [NEXT_UI, FRAMER_MOTION] as const;

export const DOCS_INSTALLED = 'https://nextui.org/docs/guide/installation#global-installation';
export const DOCS_TAILWINDCSS_SETUP =
'https://nextui.org/docs/guide/installation#tailwind-css-setup';
export const DOCS_APP_SETUP = 'https://nextui.org/docs/guide/installation#provider-setup';

// Record the required content of tailwind.config.js
export const tailwindRequired = {
content: '@nextui-org/theme/dist/**/*.{js,ts,jsx,tsx}',
darkMode: 'darkMode: "class"',
plugins: 'nextui()'
} as const;

export const appRequired = {
import: 'NextUIProvider'
};
Loading

0 comments on commit 107034c

Please sign in to comment.