solid-vue-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/addons/auth.js +87 -0
- package/addons/i18n.js +31 -0
- package/addons/index.js +25 -0
- package/addons/lint.js +38 -0
- package/addons/lucide.js +19 -0
- package/addons/ofetch.js +19 -0
- package/addons/tabler.js +19 -0
- package/addons/tailwind.js +41 -0
- package/addons/unhead.js +22 -0
- package/addons/vee-validate.js +20 -0
- package/addons/vitest.js +51 -0
- package/addons/vueuse.js +18 -0
- package/bin/cli.js +30 -0
- package/package.json +12 -0
package/addons/auth.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
|
|
6
|
+
export default function installAuth(cwd) {
|
|
7
|
+
console.log(chalk.blue.bold('\n🚀 Installing basic session auth (h3 useSession + bcryptjs)...'))
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
execSync('npm install bcryptjs', { stdio: 'inherit', cwd })
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.error(chalk.red.bold('\n❌ Failed to install bcryptjs:'))
|
|
13
|
+
console.error(chalk.red(err.message))
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const isTs = fs.existsSync(path.join(cwd, 'tsconfig.json'))
|
|
18
|
+
const ext = isTs ? 'ts' : 'js'
|
|
19
|
+
|
|
20
|
+
const authDir = path.join(cwd, 'src', 'server', 'api', 'auth')
|
|
21
|
+
if (!fs.existsSync(authDir)) fs.mkdirSync(authDir, { recursive: true })
|
|
22
|
+
|
|
23
|
+
fs.writeFileSync(path.join(authDir, `register.${ext}`), `import { useSession, readBody } from 'solid-vue/server'
|
|
24
|
+
import bcrypt from 'bcryptjs'
|
|
25
|
+
|
|
26
|
+
// TODO: Ganti ku query database Aa sabenerna
|
|
27
|
+
async function createUser(email, passwordHash) {
|
|
28
|
+
throw new Error('createUser() acan diimplementasikeun — sambungkeun ka database Aa')
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default async function (event) {
|
|
32
|
+
const { email, password } = await readBody(event)
|
|
33
|
+
const passwordHash = await bcrypt.hash(password, 10)
|
|
34
|
+
const user = await createUser(email, passwordHash)
|
|
35
|
+
|
|
36
|
+
const session = await useSession(event, {
|
|
37
|
+
password: process.env.SESSION_SECRET, // minimal 32 karakter acak
|
|
38
|
+
})
|
|
39
|
+
await session.update({ userId: user.id })
|
|
40
|
+
|
|
41
|
+
return { status: 'ok' }
|
|
42
|
+
}
|
|
43
|
+
`)
|
|
44
|
+
|
|
45
|
+
fs.writeFileSync(path.join(authDir, `login.${ext}`), `import { useSession, readBody } from 'solid-vue/server'
|
|
46
|
+
import bcrypt from 'bcryptjs'
|
|
47
|
+
|
|
48
|
+
// TODO: Ganti ku query database Aa sabenerna
|
|
49
|
+
async function findUserByEmail(email) {
|
|
50
|
+
throw new Error('findUserByEmail() acan diimplementasikeun — sambungkeun ka database Aa')
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export default async function (event) {
|
|
54
|
+
const { email, password } = await readBody(event)
|
|
55
|
+
const user = await findUserByEmail(email)
|
|
56
|
+
|
|
57
|
+
if (!user || !(await bcrypt.compare(password, user.passwordHash))) {
|
|
58
|
+
event.node.res.statusCode = 401
|
|
59
|
+
return { status: 'error', message: 'Email atawa password salah' }
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const session = await useSession(event, {
|
|
63
|
+
password: process.env.SESSION_SECRET,
|
|
64
|
+
})
|
|
65
|
+
await session.update({ userId: user.id })
|
|
66
|
+
|
|
67
|
+
return { status: 'ok' }
|
|
68
|
+
}
|
|
69
|
+
`)
|
|
70
|
+
|
|
71
|
+
fs.writeFileSync(path.join(authDir, `logout.${ext}`), `import { useSession } from 'solid-vue/server'
|
|
72
|
+
|
|
73
|
+
export default async function (event) {
|
|
74
|
+
const session = await useSession(event, {
|
|
75
|
+
password: process.env.SESSION_SECRET,
|
|
76
|
+
})
|
|
77
|
+
await session.clear()
|
|
78
|
+
|
|
79
|
+
return { status: 'ok' }
|
|
80
|
+
}
|
|
81
|
+
`)
|
|
82
|
+
|
|
83
|
+
console.log(chalk.green.bold('\n✅ Basic auth scaffolding installed!'))
|
|
84
|
+
console.log(chalk.yellow('⚠️ Butuh ditambihan manual sateuacan dipaké:'))
|
|
85
|
+
console.log(chalk.white(' 1. Set SESSION_SECRET di .env (minimal 32 karakter acak)'))
|
|
86
|
+
console.log(chalk.white(' 2. Implementasikeun createUser() & findUserByEmail() luyu database Aa'))
|
|
87
|
+
}
|
package/addons/i18n.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
|
|
6
|
+
export default function installI18n(cwd) {
|
|
7
|
+
console.log(chalk.blue.bold('\n🚀 Installing vue-i18n...'))
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
execSync('npm install vue-i18n', { stdio: 'inherit', cwd })
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.error(chalk.red.bold('\n❌ Failed to install vue-i18n:'))
|
|
13
|
+
console.error(chalk.red(err.message))
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const localesDir = path.join(cwd, 'src', 'locales')
|
|
18
|
+
if (!fs.existsSync(localesDir)) {
|
|
19
|
+
fs.mkdirSync(localesDir, { recursive: true })
|
|
20
|
+
fs.writeFileSync(path.join(localesDir, 'id.json'), JSON.stringify({ hello: 'Halo!' }, null, 2))
|
|
21
|
+
fs.writeFileSync(path.join(localesDir, 'en.json'), JSON.stringify({ hello: 'Hello!' }, null, 2))
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
console.log(chalk.green.bold('\n✅ vue-i18n installed successfully!'))
|
|
25
|
+
console.log(chalk.white('💡 Setup di main entry:'))
|
|
26
|
+
console.log(chalk.cyan(' import { createI18n } from "vue-i18n"'))
|
|
27
|
+
console.log(chalk.cyan(' import id from "./locales/id.json"'))
|
|
28
|
+
console.log(chalk.cyan(' import en from "./locales/en.json"'))
|
|
29
|
+
console.log(chalk.cyan(' const i18n = createI18n({ legacy: false, locale: "id", messages: { id, en } })'))
|
|
30
|
+
console.log(chalk.cyan(' app.use(i18n)'))
|
|
31
|
+
}
|
package/addons/index.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import tailwind from './tailwind.js'
|
|
2
|
+
import lucide from './lucide.js'
|
|
3
|
+
import tabler from './tabler.js'
|
|
4
|
+
import vueuse from './vueuse.js'
|
|
5
|
+
import vitest from './vitest.js'
|
|
6
|
+
import veeValidate from './vee-validate.js'
|
|
7
|
+
import unhead from './unhead.js'
|
|
8
|
+
import ofetch from './ofetch.js'
|
|
9
|
+
import i18n from './i18n.js'
|
|
10
|
+
import lint from './lint.js'
|
|
11
|
+
import auth from './auth.js'
|
|
12
|
+
|
|
13
|
+
export const addons = {
|
|
14
|
+
tailwind,
|
|
15
|
+
lucide,
|
|
16
|
+
tabler,
|
|
17
|
+
vueuse,
|
|
18
|
+
vitest,
|
|
19
|
+
'vee-validate': veeValidate,
|
|
20
|
+
unhead,
|
|
21
|
+
ofetch,
|
|
22
|
+
i18n,
|
|
23
|
+
lint,
|
|
24
|
+
auth,
|
|
25
|
+
}
|
package/addons/lint.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
|
|
6
|
+
export default function installLint(cwd) {
|
|
7
|
+
console.log(chalk.blue.bold('\n🚀 Installing ESLint + Prettier...'))
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
execSync('npm install -D eslint eslint-plugin-vue @vue/eslint-config-prettier prettier', { stdio: 'inherit', cwd })
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.error(chalk.red.bold('\n❌ Failed to install lint packages:'))
|
|
13
|
+
console.error(chalk.red(err.message))
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const eslintConfigPath = path.join(cwd, 'eslint.config.js')
|
|
18
|
+
if (!fs.existsSync(eslintConfigPath)) {
|
|
19
|
+
fs.writeFileSync(eslintConfigPath, `import pluginVue from 'eslint-plugin-vue'
|
|
20
|
+
import prettierConfig from '@vue/eslint-config-prettier'
|
|
21
|
+
|
|
22
|
+
export default [
|
|
23
|
+
...pluginVue.configs['flat/recommended'],
|
|
24
|
+
prettierConfig,
|
|
25
|
+
]
|
|
26
|
+
`)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const prettierConfigPath = path.join(cwd, '.prettierrc.json')
|
|
30
|
+
if (!fs.existsSync(prettierConfigPath)) {
|
|
31
|
+
fs.writeFileSync(prettierConfigPath, JSON.stringify({ semi: false, singleQuote: true, printWidth: 100 }, null, 2))
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(chalk.green.bold('\n✅ ESLint + Prettier installed successfully!'))
|
|
35
|
+
console.log(chalk.white('💡 Run:'))
|
|
36
|
+
console.log(chalk.cyan(' npx eslint . --fix'))
|
|
37
|
+
console.log(chalk.cyan(' npx prettier --write .'))
|
|
38
|
+
}
|
package/addons/lucide.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export default function installLucide(cwd) {
|
|
5
|
+
console.log(chalk.blue.bold('\n🚀 Installing Lucide Icons...'))
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
execSync('npm install @lucide/vue', { stdio: 'inherit', cwd })
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.error(chalk.red.bold('\n❌ Failed to install Lucide Icons:'))
|
|
11
|
+
console.error(chalk.red(err.message))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.green.bold('\n✅ Lucide Icons installed successfully!'))
|
|
16
|
+
console.log(chalk.white('💡 Usage in a .vue file:'))
|
|
17
|
+
console.log(chalk.cyan(' import { Home, User, Settings } from "@lucide/vue"'))
|
|
18
|
+
console.log(chalk.cyan(' <Home class="text-blue-500 w-6 h-6" />'))
|
|
19
|
+
}
|
package/addons/ofetch.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export default function installOfetch(cwd) {
|
|
5
|
+
console.log(chalk.blue.bold('\n🚀 Installing ofetch...'))
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
execSync('npm install ofetch', { stdio: 'inherit', cwd })
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.error(chalk.red.bold('\n❌ Failed to install ofetch:'))
|
|
11
|
+
console.error(chalk.red(err.message))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.green.bold('\n✅ ofetch installed successfully!'))
|
|
16
|
+
console.log(chalk.white('💡 Usage:'))
|
|
17
|
+
console.log(chalk.cyan(' import { ofetch } from "ofetch"'))
|
|
18
|
+
console.log(chalk.cyan(' const data = await ofetch("/api/hello")'))
|
|
19
|
+
}
|
package/addons/tabler.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export default function installTabler(cwd) {
|
|
5
|
+
console.log(chalk.blue.bold('\n🚀 Installing Tabler Icons...'))
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
execSync('npm install @tabler/icons-vue', { stdio: 'inherit', cwd })
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.error(chalk.red.bold('\n❌ Failed to install Tabler Icons:'))
|
|
11
|
+
console.error(chalk.red(err.message))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.green.bold('\n✅ Tabler Icons installed successfully!'))
|
|
16
|
+
console.log(chalk.white('💡 Usage in a .vue file:'))
|
|
17
|
+
console.log(chalk.cyan(' import { IconHome, IconUser } from "@tabler/icons-vue"'))
|
|
18
|
+
console.log(chalk.cyan(' <IconHome stroke="2" />'))
|
|
19
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
|
|
6
|
+
export default function installTailwind(cwd) {
|
|
7
|
+
console.log(chalk.blue.bold('\n🚀 Installing Tailwind CSS (v4) in the Solid-Vue project...'))
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
execSync('npm install -D tailwindcss @tailwindcss/postcss postcss', { stdio: 'inherit', cwd })
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.error(chalk.red.bold('\n❌ Failed to install Tailwind CSS packages:'))
|
|
13
|
+
console.error(chalk.red(err.message))
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const postcssConfigPath = path.join(cwd, 'postcss.config.js')
|
|
18
|
+
fs.writeFileSync(postcssConfigPath, `export default {
|
|
19
|
+
plugins: {
|
|
20
|
+
'@tailwindcss/postcss': {},
|
|
21
|
+
},
|
|
22
|
+
}
|
|
23
|
+
`)
|
|
24
|
+
|
|
25
|
+
const cssDir = path.join(cwd, 'src', 'styles')
|
|
26
|
+
const cssFile = path.join(cssDir, 'global.css')
|
|
27
|
+
const tailwindImport = `@import "tailwindcss";\n\n`
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(cssDir)) fs.mkdirSync(cssDir, { recursive: true })
|
|
30
|
+
|
|
31
|
+
if (fs.existsSync(cssFile)) {
|
|
32
|
+
const currentCss = fs.readFileSync(cssFile, 'utf-8')
|
|
33
|
+
if (!currentCss.includes('@import "tailwindcss"')) {
|
|
34
|
+
fs.writeFileSync(cssFile, tailwindImport + currentCss)
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
fs.writeFileSync(cssFile, tailwindImport)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
console.log(chalk.green.bold('\n✅ Tailwind CSS v4 has been installed successfully! Let\'s get started! ☕'))
|
|
41
|
+
}
|
package/addons/unhead.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export default function installUnhead(cwd) {
|
|
5
|
+
console.log(chalk.blue.bold('\n🚀 Installing @unhead/vue...'))
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
execSync('npm install @unhead/vue', { stdio: 'inherit', cwd })
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.error(chalk.red.bold('\n❌ Failed to install @unhead/vue:'))
|
|
11
|
+
console.error(chalk.red(err.message))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.green.bold('\n✅ @unhead/vue installed successfully!'))
|
|
16
|
+
console.log(chalk.white('💡 Setup di main entry:'))
|
|
17
|
+
console.log(chalk.cyan(' import { createHead } from "@unhead/vue/client"'))
|
|
18
|
+
console.log(chalk.cyan(' app.use(createHead())'))
|
|
19
|
+
console.log(chalk.white('💡 Usage di .vue file:'))
|
|
20
|
+
console.log(chalk.cyan(' import { useHead } from "@unhead/vue"'))
|
|
21
|
+
console.log(chalk.cyan(' useHead({ title: "Judul Halaman" })'))
|
|
22
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export default function installVeeValidate(cwd) {
|
|
5
|
+
console.log(chalk.blue.bold('\n🚀 Installing VeeValidate + Zod...'))
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
execSync('npm install vee-validate zod @vee-validate/zod', { stdio: 'inherit', cwd })
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.error(chalk.red.bold('\n❌ Failed to install validation packages:'))
|
|
11
|
+
console.error(chalk.red(err.message))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.green.bold('\n✅ VeeValidate + Zod installed successfully!'))
|
|
16
|
+
console.log(chalk.white('💡 Usage in a .vue file:'))
|
|
17
|
+
console.log(chalk.cyan(' import { useForm } from "vee-validate"'))
|
|
18
|
+
console.log(chalk.cyan(' import { toTypedSchema } from "@vee-validate/zod"'))
|
|
19
|
+
console.log(chalk.cyan(' import { z } from "zod"'))
|
|
20
|
+
}
|
package/addons/vitest.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import { execSync } from 'node:child_process'
|
|
4
|
+
import chalk from 'chalk'
|
|
5
|
+
|
|
6
|
+
export default function installVitest(cwd) {
|
|
7
|
+
console.log(chalk.blue.bold('\n🚀 Installing Vitest...'))
|
|
8
|
+
|
|
9
|
+
try {
|
|
10
|
+
execSync('npm install -D vitest @vue/test-utils jsdom', { stdio: 'inherit', cwd })
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.error(chalk.red.bold('\n❌ Failed to install Vitest:'))
|
|
13
|
+
console.error(chalk.red(err.message))
|
|
14
|
+
return
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const isTs = fs.existsSync(path.join(cwd, 'tsconfig.json'))
|
|
18
|
+
const ext = isTs ? 'ts' : 'js'
|
|
19
|
+
|
|
20
|
+
const vitestConfigPath = path.join(cwd, `vitest.config.${ext}`)
|
|
21
|
+
if (!fs.existsSync(vitestConfigPath)) {
|
|
22
|
+
fs.writeFileSync(vitestConfigPath, `import { defineConfig } from 'vitest/config'
|
|
23
|
+
import vue from '@vitejs/plugin-vue'
|
|
24
|
+
|
|
25
|
+
export default defineConfig({
|
|
26
|
+
plugins: [vue()],
|
|
27
|
+
test: {
|
|
28
|
+
environment: 'jsdom',
|
|
29
|
+
globals: true,
|
|
30
|
+
},
|
|
31
|
+
})
|
|
32
|
+
`)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const testDir = path.join(cwd, 'src', '__tests__')
|
|
36
|
+
if (!fs.existsSync(testDir)) {
|
|
37
|
+
fs.mkdirSync(testDir, { recursive: true })
|
|
38
|
+
fs.writeFileSync(path.join(testDir, `example.test.${ext}`), `import { describe, it, expect } from 'vitest'
|
|
39
|
+
|
|
40
|
+
describe('example', () => {
|
|
41
|
+
it('works', () => {
|
|
42
|
+
expect(1 + 1).toBe(2)
|
|
43
|
+
})
|
|
44
|
+
})
|
|
45
|
+
`)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
console.log(chalk.green.bold('\n✅ Vitest installed successfully!'))
|
|
49
|
+
console.log(chalk.white('💡 Run:'))
|
|
50
|
+
console.log(chalk.cyan(' npx vitest'))
|
|
51
|
+
}
|
package/addons/vueuse.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { execSync } from 'node:child_process'
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
|
|
4
|
+
export default function installVueUse(cwd) {
|
|
5
|
+
console.log(chalk.blue.bold('\n🚀 Installing VueUse...'))
|
|
6
|
+
|
|
7
|
+
try {
|
|
8
|
+
execSync('npm install @vueuse/core', { stdio: 'inherit', cwd })
|
|
9
|
+
} catch (err) {
|
|
10
|
+
console.error(chalk.red.bold('\n❌ Failed to install VueUse:'))
|
|
11
|
+
console.error(chalk.red(err.message))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log(chalk.green.bold('\n✅ VueUse installed successfully!'))
|
|
16
|
+
console.log(chalk.white('💡 Usage in a .vue file:'))
|
|
17
|
+
console.log(chalk.cyan(' import { useLocalStorage, useDebounce } from "@vueuse/core"'))
|
|
18
|
+
}
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import chalk from 'chalk'
|
|
3
|
+
import { addons } from '../addons/index.js'
|
|
4
|
+
|
|
5
|
+
function addAddon(addonName) {
|
|
6
|
+
const handler = addons[addonName]
|
|
7
|
+
|
|
8
|
+
if (!handler) {
|
|
9
|
+
console.log(chalk.red(`\n❌ Add-on '${addonName}' is not supported yet by Solid-Vue.`))
|
|
10
|
+
console.log(chalk.gray(` Available add-ons: ${Object.keys(addons).join(', ')}`))
|
|
11
|
+
process.exit(1)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
handler(process.cwd())
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const args = process.argv.slice(2)
|
|
18
|
+
const command = args[0]
|
|
19
|
+
|
|
20
|
+
if (command === 'add') {
|
|
21
|
+
const addonName = args[1]
|
|
22
|
+
if (!addonName) {
|
|
23
|
+
console.log(chalk.yellow('\n⚠️ Please specify the addon name. Example: npx solid-vue add tailwind'))
|
|
24
|
+
process.exit(1)
|
|
25
|
+
}
|
|
26
|
+
addAddon(addonName)
|
|
27
|
+
} else {
|
|
28
|
+
console.log(chalk.red(`\n❌ Command '${command}' is not recognized. Supported commands are: 'add <addon-name>'.`))
|
|
29
|
+
process.exit(1)
|
|
30
|
+
}
|