-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add packages detect & check featt: command init feat: resolve package & detect framework feat: init feat: prompts & components.json chore: add test script chore: workflow add test fix: check feat: init
- Loading branch information
Showing
49 changed files
with
4,560 additions
and
257 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
name: Test | ||
|
||
on: | ||
pull_request: | ||
branches: ["*"] | ||
|
||
jobs: | ||
test: | ||
runs-on: ubuntu-latest | ||
name: pnpm test | ||
steps: | ||
- uses: actions/checkout@v4 | ||
|
||
- name: Install Node.js | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 20 | ||
|
||
- uses: pnpm/action-setup@v4 | ||
name: Install pnpm | ||
id: pnpm-install | ||
|
||
- name: Get pnpm store directory | ||
id: pnpm-cache | ||
run: | | ||
echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT | ||
- uses: actions/cache@v3 | ||
name: Setup pnpm cache | ||
with: | ||
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }} | ||
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} | ||
restore-keys: | | ||
${{ runner.os }}-pnpm-store- | ||
- name: Install dependencies | ||
run: pnpm install | ||
|
||
- run: pnpm test |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,9 +6,9 @@ | |
"scripts": { | ||
"bump": "taze -r -l", | ||
"dev": "turbo dev", | ||
"test": "turbo run test", | ||
"build": "turbo run build", | ||
"check": "biome check", | ||
"check:write": "biome check --write", | ||
"repocheck": "sherif", | ||
"check-types": "turbo run check-types", | ||
"clean": "rimraf -g **/node_modules **/dist **/.turbo **/.astro", | ||
|
@@ -25,13 +25,16 @@ | |
"simple-git-hooks": "^2.11.1", | ||
"taze": "^0.17.2", | ||
"turbo": "^2.1.3", | ||
"typescript": "^5.6.2" | ||
"typescript": "^5.6.2", | ||
"vite": "^5.4.3" | ||
}, | ||
"packageManager": "[email protected]", | ||
"simple-git-hooks": { | ||
"pre-commit": "pnpm lint-staged" | ||
}, | ||
"lint-staged": { | ||
"*": "pnpm check:write" | ||
"*": [ | ||
"biome check --write --no-errors-on-unmatched --files-ignore-unknown=true" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"name": "shipbase-ui", | ||
"version": "0.0.0", | ||
"type": "module", | ||
"description": "Add components to your apps.", | ||
"exports": "./dist/index.js", | ||
"bin": "./dist/index.js", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/shipbase/ui.git", | ||
"directory": "packages/cli" | ||
}, | ||
"author": "@shipbase", | ||
"license": "MIT", | ||
"files": ["dist"], | ||
"keywords": ["shipbase", "components", "ui", "tailwind", "ark-ui"], | ||
"scripts": { | ||
"dev": "tsup --watch", | ||
"build": "tsup", | ||
"check-types": "tsc --noEmit", | ||
"test": "vitest" | ||
}, | ||
"devDependencies": { | ||
"@types/prompts": "^2.4.9", | ||
"@ui/lib": "workspace:*", | ||
"@ui/tsconfig": "workspace:*", | ||
"tsup": "^8.2.4", | ||
"vitest": "^2.0.5" | ||
}, | ||
"dependencies": { | ||
"cac": "^6.7.14", | ||
"kleur": "^4.1.5", | ||
"mlly": "^1.7.1", | ||
"nypm": "^0.3.11", | ||
"ora": "^8.1.0", | ||
"prompts": "^2.4.2", | ||
"ufo": "^1.5.4", | ||
"zod": "^3.23.8" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
import fs from "node:fs/promises" | ||
import path from "node:path" | ||
import { safeResolveAndRead } from "@ui/lib/utils/mlly" | ||
import { cyan } from "kleur/colors" | ||
import ora from "ora" | ||
import prompts from "prompts" | ||
import { | ||
type Config, | ||
type UserConfig, | ||
userConfigSchema, | ||
} from "../config/schema" | ||
import { | ||
DEFAULT_COMPONENTS, | ||
DEFAULT_STYLE, | ||
DEFAULT_TAILWIND_BASE_COLOR, | ||
DEFAULT_TAILWIND_CONFIG, | ||
DEFAULT_UTILS, | ||
LIBRARIES, | ||
TAILWIND_CSS_FILE_PATH, | ||
} from "../constants" | ||
import { logger } from "../utils/logger" | ||
import { prepare } from "../utils/prepare" | ||
|
||
export async function init({ library }: { library?: Config["library"] }) { | ||
let userConfig: UserConfig | ||
|
||
try { | ||
await prepare() | ||
userConfig = await promptConfig({ library }) | ||
|
||
const { write } = await prompts({ | ||
type: "confirm", | ||
name: "write", | ||
message: `Write configuration to ${cyan("components.json")}. Proceed?`, | ||
initial: true, | ||
}) | ||
|
||
// Write components.json. | ||
if (write) { | ||
const writeSpinner = ora("Writing components.json...").start() | ||
const targetPath = path.resolve(process.cwd(), "components.json") | ||
await fs.writeFile( | ||
targetPath, | ||
JSON.stringify(userConfig, null, 2), | ||
"utf8" | ||
) | ||
writeSpinner.succeed() | ||
} | ||
} catch (error: unknown) { | ||
if (error instanceof Error) { | ||
logger.error(error.message) | ||
} else { | ||
logger.error("unknown errors") | ||
} | ||
process.exit(1) | ||
} | ||
} | ||
|
||
async function validateFilePath(relative: string) { | ||
const file = await safeResolveAndRead(path.resolve(process.cwd(), relative)) | ||
if (!file.success) | ||
return "File not found. Please check the path and try again." | ||
return true | ||
} | ||
|
||
async function validateTailwindGlobalCss(relative: string) { | ||
const file = await safeResolveAndRead(path.resolve(process.cwd(), relative)) | ||
if (!file.success) | ||
return "File not found. Please check the path and try again." | ||
if (!file.result.includes("@tailwind base")) { | ||
return "The file does not include '@tailwind base'. Please ensure it contains the necessary Tailwind directives." | ||
} | ||
return true | ||
} | ||
|
||
async function promptConfig(defaultConfig: Partial<UserConfig>) { | ||
const result = await prompts( | ||
[ | ||
{ | ||
type: | ||
defaultConfig.library && | ||
LIBRARIES.findIndex((lib) => lib.value === defaultConfig.library) > -1 | ||
? null | ||
: "select", | ||
name: "library", | ||
initial: defaultConfig.library, | ||
message: "Pick your favorite library", | ||
choices: LIBRARIES, | ||
}, | ||
{ | ||
type: null, // TODO: Implement toggle | ||
name: "typescript", | ||
message: `Would you like to use ${cyan("TypeScript")} (recommended)?`, | ||
initial: true, | ||
active: "yes", | ||
inactive: "no", | ||
}, | ||
{ | ||
type: null, // TODO: Implement select | ||
name: "style", | ||
message: `Which ${cyan("style")} would you like to use?`, | ||
choices: [{ title: "Default", value: "default" }], | ||
initial: DEFAULT_STYLE, | ||
}, | ||
{ | ||
type: null, // TODO: Implement select | ||
name: "tailwindBaseColor", | ||
message: `Which color would you like to use as the ${cyan("base color")}?`, | ||
choices: [{ title: "Slate", value: "slate" }], | ||
initial: DEFAULT_TAILWIND_BASE_COLOR, | ||
}, | ||
{ | ||
type: "text", | ||
name: "tailwindCss", | ||
message: `Where is your ${cyan("global CSS")} file?`, | ||
initial: TAILWIND_CSS_FILE_PATH.vite, | ||
validate: validateTailwindGlobalCss, | ||
}, | ||
{ | ||
type: "toggle", | ||
name: "tailwindCssVariables", | ||
message: `Would you like to use ${cyan("CSS variables")} for theming?`, | ||
initial: true, | ||
active: "yes", | ||
inactive: "no", | ||
}, | ||
{ | ||
type: null, // TODO: Implement text | ||
name: "tailwindPrefix", | ||
message: `Are you using a custom ${cyan( | ||
"tailwind prefix eg. tw-" | ||
)}? (Leave blank if not)`, | ||
initial: "", | ||
}, | ||
{ | ||
type: "text", | ||
name: "tailwindConfig", | ||
message: `Where is your ${cyan("tailwind.config.js")} located?`, | ||
initial: DEFAULT_TAILWIND_CONFIG, | ||
validate: validateFilePath, | ||
}, | ||
{ | ||
type: "text", | ||
name: "aliasComponents", | ||
message: `Configure the import alias for ${cyan("components")}:`, | ||
initial: DEFAULT_COMPONENTS, | ||
}, | ||
{ | ||
type: "text", | ||
name: "utils", | ||
message: `Configure the import alias for ${cyan("utils")}:`, | ||
initial: DEFAULT_UTILS, | ||
}, | ||
], | ||
{ | ||
onCancel: () => { | ||
throw new Error("✖ Operation cancelled") | ||
}, | ||
} | ||
) | ||
|
||
return userConfigSchema.parse({ | ||
library: defaultConfig.library ?? result.library, | ||
style: "default", | ||
tsx: true, | ||
tailwind: { | ||
config: result.tailwindConfig, | ||
css: result.tailwindCss, | ||
baseColor: "slate", | ||
cssVariables: result.tailwindCssVariables, | ||
prefix: "", | ||
}, | ||
aliases: { | ||
components: result.aliasComponents, | ||
utils: result.utils, | ||
}, | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import type { Config } from "./schema" | ||
|
||
export async function resolveConfig() { | ||
// return { | ||
// framework: "react", | ||
// style: "css", | ||
// tailwind: { | ||
// config: "tailwind.config.js", | ||
// css: "src/index.css", | ||
// baseColor: "blue", | ||
// cssVariables: true, | ||
// prefix: "", | ||
// }, | ||
// aliases: { | ||
// components: "src/components", | ||
// utils: "src /utils", | ||
// }, | ||
// } satisfies Config | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { z } from "zod" | ||
|
||
export const userConfigSchema = z | ||
.object({ | ||
// $schema: z.string().optional(), | ||
library: z.enum(["react", "vue"]), | ||
style: z.string(), | ||
// rsc: z.coerce.boolean().default(false), | ||
tsx: z.coerce.boolean().default(true), | ||
tailwind: z.object({ | ||
config: z.string(), | ||
css: z.string(), | ||
baseColor: z.string(), | ||
cssVariables: z.boolean().default(true), | ||
prefix: z.string().default("").optional(), | ||
}), | ||
aliases: z.object({ | ||
components: z.string(), | ||
utils: z.string(), | ||
}), | ||
}) | ||
.strict() | ||
|
||
export type UserConfig = z.infer<typeof userConfigSchema> | ||
|
||
export const configSchema = userConfigSchema.extend({ | ||
resolvedPaths: z.object({ | ||
cwd: z.string(), | ||
tailwindConfig: z.string(), | ||
tailwindCss: z.string(), | ||
components: z.string(), | ||
utils: z.string(), | ||
}), | ||
}) | ||
|
||
export type Config = z.infer<typeof configSchema> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
export const DEFAULT_LIBRARY = "react" | ||
|
||
export const DEFAULT_STYLE = "default" | ||
export const DEFAULT_COMPONENTS = "@/components" | ||
export const DEFAULT_UTILS = "@/lib/utils" | ||
export const DEFAULT_TAILWIND_CONFIG = "tailwind.config.js" | ||
export const DEFAULT_TAILWIND_BASE_COLOR = "slate" | ||
|
||
export const TAILWIND_CSS_FILE_PATH = { | ||
vite: "src/assets/base.css", | ||
} |
Oops, something went wrong.