@axis-ds/cli 1.2.0 → 1.3.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/README.md +7 -0
- package/dist/{chunk-GCOWKKXG.js → chunk-AHQT77FJ.js} +4 -4
- package/dist/{chunk-D26GW2HO.js → chunk-QORBOSUA.js} +1 -1
- package/dist/{chunk-WRDOGNSG.js → chunk-ZVVACWEW.js} +3 -3
- package/dist/index.js +494 -154
- package/dist/monet.d.ts +3 -3
- package/dist/monet.js +1 -1
- package/dist/sync/index.js +1 -1
- package/dist/v0.d.ts +3 -3
- package/dist/v0.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,13 @@ axis theme add ontology
|
|
|
44
44
|
- `@axis-ds/tokens` 가 없거나 1.3.0 미만이면 목록 대신 설치 · 업그레이드 안내를 내고 종료 코드 1 로 끝납니다.
|
|
45
45
|
- `axis check` 는 `axis.config.json` 의 `brand` 와 CSS 의 브랜드 import 가 맞는지도 봅니다.
|
|
46
46
|
|
|
47
|
+
## 프로젝트 검증 (`axis check`)
|
|
48
|
+
|
|
49
|
+
- Tailwind 구성 항목: Tailwind 4 이상(설치본, 없으면 `package.json` 선언으로 판정)은 설정 파일 대신 전역 CSS(`globals.css` · `app/globals.css` · `src/app/globals.css` · `src/globals.css` · `styles/globals.css` 순)의 `@import "tailwindcss"` 를 봅니다. Tailwind 3 이하는 `tailwind.config.ts` · `.js` · `.mjs` · `.cjs` 를 찾습니다.
|
|
50
|
+
- 이 항목은 Tailwind 진입 import 만 봅니다. `@axis-ds/tokens` 의 Tailwind 연동은 Tailwind 3 preset(`@axis-ds/tokens/tailwind`)뿐이라, Tailwind 4 에서 PASS 여도 `bg-primary` 같은 AXIS 색 클래스가 만들어진다는 뜻은 아닙니다.
|
|
51
|
+
- FAIL 이 하나라도 있으면 종료 코드 1 로 끝납니다. WARN 만 있으면 0 입니다(1.3.0 부터, 이전에는 결과와 관계없이 0).
|
|
52
|
+
- MCP `axis.check_project` 도 같은 항목 · 문구를 냅니다.
|
|
53
|
+
|
|
47
54
|
## 문서
|
|
48
55
|
|
|
49
56
|
자세한 사용법은 [AXIS Design System 문서](https://axis.minu.best)를 참고하세요.
|
|
@@ -84,7 +84,7 @@ ${result}`;
|
|
|
84
84
|
console.log(chalk.bold("\uBC29\uBC95 3: \uCF54\uB4DC \uBCF5\uC0AC"));
|
|
85
85
|
console.log(chalk.gray(" 1. v0.app\uC5D0\uC11C \uCF54\uB4DC \uD0ED \uC5F4\uAE30"));
|
|
86
86
|
console.log(chalk.gray(" 2. \uD30C\uC77C\uBCC4\uB85C \uCF54\uB4DC \uBCF5\uC0AC"));
|
|
87
|
-
console.log(chalk.gray(" 3. axis-cli v0 convert\uB85C \uBCC0\uD658\n"));
|
|
87
|
+
console.log(chalk.gray(" 3. npx @axis-ds/cli v0 convert\uB85C \uBCC0\uD658\n"));
|
|
88
88
|
const { method } = await prompts({
|
|
89
89
|
type: "select",
|
|
90
90
|
name: "method",
|
|
@@ -118,7 +118,7 @@ ${result}`;
|
|
|
118
118
|
console.log(chalk.bold("3. \uB85C\uCEEC\uC5D0\uC11C \uD074\uB860:"));
|
|
119
119
|
console.log(chalk.cyan(" git clone https://github.com/your-org/v0-project.git\n"));
|
|
120
120
|
console.log(chalk.bold("4. AXIS \uBCC0\uD658:"));
|
|
121
|
-
console.log(chalk.cyan(" axis-cli v0 convert ./v0-project/components/*.tsx\n"));
|
|
121
|
+
console.log(chalk.cyan(" npx @axis-ds/cli v0 convert ./v0-project/components/*.tsx\n"));
|
|
122
122
|
console.log(chalk.gray("\uD301: GitHub Actions\uB85C \uC790\uB3D9 \uBCC0\uD658 \uC6CC\uD06C\uD50C\uB85C\uB3C4 \uC124\uC815 \uAC00\uB2A5\uD569\uB2C8\uB2E4.\n"));
|
|
123
123
|
}
|
|
124
124
|
// ZIP 파일에서 변환
|
|
@@ -134,7 +134,7 @@ ${result}`;
|
|
|
134
134
|
console.log(chalk.yellow("\nZIP \uBCC0\uD658 \uAE30\uB2A5\uC740 \uCD94\uD6C4 \uAD6C\uD604 \uC608\uC815\uC785\uB2C8\uB2E4."));
|
|
135
135
|
console.log(chalk.gray("\uD604\uC7AC\uB294 \uC218\uB3D9\uC73C\uB85C \uC555\uCD95 \uD574\uC81C \uD6C4 convert \uBA85\uB839\uC5B4\uB97C \uC0AC\uC6A9\uD558\uC138\uC694:\n"));
|
|
136
136
|
console.log(chalk.cyan(" unzip v0-project.zip -d ./v0-project"));
|
|
137
|
-
console.log(chalk.cyan(" axis-cli v0 convert ./v0-project/components/*.tsx\n"));
|
|
137
|
+
console.log(chalk.cyan(" npx @axis-ds/cli v0 convert ./v0-project/components/*.tsx\n"));
|
|
138
138
|
}
|
|
139
139
|
// 클립보드에서 변환
|
|
140
140
|
async convertFromClipboard() {
|
|
@@ -185,7 +185,7 @@ ${result}`;
|
|
|
185
185
|
console.log(chalk.gray(" AI/LLM \uAD00\uB828 UI\uC5D0\uB294 @axis-ds/agentic-ui \uC0AC\uC6A9:"));
|
|
186
186
|
console.log(chalk.cyan(" import { StreamingText } from '@axis-ds/agentic-ui'\n"));
|
|
187
187
|
console.log(chalk.bold("5. \uC790\uB3D9 \uBCC0\uD658"));
|
|
188
|
-
console.log(chalk.cyan(" axis-cli v0 convert <file.tsx>\n"));
|
|
188
|
+
console.log(chalk.cyan(" npx @axis-ds/cli v0 convert <file.tsx>\n"));
|
|
189
189
|
}
|
|
190
190
|
};
|
|
191
191
|
function getV0Url(path2 = "") {
|
|
@@ -852,7 +852,7 @@ async function initSync(owner, repo, projectNumber) {
|
|
|
852
852
|
console.log(chalk.gray(` \uD504\uB85C\uC81D\uD2B8: #${projectNumber}`));
|
|
853
853
|
console.log();
|
|
854
854
|
console.log(chalk.cyan("\uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uB3D9\uAE30\uD654\uB97C \uC2DC\uC791\uD558\uC138\uC694:"));
|
|
855
|
-
console.log(chalk.cyan(" npx axis-cli sync"));
|
|
855
|
+
console.log(chalk.cyan(" npx @axis-ds/cli sync"));
|
|
856
856
|
console.log();
|
|
857
857
|
} catch (error) {
|
|
858
858
|
spinner.fail(`\uC624\uB958: ${error.message}`);
|
|
@@ -35,8 +35,8 @@ var MonetClient = class {
|
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
37
|
console.log(chalk.gray("\n\uC0AC\uC6A9\uBC95:"));
|
|
38
|
-
console.log(chalk.gray(" axis-cli monet browse <category> # \uCE74\uD14C\uACE0\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBCF4\uAE30"));
|
|
39
|
-
console.log(chalk.gray(" axis-cli monet search <query> # \uCEF4\uD3EC\uB10C\uD2B8 \uAC80\uC0C9\n"));
|
|
38
|
+
console.log(chalk.gray(" npx @axis-ds/cli monet browse <category> # \uCE74\uD14C\uACE0\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBCF4\uAE30"));
|
|
39
|
+
console.log(chalk.gray(" npx @axis-ds/cli monet search <query> # \uCEF4\uD3EC\uB10C\uD2B8 \uAC80\uC0C9\n"));
|
|
40
40
|
}
|
|
41
41
|
// 컴포넌트 검색 (웹 URL 안내)
|
|
42
42
|
async searchComponents(query) {
|
|
@@ -82,7 +82,7 @@ var MonetClient = class {
|
|
|
82
82
|
console.log(chalk.gray("\n\uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uAE30:"));
|
|
83
83
|
console.log(chalk.gray(" 1. \uC6F9\uC5D0\uC11C \uCEF4\uD3EC\uB10C\uD2B8 \uC120\uD0DD"));
|
|
84
84
|
console.log(chalk.gray(" 2. Copy Code \uBC84\uD2BC \uD074\uB9AD"));
|
|
85
|
-
console.log(chalk.gray(" 3. axis-cli monet import \uC2E4\uD589\n"));
|
|
85
|
+
console.log(chalk.gray(" 3. npx @axis-ds/cli monet import \uC2E4\uD589\n"));
|
|
86
86
|
}
|
|
87
87
|
// 카테고리별 예시 컴포넌트
|
|
88
88
|
getCategoryExamples(category) {
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
MonetClient
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-ZVVACWEW.js";
|
|
5
5
|
import {
|
|
6
6
|
V0Client
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-AHQT77FJ.js";
|
|
8
8
|
import {
|
|
9
9
|
registerSyncCommand
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-QORBOSUA.js";
|
|
11
11
|
import {
|
|
12
12
|
fetchTemplateDetail,
|
|
13
13
|
fetchTemplateIndex
|
|
@@ -15,12 +15,12 @@ import {
|
|
|
15
15
|
|
|
16
16
|
// src/index.ts
|
|
17
17
|
import { Command } from "commander";
|
|
18
|
-
import
|
|
18
|
+
import chalk11 from "chalk";
|
|
19
19
|
import ora6 from "ora";
|
|
20
|
-
import
|
|
21
|
-
import
|
|
20
|
+
import fs11 from "fs-extra";
|
|
21
|
+
import path12 from "path";
|
|
22
22
|
import { createRequire as createRequire2 } from "module";
|
|
23
|
-
import
|
|
23
|
+
import prompts3 from "prompts";
|
|
24
24
|
|
|
25
25
|
// src/library/base-collector.ts
|
|
26
26
|
import crypto from "crypto";
|
|
@@ -484,11 +484,11 @@ var ShadcnCollector = class extends BaseCollector {
|
|
|
484
484
|
/**
|
|
485
485
|
* 파일 타입 추론
|
|
486
486
|
*/
|
|
487
|
-
getFileType(
|
|
488
|
-
if (
|
|
489
|
-
if (
|
|
490
|
-
if (
|
|
491
|
-
if (
|
|
487
|
+
getFileType(path13) {
|
|
488
|
+
if (path13.includes("hook") || path13.startsWith("use")) return "hook";
|
|
489
|
+
if (path13.includes("util") || path13.includes("lib")) return "util";
|
|
490
|
+
if (path13.endsWith(".css")) return "style";
|
|
491
|
+
if (path13.endsWith(".d.ts") || path13.includes("types")) return "type";
|
|
492
492
|
return "component";
|
|
493
493
|
}
|
|
494
494
|
};
|
|
@@ -1474,7 +1474,7 @@ var LibraryCurator = class {
|
|
|
1474
1474
|
const index = await this.loadIndex();
|
|
1475
1475
|
if (!index) {
|
|
1476
1476
|
console.log(chalk2.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
1477
|
-
console.log(chalk2.gray(" axis-cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
1477
|
+
console.log(chalk2.gray(" npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
1478
1478
|
return;
|
|
1479
1479
|
}
|
|
1480
1480
|
console.log(chalk2.blue("\n\u{1F4CA} Library Curator - \uD1B5\uACC4\n"));
|
|
@@ -2099,6 +2099,178 @@ function getBrand(baseDir, name) {
|
|
|
2099
2099
|
};
|
|
2100
2100
|
}
|
|
2101
2101
|
|
|
2102
|
+
// src/template/tailwind-core.ts
|
|
2103
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
2104
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
2105
|
+
function hasDependency(pkg, name) {
|
|
2106
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
2107
|
+
const deps = pkg[field];
|
|
2108
|
+
if (typeof deps === "object" && deps !== null && name in deps) {
|
|
2109
|
+
return String(deps[name]);
|
|
2110
|
+
}
|
|
2111
|
+
}
|
|
2112
|
+
return void 0;
|
|
2113
|
+
}
|
|
2114
|
+
function isPlainObject(value) {
|
|
2115
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2116
|
+
}
|
|
2117
|
+
var VERSION = String.raw`v?(\d+)(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?`;
|
|
2118
|
+
function versionParts(token) {
|
|
2119
|
+
const m = new RegExp(`^${VERSION}$`).exec(token);
|
|
2120
|
+
if (!m) return void 0;
|
|
2121
|
+
if (/^v?0\.0\.0-/.test(token)) return void 0;
|
|
2122
|
+
return { major: Number(m[1]), minor: m[2], patch: m[3] };
|
|
2123
|
+
}
|
|
2124
|
+
var isWild = (part) => part === void 0 || /^[xX*]$/.test(part);
|
|
2125
|
+
function comparatorBounds(op, v) {
|
|
2126
|
+
switch (op) {
|
|
2127
|
+
case ">=":
|
|
2128
|
+
return { lower: v.major };
|
|
2129
|
+
case ">":
|
|
2130
|
+
return { lower: isWild(v.minor) ? v.major + 1 : v.major };
|
|
2131
|
+
case "<=":
|
|
2132
|
+
return { upper: v.major };
|
|
2133
|
+
case "<": {
|
|
2134
|
+
const zeroOrWild = (part) => isWild(part) || Number(part) === 0;
|
|
2135
|
+
return { upper: zeroOrWild(v.minor) && zeroOrWild(v.patch) ? v.major - 1 : v.major };
|
|
2136
|
+
}
|
|
2137
|
+
default:
|
|
2138
|
+
return { lower: v.major, upper: v.major };
|
|
2139
|
+
}
|
|
2140
|
+
}
|
|
2141
|
+
function tailwindMajorBounds(range) {
|
|
2142
|
+
const r = range.trim();
|
|
2143
|
+
if (r === "" || r.includes("||")) return void 0;
|
|
2144
|
+
const simple = new RegExp(`^(?:\\^|~|=)?\\s*(${VERSION})$`).exec(r);
|
|
2145
|
+
if (simple) {
|
|
2146
|
+
const v = versionParts(simple[1]);
|
|
2147
|
+
return v ? { lower: v.major, upper: v.major } : void 0;
|
|
2148
|
+
}
|
|
2149
|
+
const hyphen = new RegExp(`^(${VERSION})\\s+-\\s+(${VERSION})$`).exec(r);
|
|
2150
|
+
if (hyphen) {
|
|
2151
|
+
const tokens2 = r.split(/\s+-\s+/);
|
|
2152
|
+
const a = versionParts(tokens2[0]);
|
|
2153
|
+
const b = versionParts(tokens2[1]);
|
|
2154
|
+
return a && b && a.major <= b.major ? { lower: a.major, upper: b.major } : void 0;
|
|
2155
|
+
}
|
|
2156
|
+
const tokens = r.replace(/(>=|<=|>|<|=)\s+/g, "$1").split(/\s+/);
|
|
2157
|
+
const lowers = [];
|
|
2158
|
+
const uppers = [];
|
|
2159
|
+
for (const t of tokens) {
|
|
2160
|
+
const c = /^(>=|<=|>|<|=)(.+)$/.exec(t);
|
|
2161
|
+
if (!c) return void 0;
|
|
2162
|
+
const v = versionParts(c[2]);
|
|
2163
|
+
if (v === void 0) return void 0;
|
|
2164
|
+
const b = comparatorBounds(c[1], v);
|
|
2165
|
+
if (b.lower !== void 0) lowers.push(b.lower);
|
|
2166
|
+
if (b.upper !== void 0) uppers.push(b.upper);
|
|
2167
|
+
}
|
|
2168
|
+
if (lowers.length === 0) return void 0;
|
|
2169
|
+
const lower = Math.max(...lowers);
|
|
2170
|
+
const upper = uppers.length > 0 ? Math.min(...uppers) : void 0;
|
|
2171
|
+
if (upper !== void 0 && upper < lower) return void 0;
|
|
2172
|
+
return upper !== void 0 ? { lower, upper } : { lower };
|
|
2173
|
+
}
|
|
2174
|
+
function majorWithin(major, bounds) {
|
|
2175
|
+
return major >= bounds.lower && (bounds.upper === void 0 || major <= bounds.upper);
|
|
2176
|
+
}
|
|
2177
|
+
function majorFromVersion(version) {
|
|
2178
|
+
if (typeof version !== "string") return void 0;
|
|
2179
|
+
const v = version.trim();
|
|
2180
|
+
const m = /^v?(\d+)\.\d+\.\d+(?:[-+][0-9A-Za-z.+-]*)?$/.exec(v);
|
|
2181
|
+
if (!m || /^v?0\.0\.0-/.test(v)) return void 0;
|
|
2182
|
+
return Number(m[1]);
|
|
2183
|
+
}
|
|
2184
|
+
function detectTailwind(baseDirInput, pkg) {
|
|
2185
|
+
const baseDir = resolve2(baseDirInput);
|
|
2186
|
+
const installedFile = join2(baseDir, "node_modules", "tailwindcss", "package.json");
|
|
2187
|
+
const declared = pkg ? hasDependency(pkg, "tailwindcss") : void 0;
|
|
2188
|
+
const bounds = declared !== void 0 ? tailwindMajorBounds(declared) : void 0;
|
|
2189
|
+
const declaredMajor = bounds?.lower;
|
|
2190
|
+
try {
|
|
2191
|
+
const installed = JSON.parse(readFileSync2(installedFile, "utf8"));
|
|
2192
|
+
const version = isPlainObject(installed) ? installed.version : void 0;
|
|
2193
|
+
const major = majorFromVersion(version);
|
|
2194
|
+
if (major !== void 0) {
|
|
2195
|
+
const found = { major, source: "installed", value: String(version) };
|
|
2196
|
+
if (declared !== void 0 && bounds !== void 0 && !majorWithin(major, bounds)) {
|
|
2197
|
+
found.mismatch = { declared, declaredMajor: bounds.lower };
|
|
2198
|
+
}
|
|
2199
|
+
return found;
|
|
2200
|
+
}
|
|
2201
|
+
} catch {
|
|
2202
|
+
}
|
|
2203
|
+
if (declared !== void 0) {
|
|
2204
|
+
if (declaredMajor !== void 0) return { major: declaredMajor, source: "declared", value: declared };
|
|
2205
|
+
return { source: "none", value: declared };
|
|
2206
|
+
}
|
|
2207
|
+
return { source: "none" };
|
|
2208
|
+
}
|
|
2209
|
+
var TAILWIND_CONFIG_FILES = [
|
|
2210
|
+
"tailwind.config.ts",
|
|
2211
|
+
"tailwind.config.js",
|
|
2212
|
+
"tailwind.config.mjs",
|
|
2213
|
+
"tailwind.config.cjs"
|
|
2214
|
+
];
|
|
2215
|
+
var TAILWIND_CSS_CANDIDATES = [
|
|
2216
|
+
"globals.css",
|
|
2217
|
+
"app/globals.css",
|
|
2218
|
+
"src/app/globals.css",
|
|
2219
|
+
"src/globals.css",
|
|
2220
|
+
"styles/globals.css"
|
|
2221
|
+
];
|
|
2222
|
+
var TAILWIND_IMPORT = /@import\s+(?:url\(\s*)?["']tailwindcss["']/;
|
|
2223
|
+
function hasTailwindImport(css) {
|
|
2224
|
+
return TAILWIND_IMPORT.test(css.replace(/\/\*[\s\S]*?\*\//g, ""));
|
|
2225
|
+
}
|
|
2226
|
+
function readPackageJson(baseDir) {
|
|
2227
|
+
try {
|
|
2228
|
+
const parsed = JSON.parse(readFileSync2(join2(baseDir, "package.json"), "utf8"));
|
|
2229
|
+
return isPlainObject(parsed) ? parsed : void 0;
|
|
2230
|
+
} catch {
|
|
2231
|
+
return void 0;
|
|
2232
|
+
}
|
|
2233
|
+
}
|
|
2234
|
+
function checkTailwindSetup(baseDirInput) {
|
|
2235
|
+
const baseDir = resolve2(baseDirInput);
|
|
2236
|
+
const tailwind = detectTailwind(baseDir, readPackageJson(baseDir));
|
|
2237
|
+
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
2238
|
+
const label = `Tailwind ${tailwind.major}`;
|
|
2239
|
+
for (const candidate of TAILWIND_CSS_CANDIDATES) {
|
|
2240
|
+
const file = join2(baseDir, candidate);
|
|
2241
|
+
if (!existsSync2(file)) continue;
|
|
2242
|
+
const found = hasTailwindImport(readFileSync2(file, "utf8"));
|
|
2243
|
+
return {
|
|
2244
|
+
name: "tailwind.config",
|
|
2245
|
+
severity: found ? "pass" : "warn",
|
|
2246
|
+
message: found ? `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC788\uC2B5\uB2C8\uB2E4` : `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2247
|
+
};
|
|
2248
|
+
}
|
|
2249
|
+
return {
|
|
2250
|
+
name: "tailwind.config",
|
|
2251
|
+
severity: "warn",
|
|
2252
|
+
message: `${label}: @import "tailwindcss" \uB97C \uD655\uC778\uD560 CSS \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`
|
|
2253
|
+
};
|
|
2254
|
+
}
|
|
2255
|
+
const [tsFile, ...otherFiles] = TAILWIND_CONFIG_FILES;
|
|
2256
|
+
const tsPath = join2(baseDir, tsFile);
|
|
2257
|
+
if (existsSync2(tsPath)) {
|
|
2258
|
+
const content = readFileSync2(tsPath, "utf8");
|
|
2259
|
+
const hasTokens = content.includes("--background") || content.includes("hsl(var(");
|
|
2260
|
+
return {
|
|
2261
|
+
name: "tailwind.config",
|
|
2262
|
+
severity: hasTokens ? "pass" : "warn",
|
|
2263
|
+
message: hasTokens ? "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4" : "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
2264
|
+
};
|
|
2265
|
+
}
|
|
2266
|
+
for (const file of otherFiles) {
|
|
2267
|
+
if (existsSync2(join2(baseDir, file))) {
|
|
2268
|
+
return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
return { name: "tailwind.config", severity: "fail", message: "tailwind.config \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
|
|
2272
|
+
}
|
|
2273
|
+
|
|
2102
2274
|
// src/template/template-check.ts
|
|
2103
2275
|
var SEVERITY_ICON = {
|
|
2104
2276
|
pass: chalk6.green("PASS"),
|
|
@@ -2109,7 +2281,7 @@ async function collectCheckResults(dir) {
|
|
|
2109
2281
|
const baseDir = path8.resolve(dir || ".");
|
|
2110
2282
|
const results = [];
|
|
2111
2283
|
results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
|
|
2112
|
-
results.push(
|
|
2284
|
+
results.push(checkTailwindSetup(baseDir));
|
|
2113
2285
|
results.push(await checkGlobalsCss(baseDir));
|
|
2114
2286
|
results.push(await checkUtils(baseDir));
|
|
2115
2287
|
results.push(await checkDependencies(baseDir));
|
|
@@ -2148,6 +2320,7 @@ async function runCheck(dir) {
|
|
|
2148
2320
|
} else {
|
|
2149
2321
|
console.log(chalk6.green("\n\uBAA8\uB4E0 \uAC80\uC99D\uC744 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4!"));
|
|
2150
2322
|
}
|
|
2323
|
+
return { pass: passCount, warn: warnCount, fail: failCount };
|
|
2151
2324
|
}
|
|
2152
2325
|
async function checkFileExists(baseDir, fileName, label) {
|
|
2153
2326
|
const exists = await fs9.pathExists(path8.join(baseDir, fileName));
|
|
@@ -2157,31 +2330,6 @@ async function checkFileExists(baseDir, fileName, label) {
|
|
|
2157
2330
|
message: exists ? `${label} \uD30C\uC77C\uC774 \uC874\uC7AC\uD569\uB2C8\uB2E4` : `${label} \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 'axis init'\uC744 \uC2E4\uD589\uD558\uC138\uC694`
|
|
2158
2331
|
};
|
|
2159
2332
|
}
|
|
2160
|
-
async function checkTailwindConfig(baseDir) {
|
|
2161
|
-
const tsPath = path8.join(baseDir, "tailwind.config.ts");
|
|
2162
|
-
const jsPath = path8.join(baseDir, "tailwind.config.js");
|
|
2163
|
-
if (await fs9.pathExists(tsPath)) {
|
|
2164
|
-
const content = await fs9.readFile(tsPath, "utf-8");
|
|
2165
|
-
const hasTokens = content.includes("--background") || content.includes("hsl(var(");
|
|
2166
|
-
return {
|
|
2167
|
-
name: "tailwind.config",
|
|
2168
|
-
severity: hasTokens ? "pass" : "warn",
|
|
2169
|
-
message: hasTokens ? "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070\uC774 \uC124\uC815\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4" : "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
2170
|
-
};
|
|
2171
|
-
}
|
|
2172
|
-
if (await fs9.pathExists(jsPath)) {
|
|
2173
|
-
return {
|
|
2174
|
-
name: "tailwind.config",
|
|
2175
|
-
severity: "warn",
|
|
2176
|
-
message: "tailwind.config.js \uC874\uC7AC (TypeScript \uAD8C\uC7A5)"
|
|
2177
|
-
};
|
|
2178
|
-
}
|
|
2179
|
-
return {
|
|
2180
|
-
name: "tailwind.config",
|
|
2181
|
-
severity: "fail",
|
|
2182
|
-
message: "tailwind.config \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
2183
|
-
};
|
|
2184
|
-
}
|
|
2185
2333
|
async function checkGlobalsCss(baseDir) {
|
|
2186
2334
|
const candidates = [
|
|
2187
2335
|
"globals.css",
|
|
@@ -2402,7 +2550,8 @@ function registerTemplateCommand(program2) {
|
|
|
2402
2550
|
}
|
|
2403
2551
|
function registerCheckCommand(program2) {
|
|
2404
2552
|
program2.command("check").description("AXIS \uD504\uB85C\uC81D\uD2B8 \uC124\uC815 \uAC80\uC99D").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action(async (options) => {
|
|
2405
|
-
await runCheck(options.dir);
|
|
2553
|
+
const summary = await runCheck(options.dir);
|
|
2554
|
+
if (summary.fail > 0) process.exitCode = 1;
|
|
2406
2555
|
});
|
|
2407
2556
|
}
|
|
2408
2557
|
|
|
@@ -2411,12 +2560,12 @@ import chalk8 from "chalk";
|
|
|
2411
2560
|
import path10 from "path";
|
|
2412
2561
|
|
|
2413
2562
|
// src/theme/theme-add.ts
|
|
2414
|
-
import { accessSync, constants, existsSync as
|
|
2563
|
+
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
|
|
2415
2564
|
import path9 from "path";
|
|
2416
2565
|
var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
|
|
2417
2566
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
2418
2567
|
function readText(file) {
|
|
2419
|
-
return
|
|
2568
|
+
return existsSync3(file) ? readFileSync3(file, "utf8") : null;
|
|
2420
2569
|
}
|
|
2421
2570
|
function eolOf(text) {
|
|
2422
2571
|
return text.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -2492,12 +2641,12 @@ function isStylesheet(realPath) {
|
|
|
2492
2641
|
return path9.extname(realPath).toLowerCase() === ".css";
|
|
2493
2642
|
}
|
|
2494
2643
|
function detectInstallCommand(baseDir) {
|
|
2495
|
-
if (
|
|
2496
|
-
if (
|
|
2497
|
-
if (
|
|
2644
|
+
if (existsSync3(path9.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
|
|
2645
|
+
if (existsSync3(path9.join(baseDir, "yarn.lock"))) return "yarn install";
|
|
2646
|
+
if (existsSync3(path9.join(baseDir, "package-lock.json"))) return "npm install";
|
|
2498
2647
|
return "pnpm install";
|
|
2499
2648
|
}
|
|
2500
|
-
function
|
|
2649
|
+
function hasDependency2(pkg, name) {
|
|
2501
2650
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
2502
2651
|
const deps = pkg[field];
|
|
2503
2652
|
if (typeof deps === "object" && deps !== null && name in deps) {
|
|
@@ -2506,7 +2655,7 @@ function hasDependency(pkg, name) {
|
|
|
2506
2655
|
}
|
|
2507
2656
|
return void 0;
|
|
2508
2657
|
}
|
|
2509
|
-
function
|
|
2658
|
+
function isPlainObject2(value) {
|
|
2510
2659
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2511
2660
|
}
|
|
2512
2661
|
function planThemeAdd(baseDirInput, brand) {
|
|
@@ -2531,7 +2680,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2531
2680
|
let config;
|
|
2532
2681
|
try {
|
|
2533
2682
|
const parsed = JSON.parse(configText);
|
|
2534
|
-
if (!
|
|
2683
|
+
if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
|
|
2535
2684
|
config = parsed;
|
|
2536
2685
|
} catch (err) {
|
|
2537
2686
|
plan.errors.push({ kind: "invalid-config", message: err.message });
|
|
@@ -2543,7 +2692,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2543
2692
|
}
|
|
2544
2693
|
plan.tokens = resolveTokens(baseDir);
|
|
2545
2694
|
if (plan.tokens.status === "ok" && plan.tokens.indexPath) {
|
|
2546
|
-
const data = JSON.parse(
|
|
2695
|
+
const data = JSON.parse(readFileSync3(plan.tokens.indexPath, "utf8"));
|
|
2547
2696
|
const entries = Array.isArray(data.brands) ? data.brands : [];
|
|
2548
2697
|
const entry = entries.find((e) => e.name === brand);
|
|
2549
2698
|
if (!entry) {
|
|
@@ -2572,7 +2721,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2572
2721
|
plan.writes = [];
|
|
2573
2722
|
return plan;
|
|
2574
2723
|
}
|
|
2575
|
-
const before =
|
|
2724
|
+
const before = readFileSync3(location.path, "utf8");
|
|
2576
2725
|
const imported = findBrandImports(before);
|
|
2577
2726
|
const otherBrands = [...new Set(imported.filter((n) => n !== brand))];
|
|
2578
2727
|
if (imported.includes(brand)) {
|
|
@@ -2598,19 +2747,19 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2598
2747
|
let pkg;
|
|
2599
2748
|
try {
|
|
2600
2749
|
const parsed = JSON.parse(pkgText);
|
|
2601
|
-
if (!
|
|
2750
|
+
if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
|
|
2602
2751
|
pkg = parsed;
|
|
2603
2752
|
} catch (err) {
|
|
2604
2753
|
plan.errors.push({ kind: "invalid-package-json", message: err.message });
|
|
2605
2754
|
plan.writes = [];
|
|
2606
2755
|
return plan;
|
|
2607
2756
|
}
|
|
2608
|
-
const themeMissing =
|
|
2609
|
-
const declared =
|
|
2757
|
+
const themeMissing = hasDependency2(pkg, THEME_PACKAGE) === void 0;
|
|
2758
|
+
const declared = hasDependency2(pkg, TOKENS_PACKAGE);
|
|
2610
2759
|
if (declared !== void 0) {
|
|
2611
2760
|
plan.dependency = { action: "present", declaredRange: declared, upgrade, themeMissing };
|
|
2612
2761
|
} else {
|
|
2613
|
-
const deps =
|
|
2762
|
+
const deps = isPlainObject2(pkg.dependencies) ? { ...pkg.dependencies } : {};
|
|
2614
2763
|
deps[TOKENS_PACKAGE] = TOKENS_DEPENDENCY_RANGE;
|
|
2615
2764
|
const next = { ...pkg, dependencies: deps };
|
|
2616
2765
|
plan.dependency = { action: "add", upgrade, themeMissing };
|
|
@@ -2985,74 +3134,265 @@ function registerThemeCommand(program2) {
|
|
|
2985
3134
|
});
|
|
2986
3135
|
}
|
|
2987
3136
|
|
|
2988
|
-
// src/index.ts
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3008
|
-
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
|
|
3137
|
+
// src/init/index.ts
|
|
3138
|
+
import chalk10 from "chalk";
|
|
3139
|
+
import prompts2 from "prompts";
|
|
3140
|
+
|
|
3141
|
+
// src/init/init.ts
|
|
3142
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
3143
|
+
import path11 from "path";
|
|
3144
|
+
import chalk9 from "chalk";
|
|
3145
|
+
import fs10 from "fs-extra";
|
|
3146
|
+
var CLSX_RANGE = "^2.1.1";
|
|
3147
|
+
var TAILWIND_MERGE_RANGES = {
|
|
3148
|
+
tailwind4: "^3.4.0",
|
|
3149
|
+
tailwind3: "^2.6.0"
|
|
3150
|
+
};
|
|
3151
|
+
function selectUtilsDependencies(tailwind) {
|
|
3152
|
+
return {
|
|
3153
|
+
clsx: CLSX_RANGE,
|
|
3154
|
+
"tailwind-merge": tailwind.major !== void 0 && tailwind.major >= 4 ? TAILWIND_MERGE_RANGES.tailwind4 : TAILWIND_MERGE_RANGES.tailwind3
|
|
3155
|
+
};
|
|
3156
|
+
}
|
|
3157
|
+
function tailwindWarnings(tailwind, installCommand) {
|
|
3158
|
+
const out = [];
|
|
3159
|
+
if (tailwind.source === "none" && tailwind.value !== void 0) {
|
|
3160
|
+
out.push(
|
|
3161
|
+
`! tailwindcss \uC120\uC5B8(${tailwind.value})\uC740 \uD310\uC815 \uBD88\uAC00 - \uAE30\uBCF8\uAC12 \uC0AC\uC6A9(Tailwind 3, tailwind-merge ${TAILWIND_MERGE_RANGES.tailwind3}). Tailwind 4 \uC774\uC0C1\uC774\uBA74 tailwind-merge \uB97C ${TAILWIND_MERGE_RANGES.tailwind4} \uC73C\uB85C \uBC14\uAFB8\uC138\uC694.`
|
|
3162
|
+
);
|
|
3163
|
+
}
|
|
3164
|
+
if (tailwind.mismatch) {
|
|
3165
|
+
out.push(
|
|
3166
|
+
`! \uC124\uCE58\uBCF8 tailwindcss ${tailwind.value}(major ${tailwind.major})\uC640 package.json \uC120\uC5B8 ${tailwind.mismatch.declared}(major ${tailwind.mismatch.declaredMajor})\uAC00 \uB2E4\uB984 - \uC124\uCE58\uBCF8\uC744 \uB530\uB790\uC2B5\uB2C8\uB2E4. ${installCommand} \uB4A4 tailwind-merge \uBC94\uC704\uB97C \uB2E4\uC2DC \uD655\uC778\uD558\uC138\uC694.`
|
|
3167
|
+
);
|
|
3168
|
+
}
|
|
3169
|
+
return out;
|
|
3170
|
+
}
|
|
3171
|
+
function describeTailwindBasis(tailwind) {
|
|
3172
|
+
if (tailwind.source === "installed") return `\uC124\uCE58\uB41C tailwindcss ${tailwind.value}`;
|
|
3173
|
+
if (tailwind.source === "declared") return `package.json \uC758 tailwindcss ${tailwind.value}`;
|
|
3174
|
+
if (tailwind.value !== void 0) {
|
|
3175
|
+
return `package.json \uC758 tailwindcss ${tailwind.value} \uB85C \uBC84\uC804\uC744 \uD310\uC815\uD558\uC9C0 \uBABB\uD574 \uAE30\uBCF8\uAC12(Tailwind 3)`;
|
|
3176
|
+
}
|
|
3177
|
+
return "tailwindcss \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uAE30\uBCF8\uAC12(Tailwind 3)";
|
|
3178
|
+
}
|
|
3179
|
+
var UTILS_TS_CONTENT = `import { type ClassValue, clsx } from "clsx";
|
|
3180
|
+
import { twMerge } from "tailwind-merge";
|
|
3181
|
+
|
|
3182
|
+
export function cn(...inputs: ClassValue[]) {
|
|
3183
|
+
return twMerge(clsx(inputs));
|
|
3184
|
+
}
|
|
3185
|
+
`;
|
|
3186
|
+
var INIT_DEFAULTS = {
|
|
3187
|
+
componentsDir: "./src/components/ui",
|
|
3188
|
+
tailwindConfig: "./tailwind.config.ts",
|
|
3189
|
+
globalCss: "./src/app/globals.css"
|
|
3190
|
+
};
|
|
3191
|
+
var INIT_NEXT_STEP_COMMAND = "npx @axis-ds/cli add button";
|
|
3192
|
+
var BOM = "\uFEFF";
|
|
3193
|
+
function addCommandFor(installCommand, deps) {
|
|
3194
|
+
const specs = Object.entries(deps).map(([name, range]) => `"${name}@${range}"`).join(" ");
|
|
3195
|
+
if (installCommand.startsWith("yarn")) return `yarn add ${specs}`;
|
|
3196
|
+
if (installCommand.startsWith("npm")) return `npm install ${specs}`;
|
|
3197
|
+
return `pnpm add ${specs}`;
|
|
3198
|
+
}
|
|
3199
|
+
function planUtilsDependencies(baseDirInput) {
|
|
3200
|
+
const baseDir = path11.resolve(baseDirInput);
|
|
3201
|
+
const installCommand = detectInstallCommand(baseDir);
|
|
3202
|
+
const tailwind0 = detectTailwind(baseDir);
|
|
3203
|
+
const ranges0 = selectUtilsDependencies(tailwind0);
|
|
3204
|
+
const plan = {
|
|
3205
|
+
action: "no-package-json",
|
|
3206
|
+
added: [],
|
|
3207
|
+
present: [],
|
|
3208
|
+
ranges: ranges0,
|
|
3209
|
+
tailwind: tailwind0,
|
|
3210
|
+
installCommand,
|
|
3211
|
+
addCommand: addCommandFor(installCommand, ranges0)
|
|
3212
|
+
};
|
|
3213
|
+
const pkgFile = path11.join(baseDir, "package.json");
|
|
3214
|
+
if (!existsSync4(pkgFile)) return plan;
|
|
3215
|
+
const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
|
|
3216
|
+
let where;
|
|
3217
|
+
try {
|
|
3218
|
+
where = realPathInside(baseDir, pkgFile);
|
|
3219
|
+
} catch (err) {
|
|
3220
|
+
return unwritable(err.message);
|
|
3221
|
+
}
|
|
3222
|
+
if (!where.inside) return unwritable(`\uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`);
|
|
3223
|
+
let text;
|
|
3224
|
+
try {
|
|
3225
|
+
text = readFileSync4(pkgFile, "utf8");
|
|
3226
|
+
} catch (err) {
|
|
3227
|
+
return unwritable(err.message);
|
|
3228
|
+
}
|
|
3229
|
+
const bom = text.startsWith(BOM) ? BOM : "";
|
|
3230
|
+
const body = bom ? text.slice(1) : text;
|
|
3231
|
+
let pkg;
|
|
3232
|
+
try {
|
|
3233
|
+
const parsed = JSON.parse(body);
|
|
3234
|
+
if (!isPlainObject2(parsed)) throw new Error("\uCD5C\uC0C1\uC704\uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
|
|
3235
|
+
pkg = parsed;
|
|
3236
|
+
} catch (err) {
|
|
3237
|
+
return unwritable(`JSON \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${err.message}`);
|
|
3238
|
+
}
|
|
3239
|
+
plan.tailwind = detectTailwind(baseDir, pkg);
|
|
3240
|
+
plan.ranges = selectUtilsDependencies(plan.tailwind);
|
|
3241
|
+
plan.addCommand = addCommandFor(installCommand, plan.ranges);
|
|
3242
|
+
const missing = {};
|
|
3243
|
+
for (const [name, range] of Object.entries(plan.ranges)) {
|
|
3244
|
+
const declared = hasDependency2(pkg, name);
|
|
3245
|
+
if (declared !== void 0) plan.present.push({ name, range: declared });
|
|
3246
|
+
else missing[name] = range;
|
|
3247
|
+
}
|
|
3248
|
+
plan.added = Object.keys(missing);
|
|
3249
|
+
plan.addCommand = addCommandFor(installCommand, plan.added.length > 0 ? missing : plan.ranges);
|
|
3250
|
+
if (plan.added.length === 0) return { ...plan, action: "present" };
|
|
3251
|
+
if (pkg.dependencies !== void 0 && !isPlainObject2(pkg.dependencies)) {
|
|
3252
|
+
return unwritable("dependencies \uAC00 \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4");
|
|
3253
|
+
}
|
|
3254
|
+
try {
|
|
3255
|
+
accessSync2(pkgFile, constants2.W_OK);
|
|
3256
|
+
} catch (err) {
|
|
3257
|
+
return unwritable(`\uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${err.message})`);
|
|
3258
|
+
}
|
|
3259
|
+
const deps = { ...pkg.dependencies ?? {}, ...missing };
|
|
3260
|
+
const after = bom + formatJsonLike(body, { ...pkg, dependencies: deps });
|
|
3261
|
+
return { ...plan, action: "add", write: { file: pkgFile, before: text, after } };
|
|
3262
|
+
}
|
|
3263
|
+
var defaultWriteFile = (file, data) => writeFileSync2(file, data);
|
|
3264
|
+
function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
|
|
3265
|
+
const w = plan.write;
|
|
3266
|
+
if (plan.action !== "add" || !w) return false;
|
|
3267
|
+
const baseDir = path11.resolve(baseDirInput);
|
|
3268
|
+
const current = existsSync4(w.file) ? readFileSync4(w.file, "utf8") : null;
|
|
3269
|
+
if (current !== w.before) {
|
|
3270
|
+
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
3271
|
+
}
|
|
3272
|
+
const where = realPathInside(baseDir, w.file);
|
|
3273
|
+
if (!where.inside) {
|
|
3274
|
+
throw new Error(`${w.file} \uC758 \uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4. \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`);
|
|
3275
|
+
}
|
|
3276
|
+
JSON.parse(w.after.startsWith(BOM) ? w.after.slice(1) : w.after);
|
|
3277
|
+
try {
|
|
3278
|
+
writeFile(w.file, w.after);
|
|
3279
|
+
} catch (err) {
|
|
3280
|
+
const cause = err.message;
|
|
3281
|
+
let restored;
|
|
3282
|
+
try {
|
|
3283
|
+
writeFile(w.file, w.before);
|
|
3284
|
+
if (readFileSync4(w.file, "utf8") !== w.before) throw new Error("\uB418\uB3CC\uB9B0 \uB0B4\uC6A9\uC774 \uC6D0\uB798 \uB0B4\uC6A9\uACFC \uB2E4\uB985\uB2C8\uB2E4");
|
|
3285
|
+
restored = "\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4";
|
|
3286
|
+
} catch (restoreErr) {
|
|
3287
|
+
restored = `\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${restoreErr.message}). \uD30C\uC77C\uC774 \uC798\uB838\uAC70\uB098 \uBE44\uC5C8\uC744 \uC218 \uC788\uC73C\uB2C8 \uBC84\uC804 \uAD00\uB9AC \uB3C4\uAD6C \uB4F1\uC73C\uB85C \uBCF5\uAD6C\uD558\uC138\uC694`;
|
|
3288
|
+
}
|
|
3289
|
+
throw new Error(`${w.file} \uC744 \uC4F0\uB294 \uB3C4\uC911 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4(${cause}). ${restored}.`);
|
|
3290
|
+
}
|
|
3291
|
+
return true;
|
|
3292
|
+
}
|
|
3293
|
+
function reportDependencies(plan, log) {
|
|
3294
|
+
const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
|
|
3295
|
+
const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
|
|
3296
|
+
const logBasis = () => {
|
|
3297
|
+
log(chalk9.gray(basis));
|
|
3298
|
+
for (const w of tailwindWarnings(plan.tailwind, plan.installCommand)) log(chalk9.yellow(` ${w}`));
|
|
3299
|
+
};
|
|
3300
|
+
if (plan.action === "add") {
|
|
3301
|
+
const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
|
|
3302
|
+
log(chalk9.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
|
|
3303
|
+
if (plan.present.length > 0) log(chalk9.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
|
|
3304
|
+
if (plan.added.includes("tailwind-merge")) logBasis();
|
|
3305
|
+
log(chalk9.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`));
|
|
3306
|
+
} else if (plan.action === "present") {
|
|
3307
|
+
log(chalk9.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
|
|
3308
|
+
log(chalk9.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`));
|
|
3309
|
+
} else if (plan.action === "no-package-json") {
|
|
3310
|
+
log(chalk9.yellow("! package.json \uC774 \uC5C6\uC5B4 utils.ts \uC758\uC874\uC131(clsx, tailwind-merge)\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
|
|
3311
|
+
log(chalk9.yellow(` \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
|
|
3312
|
+
logBasis();
|
|
3313
|
+
} else {
|
|
3314
|
+
log(chalk9.yellow(`! package.json \uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${plan.reason}).`));
|
|
3315
|
+
log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
|
|
3316
|
+
if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
3320
|
+
const baseDir = path11.resolve(baseDirInput);
|
|
3019
3321
|
const axisConfig = createInitConfig(
|
|
3020
3322
|
{
|
|
3021
|
-
componentsDir:
|
|
3022
|
-
tailwindConfig:
|
|
3023
|
-
globalCss:
|
|
3323
|
+
componentsDir: answers.componentsDir,
|
|
3324
|
+
tailwindConfig: answers.tailwindConfig,
|
|
3325
|
+
globalCss: answers.globalCss
|
|
3024
3326
|
},
|
|
3025
|
-
|
|
3327
|
+
registryUrl
|
|
3026
3328
|
);
|
|
3027
|
-
await fs10.writeJSON("axis.config.json", axisConfig, { spaces: 2 });
|
|
3028
|
-
|
|
3029
|
-
const utilsPath = path11.
|
|
3329
|
+
await fs10.writeJSON(path11.join(baseDir, "axis.config.json"), axisConfig, { spaces: 2 });
|
|
3330
|
+
log(chalk9.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
|
|
3331
|
+
const utilsPath = path11.resolve(baseDir, answers.componentsDir, "utils.ts");
|
|
3030
3332
|
await fs10.ensureDir(path11.dirname(utilsPath));
|
|
3031
|
-
await fs10.writeFile(
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3333
|
+
await fs10.writeFile(utilsPath, UTILS_TS_CONTENT);
|
|
3334
|
+
log(chalk9.green("\u2713 utils.ts \uC0DD\uC131 \uC644\uB8CC"));
|
|
3335
|
+
const plan = planUtilsDependencies(baseDir);
|
|
3336
|
+
try {
|
|
3337
|
+
applyUtilsDependencies(baseDir, plan);
|
|
3338
|
+
} catch (err) {
|
|
3339
|
+
log(chalk9.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
|
|
3340
|
+
log(chalk9.yellow(" axis.config.json \uACFC utils.ts \uB294 \uC774\uBBF8 \uB9CC\uB4E4\uC5B4\uC84C\uC2B5\uB2C8\uB2E4."));
|
|
3341
|
+
log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
|
|
3342
|
+
process.exitCode = 1;
|
|
3343
|
+
return;
|
|
3344
|
+
}
|
|
3345
|
+
reportDependencies(plan, log);
|
|
3346
|
+
log(chalk9.blue("\n\uCD08\uAE30\uD654 \uC644\uB8CC! \uC774\uC81C \uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD558\uC138\uC694:"));
|
|
3347
|
+
log(chalk9.cyan(` ${INIT_NEXT_STEP_COMMAND}
|
|
3348
|
+
`));
|
|
3349
|
+
}
|
|
3035
3350
|
|
|
3036
|
-
|
|
3037
|
-
|
|
3351
|
+
// src/init/index.ts
|
|
3352
|
+
function registerInitCommand(program2, registryUrl) {
|
|
3353
|
+
program2.command("init").description("\uD504\uB85C\uC81D\uD2B8\uC5D0 AXIS Design System \uCD08\uAE30\uD654").option("-y, --yes", "\uAE30\uBCF8\uAC12\uC73C\uB85C \uC790\uB3D9 \uC124\uC815").action(async (options) => {
|
|
3354
|
+
console.log(chalk10.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
|
|
3355
|
+
const config = options.yes ? { ...INIT_DEFAULTS } : await prompts2([
|
|
3356
|
+
{
|
|
3357
|
+
type: "text",
|
|
3358
|
+
name: "componentsDir",
|
|
3359
|
+
message: "\uCEF4\uD3EC\uB10C\uD2B8 \uB514\uB809\uD1A0\uB9AC:",
|
|
3360
|
+
initial: INIT_DEFAULTS.componentsDir
|
|
3361
|
+
},
|
|
3362
|
+
{
|
|
3363
|
+
type: "text",
|
|
3364
|
+
name: "tailwindConfig",
|
|
3365
|
+
message: "Tailwind \uC124\uC815 \uD30C\uC77C:",
|
|
3366
|
+
initial: INIT_DEFAULTS.tailwindConfig
|
|
3367
|
+
},
|
|
3368
|
+
{
|
|
3369
|
+
type: "text",
|
|
3370
|
+
name: "globalCss",
|
|
3371
|
+
message: "\uAE00\uB85C\uBC8C CSS \uD30C\uC77C:",
|
|
3372
|
+
initial: INIT_DEFAULTS.globalCss
|
|
3373
|
+
}
|
|
3374
|
+
]);
|
|
3375
|
+
await runInit(process.cwd(), config, registryUrl);
|
|
3376
|
+
});
|
|
3038
3377
|
}
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3378
|
+
|
|
3379
|
+
// src/index.ts
|
|
3380
|
+
var { version: CLI_VERSION } = createRequire2(import.meta.url)("../package.json");
|
|
3381
|
+
var REGISTRY_URL = process.env.AXIS_REGISTRY_URL || "https://axis.minu.best/r";
|
|
3382
|
+
var program = new Command();
|
|
3383
|
+
program.name("axis").description("AXIS Design System CLI - shadcn \uD638\uD658 \uCEF4\uD3EC\uB10C\uD2B8 \uC124\uCE58 \uB3C4\uAD6C").version(CLI_VERSION);
|
|
3384
|
+
registerInitCommand(program, REGISTRY_URL);
|
|
3045
3385
|
program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00").option("--agentic", "Agentic UI \uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00").option("-y, --yes", "\uD655\uC778 \uC5C6\uC774 \uB36E\uC5B4\uC4F0\uAE30").action(async (component, options) => {
|
|
3046
3386
|
const spinner = ora6(`${component} \uCEF4\uD3EC\uB10C\uD2B8 \uAC00\uC838\uC624\uB294 \uC911...`).start();
|
|
3047
3387
|
try {
|
|
3048
|
-
const configPath =
|
|
3049
|
-
if (!await
|
|
3388
|
+
const configPath = path12.resolve("axis.config.json");
|
|
3389
|
+
if (!await fs11.pathExists(configPath)) {
|
|
3050
3390
|
spinner.fail(
|
|
3051
3391
|
"axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.\n \uD574\uACB0: \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0\uC11C 'npx @axis-ds/cli init'\uC744 \uC2E4\uD589\uD558\uC138\uC694.\n \uCC38\uACE0: https://axis.minu.best/docs/guides/quick-start"
|
|
3052
3392
|
);
|
|
3053
3393
|
process.exit(1);
|
|
3054
3394
|
}
|
|
3055
|
-
const config = await
|
|
3395
|
+
const config = await fs11.readJSON(configPath);
|
|
3056
3396
|
const category = options.agentic ? "agentic" : "ui";
|
|
3057
3397
|
const componentInfo = await getComponentInfo(component, category);
|
|
3058
3398
|
if (!componentInfo) {
|
|
@@ -3065,10 +3405,10 @@ program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\
|
|
|
3065
3405
|
}
|
|
3066
3406
|
spinner.text = `${component} \uCEF4\uD3EC\uB10C\uD2B8 \uC124\uCE58 \uC911...`;
|
|
3067
3407
|
for (const file of componentInfo.files) {
|
|
3068
|
-
const filePath =
|
|
3069
|
-
if (await
|
|
3408
|
+
const filePath = path12.join(config.componentsDir, file.path);
|
|
3409
|
+
if (await fs11.pathExists(filePath)) {
|
|
3070
3410
|
if (!options.yes) {
|
|
3071
|
-
const { overwrite } = await
|
|
3411
|
+
const { overwrite } = await prompts3({
|
|
3072
3412
|
type: "confirm",
|
|
3073
3413
|
name: "overwrite",
|
|
3074
3414
|
message: `${file.path}\uC774(\uAC00) \uC774\uBBF8 \uC874\uC7AC\uD569\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`,
|
|
@@ -3077,13 +3417,13 @@ program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\
|
|
|
3077
3417
|
if (!overwrite) continue;
|
|
3078
3418
|
}
|
|
3079
3419
|
}
|
|
3080
|
-
await
|
|
3081
|
-
await
|
|
3420
|
+
await fs11.ensureDir(path12.dirname(filePath));
|
|
3421
|
+
await fs11.writeFile(filePath, file.content);
|
|
3082
3422
|
}
|
|
3083
|
-
spinner.succeed(
|
|
3423
|
+
spinner.succeed(chalk11.green(`${component} \uCEF4\uD3EC\uB10C\uD2B8 \uCD94\uAC00 \uC644\uB8CC`));
|
|
3084
3424
|
if (componentInfo.dependencies.length > 0) {
|
|
3085
|
-
console.log(
|
|
3086
|
-
console.log(
|
|
3425
|
+
console.log(chalk11.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
|
|
3426
|
+
console.log(chalk11.cyan(` pnpm add ${componentInfo.dependencies.join(" ")}`));
|
|
3087
3427
|
}
|
|
3088
3428
|
} catch (error) {
|
|
3089
3429
|
spinner.fail(
|
|
@@ -3095,7 +3435,7 @@ program.command("add <component>").description("\uCEF4\uD3EC\uB10C\uD2B8 \uCD94\
|
|
|
3095
3435
|
}
|
|
3096
3436
|
});
|
|
3097
3437
|
program.command("list").description("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("--category <type>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130 (ui, agentic)").action(async (options) => {
|
|
3098
|
-
console.log(
|
|
3438
|
+
console.log(chalk11.blue("\n\u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8\n"));
|
|
3099
3439
|
const components = {
|
|
3100
3440
|
ui: [
|
|
3101
3441
|
{ name: "button", description: "\uAE30\uBCF8 \uBC84\uD2BC \uCEF4\uD3EC\uB10C\uD2B8" },
|
|
@@ -3123,9 +3463,9 @@ program.command("list").description("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCEF4\uD3E
|
|
|
3123
3463
|
]
|
|
3124
3464
|
};
|
|
3125
3465
|
const showCategory = (category, items) => {
|
|
3126
|
-
console.log(
|
|
3466
|
+
console.log(chalk11.bold(category === "ui" ? "Core UI" : "Agentic UI"));
|
|
3127
3467
|
items.forEach((c) => {
|
|
3128
|
-
console.log(` ${
|
|
3468
|
+
console.log(` ${chalk11.cyan(c.name.padEnd(20))} ${chalk11.gray(c.description)}`);
|
|
3129
3469
|
});
|
|
3130
3470
|
console.log();
|
|
3131
3471
|
};
|
|
@@ -3135,8 +3475,8 @@ program.command("list").description("\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uCEF4\uD3E
|
|
|
3135
3475
|
if (!options.category || options.category === "agentic") {
|
|
3136
3476
|
showCategory("agentic", components.agentic);
|
|
3137
3477
|
}
|
|
3138
|
-
console.log(
|
|
3139
|
-
console.log(
|
|
3478
|
+
console.log(chalk11.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <component-name>"));
|
|
3479
|
+
console.log(chalk11.gray("Agentic: npx @axis-ds/cli add <component-name> --agentic\n"));
|
|
3140
3480
|
});
|
|
3141
3481
|
var monetCmd = program.command("monet").description("Monet Design \uCEF4\uD3EC\uB10C\uD2B8 \uAD00\uB9AC (https://monet.design)");
|
|
3142
3482
|
monetCmd.command("list").alias("ls").description("Monet \uCE74\uD14C\uACE0\uB9AC \uBAA9\uB85D").action(async () => {
|
|
@@ -3156,24 +3496,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
|
|
|
3156
3496
|
await client.importFromClipboard();
|
|
3157
3497
|
});
|
|
3158
3498
|
monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
|
|
3159
|
-
console.log(
|
|
3160
|
-
console.log(
|
|
3161
|
-
console.log(
|
|
3162
|
-
console.log(
|
|
3163
|
-
console.log(
|
|
3164
|
-
console.log(
|
|
3165
|
-
console.log(
|
|
3166
|
-
console.log(
|
|
3499
|
+
console.log(chalk11.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
|
|
3500
|
+
console.log(chalk11.bold("1. API \uD0A4 \uBC1C\uAE09:"));
|
|
3501
|
+
console.log(chalk11.cyan(" https://monet.design/mcp\n"));
|
|
3502
|
+
console.log(chalk11.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
|
|
3503
|
+
console.log(chalk11.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
|
|
3504
|
+
console.log(chalk11.cyan(" MONET_API_KEY=your-api-key-here\n"));
|
|
3505
|
+
console.log(chalk11.bold("3. Claude Code MCP \uC124\uC815:"));
|
|
3506
|
+
console.log(chalk11.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
|
|
3167
3507
|
console.log(
|
|
3168
|
-
|
|
3508
|
+
chalk11.cyan(` "monet": {
|
|
3169
3509
|
"url": "https://www.monet.design/api/remote/mcp",
|
|
3170
3510
|
"headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
|
|
3171
3511
|
"disabled": false
|
|
3172
3512
|
}
|
|
3173
3513
|
`)
|
|
3174
3514
|
);
|
|
3175
|
-
console.log(
|
|
3176
|
-
console.log(
|
|
3515
|
+
console.log(chalk11.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
|
|
3516
|
+
console.log(chalk11.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
|
|
3177
3517
|
});
|
|
3178
3518
|
var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
|
|
3179
3519
|
v0Cmd.command("convert <file>").alias("c").description("V0 \uCF54\uB4DC\uB97C AXIS \uC2A4\uD0C0\uC77C\uB85C \uBCC0\uD658").option("-o, --output <path>", "\uCD9C\uB825 \uD30C\uC77C \uACBD\uB85C").action(async (file, options) => {
|
|
@@ -3210,18 +3550,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
|
|
|
3210
3550
|
total += result.collected;
|
|
3211
3551
|
failed += result.failed;
|
|
3212
3552
|
}
|
|
3213
|
-
console.log(
|
|
3553
|
+
console.log(chalk11.blue(`
|
|
3214
3554
|
\u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
|
|
3215
3555
|
if (failed > 0) {
|
|
3216
|
-
console.log(
|
|
3556
|
+
console.log(chalk11.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
|
|
3217
3557
|
}
|
|
3218
3558
|
});
|
|
3219
3559
|
libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("-c, --category <category>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130").option("-s, --source <source>", "\uC18C\uC2A4 \uD544\uD130").action(async (options) => {
|
|
3220
3560
|
const curator = new LibraryCurator();
|
|
3221
3561
|
const index = await curator.loadIndex();
|
|
3222
3562
|
if (!index) {
|
|
3223
|
-
console.log(
|
|
3224
|
-
console.log(
|
|
3563
|
+
console.log(chalk11.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
3564
|
+
console.log(chalk11.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
3225
3565
|
return;
|
|
3226
3566
|
}
|
|
3227
3567
|
let components = index.components;
|
|
@@ -3231,7 +3571,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
3231
3571
|
if (options.source) {
|
|
3232
3572
|
components = components.filter((c) => c.source.type === options.source);
|
|
3233
3573
|
}
|
|
3234
|
-
console.log(
|
|
3574
|
+
console.log(chalk11.blue(`
|
|
3235
3575
|
\u{1F4E6} Library Components (${components.length}\uAC1C)
|
|
3236
3576
|
`));
|
|
3237
3577
|
const byCategory = /* @__PURE__ */ new Map();
|
|
@@ -3243,14 +3583,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
3243
3583
|
byCategory.get(cat).push(comp);
|
|
3244
3584
|
}
|
|
3245
3585
|
for (const [category, items] of byCategory) {
|
|
3246
|
-
console.log(
|
|
3586
|
+
console.log(chalk11.bold(`${category} (${items.length})`));
|
|
3247
3587
|
for (const item of items.slice(0, 10)) {
|
|
3248
3588
|
console.log(
|
|
3249
|
-
` ${
|
|
3589
|
+
` ${chalk11.cyan(item.name.padEnd(25))} ${chalk11.gray(item.source.type.padEnd(8))} ${chalk11.gray(item.description.slice(0, 40))}`
|
|
3250
3590
|
);
|
|
3251
3591
|
}
|
|
3252
3592
|
if (items.length > 10) {
|
|
3253
|
-
console.log(
|
|
3593
|
+
console.log(chalk11.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
|
|
3254
3594
|
}
|
|
3255
3595
|
console.log();
|
|
3256
3596
|
}
|
|
@@ -3262,21 +3602,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
|
|
|
3262
3602
|
source: options.source
|
|
3263
3603
|
});
|
|
3264
3604
|
if (results.length === 0) {
|
|
3265
|
-
console.log(
|
|
3605
|
+
console.log(chalk11.yellow(`
|
|
3266
3606
|
'${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
3267
3607
|
`));
|
|
3268
3608
|
return;
|
|
3269
3609
|
}
|
|
3270
|
-
console.log(
|
|
3610
|
+
console.log(chalk11.blue(`
|
|
3271
3611
|
\u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
|
|
3272
3612
|
`));
|
|
3273
3613
|
for (const comp of results.slice(0, 20)) {
|
|
3274
3614
|
console.log(
|
|
3275
|
-
` ${
|
|
3615
|
+
` ${chalk11.cyan(comp.name.padEnd(25))} ${chalk11.gray(comp.source.type.padEnd(8))} ${chalk11.gray(comp.category.padEnd(12))} ${chalk11.gray(comp.description.slice(0, 30))}`
|
|
3276
3616
|
);
|
|
3277
3617
|
}
|
|
3278
3618
|
if (results.length > 20) {
|
|
3279
|
-
console.log(
|
|
3619
|
+
console.log(chalk11.gray(`
|
|
3280
3620
|
... \uC678 ${results.length - 20}\uAC1C`));
|
|
3281
3621
|
}
|
|
3282
3622
|
console.log();
|
|
@@ -3290,12 +3630,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
3290
3630
|
const publisher2 = new Publisher();
|
|
3291
3631
|
const index = await curator.loadIndex();
|
|
3292
3632
|
if (!index) {
|
|
3293
|
-
console.log(
|
|
3294
|
-
console.log(
|
|
3633
|
+
console.log(chalk11.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
3634
|
+
console.log(chalk11.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
3295
3635
|
return;
|
|
3296
3636
|
}
|
|
3297
|
-
console.log(
|
|
3298
|
-
console.log(
|
|
3637
|
+
console.log(chalk11.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
|
|
3638
|
+
console.log(chalk11.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
|
|
3299
3639
|
`));
|
|
3300
3640
|
if (options.clean) {
|
|
3301
3641
|
await publisher2.clean(options.output);
|
|
@@ -3306,17 +3646,17 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
3306
3646
|
generateSearchIndex: true
|
|
3307
3647
|
});
|
|
3308
3648
|
if (result.success) {
|
|
3309
|
-
console.log(
|
|
3649
|
+
console.log(chalk11.green(`
|
|
3310
3650
|
\u2713 \uBC30\uCE58 \uC644\uB8CC`));
|
|
3311
|
-
console.log(
|
|
3312
|
-
console.log(
|
|
3313
|
-
console.log(
|
|
3314
|
-
console.log(
|
|
3651
|
+
console.log(chalk11.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
|
|
3652
|
+
console.log(chalk11.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
|
|
3653
|
+
console.log(chalk11.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
|
|
3654
|
+
console.log(chalk11.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
|
|
3315
3655
|
} else {
|
|
3316
|
-
console.log(
|
|
3656
|
+
console.log(chalk11.red(`
|
|
3317
3657
|
\u2717 \uBC30\uCE58 \uC2E4\uD328`));
|
|
3318
3658
|
for (const error of result.errors) {
|
|
3319
|
-
console.log(
|
|
3659
|
+
console.log(chalk11.red(` - ${error}`));
|
|
3320
3660
|
}
|
|
3321
3661
|
}
|
|
3322
3662
|
console.log();
|
package/dist/monet.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* Monet (https://monet.design) 컴포넌트를 검색하고 AXIS 프로젝트에 가져옵니다.
|
|
5
5
|
*
|
|
6
6
|
* 사용법:
|
|
7
|
-
* axis-cli monet list # 카테고리 목록
|
|
8
|
-
* axis-cli monet search <query> # 컴포넌트 검색
|
|
9
|
-
* axis-cli monet add <id> # 컴포넌트 추가
|
|
7
|
+
* npx @axis-ds/cli monet list # 카테고리 목록
|
|
8
|
+
* npx @axis-ds/cli monet search <query> # 컴포넌트 검색
|
|
9
|
+
* npx @axis-ds/cli monet add <id> # 컴포넌트 추가
|
|
10
10
|
*/
|
|
11
11
|
declare const MONET_CATEGORIES: readonly [{
|
|
12
12
|
readonly id: "hero";
|
package/dist/monet.js
CHANGED
package/dist/sync/index.js
CHANGED
package/dist/v0.d.ts
CHANGED
|
@@ -4,9 +4,9 @@
|
|
|
4
4
|
* V0 (https://v0.app) 생성 코드를 AXIS 프로젝트에 통합합니다.
|
|
5
5
|
*
|
|
6
6
|
* 사용법:
|
|
7
|
-
* axis-cli v0 convert <file> # V0 코드를 AXIS 스타일로 변환
|
|
8
|
-
* axis-cli v0 import <url> # V0 URL에서 가져오기
|
|
9
|
-
* axis-cli v0 setup # GitHub 연동 안내
|
|
7
|
+
* npx @axis-ds/cli v0 convert <file> # V0 코드를 AXIS 스타일로 변환
|
|
8
|
+
* npx @axis-ds/cli v0 import <url> # V0 URL에서 가져오기
|
|
9
|
+
* npx @axis-ds/cli v0 setup # GitHub 연동 안내
|
|
10
10
|
*/
|
|
11
11
|
declare class V0Client {
|
|
12
12
|
convertCode(code: string, options?: {
|
package/dist/v0.js
CHANGED