@lyda/kilo-ui 0.1.0 → 0.1.4
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/README.md +9 -11
- package/bin/kilo-ui.mjs +221 -17
- package/bin/postinstall.mjs +47 -0
- package/config/define-config.d.ts +26 -0
- package/config/define-config.mjs +4 -0
- package/config/kilo.config.example.ts +29 -0
- package/package.json +13 -2
- package/registry/vue/env.d.ts +7 -0
package/README.md
CHANGED
|
@@ -8,30 +8,28 @@ This package does **not** work like a normal UI runtime dependency. It works lik
|
|
|
8
8
|
|
|
9
9
|
From any Vue project:
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
npm install -D "C:\UI Library"
|
|
13
|
-
npx kilo-ui init
|
|
14
|
-
npx kilo-ui add data-table app-navbar activity-log
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
After you **publish** this project to npm, install the **exact** `name` from its `package.json` (for example `@ui-library/kilo-ui`).
|
|
11
|
+
After you **publish** this project to npm, install the **exact** `name` from its `package.json` (for example `@lyda/kilo-ui`).
|
|
18
12
|
**Do not** run `npm install -D kilo-ui` expecting this Vue CLI — the public npm name `kilo-ui` is already used by a different project.
|
|
19
13
|
|
|
20
14
|
```bash
|
|
21
|
-
npm install -D @
|
|
22
|
-
npx kilo-ui init
|
|
15
|
+
npm install -D @lyda/kilo-ui
|
|
23
16
|
npx kilo-ui add data-table
|
|
24
17
|
```
|
|
25
18
|
|
|
19
|
+
**First install in a new project:** the package **postinstall** runs `kilo-ui init` once (unless `kilo.config.ts` already exists). That creates **`kilo.config.ts` in your app root** (next to `package.json`) — not inside `node_modules`. Edit it for **aliases**, **`ui.componentsDir`** (folder prefix under `src/components`, default `ui`), and **Tailwind CSS path**. An annotated example ships with the library at **`node_modules/@lyda/kilo-ui/config/kilo.config.example.ts`**. If install used **`--ignore-scripts`**, run **`npx kilo-ui init`** once yourself.
|
|
20
|
+
|
|
21
|
+
You can still run **`npx kilo-ui init`** anytime to add missing scaffold files; use **`init --force`** to reset **`kilo.config.ts`** to defaults (back up first if you customized it).
|
|
22
|
+
|
|
26
23
|
**Note:** The public npm name `kilo-ui` may point to a different project (not this Vue CLI). If `npm install -D kilo-ui` pulls SvelteKit or other wrong peers, use a scoped name or install from `file:` / Git. See [Installation](docs/docs/installation.md) in the docs site.
|
|
27
24
|
|
|
28
25
|
## What `init` Creates
|
|
29
26
|
|
|
30
27
|
`npx kilo-ui init` creates:
|
|
31
28
|
|
|
32
|
-
-
|
|
29
|
+
- **`kilo.config.ts`** - TypeScript project config (`defineConfig` from `@lyda/kilo-ui/config`), aliases, and **`ui.componentsDir`** (subfolder for installed components, default `ui`)
|
|
33
30
|
- `src/styles/teamwork-ui.css` - Tailwind v4 import + Kilo UI theme tokens
|
|
34
31
|
- `src/lib/utils.ts` - shared helper utilities
|
|
32
|
+
- `env.d.ts` (project root) - Vue + Vite TypeScript declarations for `*.vue` modules (skip if the file already exists); `init` also updates `tsconfig.app.json` / `tsconfig.json` with `paths` for `@/*` when possible
|
|
35
33
|
|
|
36
34
|
Add the stylesheet once in your app entry, usually `src/main.ts`:
|
|
37
35
|
|
|
@@ -159,7 +157,7 @@ Editing a component? Update the file in `registry/`. The CLI and docs both pick
|
|
|
159
157
|
5. Consumers install with:
|
|
160
158
|
|
|
161
159
|
```bash
|
|
162
|
-
npm install -D @
|
|
160
|
+
npm install -D @lyda/kilo-ui
|
|
163
161
|
npx kilo-ui init
|
|
164
162
|
npx kilo-ui add data-table
|
|
165
163
|
```
|
package/bin/kilo-ui.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createJiti } from 'jiti'
|
|
2
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
|
|
3
4
|
import { dirname, join, relative, resolve } from 'node:path'
|
|
4
5
|
import { fileURLToPath } from 'node:url'
|
|
@@ -6,15 +7,24 @@ import { fileURLToPath } from 'node:url'
|
|
|
6
7
|
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
7
8
|
const packageRoot = resolve(__dirname, '..')
|
|
8
9
|
const registryRoot = join(packageRoot, 'registry')
|
|
10
|
+
const cliEntry = fileURLToPath(import.meta.url)
|
|
9
11
|
|
|
10
12
|
const pkg = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'))
|
|
11
13
|
const cliName = typeof pkg.name === 'string' ? pkg.name : 'kilo-ui'
|
|
14
|
+
const pkgName = cliName
|
|
12
15
|
|
|
13
16
|
const commands = new Set(['init', 'add', 'list', 'help'])
|
|
14
17
|
const [, , maybeCommand, ...args] = process.argv
|
|
15
18
|
const command = commands.has(maybeCommand) ? maybeCommand : 'help'
|
|
16
19
|
|
|
17
|
-
const
|
|
20
|
+
const KILO_TS = 'kilo.config.ts'
|
|
21
|
+
const KILO_MTS = 'kilo.config.mts'
|
|
22
|
+
const KILO_JS = 'kilo.config.js'
|
|
23
|
+
const KILO_MJS = 'kilo.config.mjs'
|
|
24
|
+
const CONFIG_MODULES = [KILO_TS, KILO_MTS, KILO_JS, KILO_MJS]
|
|
25
|
+
|
|
26
|
+
const UI_JSON = 'ui.json'
|
|
27
|
+
const LEGACY_JSON = 'components.json'
|
|
18
28
|
|
|
19
29
|
function log(message = '') {
|
|
20
30
|
console.log(message)
|
|
@@ -26,7 +36,8 @@ function fail(message) {
|
|
|
26
36
|
}
|
|
27
37
|
|
|
28
38
|
function readJson(path) {
|
|
29
|
-
|
|
39
|
+
const raw = readFileSync(path, 'utf8').replace(/^\uFEFF/, '')
|
|
40
|
+
return JSON.parse(raw)
|
|
30
41
|
}
|
|
31
42
|
|
|
32
43
|
function writeJson(path, value) {
|
|
@@ -51,17 +62,82 @@ function registry() {
|
|
|
51
62
|
return readJson(join(registryRoot, 'index.json'))
|
|
52
63
|
}
|
|
53
64
|
|
|
65
|
+
const defaultAliases = {
|
|
66
|
+
components: '@/components',
|
|
67
|
+
composables: '@/composables',
|
|
68
|
+
lib: '@/lib',
|
|
69
|
+
types: '@/types',
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function normalizeConfig(raw) {
|
|
73
|
+
const c = typeof raw === 'object' && raw !== null ? { ...raw } : {}
|
|
74
|
+
c.srcDir = c.srcDir || 'src'
|
|
75
|
+
c.aliases = { ...defaultAliases, ...(c.aliases || {}) }
|
|
76
|
+
c.tailwind = c.tailwind || { css: `${c.srcDir}/styles/teamwork-ui.css` }
|
|
77
|
+
const uiRaw =
|
|
78
|
+
typeof c.ui === 'object' && c.ui !== null ? { ...c.ui } : {}
|
|
79
|
+
const componentsPrefix = uiRaw.componentsPrefix
|
|
80
|
+
delete uiRaw.componentsPrefix
|
|
81
|
+
c.ui = { componentsDir: 'ui', ...uiRaw }
|
|
82
|
+
if (
|
|
83
|
+
(c.ui.componentsDir === undefined || c.ui.componentsDir === null) &&
|
|
84
|
+
componentsPrefix !== undefined &&
|
|
85
|
+
componentsPrefix !== null
|
|
86
|
+
) {
|
|
87
|
+
c.ui.componentsDir = componentsPrefix
|
|
88
|
+
}
|
|
89
|
+
if (c.ui.componentsDir === undefined || c.ui.componentsDir === null) {
|
|
90
|
+
c.ui.componentsDir = 'ui'
|
|
91
|
+
}
|
|
92
|
+
return c
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function hasKiloModuleConfig(cwd) {
|
|
96
|
+
return CONFIG_MODULES.some((name) => existsSync(join(cwd, name)))
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function loadProjectConfigFromDisk(cwd) {
|
|
100
|
+
const jiti = createJiti(cliEntry, { interopDefault: true, cwd })
|
|
101
|
+
|
|
102
|
+
for (const name of CONFIG_MODULES) {
|
|
103
|
+
const p = join(cwd, name)
|
|
104
|
+
if (!existsSync(p)) continue
|
|
105
|
+
try {
|
|
106
|
+
const mod = jiti(p)
|
|
107
|
+
const raw = mod?.default ?? mod
|
|
108
|
+
if (!raw || typeof raw !== 'object') {
|
|
109
|
+
fail(`${name} must default-export a config object.`)
|
|
110
|
+
}
|
|
111
|
+
return normalizeConfig(raw)
|
|
112
|
+
} catch (e) {
|
|
113
|
+
const msg = e instanceof Error ? e.message : String(e)
|
|
114
|
+
fail(`Failed to load ${name}: ${msg}`)
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const uiPath = join(cwd, UI_JSON)
|
|
119
|
+
if (existsSync(uiPath)) return normalizeConfig(readJson(uiPath))
|
|
120
|
+
|
|
121
|
+
const legacyPath = join(cwd, LEGACY_JSON)
|
|
122
|
+
if (existsSync(legacyPath)) return normalizeConfig(readJson(legacyPath))
|
|
123
|
+
|
|
124
|
+
return null
|
|
125
|
+
}
|
|
126
|
+
|
|
54
127
|
function projectConfig() {
|
|
55
|
-
const
|
|
56
|
-
|
|
57
|
-
|
|
128
|
+
const cwd = process.cwd()
|
|
129
|
+
const config = loadProjectConfigFromDisk(cwd)
|
|
130
|
+
if (!config) {
|
|
131
|
+
fail(
|
|
132
|
+
`Missing kilo.config.ts (or kilo.config.mjs, ${UI_JSON}, ${LEGACY_JSON}). Run "npx ${cliName} init" first.`,
|
|
133
|
+
)
|
|
58
134
|
}
|
|
59
|
-
return
|
|
135
|
+
return config
|
|
60
136
|
}
|
|
61
137
|
|
|
62
138
|
function aliasPath(config, key) {
|
|
63
139
|
const value = config.aliases?.[key]
|
|
64
|
-
if (!value) fail(`Missing aliases.${key} in ${
|
|
140
|
+
if (!value) fail(`Missing aliases.${key} in kilo.config / ${UI_JSON} / ${LEGACY_JSON}`)
|
|
65
141
|
return value.replace(/^@\//, config.srcDir ? `${config.srcDir}/` : 'src/')
|
|
66
142
|
}
|
|
67
143
|
|
|
@@ -69,8 +145,22 @@ function resolveTarget(config, alias, fileName) {
|
|
|
69
145
|
return join(process.cwd(), aliasPath(config, alias), fileName)
|
|
70
146
|
}
|
|
71
147
|
|
|
148
|
+
/** Path segments under the components alias (e.g. ["ui"] → …/components/ui/…). Empty string = no extra folder. */
|
|
149
|
+
function componentDirSegments(config) {
|
|
150
|
+
const dir = config.ui?.componentsDir
|
|
151
|
+
if (dir === '') return []
|
|
152
|
+
if (dir === undefined) return ['ui']
|
|
153
|
+
return String(dir).replace(/\\/g, '/').split('/').filter(Boolean)
|
|
154
|
+
}
|
|
155
|
+
|
|
72
156
|
function componentFilePath(config, componentName, fileName) {
|
|
73
|
-
return join(
|
|
157
|
+
return join(
|
|
158
|
+
process.cwd(),
|
|
159
|
+
aliasPath(config, 'components'),
|
|
160
|
+
...componentDirSegments(config),
|
|
161
|
+
componentName,
|
|
162
|
+
fileName,
|
|
163
|
+
)
|
|
74
164
|
}
|
|
75
165
|
|
|
76
166
|
function copyRegistryFile(sourceRelative, targetPath, config, force) {
|
|
@@ -84,13 +174,105 @@ function copyRegistryFile(sourceRelative, targetPath, config, force) {
|
|
|
84
174
|
writeFile(targetPath, content, force)
|
|
85
175
|
}
|
|
86
176
|
|
|
177
|
+
/**
|
|
178
|
+
* Vite resolves `@` from vite.config; TypeScript needs matching paths or `@/…` imports fail in the editor / vue-tsc.
|
|
179
|
+
* Vue templates usually keep env.d.ts at the project root next to tsconfig.app.json (not under src/).
|
|
180
|
+
*/
|
|
181
|
+
function kiloConfigSerializable(config) {
|
|
182
|
+
const n = normalizeConfig(config)
|
|
183
|
+
return {
|
|
184
|
+
style: n.style ?? 'default',
|
|
185
|
+
srcDir: n.srcDir,
|
|
186
|
+
ui: n.ui,
|
|
187
|
+
tailwind: n.tailwind,
|
|
188
|
+
aliases: n.aliases,
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function buildKiloConfigFileContent(config) {
|
|
193
|
+
const obj = kiloConfigSerializable(config)
|
|
194
|
+
const body = JSON.stringify(obj, null, 2)
|
|
195
|
+
const header = `// Kilo UI — app config (generated in your project root by ${pkgName}, not inside the library package)\n// ui.componentsDir = folder prefix under aliases.components (default "ui" → …/components/ui/<component>/)\n// Use "" for no prefix: …/components/<component>/\n\n`
|
|
196
|
+
return `${header}import { defineConfig } from '${pkgName}/config'\n\nexport default defineConfig(${body})\n`
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Create kilo.config.ts when missing, or overwrite when force (unless a non-.ts kilo module is the only config). */
|
|
200
|
+
function writeKiloConfigTs(cwd, config, force) {
|
|
201
|
+
const kiloPath = join(cwd, KILO_TS)
|
|
202
|
+
if (hasKiloModuleConfig(cwd) && !force) return
|
|
203
|
+
if (!force && existsSync(kiloPath)) return
|
|
204
|
+
|
|
205
|
+
const rel = relative(cwd, kiloPath)
|
|
206
|
+
const existed = existsSync(kiloPath)
|
|
207
|
+
ensureDir(dirname(kiloPath))
|
|
208
|
+
writeFileSync(kiloPath, buildKiloConfigFileContent(config), 'utf8')
|
|
209
|
+
log(`${force || existed ? 'write' : 'add'} ${rel}`)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
function mergeTsconfigForAliases(cwd, srcDir = 'src') {
|
|
213
|
+
const srcNorm = String(srcDir || 'src').replace(/\\/g, '/').replace(/\/$/, '') || 'src'
|
|
214
|
+
const pathPattern = `./${srcNorm}/*`
|
|
215
|
+
const appPath = join(cwd, 'tsconfig.app.json')
|
|
216
|
+
const rootPath = join(cwd, 'tsconfig.json')
|
|
217
|
+
|
|
218
|
+
function tryMerge(filePath) {
|
|
219
|
+
if (!existsSync(filePath)) return false
|
|
220
|
+
let parsed
|
|
221
|
+
try {
|
|
222
|
+
parsed = readJson(filePath)
|
|
223
|
+
} catch {
|
|
224
|
+
log(`skip ${relative(cwd, filePath)} (invalid JSON — fix or add paths manually)`)
|
|
225
|
+
return false
|
|
226
|
+
}
|
|
227
|
+
const relName = relative(cwd, filePath)
|
|
228
|
+
if (relName === 'tsconfig.json' && parsed.references?.length && !parsed.compilerOptions) {
|
|
229
|
+
return false
|
|
230
|
+
}
|
|
231
|
+
parsed.compilerOptions = parsed.compilerOptions || {}
|
|
232
|
+
const co = parsed.compilerOptions
|
|
233
|
+
const paths = { ...(co.paths || {}) }
|
|
234
|
+
const key = '@/*'
|
|
235
|
+
if (paths[key]?.[0] === pathPattern) {
|
|
236
|
+
log(`skip ${relName} (paths "@/*" already set)`)
|
|
237
|
+
return true
|
|
238
|
+
}
|
|
239
|
+
if (paths[key]?.length) {
|
|
240
|
+
log(
|
|
241
|
+
`skip ${relName} (paths "@/*" already defined — ensure it points at your ${srcNorm}/ folder for kilo-ui imports)`,
|
|
242
|
+
)
|
|
243
|
+
return true
|
|
244
|
+
}
|
|
245
|
+
paths[key] = [pathPattern]
|
|
246
|
+
co.paths = paths
|
|
247
|
+
if (co.baseUrl === undefined) co.baseUrl = '.'
|
|
248
|
+
|
|
249
|
+
if (Array.isArray(parsed.include)) {
|
|
250
|
+
const hasEnv = parsed.include.some((entry) => String(entry).includes('env.d.ts'))
|
|
251
|
+
if (!hasEnv) parsed.include.unshift('env.d.ts')
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
writeJson(filePath, parsed)
|
|
255
|
+
log(`update ${relName} (TypeScript paths for @ + env.d.ts in include)`)
|
|
256
|
+
return true
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
if (tryMerge(appPath)) return
|
|
260
|
+
if (tryMerge(rootPath)) return
|
|
261
|
+
|
|
262
|
+
log('\nTip: Add TypeScript paths so editors resolve @ imports (same folder as vite alias):')
|
|
263
|
+
log(` "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["${pathPattern}"] } }`)
|
|
264
|
+
}
|
|
265
|
+
|
|
87
266
|
function init(args) {
|
|
88
267
|
const force = args.includes('--force')
|
|
89
|
-
const
|
|
90
|
-
const
|
|
91
|
-
|
|
268
|
+
const cwd = process.cwd()
|
|
269
|
+
const uiPath = join(cwd, UI_JSON)
|
|
270
|
+
const legacyPath = join(cwd, LEGACY_JSON)
|
|
271
|
+
|
|
272
|
+
const defaultConfig = normalizeConfig({
|
|
92
273
|
style: 'default',
|
|
93
274
|
srcDir: 'src',
|
|
275
|
+
ui: { componentsDir: 'ui' },
|
|
94
276
|
tailwind: {
|
|
95
277
|
css: 'src/styles/teamwork-ui.css',
|
|
96
278
|
},
|
|
@@ -100,23 +282,43 @@ function init(args) {
|
|
|
100
282
|
lib: '@/lib',
|
|
101
283
|
types: '@/types',
|
|
102
284
|
},
|
|
103
|
-
}
|
|
104
|
-
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
let config
|
|
105
288
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
289
|
+
if (!force) {
|
|
290
|
+
if (hasKiloModuleConfig(cwd)) {
|
|
291
|
+
config = loadProjectConfigFromDisk(cwd)
|
|
292
|
+
if (!config) fail('Could not read kilo config.')
|
|
293
|
+
log(`skip kilo.config.* (already exists)`)
|
|
294
|
+
} else if (existsSync(uiPath)) {
|
|
295
|
+
config = normalizeConfig(readJson(uiPath))
|
|
296
|
+
log(`using ${UI_JSON} (legacy). Prefer ${KILO_TS} — run init on a fresh branch or add the file from docs.`)
|
|
297
|
+
} else if (existsSync(legacyPath)) {
|
|
298
|
+
config = normalizeConfig(readJson(legacyPath))
|
|
299
|
+
log(`using ${LEGACY_JSON} (legacy fields). Adding ${KILO_TS} if missing.`)
|
|
300
|
+
} else {
|
|
301
|
+
config = defaultConfig
|
|
302
|
+
}
|
|
108
303
|
} else {
|
|
109
|
-
|
|
110
|
-
log(`write ${configFile}`)
|
|
304
|
+
config = defaultConfig
|
|
111
305
|
}
|
|
112
306
|
|
|
307
|
+
writeKiloConfigTs(cwd, config, force)
|
|
308
|
+
|
|
113
309
|
copyRegistryFile('styles/teamwork-ui.css', join(process.cwd(), config.tailwind.css), config, force)
|
|
114
310
|
copyRegistryFile('lib/utils.ts', resolveTarget(config, 'lib', 'utils.ts'), config, force)
|
|
311
|
+
copyRegistryFile('vue/env.d.ts', join(process.cwd(), 'env.d.ts'), config, force)
|
|
312
|
+
|
|
313
|
+
mergeTsconfigForAliases(process.cwd(), config.srcDir || 'src')
|
|
115
314
|
|
|
315
|
+
const sub = componentDirSegments(config).join('/') || '(components root)'
|
|
116
316
|
log('\nDone. Add this once in your app entry or main stylesheet:')
|
|
117
317
|
log(` import './styles/${config.tailwind.css.replace(/^.*\//, '')}'`)
|
|
318
|
+
log(`\nComponents install under: ${aliasPath(config, 'components').replace(/\\/g, '/')}/${sub}/<name>/`)
|
|
118
319
|
log('\nThen add components:')
|
|
119
320
|
log(` npx ${cliName} add data-table app-navbar activity-log`)
|
|
321
|
+
log(`\nEdit ${KILO_TS} to change where components install (aliases, ui.componentsDir).`)
|
|
120
322
|
}
|
|
121
323
|
|
|
122
324
|
function add(args) {
|
|
@@ -163,6 +365,8 @@ Usage:
|
|
|
163
365
|
npx ${cliName} add <component...> [--force]
|
|
164
366
|
npx ${cliName} list
|
|
165
367
|
|
|
368
|
+
Config: ${KILO_TS} (or ${KILO_MJS}, legacy ${UI_JSON} / ${LEGACY_JSON}). Use defineConfig from "${pkgName}/config". Set ui.componentsDir for the folder under your components alias (default "ui").
|
|
369
|
+
|
|
166
370
|
Examples:
|
|
167
371
|
npx ${cliName} init
|
|
168
372
|
npx ${cliName} add data-table app-navbar
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
|
+
import { basename, dirname, join, resolve } from 'node:path'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { spawnSync } from 'node:child_process'
|
|
6
|
+
|
|
7
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
const packageRoot = resolve(__dirname, '..')
|
|
9
|
+
|
|
10
|
+
const initCwd = resolveConsumerProjectRoot()
|
|
11
|
+
if (!initCwd) process.exit(0)
|
|
12
|
+
|
|
13
|
+
// Avoid running when installing this repo itself.
|
|
14
|
+
if (resolve(initCwd) === resolve(packageRoot)) process.exit(0)
|
|
15
|
+
|
|
16
|
+
// Only skip auto-init when a kilo config module already exists.
|
|
17
|
+
// Do not treat components.json / ui.json as "done" — shadcn and other tools use those too,
|
|
18
|
+
// and we still need to add kilo.config.ts.
|
|
19
|
+
const kiloModuleNames = ['kilo.config.ts', 'kilo.config.mts', 'kilo.config.js', 'kilo.config.mjs']
|
|
20
|
+
if (kiloModuleNames.some((name) => existsSync(join(initCwd, name)))) process.exit(0)
|
|
21
|
+
|
|
22
|
+
const cliEntry = join(packageRoot, 'bin', 'kilo-ui.mjs')
|
|
23
|
+
|
|
24
|
+
const result = spawnSync(process.execPath, [cliEntry, 'init'], {
|
|
25
|
+
cwd: initCwd,
|
|
26
|
+
stdio: 'inherit',
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
process.exit(result.status ?? 1)
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Prefer npm's INIT_CWD or npm_config_local_prefix. If missing, infer the app root only when
|
|
33
|
+
* this package lives under node_modules (never guess from a bare repo path).
|
|
34
|
+
*/
|
|
35
|
+
function resolveConsumerProjectRoot() {
|
|
36
|
+
const fromEnv = process.env.INIT_CWD || process.env.npm_config_local_prefix
|
|
37
|
+
if (fromEnv) return resolve(fromEnv)
|
|
38
|
+
|
|
39
|
+
const norm = packageRoot.replace(/\\/g, '/')
|
|
40
|
+
if (!norm.includes('/node_modules/')) return null
|
|
41
|
+
|
|
42
|
+
const parent = dirname(packageRoot)
|
|
43
|
+
if (basename(parent).startsWith('@')) {
|
|
44
|
+
return resolve(parent, '..', '..')
|
|
45
|
+
}
|
|
46
|
+
return resolve(parent, '..')
|
|
47
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface KiloUiUserConfig {
|
|
2
|
+
/** @deprecated informational only */
|
|
3
|
+
$schema?: string
|
|
4
|
+
style?: string
|
|
5
|
+
srcDir?: string
|
|
6
|
+
ui?: {
|
|
7
|
+
/**
|
|
8
|
+
* Folder prefix under `aliases.components` where `kilo-ui add` places each component
|
|
9
|
+
* (default `"ui"` → e.g. `src/components/ui/<name>/`). Use `""` for `…/components/<name>/`.
|
|
10
|
+
*/
|
|
11
|
+
componentsDir?: string
|
|
12
|
+
/** Same as `componentsDir` if you prefer the name “prefix”. */
|
|
13
|
+
componentsPrefix?: string
|
|
14
|
+
}
|
|
15
|
+
tailwind?: {
|
|
16
|
+
css: string
|
|
17
|
+
}
|
|
18
|
+
aliases: {
|
|
19
|
+
components: string
|
|
20
|
+
composables: string
|
|
21
|
+
lib: string
|
|
22
|
+
types: string
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function defineConfig(config: KiloUiUserConfig): KiloUiUserConfig
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Example config shipped with the npm package at:
|
|
3
|
+
* node_modules/@lyda/kilo-ui/config/kilo.config.example.ts
|
|
4
|
+
*
|
|
5
|
+
* Your Vue app does NOT edit this file. On `npm install`, the CLI creates
|
|
6
|
+
* **`kilo.config.ts` in your project root** (next to package.json).
|
|
7
|
+
*
|
|
8
|
+
* Change **`ui.componentsDir`** to set the folder prefix under your components path
|
|
9
|
+
* (e.g. `"ui"` → src/components/ui/data-table/…). Use `componentsPrefix` as an alias.
|
|
10
|
+
*/
|
|
11
|
+
import { defineConfig } from '@lyda/kilo-ui/config'
|
|
12
|
+
|
|
13
|
+
export default defineConfig({
|
|
14
|
+
style: 'default',
|
|
15
|
+
srcDir: 'src',
|
|
16
|
+
ui: {
|
|
17
|
+
/** Folder prefix under `aliases.components` for copied registry components */
|
|
18
|
+
componentsDir: 'ui',
|
|
19
|
+
},
|
|
20
|
+
tailwind: {
|
|
21
|
+
css: 'src/styles/teamwork-ui.css',
|
|
22
|
+
},
|
|
23
|
+
aliases: {
|
|
24
|
+
components: '@/components',
|
|
25
|
+
composables: '@/composables',
|
|
26
|
+
lib: '@/lib',
|
|
27
|
+
types: '@/types',
|
|
28
|
+
},
|
|
29
|
+
})
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lyda/kilo-ui",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "shadcn-style Vue component registry for team CRUD apps",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -17,12 +17,20 @@
|
|
|
17
17
|
"bin": {
|
|
18
18
|
"kilo-ui": "bin/kilo-ui.mjs"
|
|
19
19
|
},
|
|
20
|
+
"exports": {
|
|
21
|
+
"./config": {
|
|
22
|
+
"types": "./config/define-config.d.ts",
|
|
23
|
+
"default": "./config/define-config.mjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
20
26
|
"files": [
|
|
21
27
|
"bin",
|
|
28
|
+
"config",
|
|
22
29
|
"registry",
|
|
23
30
|
"README.md"
|
|
24
31
|
],
|
|
25
32
|
"scripts": {
|
|
33
|
+
"postinstall": "node bin/postinstall.mjs",
|
|
26
34
|
"docs:dev": "vitepress dev docs",
|
|
27
35
|
"docs:build": "vitepress build docs",
|
|
28
36
|
"docs:preview": "vitepress preview docs",
|
|
@@ -48,5 +56,8 @@
|
|
|
48
56
|
"crud",
|
|
49
57
|
"ui"
|
|
50
58
|
],
|
|
51
|
-
"license": "MIT"
|
|
59
|
+
"license": "MIT",
|
|
60
|
+
"dependencies": {
|
|
61
|
+
"jiti": "^2.7.0"
|
|
62
|
+
}
|
|
52
63
|
}
|