fix: cli installation error
This commit is contained in:
parent
bc545c95e4
commit
ec0c3cc659
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -7,6 +7,7 @@ yarn-error.log*
|
|||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
.env
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
|
|
|
|||
|
|
@ -292,74 +292,41 @@ Add the following to your `src/app.postcss` file. You can learn more about using
|
|||
You'll want to create a `cn` helper to make it easier to conditionally add Tailwind CSS classes. Additionally, you'll want to add the custom transition that is used by various components.
|
||||
|
||||
```ts title="src/lib/utils.ts"
|
||||
import type { Updater } from '@tanstack/vue-table'
|
||||
import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { cubicOut } from 'svelte/easing'
|
||||
import type { TransitionConfig } from 'svelte/transition'
|
||||
import { type Ref, camelize, getCurrentInstance, toHandlerKey } from 'vue'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
||||
interface FlyAndScaleParams {
|
||||
y?: number
|
||||
x?: number
|
||||
start?: number
|
||||
duration?: number
|
||||
// Vue doesn't have emits forwarding, in order to bind the emits we have to convert events into `onXXX` handlers
|
||||
// issue: https://github.com/vuejs/core/issues/5917
|
||||
export function useEmitAsProps<Name extends string>(
|
||||
emit: (name: Name, ...args: any[]) => void,
|
||||
) {
|
||||
const vm = getCurrentInstance()
|
||||
|
||||
const events = vm?.type.emits as Name[]
|
||||
const result: Record<string, any> = {}
|
||||
if (!events?.length) {
|
||||
console.warn(
|
||||
`No emitted event found. Please check component: ${vm?.type.__name}`,
|
||||
)
|
||||
}
|
||||
|
||||
events?.forEach((ev) => {
|
||||
result[toHandlerKey(camelize(ev))] = (...arg: any) => emit(ev, ...arg)
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
export function flyAndScale(node: Element,
|
||||
params: FlyAndScaleParams = { y: -8, x: 0, start: 0.95, duration: 150 }): TransitionConfig {
|
||||
const style = getComputedStyle(node)
|
||||
const transform = style.transform === 'none' ? '' : style.transform
|
||||
|
||||
const scaleConversion = (
|
||||
valueA: number,
|
||||
scaleA: [number, number],
|
||||
scaleB: [number, number]
|
||||
) => {
|
||||
const [minA, maxA] = scaleA
|
||||
const [minB, maxB] = scaleB
|
||||
|
||||
const percentage = (valueA - minA) / (maxA - minA)
|
||||
const valueB = percentage * (maxB - minB) + minB
|
||||
|
||||
return valueB
|
||||
}
|
||||
|
||||
const styleToString = (
|
||||
style: Record<string, number | string | undefined>
|
||||
): string => {
|
||||
return Object.keys(style).reduce((str, key) => {
|
||||
if (style[key] === undefined)
|
||||
return str
|
||||
return `${str + key}:${style[key]};`
|
||||
}, '')
|
||||
}
|
||||
|
||||
return {
|
||||
duration: params.duration ?? 200,
|
||||
delay: 0,
|
||||
css: (t) => {
|
||||
const y = scaleConversion(t, [0, 1], [params.y ?? 5, 0])
|
||||
const x = scaleConversion(t, [0, 1], [params.x ?? 0, 0])
|
||||
const scale = scaleConversion(t, [0, 1], [params.start ?? 0.95, 1])
|
||||
|
||||
return styleToString({
|
||||
transform:
|
||||
`${transform
|
||||
}translate3d(${
|
||||
x
|
||||
}px, ${
|
||||
y
|
||||
}px, 0) scale(${
|
||||
scale
|
||||
})`,
|
||||
opacity: t
|
||||
})
|
||||
},
|
||||
easing: cubicOut
|
||||
}
|
||||
export function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
||||
ref.value
|
||||
= typeof updaterOrValue === 'function'
|
||||
? updaterOrValue(ref.value)
|
||||
: updaterOrValue
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,7 @@
|
|||
import type { Updater } from '@tanstack/vue-table'
|
||||
import type { ClassValue } from 'clsx'
|
||||
import { clsx } from 'clsx'
|
||||
import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import type { FunctionalComponent, Ref } from 'vue'
|
||||
import { camelize, defineComponent, getCurrentInstance, h, toHandlerKey } from 'vue'
|
||||
|
||||
export type ParseEmits<T extends Record<string, any>> = {
|
||||
[K in keyof T]: (...args: T[K]) => void;
|
||||
}
|
||||
import { type Ref, camelize, getCurrentInstance, toHandlerKey } from 'vue'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
|
|
@ -34,15 +28,19 @@ export function useEmitAsProps<Name extends string>(
|
|||
return result
|
||||
}
|
||||
|
||||
export function convertToComponent(component: FunctionalComponent) {
|
||||
return defineComponent({
|
||||
setup() { return () => h(component) },
|
||||
})
|
||||
}
|
||||
|
||||
export function valueUpdater<T extends Updater<any>>(updaterOrValue: T, ref: Ref) {
|
||||
ref.value
|
||||
= typeof updaterOrValue === 'function'
|
||||
? updaterOrValue(ref.value)
|
||||
: updaterOrValue
|
||||
}
|
||||
|
||||
// export type ParseEmits<T extends Record<string, any>> = {
|
||||
// [K in keyof T]: (...args: T[K]) => void;
|
||||
// }
|
||||
|
||||
// export function convertToComponent(component: FunctionalComponent) {
|
||||
// return defineComponent({
|
||||
// setup() { return () => h(component) },
|
||||
// })
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@
|
|||
"@types/lodash.template": "^4.5.1",
|
||||
"@types/prompts": "^2.4.4",
|
||||
"@vitest/ui": "^0.34.3",
|
||||
"magic-string": "^0.30.3",
|
||||
"rimraf": "^5.0.1",
|
||||
"tsup": "^7.2.0",
|
||||
"type-fest": "^4.3.0",
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { execa } from 'execa'
|
|||
import ora from 'ora'
|
||||
import prompts from 'prompts'
|
||||
import * as z from 'zod'
|
||||
import { transformImport } from '../utils/transformers/transform-import'
|
||||
import { getConfig } from '@/src/utils/get-config'
|
||||
import { getPackageManager } from '@/src/utils/get-package-manager'
|
||||
import { handleError } from '@/src/utils/handle-error'
|
||||
|
|
@ -18,7 +19,6 @@ import {
|
|||
getRegistryIndex,
|
||||
resolveTree,
|
||||
} from '@/src/utils/registry'
|
||||
import { transform } from '@/src/utils/transformers'
|
||||
|
||||
const addOptionsSchema = z.object({
|
||||
components: z.array(z.string()).optional(),
|
||||
|
|
@ -107,6 +107,7 @@ export const add = new Command()
|
|||
}
|
||||
|
||||
const spinner = ora('Installing components...').start()
|
||||
const skippedDeps = new Set<string>()
|
||||
for (const item of payload) {
|
||||
spinner.text = `Installing ${item.name}...`
|
||||
const targetDir = await getItemTargetPath(
|
||||
|
|
@ -122,41 +123,49 @@ export const add = new Command()
|
|||
await fs.mkdir(targetDir, { recursive: true })
|
||||
|
||||
const existingComponent = item.files.filter(file =>
|
||||
existsSync(path.resolve(targetDir, file.name)),
|
||||
existsSync(path.resolve(targetDir, item.name, file.name)),
|
||||
)
|
||||
|
||||
if (existingComponent.length && !options.overwrite) {
|
||||
if (selectedComponents.includes(item.name)) {
|
||||
logger.warn(
|
||||
`Component ${item.name} already exists. Use ${chalk.green(
|
||||
`\nComponent ${
|
||||
item.name
|
||||
} already exists. Use ${chalk.green(
|
||||
'--overwrite',
|
||||
)} to overwrite.`,
|
||||
)
|
||||
process.exit(1)
|
||||
spinner.stop()
|
||||
process.exitCode = 1
|
||||
return
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
for (const file of item.files) {
|
||||
const filePath = path.resolve(targetDir, file.name)
|
||||
const componentDir = path.resolve(targetDir, item.name)
|
||||
const filePath = path.resolve(
|
||||
targetDir,
|
||||
item.name,
|
||||
file.name,
|
||||
)
|
||||
|
||||
// Run transformers.
|
||||
const content = await transform({
|
||||
filename: file.name,
|
||||
raw: file.content,
|
||||
config,
|
||||
baseColor,
|
||||
})
|
||||
const content = transformImport(file.content, config)
|
||||
|
||||
// if (!config.tsx)
|
||||
// filePath = filePath.replace(/\.tsx$/, '.jsx')
|
||||
if (!existsSync(componentDir))
|
||||
await fs.mkdir(componentDir, { recursive: true })
|
||||
|
||||
await fs.writeFile(filePath, content)
|
||||
}
|
||||
|
||||
// Install dependencies.
|
||||
if (item.dependencies?.length) {
|
||||
item.dependencies.forEach(dep =>
|
||||
skippedDeps.add(dep),
|
||||
)
|
||||
|
||||
const packageManager = await getPackageManager(cwd)
|
||||
await execa(
|
||||
packageManager,
|
||||
|
|
|
|||
|
|
@ -112,8 +112,8 @@ export async function promptForConfig(
|
|||
name: 'framework',
|
||||
message: `Which ${highlight('framework')} are you using?`,
|
||||
choices: [
|
||||
{ title: 'Nuxt', value: 'nuxt' },
|
||||
{ title: 'Vite + Vue', value: 'vue' },
|
||||
{ title: 'Nuxt', value: 'nuxt' },
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
@ -140,7 +140,7 @@ export async function promptForConfig(
|
|||
type: 'text',
|
||||
name: 'tailwindCss',
|
||||
message: `Where is your ${highlight('Tailwind CSS')} file?`,
|
||||
initial: (prev, values) => defaultConfig?.tailwind.css ?? values.framework === 'nuxt' ? DEFAULT_TAILWIND_CSS_NUXT : DEFAULT_TAILWIND_CSS,
|
||||
initial: (prev, values) => defaultConfig?.tailwind.css ?? (values.framework === 'nuxt' ? DEFAULT_TAILWIND_CSS_NUXT : DEFAULT_TAILWIND_CSS),
|
||||
},
|
||||
{
|
||||
type: 'toggle',
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@ import { resolveImport } from '@/src/utils/resolve-import'
|
|||
|
||||
export const DEFAULT_STYLE = 'default'
|
||||
export const DEFAULT_COMPONENTS = '@/components'
|
||||
export const DEFAULT_UTILS = '@/utils'
|
||||
export const DEFAULT_TAILWIND_CSS = 'src/style.css'
|
||||
export const DEFAULT_UTILS = '@/lib/utils'
|
||||
export const DEFAULT_TAILWIND_CSS = 'src/assets/index.css'
|
||||
export const DEFAULT_TAILWIND_CSS_NUXT = 'assets/style/tailwind.css'
|
||||
export const DEFAULT_TAILWIND_CONFIG = 'tailwind.config.js'
|
||||
export const DEFAULT_TAILWIND_BASE_COLOR = 'slate'
|
||||
|
|
@ -61,8 +61,17 @@ export async function getConfig(cwd: string) {
|
|||
}
|
||||
|
||||
export async function resolveConfigPaths(cwd: string, config: RawConfig) {
|
||||
const TSCONFIG_PATH = config.framework === 'nuxt' ? '.nuxt/tsconfig.json' : './tsconfig.json'
|
||||
// In new Vue project, tsconfig has references to tsconfig.app.json, which is causing the path not resolving correctly
|
||||
const FALLBACK_TSCONFIG_PATH = './tsconfig.app.json'
|
||||
|
||||
// Read tsconfig.json.
|
||||
const tsConfig = await loadConfig(cwd)
|
||||
const tsconfigPath = path.resolve(cwd, TSCONFIG_PATH)
|
||||
let tsConfig = loadConfig(tsconfigPath)
|
||||
|
||||
// If no paths were found, we load the fallback tsconfig
|
||||
if ('paths' in tsConfig && Object.keys(tsConfig.paths).length === 0)
|
||||
tsConfig = loadConfig(path.resolve(cwd, FALLBACK_TSCONFIG_PATH))
|
||||
|
||||
if (tsConfig.resultType === 'failed') {
|
||||
throw new Error(
|
||||
|
|
|
|||
|
|
@ -144,7 +144,6 @@ async function fetchRegistry(paths: string[]) {
|
|||
return await response.json()
|
||||
}),
|
||||
)
|
||||
|
||||
return results
|
||||
}
|
||||
catch (error) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,29 @@
|
|||
export const UTILS = `import { type ClassValue, clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
export const UTILS = `import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
import { camelize, getCurrentInstance, toHandlerKey } from 'vue'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
`
|
||||
|
||||
export function useEmitAsProps<Name extends string>(
|
||||
emit: (name: Name, ...args: any[]) => void,
|
||||
) {
|
||||
const vm = getCurrentInstance()
|
||||
|
||||
const events = vm?.type.emits as Name[]
|
||||
const result: Record<string, any> = {}
|
||||
if (!events?.length) {
|
||||
console.warn(
|
||||
'No emitted event found. Please check component: \${vm?.type.__name}',
|
||||
)
|
||||
}
|
||||
|
||||
events?.forEach((ev) => {
|
||||
result[toHandlerKey(camelize(ev))] = (...arg: any) => emit(ev, ...arg)
|
||||
})
|
||||
return result
|
||||
}`
|
||||
|
||||
export const UTILS_JS = `import { clsx } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
|
|
@ -12,6 +31,23 @@ import { twMerge } from "tailwind-merge"
|
|||
export function cn(...inputs) {
|
||||
return twMerge(clsx(inputs))
|
||||
}
|
||||
|
||||
export function useEmitAsProps(emit) {
|
||||
const vm = getCurrentInstance()
|
||||
|
||||
const events = vm?.type.emits
|
||||
const result = {}
|
||||
if (!events?.length) {
|
||||
console.warn(
|
||||
'No emitted event found. Please check component: \${vm?.type.__name}',
|
||||
)
|
||||
}
|
||||
|
||||
events?.forEach((ev) => {
|
||||
result[toHandlerKey(camelize(ev))] = (...arg) => emit(ev, ...arg)
|
||||
})
|
||||
return result
|
||||
}
|
||||
`
|
||||
|
||||
export const TAILWIND_CONFIG = `/** @type {import('tailwindcss').Config} */
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import type * as z from 'zod'
|
|||
import type { Config } from '@/src/utils/get-config'
|
||||
import type { registryBaseColorSchema } from '@/src/utils/registry/schema'
|
||||
import { transformCssVars } from '@/src/utils/transformers/transform-css-vars'
|
||||
import { transformImport } from '@/src/utils/transformers/transform-import'
|
||||
|
||||
export interface TransformOpts {
|
||||
filename: string
|
||||
|
|
@ -22,7 +21,6 @@ export type Transformer<Output = SourceFile> = (
|
|||
) => Promise<Output>
|
||||
|
||||
const transformers: Transformer[] = [
|
||||
transformImport,
|
||||
transformCssVars,
|
||||
]
|
||||
|
||||
|
|
|
|||
|
|
@ -1,32 +1,49 @@
|
|||
import type { Transformer } from '@/src/utils/transformers'
|
||||
import MagicString from 'magic-string'
|
||||
import type { z } from 'zod'
|
||||
import type { Config } from '../get-config'
|
||||
import type { registryBaseColorSchema } from '../registry/schema'
|
||||
|
||||
export const transformImport: Transformer = async ({ sourceFile, config }) => {
|
||||
const importDeclarations = sourceFile.getImportDeclarations()
|
||||
|
||||
for (const importDeclaration of importDeclarations) {
|
||||
const moduleSpecifier = importDeclaration.getModuleSpecifierValue()
|
||||
|
||||
// Replace @/registry/[style] with the components alias.
|
||||
if (moduleSpecifier.startsWith('@/registry/')) {
|
||||
importDeclaration.setModuleSpecifier(
|
||||
moduleSpecifier.replace(
|
||||
/^@\/registry\/[^/]+/,
|
||||
config.aliases.components,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
// Replace `import { cn } from "@/lib/utils"`
|
||||
if (moduleSpecifier === '@/lib/utils') {
|
||||
const namedImports = importDeclaration.getNamedImports()
|
||||
const cnImport = namedImports.find(i => i.getName() === 'cn')
|
||||
if (cnImport) {
|
||||
importDeclaration.setModuleSpecifier(
|
||||
moduleSpecifier.replace(/^@\/lib\/utils/, config.aliases.utils),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return sourceFile
|
||||
export interface TransformOpts {
|
||||
filename: string
|
||||
raw: string
|
||||
config: Config
|
||||
baseColor?: z.infer<typeof registryBaseColorSchema>
|
||||
}
|
||||
|
||||
export function transformImport(content: string, config: Config) {
|
||||
const s = new MagicString(content)
|
||||
s.replaceAll(/@\/registry\/[^/]+/g, config.aliases.components)
|
||||
s.replaceAll(/\$lib\/utils/g, config.aliases.utils)
|
||||
return s.toString()
|
||||
}
|
||||
|
||||
// export const transformImport: Transformer = async ({ sourceFile, config }) => {
|
||||
// const importDeclarations = sourceFile.getImportDeclarations()
|
||||
|
||||
// for (const importDeclaration of importDeclarations) {
|
||||
// const moduleSpecifier = importDeclaration.getModuleSpecifierValue()
|
||||
|
||||
// // Replace @/registry/[style] with the components alias.
|
||||
// if (moduleSpecifier.startsWith('@/registry/')) {
|
||||
// importDeclaration.setModuleSpecifier(
|
||||
// moduleSpecifier.replace(
|
||||
// /^@\/registry\/[^/]+/,
|
||||
// config.aliases.components,
|
||||
// ),
|
||||
// )
|
||||
// }
|
||||
|
||||
// // Replace `import { cn } from "@/lib/utils"`
|
||||
// if (moduleSpecifier === '@/lib/utils') {
|
||||
// const namedImports = importDeclaration.getNamedImports()
|
||||
// const cnImport = namedImports.find(i => i.getName() === 'cn')
|
||||
// if (cnImport) {
|
||||
// importDeclaration.setModuleSpecifier(
|
||||
// moduleSpecifier.replace(/^@\/lib\/utils/, config.aliases.utils),
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// return sourceFile
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -144,9 +144,6 @@ importers:
|
|||
vite:
|
||||
specifier: ^4.3.9
|
||||
version: 4.3.9(@types/node@20.5.7)
|
||||
vite-tsconfig-paths:
|
||||
specifier: ^4.2.0
|
||||
version: 4.2.0(typescript@5.0.2)(vite@4.3.9)
|
||||
vue-tsc:
|
||||
specifier: ^1.4.2
|
||||
version: 1.4.2(typescript@5.0.2)
|
||||
|
|
@ -229,6 +226,9 @@ importers:
|
|||
'@vitest/ui':
|
||||
specifier: ^0.34.3
|
||||
version: 0.34.3(vitest@0.34.3)
|
||||
magic-string:
|
||||
specifier: ^0.30.3
|
||||
version: 0.30.3
|
||||
rimraf:
|
||||
specifier: ^5.0.1
|
||||
version: 5.0.1
|
||||
|
|
@ -7224,19 +7224,6 @@ packages:
|
|||
v8-compile-cache-lib: 3.0.1
|
||||
yn: 3.1.1
|
||||
|
||||
/tsconfck@2.1.2(typescript@5.0.2):
|
||||
resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==}
|
||||
engines: {node: ^14.13.1 || ^16 || >=18}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
typescript: ^4.3.5 || ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
typescript: 5.0.2
|
||||
dev: true
|
||||
|
||||
/tsconfck@2.1.2(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==}
|
||||
engines: {node: ^14.13.1 || ^16 || >=18}
|
||||
|
|
@ -7586,23 +7573,6 @@ packages:
|
|||
- terser
|
||||
dev: true
|
||||
|
||||
/vite-tsconfig-paths@4.2.0(typescript@5.0.2)(vite@4.3.9):
|
||||
resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==}
|
||||
peerDependencies:
|
||||
vite: '*'
|
||||
peerDependenciesMeta:
|
||||
vite:
|
||||
optional: true
|
||||
dependencies:
|
||||
debug: 4.3.4
|
||||
globrex: 0.1.2
|
||||
tsconfck: 2.1.2(typescript@5.0.2)
|
||||
vite: 4.3.9(@types/node@20.5.7)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
- typescript
|
||||
dev: true
|
||||
|
||||
/vite-tsconfig-paths@4.2.0(typescript@5.2.2):
|
||||
resolution: {integrity: sha512-jGpus0eUy5qbbMVGiTxCL1iB9ZGN6Bd37VGLJU39kTDD6ZfULTTb1bcc5IeTWqWJKiWV5YihCaibeASPiGi8kw==}
|
||||
peerDependencies:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user