@axis-ds/mcp 1.4.3 → 1.4.5
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 +1 -0
- package/dist/index.js +209 -44
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,6 +66,7 @@ Claude Desktop 또는 기타 MCP 호환 클라이언트에서 설정:
|
|
|
66
66
|
|
|
67
67
|
- `targetDir` 를 주지 않으면 서버의 현재 디렉터리를 봅니다.
|
|
68
68
|
- `@axis-ds/tokens` 가 없거나 1.3.0 미만이거나 빌드 산출물이 없으면 오류(`isError`)가 아니라 설치 · 업그레이드 안내를 돌려줍니다. 빈 목록으로 답하지 않습니다.
|
|
69
|
+
- 1.4.5 부터 안내는 CLI `axis theme list` 와 같게 선언 출처를 따릅니다(앱 · pnpm · yarn 루트 선언은 `<pm> install`, npm 루트 선언은 「워크스페이스 루트에서 `npm install`」, Yarn PnP 앱 선언은 판정하지 못했다는 한 줄, 선언이 없으면 종전 추가 명령).
|
|
69
70
|
- 프로젝트에 적용하는 일(import 추가 · `axis.config.json` 의 `brand`)은 CLI `axis theme add <brand>` 가 맡습니다.
|
|
70
71
|
|
|
71
72
|
## 문서
|
package/dist/index.js
CHANGED
|
@@ -970,14 +970,56 @@ function workspaceRootPackage(baseDirInput) {
|
|
|
970
970
|
return void 0;
|
|
971
971
|
}
|
|
972
972
|
}
|
|
973
|
-
function declaredDependency(baseDir, pkg, name, rootPkg) {
|
|
973
|
+
function declaredDependency(baseDir, pkg, name, rootPkg, options = {}) {
|
|
974
974
|
if (pkg === void 0) return void 0;
|
|
975
975
|
const own = hasDependency(pkg, name);
|
|
976
976
|
if (own !== void 0) return { range: own, source: "app" };
|
|
977
|
+
if (options.appOnlyInPnp && isPnpProject(baseDir)) return void 0;
|
|
977
978
|
const root = rootPkg === void 0 ? workspaceRootPackage(baseDir) : rootPkg ?? void 0;
|
|
978
979
|
const fromRoot = root !== void 0 ? hasDependency(root, name) : void 0;
|
|
979
980
|
return fromRoot !== void 0 ? { range: fromRoot, source: "root" } : void 0;
|
|
980
981
|
}
|
|
982
|
+
function pnpRootOnlyDependency(baseDir, pkg, name, rootPkg) {
|
|
983
|
+
if (pkg === void 0 || hasDependency(pkg, name) !== void 0 || !isPnpProject(baseDir)) return void 0;
|
|
984
|
+
const found = declaredDependency(baseDir, pkg, name, rootPkg);
|
|
985
|
+
return found?.source === "root" ? found : void 0;
|
|
986
|
+
}
|
|
987
|
+
var PNP_ROOT_ONLY_NOTE = "\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uB9CC \uC120\uC5B8\uB3FC Plug'n'Play \uC5D0\uC11C \uC571\uC774 \uD574\uC11D\uD558\uC9C0 \uBABB\uD569\uB2C8\uB2E4";
|
|
988
|
+
var APP_LOCKFILES = ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"];
|
|
989
|
+
function hasAppLockfile(baseDirInput) {
|
|
990
|
+
const baseDir = path3.resolve(baseDirInput);
|
|
991
|
+
return APP_LOCKFILES.some((f) => existsSync2(path3.join(baseDir, f)));
|
|
992
|
+
}
|
|
993
|
+
function rootDeclarationsAllowed(baseDir, pkg) {
|
|
994
|
+
return pkg !== void 0 && !isPnpProject(baseDir) && !hasAppLockfile(baseDir);
|
|
995
|
+
}
|
|
996
|
+
function readPackageJsonAt(dir) {
|
|
997
|
+
try {
|
|
998
|
+
const parsed = JSON.parse(readFileSync3(path3.join(dir, "package.json"), "utf8"));
|
|
999
|
+
return isPlainObject(parsed) ? parsed : void 0;
|
|
1000
|
+
} catch {
|
|
1001
|
+
return void 0;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function dependencyInstallGuide(baseDirInput, name, range) {
|
|
1005
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1006
|
+
const installCommand = detectInstallCommand(baseDir);
|
|
1007
|
+
const base = { installCommand, addCommand: addCommandFor(installCommand, { [name]: range }) };
|
|
1008
|
+
const pkg = readPackageJsonAt(baseDir);
|
|
1009
|
+
if (pkg === void 0) return { kind: "add", ...base };
|
|
1010
|
+
const own = hasDependency(pkg, name);
|
|
1011
|
+
if (isPnpProject(baseDir)) return own !== void 0 ? { kind: "pnp", source: "app", range: own, ...base } : { kind: "add", ...base };
|
|
1012
|
+
if (own !== void 0) return { kind: "install", source: "app", range: own, ...base };
|
|
1013
|
+
if (!rootDeclarationsAllowed(baseDir, pkg)) return { kind: "add", ...base };
|
|
1014
|
+
const declared = declaredDependency(baseDir, pkg, name);
|
|
1015
|
+
if (declared?.source !== "root") return { kind: "add", ...base };
|
|
1016
|
+
return {
|
|
1017
|
+
kind: packageManagerOf(installCommand) === "npm" ? "install-at-root" : "install",
|
|
1018
|
+
source: "root",
|
|
1019
|
+
range: declared.range,
|
|
1020
|
+
...base
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
981
1023
|
function isPlainObject(value) {
|
|
982
1024
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
983
1025
|
}
|
|
@@ -1066,6 +1108,7 @@ function isPnpProject(baseDirInput) {
|
|
|
1066
1108
|
let dir = resolveBaseDir(baseDirInput);
|
|
1067
1109
|
for (; ; ) {
|
|
1068
1110
|
if (isFile(path3.join(dir, ".pnp.cjs")) || isFile(path3.join(dir, ".pnp.js"))) return true;
|
|
1111
|
+
if (existsSync2(path3.join(dir, ".git"))) return false;
|
|
1069
1112
|
const parent = path3.dirname(dir);
|
|
1070
1113
|
if (parent === dir) return false;
|
|
1071
1114
|
dir = parent;
|
|
@@ -1089,6 +1132,9 @@ import { basename, dirname as dirname2, extname, isAbsolute, join as join2, rela
|
|
|
1089
1132
|
function declaredRange(baseDir, pkg, name) {
|
|
1090
1133
|
return declaredDependency(baseDir, pkg, name)?.range;
|
|
1091
1134
|
}
|
|
1135
|
+
function declaredRangeForCheck(baseDir, pkg, name) {
|
|
1136
|
+
return declaredDependency(baseDir, pkg, name, void 0, { appOnlyInPnp: true })?.range;
|
|
1137
|
+
}
|
|
1092
1138
|
function isPlainObject2(value) {
|
|
1093
1139
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1094
1140
|
}
|
|
@@ -1463,7 +1509,7 @@ function hasBareCjsPresetRequire(code) {
|
|
|
1463
1509
|
function isCommonJsConfig(file, source) {
|
|
1464
1510
|
return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
|
|
1465
1511
|
}
|
|
1466
|
-
function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
1512
|
+
function packageVersionGate(baseDirInput, pkg, name, min, options = {}) {
|
|
1467
1513
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1468
1514
|
if (!isPnpProject(baseDir)) {
|
|
1469
1515
|
const installed = findInstalledPackage(baseDir, name)?.version;
|
|
@@ -1472,7 +1518,11 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
1472
1518
|
if (cmp !== void 0) return { status: cmp >= 0 ? "ok" : "below", source: "installed", value: installed };
|
|
1473
1519
|
}
|
|
1474
1520
|
}
|
|
1475
|
-
const declared = pkg ?
|
|
1521
|
+
const declared = pkg ? declaredDependency(baseDir, pkg, name, void 0, options)?.range : void 0;
|
|
1522
|
+
if (declared === void 0 && options.appOnlyInPnp) {
|
|
1523
|
+
const rootOnly = pnpRootOnlyDependency(baseDir, pkg, name);
|
|
1524
|
+
if (rootOnly !== void 0) return { status: "unresolved", source: "declared", value: rootOnly.range };
|
|
1525
|
+
}
|
|
1476
1526
|
if (declared !== void 0) {
|
|
1477
1527
|
const atLeast = rangeLowerAtLeast(declared, min);
|
|
1478
1528
|
if (atLeast !== void 0) return { status: atLeast ? "ok" : "below", source: "declared", value: declared };
|
|
@@ -1481,6 +1531,7 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
1481
1531
|
return { status: "unknown", source: "none" };
|
|
1482
1532
|
}
|
|
1483
1533
|
function versionGateLabel(gate) {
|
|
1534
|
+
if (gate.status === "unresolved") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uC120\uC5B8 ${gate.value}`;
|
|
1484
1535
|
if (gate.source === "installed") return `\uC124\uCE58\uBCF8 ${gate.value}`;
|
|
1485
1536
|
if (gate.source === "declared") return `\uC120\uC5B8 ${gate.value}`;
|
|
1486
1537
|
return "\uC124\uCE58\uBCF8 \xB7 \uC120\uC5B8 \uC5C6\uC74C";
|
|
@@ -1562,7 +1613,14 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
1562
1613
|
if (hasTokensPresetReference(content)) {
|
|
1563
1614
|
const code = stripJsComments(content);
|
|
1564
1615
|
if (isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code)) {
|
|
1565
|
-
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION);
|
|
1616
|
+
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION, { appOnlyInPnp: true });
|
|
1617
|
+
if (gate.status === "unresolved") {
|
|
1618
|
+
return {
|
|
1619
|
+
name: "tailwind.config",
|
|
1620
|
+
severity: "warn",
|
|
1621
|
+
message: `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC @axis-ds/tokens \uAC00 ${PNP_ROOT_ONLY_NOTE}(${versionGateLabel(gate)}) \u2192 \uC571 package.json \uC5D0 @axis-ds/tokens ${TOKENS_CJS_PRESET_FIXED_VERSION} \uC774\uC0C1\uC744 \uC120\uC5B8\uD558\uC138\uC694`
|
|
1622
|
+
};
|
|
1623
|
+
}
|
|
1566
1624
|
if (gate.status !== "ok") {
|
|
1567
1625
|
const why = gate.status === "below" ? `@axis-ds/tokens ${versionGateLabel(gate)} \uC5D0\uC11C\uB294 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uAC00 preset \uC774 \uC544\uB2C8\uB77C { default } \uB97C \uB3CC\uB824\uC918 \uC0C9 \xB7 keyframes \uAC00 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` : `@axis-ds/tokens \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${versionGateLabel(gate)}). ${TOKENS_CJS_PRESET_FIXED_VERSION} \uBBF8\uB9CC\uC774\uBA74 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uB85C\uB294 preset \uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
1568
1626
|
return {
|
|
@@ -1700,13 +1758,61 @@ function contentGlobCovers(glob, sample, baseDirInput) {
|
|
|
1700
1758
|
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir));
|
|
1701
1759
|
}
|
|
1702
1760
|
var CONTENT_PARENT_PATH_NOTE = "\uC0C1\uC704 \uACBD\uB85C\uB294 Tailwind 3 \uAC00 \uBE4C\uB4DC\uB97C \uC2E4\uD589\uD55C \uB514\uB809\uD130\uB9AC \uAE30\uC900\uC73C\uB85C \uD480\uB824\uC694. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8 \uB4F1 \uC571 \uB514\uB809\uD130\uB9AC \uBC16\uC5D0\uC11C \uBE4C\uB4DC\uD558\uBA74 content: { relative: true, files: [...] } \uB85C \uC124\uC815 \uD30C\uC77C \uAE30\uC900\uC73C\uB85C \uBC14\uAFB8\uC138\uC694";
|
|
1761
|
+
function relDirOf(baseDir, dir) {
|
|
1762
|
+
const rel2 = relative(baseDir, dir);
|
|
1763
|
+
return rel2 === "" || isAbsolute(rel2) ? void 0 : rel2.split(sep).join("/");
|
|
1764
|
+
}
|
|
1765
|
+
function realDir(dir) {
|
|
1766
|
+
try {
|
|
1767
|
+
return realpathSync2(dir);
|
|
1768
|
+
} catch {
|
|
1769
|
+
return void 0;
|
|
1770
|
+
}
|
|
1771
|
+
}
|
|
1772
|
+
function packageVersion(dir) {
|
|
1773
|
+
try {
|
|
1774
|
+
const parsed = JSON.parse(readFileSync4(join2(dir, "package.json"), "utf8"));
|
|
1775
|
+
return isPlainObject2(parsed) && typeof parsed.version === "string" ? parsed.version : void 0;
|
|
1776
|
+
} catch {
|
|
1777
|
+
return void 0;
|
|
1778
|
+
}
|
|
1779
|
+
}
|
|
1703
1780
|
function packageContentTarget(baseDir, name) {
|
|
1704
1781
|
const found = isPnpProject(baseDir) ? void 0 : findInstalledPackage(baseDir, name);
|
|
1705
|
-
const
|
|
1706
|
-
const
|
|
1782
|
+
const relDir = (found === void 0 ? void 0 : relDirOf(baseDir, found.dir)) ?? `node_modules/${name}`;
|
|
1783
|
+
const alternates = [];
|
|
1784
|
+
const others = [];
|
|
1785
|
+
const real = found === void 0 ? void 0 : realDir(found.dir);
|
|
1786
|
+
if (found !== void 0 && real !== void 0) {
|
|
1787
|
+
const relReal = relDirOf(baseDir, real);
|
|
1788
|
+
if (relReal !== void 0 && relReal !== relDir) alternates.push(`${relReal}/dist/index.js`);
|
|
1789
|
+
let dir = dirname2(resolve(found.dir, ...name.split("/").map(() => ".."), ".."));
|
|
1790
|
+
for (; ; ) {
|
|
1791
|
+
const candidate = join2(dir, "node_modules", ...name.split("/"));
|
|
1792
|
+
const rel2 = existsSync3(join2(candidate, "package.json")) ? relDirOf(baseDir, candidate) : void 0;
|
|
1793
|
+
if (rel2 !== void 0) {
|
|
1794
|
+
const candidateReal = realDir(candidate);
|
|
1795
|
+
if (candidateReal === real) alternates.push(`${rel2}/dist/index.js`);
|
|
1796
|
+
else {
|
|
1797
|
+
const theirs = packageVersion(candidate);
|
|
1798
|
+
const ours = found.version ?? packageVersion(found.dir);
|
|
1799
|
+
const versions = theirs === void 0 || ours === void 0 ? "" : theirs === ours ? `(\uBC84\uC804\uC740 ${ours} \uB85C \uAC19\uC74C)` : `(${theirs}, \uC571 ${ours})`;
|
|
1800
|
+
others.push({
|
|
1801
|
+
sample: `${rel2}/dist/index.js`,
|
|
1802
|
+
note: `\uC0C1\uC704 \uACBD\uB85C ${rel2} \uB294 \uC571\uC774 \uC4F0\uB294 \uC124\uCE58\uBCF8\uACFC \uB2E4\uB978 \uC124\uCE58\uBCF8${versions}\uC774\uB77C \uB36E\uC74C\uC73C\uB85C \uBCF4\uC9C0 \uC54A\uC544\uC694`
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
const parent = dirname2(dir);
|
|
1807
|
+
if (parent === dir) break;
|
|
1808
|
+
dir = parent;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1707
1811
|
return {
|
|
1708
1812
|
sample: `${relDir}/dist/index.js`,
|
|
1709
|
-
suggest: `${relDir.startsWith("../") ? "" : "./"}${relDir}/dist/**/*.{js,mjs}
|
|
1813
|
+
suggest: `${relDir.startsWith("../") ? "" : "./"}${relDir}/dist/**/*.{js,mjs}`,
|
|
1814
|
+
alternates,
|
|
1815
|
+
others
|
|
1710
1816
|
};
|
|
1711
1817
|
}
|
|
1712
1818
|
function balancedSlice(src, start) {
|
|
@@ -1780,7 +1886,12 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
1780
1886
|
configFile,
|
|
1781
1887
|
unreadable: read === void 0,
|
|
1782
1888
|
dynamic: read?.dynamic ?? false,
|
|
1783
|
-
targets: targets.map((
|
|
1889
|
+
targets: targets.map(({ alternates = [], others = [], ...t }) => {
|
|
1890
|
+
const covers = (sample) => globs.some((g) => contentGlobCovers(g, sample, baseDir));
|
|
1891
|
+
const covered = [t.sample, ...alternates].some(covers);
|
|
1892
|
+
const note = covered ? void 0 : others.find((o) => covers(o.sample))?.note;
|
|
1893
|
+
return note === void 0 ? { ...t, covered } : { ...t, covered, note };
|
|
1894
|
+
})
|
|
1784
1895
|
};
|
|
1785
1896
|
}
|
|
1786
1897
|
function checkTailwindContent(baseDir) {
|
|
@@ -1794,7 +1905,7 @@ function checkTailwindContent(baseDir) {
|
|
|
1794
1905
|
message: `${r.configFile}\uC758 content \uAC00 ${r.targets.map((t) => t.label).join(" \xB7 ")} \uB97C \uB36E\uC2B5\uB2C8\uB2E4`
|
|
1795
1906
|
};
|
|
1796
1907
|
}
|
|
1797
|
-
const list = missing.map((t) => `${t.label} \u2192 "${t.suggest}"`).join(" \xB7 ");
|
|
1908
|
+
const list = missing.map((t) => `${t.label} \u2192 "${t.suggest}"${t.note === void 0 ? "" : ` (${t.note})`}`).join(" \xB7 ");
|
|
1798
1909
|
const note = missing.some((t) => t.suggest.startsWith("../")) ? ` (${CONTENT_PARENT_PATH_NOTE})` : "";
|
|
1799
1910
|
if (r.unreadable || r.dynamic) {
|
|
1800
1911
|
return {
|
|
@@ -1855,30 +1966,56 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
1855
1966
|
if (!declared && !copied) return null;
|
|
1856
1967
|
const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
|
|
1857
1968
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
1969
|
+
const pnp = isPnpProject(baseDir);
|
|
1970
|
+
const pluginProblem = (name) => {
|
|
1971
|
+
if (declaredRangeForCheck(baseDir, pkg, name) === void 0) {
|
|
1972
|
+
return pnpRootOnlyDependency(baseDir, pkg, name) !== void 0 ? `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE}` : `${name} \uC120\uC5B8 \uC5C6\uC74C`;
|
|
1973
|
+
}
|
|
1974
|
+
if (!pnp && findInstalledPackage(baseDir, name) === void 0) return `${name} \uBBF8\uC124\uCE58(\uC120\uC5B8\uB9CC \uC788\uC74C)`;
|
|
1975
|
+
return void 0;
|
|
1976
|
+
};
|
|
1858
1977
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
1859
1978
|
const file = TAILWIND_CSS_CANDIDATES.find((c) => existsSync3(join2(baseDir, c)));
|
|
1860
1979
|
const css = file !== void 0 ? stripCssComments(readFileSync4(join2(baseDir, file), "utf8")) : "";
|
|
1861
|
-
const
|
|
1862
|
-
|
|
1980
|
+
const lines = [];
|
|
1981
|
+
if (new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`).test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND4);
|
|
1982
|
+
if (new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`).test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND3);
|
|
1983
|
+
if (lines.length === 0) {
|
|
1984
|
+
return {
|
|
1985
|
+
name: "animation",
|
|
1986
|
+
severity: "warn",
|
|
1987
|
+
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND4} \uC124\uCE58 \uB4A4 @import "${ANIMATION_PLUGIN_TAILWIND4}";`
|
|
1988
|
+
};
|
|
1989
|
+
}
|
|
1990
|
+
const problems = lines.map((name) => ({ name, why: pluginProblem(name) })).filter((x) => x.why !== void 0);
|
|
1991
|
+
if (problems.length === 0) return { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
1992
|
+
return {
|
|
1863
1993
|
name: "animation",
|
|
1864
1994
|
severity: "warn",
|
|
1865
|
-
message:
|
|
1995
|
+
message: `${file}\uC758 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC744 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${by}, ${problems.map((x) => x.why).join(" \xB7 ")}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uACE0 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2192 ${problems.map((x) => x.name).join(" \xB7 ")} \uB97C package.json \uC5D0 \uC120\uC5B8 \xB7 \uC124\uCE58\uD558\uC138\uC694`
|
|
1866
1996
|
};
|
|
1867
1997
|
}
|
|
1868
1998
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync3(join2(baseDir, f)));
|
|
1869
1999
|
const source = configFile !== void 0 ? stripJsComments(readFileSync4(join2(baseDir, configFile), "utf8")) : "";
|
|
1870
2000
|
const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
|
|
1871
|
-
const
|
|
1872
|
-
|
|
1873
|
-
if (plugins === "found" && pluginDeclared && pluginInstalled) {
|
|
2001
|
+
const pluginReason = pluginProblem(ANIMATION_PLUGIN_TAILWIND3);
|
|
2002
|
+
if (plugins === "found" && pluginReason === void 0) {
|
|
1874
2003
|
return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
1875
2004
|
}
|
|
1876
2005
|
const cfg = configFile ?? "tailwind.config";
|
|
2006
|
+
const configReason = plugins === "dynamic" ? `${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568` : plugins !== "found" ? `${cfg} plugins \uC5D0 \uC5C6\uC74C` : void 0;
|
|
2007
|
+
if (pluginReason !== void 0 && pnpRootOnlyDependency(baseDir, pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0) {
|
|
2008
|
+
const extra = configReason !== void 0 ? `, ${configReason}` : "";
|
|
2009
|
+
const plug = configReason !== void 0 ? ` \xB7 plugins \uC5D0 require("${ANIMATION_PLUGIN_TAILWIND3}")` : "";
|
|
2010
|
+
return {
|
|
2011
|
+
name: "animation",
|
|
2012
|
+
severity: "warn",
|
|
2013
|
+
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 ${PNP_ROOT_ONLY_NOTE}(${by}${extra}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC571 package.json \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uB97C \uC120\uC5B8\uD558\uC138\uC694${plug}`
|
|
2014
|
+
};
|
|
2015
|
+
}
|
|
1877
2016
|
const reasons = [];
|
|
1878
|
-
if (
|
|
1879
|
-
|
|
1880
|
-
if (plugins === "dynamic") reasons.push(`${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568`);
|
|
1881
|
-
else if (plugins !== "found") reasons.push(`${cfg} plugins \uC5D0 \uC5C6\uC74C`);
|
|
2017
|
+
if (pluginReason !== void 0) reasons.push(pluginReason);
|
|
2018
|
+
if (configReason !== void 0) reasons.push(configReason);
|
|
1882
2019
|
return {
|
|
1883
2020
|
name: "animation",
|
|
1884
2021
|
severity: "warn",
|
|
@@ -4871,7 +5008,11 @@ function inspectBrandActivation(baseDir) {
|
|
|
4871
5008
|
if (typeof brand !== "string" || brand.trim() === "") return null;
|
|
4872
5009
|
const location = findBrandActivation(baseDir);
|
|
4873
5010
|
if (!location.markupWithProvider) return { brand, ...location };
|
|
4874
|
-
return {
|
|
5011
|
+
return {
|
|
5012
|
+
brand,
|
|
5013
|
+
...location,
|
|
5014
|
+
theme: packageVersionGate(baseDir, readProjectPackageJson(baseDir), THEME_PACKAGE, THEME_MARKUP_BRAND_MIN_VERSION, { appOnlyInPnp: true })
|
|
5015
|
+
};
|
|
4875
5016
|
}
|
|
4876
5017
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
4877
5018
|
function readProjectPackageJson(baseDir) {
|
|
@@ -4944,25 +5085,43 @@ function checkDependencies(baseDirInput) {
|
|
|
4944
5085
|
return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
|
|
4945
5086
|
}
|
|
4946
5087
|
const rootPkg = workspaceRootPackage(baseDir) ?? null;
|
|
4947
|
-
const
|
|
5088
|
+
const pnp = isPnpProject(baseDir);
|
|
5089
|
+
const declared = (d) => declaredDependency(baseDir, pkg, d, rootPkg, { appOnlyInPnp: true });
|
|
5090
|
+
const pnpRootOnly = (d) => pnpRootOnlyDependency(baseDir, pkg, d, rootPkg) !== void 0;
|
|
4948
5091
|
const fromRoot = (d) => declared(d)?.source === "root";
|
|
4949
|
-
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0);
|
|
4950
|
-
|
|
4951
|
-
|
|
4952
|
-
|
|
4953
|
-
|
|
4954
|
-
|
|
5092
|
+
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0 && !pnpRootOnly(d));
|
|
5093
|
+
const pnpRootRequired = REQUIRED_DEPENDENCIES.filter((d) => pnpRootOnly(d));
|
|
5094
|
+
if (missingRequired.length > 0 || pnpRootRequired.length > 0) {
|
|
5095
|
+
const fails = [];
|
|
5096
|
+
if (missingRequired.length > 0) fails.push(`\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}`);
|
|
5097
|
+
if (pnpRootRequired.length > 0) fails.push(`\uD544\uC218 \uC758\uC874\uC131 ${pnpRootRequired.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
5098
|
+
return { name: "dependencies", severity: "fail", message: fails.join(" / ") };
|
|
5099
|
+
}
|
|
5100
|
+
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => declared(d) === void 0 && !pnpRootOnly(d));
|
|
5101
|
+
const pnpRootRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => pnpRootOnly(d));
|
|
5102
|
+
const appAxis = declaredAxisPackages(pkg);
|
|
5103
|
+
const rootOnlyAxis = rootPkg !== null ? declaredAxisPackages(rootPkg).filter((d) => !appAxis.includes(d)) : [];
|
|
5104
|
+
const rootAxis = pnp ? [] : rootOnlyAxis;
|
|
5105
|
+
const pnpRootAxis = pnp ? rootOnlyAxis : [];
|
|
5106
|
+
const rootDeclared = [...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => fromRoot(d)), ...rootAxis];
|
|
4955
5107
|
const rootNote = rootDeclared.length > 0 ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootDeclared.join(", ")}` : void 0;
|
|
4956
5108
|
const targets = [
|
|
4957
5109
|
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => declared(d) !== void 0),
|
|
4958
|
-
...
|
|
5110
|
+
...appAxis,
|
|
5111
|
+
...rootAxis
|
|
4959
5112
|
];
|
|
4960
|
-
const pnp = isPnpProject(baseDir);
|
|
4961
5113
|
const notInstalled = pnp ? [] : targets.filter((d) => findInstalledPackage(baseDir, d) === void 0);
|
|
5114
|
+
const notInstalledRoot = notInstalled.filter((d) => rootAxis.includes(d));
|
|
5115
|
+
const notInstalledOther = notInstalled.filter((d) => !rootAxis.includes(d));
|
|
4962
5116
|
const problems = [];
|
|
4963
5117
|
if (missingRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 \uB204\uB77D: ${missingRecommended.join(", ")}`);
|
|
4964
|
-
if (
|
|
4965
|
-
|
|
5118
|
+
if (pnpRootRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 ${pnpRootRecommended.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
5119
|
+
if (pnpRootAxis.length > 0) problems.push(`${pnpRootAxis.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
5120
|
+
if (notInstalledOther.length > 0) {
|
|
5121
|
+
problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalledOther.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
5122
|
+
}
|
|
5123
|
+
if (notInstalledRoot.length > 0) {
|
|
5124
|
+
problems.push(`\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: ${notInstalledRoot.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
4966
5125
|
}
|
|
4967
5126
|
if (problems.length > 0) {
|
|
4968
5127
|
return { name: "dependencies", severity: "warn", message: problems.join(" / ") + (rootNote ? ` (${rootNote})` : "") };
|
|
@@ -5132,6 +5291,13 @@ function brandCheckResult(check) {
|
|
|
5132
5291
|
}
|
|
5133
5292
|
}
|
|
5134
5293
|
function brandActivationResult(check) {
|
|
5294
|
+
if (check.found && check.theme?.status === "unresolved") {
|
|
5295
|
+
return {
|
|
5296
|
+
name: "brand.activation",
|
|
5297
|
+
severity: "warn",
|
|
5298
|
+
message: `${check.found}\uC758 <html data-brand> \uB97C ThemeProvider \uC640 \uD568\uAED8 \uC4F0\uB294\uB370 @axis-ds/theme \uAC00 ${PNP_ROOT_ONLY_NOTE}(${versionGateLabel(check.theme)}) \u2192 \uC571 package.json \uC5D0 @axis-ds/theme ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1\uC744 \uC120\uC5B8\uD558\uAC70\uB098 setBrand("${check.brand}")`
|
|
5299
|
+
};
|
|
5300
|
+
}
|
|
5135
5301
|
if (check.found && check.theme && check.theme.status !== "ok") {
|
|
5136
5302
|
const label = versionGateLabel(check.theme);
|
|
5137
5303
|
const why = check.theme.status === "below" ? `@axis-ds/theme ${label} \uC758 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4` : `@axis-ds/theme \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${label}). ${THEME_MARKUP_BRAND_MIN_VERSION} \uBBF8\uB9CC\uC774\uBA74 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4`;
|
|
@@ -5325,10 +5491,8 @@ var TOKENS_INSTALL_COMMAND = addCommandFor("pnpm install", { [TOKENS_PACKAGE]: `
|
|
|
5325
5491
|
function baseDirOf(targetDir) {
|
|
5326
5492
|
return path10.resolve(targetDir || process.cwd());
|
|
5327
5493
|
}
|
|
5328
|
-
function
|
|
5329
|
-
return
|
|
5330
|
-
[TOKENS_PACKAGE]: `^${TOKENS_DEPENDENCY_MIN_VERSION}`
|
|
5331
|
-
});
|
|
5494
|
+
function tokensInstallGuideFor(targetDir) {
|
|
5495
|
+
return dependencyInstallGuide(baseDirOf(targetDir), TOKENS_PACKAGE, `^${TOKENS_DEPENDENCY_MIN_VERSION}`);
|
|
5332
5496
|
}
|
|
5333
5497
|
async function handleListBrands(params) {
|
|
5334
5498
|
return listBrands(baseDirOf(params.targetDir));
|
|
@@ -5341,24 +5505,25 @@ async function handleGetBrand(params) {
|
|
|
5341
5505
|
return getBrand(baseDirOf(params.targetDir), name);
|
|
5342
5506
|
}
|
|
5343
5507
|
function formatTokensStatusGuide(status, version, installCommand = TOKENS_INSTALL_COMMAND) {
|
|
5508
|
+
const g = typeof installCommand === "string" ? { kind: "add", installCommand, addCommand: installCommand } : installCommand;
|
|
5509
|
+
if (g.kind === "pnp") {
|
|
5510
|
+
return `${TOKENS_PACKAGE}${g.range ? ` ${g.range}` : ""} \uAC00 package.json \uC5D0 \uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC Plug'n'Play \uC124\uCE58\uB77C \uC124\uCE58\uBCF8\uC744 \uD310\uC815\uD558\uC9C0 \uBABB\uD574 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`;
|
|
5511
|
+
}
|
|
5512
|
+
const install = g.kind === "install-at-root" ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C \`${g.installCommand}\`` : `\`${g.kind === "install" ? g.installCommand : g.addCommand}\``;
|
|
5344
5513
|
switch (status) {
|
|
5345
5514
|
case "not-installed":
|
|
5346
|
-
return [
|
|
5347
|
-
`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`,
|
|
5348
|
-
"",
|
|
5349
|
-
`- \uC124\uCE58: \`${installCommand}\``
|
|
5350
|
-
].join("\n");
|
|
5515
|
+
return [`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`, "", `- \uC124\uCE58: ${install}`].join("\n");
|
|
5351
5516
|
case "unsupported":
|
|
5352
5517
|
return [
|
|
5353
5518
|
`${TOKENS_PACKAGE} ${version ?? "(\uBC84\uC804 \uBAA8\uB984)"} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`,
|
|
5354
5519
|
"",
|
|
5355
|
-
`- \uC5C5\uADF8\uB808\uC774\uB4DC: \`${
|
|
5520
|
+
g.source === "root" ? `- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 package.json \uC758 ${TOKENS_PACKAGE} \uC120\uC5B8\uC744 ^${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9AC\uACE0 \uC124\uCE58\uD558\uC138\uC694.` : `- \uC5C5\uADF8\uB808\uC774\uB4DC: \`${g.addCommand}\``
|
|
5356
5521
|
].join("\n");
|
|
5357
5522
|
case "not-built":
|
|
5358
5523
|
return [
|
|
5359
5524
|
`${TOKENS_PACKAGE}${version ? ` ${version}` : ""} \uB294 \uC788\uC9C0\uB9CC \uBE4C\uB4DC \uC0B0\uCD9C\uBB3C\uC774 \uC5C6\uC5B4 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`,
|
|
5360
5525
|
"",
|
|
5361
|
-
`- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 \`${workspaceRunCommand(installCommand, TOKENS_PACKAGE, "build")}\`, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58:
|
|
5526
|
+
`- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 \`${workspaceRunCommand(g.installCommand, TOKENS_PACKAGE, "build")}\`, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${install}`
|
|
5362
5527
|
].join("\n");
|
|
5363
5528
|
}
|
|
5364
5529
|
}
|
|
@@ -6016,7 +6181,7 @@ server.tool(
|
|
|
6016
6181
|
async ({ targetDir }) => {
|
|
6017
6182
|
try {
|
|
6018
6183
|
const result = await handleListBrands({ targetDir });
|
|
6019
|
-
const formatted = formatListBrandsResult(result,
|
|
6184
|
+
const formatted = formatListBrandsResult(result, tokensInstallGuideFor(targetDir));
|
|
6020
6185
|
return {
|
|
6021
6186
|
content: [
|
|
6022
6187
|
{
|
|
@@ -6049,7 +6214,7 @@ server.tool(
|
|
|
6049
6214
|
async ({ name, targetDir }) => {
|
|
6050
6215
|
try {
|
|
6051
6216
|
const result = await handleGetBrand({ name, targetDir });
|
|
6052
|
-
const formatted = formatGetBrandResult(result, name,
|
|
6217
|
+
const formatted = formatGetBrandResult(result, name, tokensInstallGuideFor(targetDir));
|
|
6053
6218
|
return {
|
|
6054
6219
|
content: [
|
|
6055
6220
|
{
|