Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(cli): A bit smarter cli #823

Closed
wants to merge 11 commits into from
12 changes: 8 additions & 4 deletions packages/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { existsSync, promises as fs } from "fs"
import path from "path"
import {
DEFAULT_COMPONENTS,
DEFAULT_TAILWIND_CONFIG,
DEFAULT_TAILWIND_CSS,
DEFAULT_UTILS,
getConfig,
rawConfigSchema,
resolveConfigPaths,
Expand All @@ -27,6 +23,8 @@ import ora from "ora"
import prompts from "prompts"
import * as z from "zod"

import { getInitialValues } from "../utils/get-initial-values"
Bekacru marked this conversation as resolved.
Show resolved Hide resolved

const PROJECT_DEPENDENCIES = [
"tailwindcss-animate",
"class-variance-authority",
Expand Down Expand Up @@ -84,6 +82,12 @@ export async function promptForConfig(

const styles = await getRegistryStyles()
const baseColors = await getRegistryBaseColors()
const {
DEFAULT_COMPONENTS,
DEFAULT_TAILWIND_CONFIG,
DEFAULT_UTILS,
DEFAULT_TAILWIND_CSS,
} = await getInitialValues()

const options = await prompts([
{
Expand Down
9 changes: 1 addition & 8 deletions packages/cli/src/utils/get-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,6 @@ import { cosmiconfig } from "cosmiconfig"
import { loadConfig } from "tsconfig-paths"
import * as z from "zod"

export const DEFAULT_STYLE = "default"
export const DEFAULT_COMPONENTS = "@/components"
export const DEFAULT_UTILS = "@/lib/utils"
export const DEFAULT_TAILWIND_CSS = "app/globals.css"
export const DEFAULT_TAILWIND_CONFIG = "tailwind.config.js"
export const DEFAULT_TAILWIND_BASE_COLOR = "slate"

// TODO: Figure out if we want to support all cosmiconfig formats.
// A simple components.json file would be nice.
const explorer = cosmiconfig("components", {
Expand Down Expand Up @@ -61,7 +54,7 @@ export async function getConfig(cwd: string) {

export async function resolveConfigPaths(cwd: string, config: RawConfig) {
// Read tsconfig.json.
const tsConfig = await loadConfig(cwd)
const tsConfig = loadConfig(cwd)

if (tsConfig.resultType === "failed") {
throw new Error(
Expand Down
50 changes: 50 additions & 0 deletions packages/cli/src/utils/get-initial-values.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import path from "path"
import fs from "fs-extra"

import { getProjectInfo, resolveProjectDir } from "./get-project-info"
Bekacru marked this conversation as resolved.
Show resolved Hide resolved

export const getInitialValues = async () => {
const { srcDir, appDir, tsconfig, stylesDir } = await getProjectInfo()
const dir = resolveProjectDir(appDir, srcDir)
const cssDir = stylesDir ?? dir
const css = (await findCssFile(cssDir)) ?? "globals.css"
const paths = tsconfig?.compilerOptions?.paths
//find the alias for dir TODO://if there is no ts alias like @ we need to handle it better this is not ideal workaround
const alias = paths
? Object.keys(paths)
.find((key) => paths[key].toString().includes(dir))
?.split("/*")[0] ??
Object.keys(paths)[0].split("/")[0] ??
"@"
: dir
const twConfig = await findTwConfig("./")
return {
DEFAULT_TAILWIND_CSS: cssDir.length ? `${cssDir}/${css}` : css,
DEFAULT_COMPONENTS: alias.length ? `${alias}/components` : "components",
DEFAULT_UTILS: alias.length ? `${alias}/lib/utils` : "lib/utils",
DEFAULT_TAILWIND_BASE_COLOR: "slate",
DEFAULT_TAILWIND_CONFIG: twConfig,
DEFAULT_STYLE: "default",
}
}

//find common global css files
const findCssFile = async (dir: string) => {
Bekacru marked this conversation as resolved.
Show resolved Hide resolved
const files = await fs.readdir(dir || "./")
return files.find((file) => {
if (file.endsWith(".css")) {
return (
file.includes("index") ||
file.includes("global") ||
file.includes("style") ||
file.includes("tailwind") ||
file.includes("main")
)
}
})
}

const findTwConfig = async (dir: string) => {
const files = await fs.readdir(dir ?? "./")
return files.find((file) => file.includes("tailwind.config"))
}
25 changes: 22 additions & 3 deletions packages/cli/src/utils/get-project-info.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
import { existsSync } from "fs"
import path from "path"
import fs from "fs-extra"
import { TsConfigJson } from "type-fest"

export async function getProjectInfo() {
const info = {
tsconfig: null,
srcDir: false,
appDir: false,
stylesDir: null,
srcComponentsUiDir: false,
componentsUiDir: false,
}

try {
const tsconfig = await getTsConfig()

const stylesDir = getStylesDir()
return {
tsconfig,
srcDir: existsSync(path.resolve("./src")),
appDir:
existsSync(path.resolve("./app")) ||
existsSync(path.resolve("./src/app")),
stylesDir,
srcComponentsUiDir: existsSync(path.resolve("./src/components/ui")),
componentsUiDir: existsSync(path.resolve("./components/ui")),
}
Expand All @@ -36,9 +39,25 @@ export async function getTsConfig() {
if (!tsconfig) {
throw new Error("tsconfig.json is missing")
}

return tsconfig
return tsconfig as TsConfigJson
} catch (error) {
return null
}
}

export function getStylesDir() {
Bekacru marked this conversation as resolved.
Show resolved Hide resolved
const stylesDir = existsSync(path.resolve("./styles"))
? "./styles"
: existsSync(path.resolve("./src/styles"))
? "./src/styles"
: existsSync(path.resolve("./src/app/styles"))
? "./src/app/styles"
: existsSync(path.resolve("./app/styles"))
? "./app/styles"
: null
return stylesDir
}

export function resolveProjectDir(appDir: boolean, srcDir: boolean) {
Bekacru marked this conversation as resolved.
Show resolved Hide resolved
return appDir && srcDir ? "src/app" : appDir ? "app" : srcDir ? "src" : ""
}