@rokkit/cli 1.0.0-next.164 → 1.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rokkit/cli",
3
- "version": "1.0.0-next.164",
3
+ "version": "1.0.1",
4
4
  "description": "Command line utilities for icon bundling and conversion.",
5
5
  "repository": {
6
6
  "type": "git",
package/src/index.js CHANGED
@@ -61,6 +61,14 @@ prog
61
61
  await init(opts)
62
62
  })
63
63
 
64
+ prog
65
+ .command('add')
66
+ .describe('Add Rokkit to an existing SvelteKit project (alias for init)')
67
+ .action(async (opts) => {
68
+ const { init } = await import('./init.js')
69
+ await init(opts)
70
+ })
71
+
64
72
  prog
65
73
  .command('doctor')
66
74
  .describe('Validate Rokkit project setup')
package/src/init.js CHANGED
@@ -2,6 +2,51 @@
2
2
  import prompts from 'prompts'
3
3
  import { writeFileSync, readFileSync, existsSync } from 'fs'
4
4
  import { resolve } from 'path'
5
+ import { execFileSync } from 'child_process'
6
+ import { detectPackageManager, buildInstallCommand } from './upgrade.js'
7
+
8
+ const ROKKIT_PACKAGES = ['@rokkit/ui', '@rokkit/unocss', '@rokkit/themes', '@rokkit/icons']
9
+ const LOCKFILES = ['bun.lock', 'bun.lockb', 'pnpm-lock.yaml', 'yarn.lock', 'package-lock.json']
10
+
11
+ /**
12
+ * Detect if the current directory is a SvelteKit project.
13
+ * @param {string} cwd
14
+ * @returns {boolean}
15
+ */
16
+ export function detectSvelteKit(cwd) {
17
+ return existsSync(resolve(cwd, 'svelte.config.js')) || existsSync(resolve(cwd, 'svelte.config.ts'))
18
+ }
19
+
20
+ /**
21
+ * Install Rokkit packages via the detected package manager.
22
+ * Skips packages already in package.json.
23
+ * @param {string} cwd
24
+ * @param {{ runInstall?: (bin: string, args: string[]) => void }} [adapters]
25
+ */
26
+ export function installPackages(cwd, adapters = {}) {
27
+ const pkgPath = resolve(cwd, 'package.json')
28
+ if (!existsSync(pkgPath)) {
29
+ console.warn(' No package.json found — skipping install')
30
+ return
31
+ }
32
+
33
+ const pkgJson = JSON.parse(readFileSync(pkgPath, 'utf-8'))
34
+ const allDeps = { ...(pkgJson.dependencies || {}), ...(pkgJson.devDependencies || {}) }
35
+ const missing = ROKKIT_PACKAGES.filter((p) => !allDeps[p])
36
+
37
+ if (missing.length === 0) {
38
+ console.info(' All Rokkit packages already installed')
39
+ return
40
+ }
41
+
42
+ const pm = detectPackageManager(LOCKFILES.filter((f) => existsSync(resolve(cwd, f))))
43
+ const { bin, args } = buildInstallCommand(pm, missing)
44
+ const runInstall = adapters.runInstall ?? ((b, a) => execFileSync(b, a, { stdio: 'inherit' }))
45
+
46
+ console.info(` Installing ${missing.join(', ')} via ${pm}...`)
47
+ runInstall(bin, args)
48
+ console.info(' Packages installed')
49
+ }
5
50
 
6
51
  const CHART_COLOR_SETS = {
7
52
  default: ['blue', 'emerald', 'rose', 'amber', 'violet', 'sky', 'pink', 'teal',
@@ -71,6 +116,7 @@ export function generateConfig({
71
116
  customColors,
72
117
  icons,
73
118
  iconPath,
119
+ iconStyle,
74
120
  themes,
75
121
  defaultTheme,
76
122
  switcher,
@@ -86,9 +132,10 @@ export function generateConfig({
86
132
  storageKey: 'rokkit-theme'
87
133
  }
88
134
 
89
- if (icons === 'custom' && iconPath) {
90
- config.icons = { custom: iconPath }
91
- }
135
+ const iconConfig = {}
136
+ if (iconStyle) iconConfig.style = iconStyle
137
+ if (icons === 'custom' && iconPath) iconConfig.custom = iconPath
138
+ if (Object.keys(iconConfig).length > 0) config.icons = iconConfig
92
139
 
93
140
  if (includeChart) {
94
141
  config.chart = generateChartConfig({ chartColors, chartShades })
@@ -185,6 +232,17 @@ const PROMPTS_CONFIG = [
185
232
  message: 'Surface color',
186
233
  initial: 'slate'
187
234
  },
235
+ {
236
+ type: 'select',
237
+ name: 'iconStyle',
238
+ message: 'Icon style',
239
+ choices: [
240
+ { title: 'Default (duotone)', value: undefined },
241
+ { title: 'Solid', value: 'solid' },
242
+ { title: 'Outline', value: 'outline' },
243
+ { title: 'Duotone outline', value: 'duotone-outline' }
244
+ ]
245
+ },
188
246
  {
189
247
  type: 'select',
190
248
  name: 'icons',
@@ -335,10 +393,29 @@ function writeAppHtml(cwd, initScript, storageKey) {
335
393
 
336
394
  /**
337
395
  * Interactive init command — prompts the user, writes config files.
396
+ * @param {Record<string, unknown>} [_opts]
397
+ * @param {{ runInstall?: (bin: string, args: string[]) => void }} [adapters] — injectable for testing
338
398
  */
339
- export async function init() {
399
+ export async function init(_opts = {}, adapters = {}) {
400
+ const cwd = process.cwd()
401
+
402
+ // Detect SvelteKit project
403
+ if (!detectSvelteKit(cwd)) {
404
+ console.warn('No svelte.config.js found — this may not be a SvelteKit project.')
405
+ const { proceed } = await prompts({
406
+ type: 'confirm',
407
+ name: 'proceed',
408
+ message: 'Continue anyway?',
409
+ initial: false
410
+ })
411
+ if (!proceed) return
412
+ }
413
+
340
414
  console.info('Rokkit Init — Setting up your SvelteKit project\n')
341
415
 
416
+ // Install packages
417
+ installPackages(cwd, adapters)
418
+
342
419
  const response = await prompts(PROMPTS_CONFIG)
343
420
 
344
421
  if (response.palette === 'custom') {
@@ -351,7 +428,6 @@ export async function init() {
351
428
  }
352
429
 
353
430
  const config = generateConfig(response)
354
- const cwd = process.cwd()
355
431
 
356
432
  writeRokkitConfig(cwd, config)
357
433
  writeUnoConfig(cwd)