@multicomma/arkcn 0.1.0 → 0.1.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/cli/commands.mjs +11 -4
- package/cli/project.mjs +62 -16
- package/package.json +1 -1
- package/registry/index.json +1 -1
package/cli/commands.mjs
CHANGED
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
CONFIG_FILE,
|
|
5
5
|
defaultConfig,
|
|
6
6
|
detectBundlerAlias,
|
|
7
|
+
ensureViteConfig,
|
|
7
8
|
detectPackageManager,
|
|
8
9
|
ensureTsconfigAlias,
|
|
9
10
|
installDependencies,
|
|
@@ -96,10 +97,15 @@ export async function init(cwd, registry, flags) {
|
|
|
96
97
|
else if (alias === "ok") ok(`tsconfig already maps "${config.alias}/*"`)
|
|
97
98
|
else warn(`Add "paths": { "${config.alias}/*": ["./${config.srcDir}/*"] } to your tsconfig compilerOptions.`)
|
|
98
99
|
const bundler = detectBundlerAlias(cwd, config.alias)
|
|
99
|
-
if (bundler.framework === "vite"
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
)
|
|
100
|
+
if (bundler.framework === "vite") {
|
|
101
|
+
const vite = ensureViteConfig(cwd, config.alias, config.srcDir)
|
|
102
|
+
if (vite.added.length) ok(`Added ${vite.added.join(" and ")} to ${vite.file}`)
|
|
103
|
+
else if (vite.manual)
|
|
104
|
+
warn(
|
|
105
|
+
`Add to ${vite.file}: the @tailwindcss/vite plugin and resolve.alias { "${config.alias}": "./${config.srcDir}" }`
|
|
106
|
+
)
|
|
107
|
+
else ok(`${vite.file} already has the alias and the Tailwind plugin`)
|
|
108
|
+
}
|
|
103
109
|
|
|
104
110
|
const { items } = await registry.closure(["utils"])
|
|
105
111
|
for (const item of items) writeItem(cwd, config, item, { overwrite: false })
|
|
@@ -118,6 +124,7 @@ export async function init(cwd, registry, flags) {
|
|
|
118
124
|
const deps = Object.entries(index.baseDependencies)
|
|
119
125
|
.filter(([dep]) => !installedVersion(cwd, dep))
|
|
120
126
|
.map(([dep, version]) => `${dep}@${version}`)
|
|
127
|
+
if (bundler.framework === "vite" && !installedVersion(cwd, "@tailwindcss/vite")) deps.push("@tailwindcss/vite")
|
|
121
128
|
await install(cwd, deps, flags)
|
|
122
129
|
log(`\nNext: ${c.cyan("npx @multicomma/arkcn add button card dialog")}`)
|
|
123
130
|
}
|
package/cli/project.mjs
CHANGED
|
@@ -120,33 +120,79 @@ export function installDependencies(cwd, deps) {
|
|
|
120
120
|
return { ok: result.status === 0, pm, args }
|
|
121
121
|
}
|
|
122
122
|
|
|
123
|
-
/**
|
|
123
|
+
/**
|
|
124
|
+
* Ensure tsconfig paths has "<alias>/*": ["./<srcDir>/*"]. Works on JSON with comments (Vite's
|
|
125
|
+
* templates) by inserting text instead of re-serialising. Returns "ok" | "added" | "manual".
|
|
126
|
+
*/
|
|
124
127
|
export function ensureTsconfigAlias(cwd, alias, srcDir = "src") {
|
|
125
128
|
for (const name of ["tsconfig.app.json", "tsconfig.json"]) {
|
|
126
129
|
const file = join(cwd, name)
|
|
127
130
|
if (!existsSync(file)) continue
|
|
128
131
|
const raw = readFileSync(file, "utf8")
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
)
|
|
137
|
-
|
|
138
|
-
return "
|
|
132
|
+
const key = `"${alias}/*"`
|
|
133
|
+
if (raw.includes(key)) return "ok"
|
|
134
|
+
const entry = `${key}: ["./${srcDir}/*"]`
|
|
135
|
+
const pathsMatch = raw.match(/"paths"\s*:\s*\{/)
|
|
136
|
+
if (pathsMatch) {
|
|
137
|
+
const at = pathsMatch.index + pathsMatch[0].length
|
|
138
|
+
const rest = raw.slice(at)
|
|
139
|
+
const empty = /^\s*\}/.test(rest)
|
|
140
|
+
writeFileSync(file, raw.slice(0, at) + `\n ${entry}${empty ? "" : ","}` + rest)
|
|
141
|
+
return "added"
|
|
139
142
|
}
|
|
140
|
-
const
|
|
141
|
-
if (
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
const optionsMatch = raw.match(/"compilerOptions"\s*:\s*\{/)
|
|
144
|
+
if (!optionsMatch) continue
|
|
145
|
+
const at = optionsMatch.index + optionsMatch[0].length
|
|
146
|
+
const rest = raw.slice(at)
|
|
147
|
+
const empty = /^\s*\}/.test(rest)
|
|
148
|
+
writeFileSync(file, raw.slice(0, at) + `\n "paths": {\n ${entry}\n }${empty ? "" : ","}` + rest)
|
|
145
149
|
return "added"
|
|
146
150
|
}
|
|
147
151
|
return "manual"
|
|
148
152
|
}
|
|
149
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Ensure a Vite config has the "@" alias and the Tailwind plugin. Returns what was added.
|
|
156
|
+
* Next.js reads tsconfig paths on its own, so it only needs the tsconfig step.
|
|
157
|
+
*/
|
|
158
|
+
export function ensureViteConfig(cwd, alias, srcDir = "src") {
|
|
159
|
+
const name = ["vite.config.ts", "vite.config.mts", "vite.config.js", "vite.config.mjs"].find((n) =>
|
|
160
|
+
existsSync(join(cwd, n))
|
|
161
|
+
)
|
|
162
|
+
if (!name) return { file: null, added: [] }
|
|
163
|
+
const file = join(cwd, name)
|
|
164
|
+
let raw = readFileSync(file, "utf8")
|
|
165
|
+
const added = []
|
|
166
|
+
const hasAlias = raw.includes(`"${alias}"`) || raw.includes(`'${alias}'`) || raw.includes("tsconfigPaths")
|
|
167
|
+
const hasTailwind = raw.includes("@tailwindcss/vite")
|
|
168
|
+
const config = raw.match(/defineConfig\(\s*\{/)
|
|
169
|
+
if (!config) return { file: name, added, manual: !hasAlias || !hasTailwind }
|
|
170
|
+
if (!hasTailwind) {
|
|
171
|
+
raw = `import tailwindcss from "@tailwindcss/vite"\n` + raw
|
|
172
|
+
const plugins = raw.match(/plugins\s*:\s*\[/)
|
|
173
|
+
if (plugins) {
|
|
174
|
+
const at = plugins.index + plugins[0].length
|
|
175
|
+
raw = raw.slice(0, at) + "tailwindcss(), " + raw.slice(at)
|
|
176
|
+
} else {
|
|
177
|
+
const m = raw.match(/defineConfig\(\s*\{/)
|
|
178
|
+
raw = raw.slice(0, m.index + m[0].length) + "\n plugins: [tailwindcss()]," + raw.slice(m.index + m[0].length)
|
|
179
|
+
}
|
|
180
|
+
added.push("tailwind plugin")
|
|
181
|
+
}
|
|
182
|
+
if (!hasAlias) {
|
|
183
|
+
if (!/from ["']node:path["']|from ["']path["']/.test(raw)) raw = `import path from "node:path"\n` + raw
|
|
184
|
+
const m = raw.match(/defineConfig\(\s*\{/)
|
|
185
|
+
const at = m.index + m[0].length
|
|
186
|
+
raw =
|
|
187
|
+
raw.slice(0, at) +
|
|
188
|
+
`\n resolve: {\n alias: { "${alias}": path.resolve(import.meta.dirname, "./${srcDir}") },\n },` +
|
|
189
|
+
raw.slice(at)
|
|
190
|
+
added.push("alias")
|
|
191
|
+
}
|
|
192
|
+
if (added.length) writeFileSync(file, raw)
|
|
193
|
+
return { file: name, added }
|
|
194
|
+
}
|
|
195
|
+
|
|
150
196
|
export function detectBundlerAlias(cwd, alias) {
|
|
151
197
|
const candidates = [
|
|
152
198
|
"vite.config.ts",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@multicomma/arkcn",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "arkcn: shadcn/ui-style components ported to Ark UI, plus data-heavy primitives (data grid, kanban, gantt, scheduler, node graph, ...). Tailwind v4. Ships a copy-into-your-project CLI and an MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|