@axis-ds/cli 1.7.0 → 1.7.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/README.md +1 -1
- package/dist/index.js +176 -36
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -107,7 +107,7 @@ axis theme add ontology
|
|
|
107
107
|
- dependencies 항목(1.6.1 부터): `tailwindcss` 선언이 없으면 FAIL, `clsx` · `tailwind-merge` 선언이 없으면 WARN(종전과 같음). 여기에 선언된 `tailwindcss` · `clsx` · `tailwind-merge` · `@axis-ds/*` 가 `node_modules` 에 없으면 「선언됐지만 설치되지 않은 의존성」 WARN 과 lockfile 에 맞는 설치 명령을 냅니다. 상위 디렉터리의 `node_modules`(모노레포 호이스팅)도 찾고, Plug'n'Play(`.pnp.cjs`)는 설치본을 읽지 않고 선언 기준입니다. 1.6.0 까지는 선언만 보고 「모두 설치되어 있습니다」였습니다.
|
|
108
108
|
- 해당할 때만 더하는 항목(1.6.0 부터, brand 항목 뒤 이 순서):
|
|
109
109
|
- `brand.activation`: `brand` 가 있을 때 루트 레이아웃(`app/layout.tsx` · `src/app/layout.tsx` · `pages/_app` 등, 그 레이아웃이 import 하는 같은 디렉터리의 `./providers` 한 단계 포함)에 `data-brand` · `setBrand(` · `defaultBrand=` 가 없으면 WARN 입니다(휴리스틱, `ThemeProvider` 단독은 켜는 코드가 아님). 1.6.1 부터 마크업 `data-brand` 와 `ThemeProvider` 만 있고 `setBrand(` · `defaultBrand=` 가 없으면 설치본(없으면 선언) `@axis-ds/theme` 가 1.7.0 미만이거나 판정할 수 없을 때 WARN 입니다(1.6.2 이하는 마운트 때 속성을 지움).
|
|
110
|
-
- `tailwind.content`: Tailwind 3 설정 파일이 있고 `componentsDir` 나 선언된 `@axis-ds/ui-react` · `@axis-ds/agentic-ui` 가 있을 때, `content` 의 문자열 glob 이 그 경로를 덮지 않으면 FAIL 입니다(그 경로의 클래스가 생성되지 않음). `content` 를 정적으로 다 읽지 못하면(변수 · 펼침) WARN 입니다.
|
|
110
|
+
- `tailwind.content`: Tailwind 3 설정 파일이 있고 `componentsDir` 나 선언된 `@axis-ds/ui-react` · `@axis-ds/agentic-ui` 가 있을 때, `content` 의 문자열 glob 이 그 경로를 덮지 않으면 FAIL 입니다(그 경로의 클래스가 생성되지 않음). `content` 를 정적으로 다 읽지 못하면(변수 · 펼침) WARN 입니다. 패키지 경로는 프로젝트 디렉터리부터 상위로 찾은 설치본 위치 기준이라, npm workspaces · pnpm hoisted 처럼 루트에만 설치된 앱은 `../../node_modules/@axis-ds/ui-react/dist/**/*.{js,mjs}` 를 안내합니다(1.7.1 부터, 설치본이 없거나 Plug'n'Play 면 `./node_modules/...`). `**` 는 `../` 를 넘지 않는 것으로, 절대경로 glob 은 실제 위치와 비교해 판정합니다. 상위 경로는 Tailwind 3 가 빌드를 실행한 디렉터리 기준으로 풀리므로 모노레포 루트에서 빌드하면 `content: { relative: true, files: [...] }` 를 쓰세요(판정은 프로젝트 디렉터리에서 빌드한다고 보고 함).
|
|
111
111
|
- `animation`: `@axis-ds/ui-react` 선언이나 `componentsDir` 의 `animate-in` 류 클래스가 있을 때 애니메이션 플러그인(Tailwind 3 `tailwindcss-animate` 선언 + 설치본 + `plugins` 배열 참조, Tailwind 4 `@import "tw-animate-css"`)이 없으면 WARN 입니다. 1.6.1 부터 Tailwind 3 은 `plugins` 배열 안의 `require("tailwindcss-animate")` 나 그 패키지를 받은 식별자(`import animate from` · `const animate = require(...)`)만 인정합니다(import 만 있거나 다른 곳의 같은 문자열은 아님). 배열을 정적으로 다 읽지 못하면(펼침 · 단축 속성) 「확인하지 못함」 WARN 입니다.
|
|
112
112
|
- FAIL 이 하나라도 있으면 종료 코드 1 로 끝납니다. WARN 만 있으면 0 입니다(1.3.0 부터, 이전에는 결과와 관계없이 0).
|
|
113
113
|
- MCP `axis.check_project` 도 같은 항목 · 문구를 냅니다.
|
package/dist/index.js
CHANGED
|
@@ -1907,16 +1907,51 @@ async function readAxisConfig(baseDir) {
|
|
|
1907
1907
|
}
|
|
1908
1908
|
|
|
1909
1909
|
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
1910
|
-
import { existsSync as existsSync2, lstatSync, readdirSync, readFileSync as readFileSync2 } from "fs";
|
|
1911
|
-
import { extname, join, resolve } from "path";
|
|
1910
|
+
import { existsSync as existsSync2, lstatSync, readdirSync, readFileSync as readFileSync2, realpathSync } from "fs";
|
|
1911
|
+
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "path";
|
|
1912
1912
|
|
|
1913
1913
|
// ../axis-registry-core/src/project.ts
|
|
1914
1914
|
import { existsSync, readFileSync, statSync } from "fs";
|
|
1915
1915
|
import path8 from "path";
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1916
|
+
var LOCKFILE_COMMANDS = [
|
|
1917
|
+
["pnpm-lock.yaml", "pnpm install"],
|
|
1918
|
+
["yarn.lock", "yarn install"],
|
|
1919
|
+
["package-lock.json", "npm install"]
|
|
1920
|
+
];
|
|
1921
|
+
function lockfileCommandAt(dir) {
|
|
1922
|
+
return LOCKFILE_COMMANDS.find(([file]) => existsSync(path8.join(dir, file)))?.[1];
|
|
1923
|
+
}
|
|
1924
|
+
function isWorkspaceRootDir(dir) {
|
|
1925
|
+
if (isFile(path8.join(dir, "pnpm-workspace.yaml"))) return true;
|
|
1926
|
+
let parsed;
|
|
1927
|
+
try {
|
|
1928
|
+
parsed = JSON.parse(readFileSync(path8.join(dir, "package.json"), "utf8"));
|
|
1929
|
+
} catch {
|
|
1930
|
+
return false;
|
|
1931
|
+
}
|
|
1932
|
+
if (!isPlainObject(parsed)) return false;
|
|
1933
|
+
const ws = parsed.workspaces;
|
|
1934
|
+
return Array.isArray(ws) || isPlainObject(ws) && Array.isArray(ws.packages);
|
|
1935
|
+
}
|
|
1936
|
+
function findWorkspaceRoot(baseDirInput) {
|
|
1937
|
+
let dir = path8.resolve(baseDirInput);
|
|
1938
|
+
for (; ; ) {
|
|
1939
|
+
if (isWorkspaceRootDir(dir)) return dir;
|
|
1940
|
+
if (existsSync(path8.join(dir, ".git"))) return void 0;
|
|
1941
|
+
const parent = path8.dirname(dir);
|
|
1942
|
+
if (parent === dir) return void 0;
|
|
1943
|
+
dir = parent;
|
|
1944
|
+
}
|
|
1945
|
+
}
|
|
1946
|
+
function detectInstallCommand(baseDirInput) {
|
|
1947
|
+
const baseDir = path8.resolve(baseDirInput);
|
|
1948
|
+
const own = lockfileCommandAt(baseDir);
|
|
1949
|
+
if (own !== void 0) return own;
|
|
1950
|
+
const root = findWorkspaceRoot(baseDir);
|
|
1951
|
+
if (root !== void 0 && root !== baseDir) {
|
|
1952
|
+
const fromRoot = lockfileCommandAt(root);
|
|
1953
|
+
if (fromRoot !== void 0) return fromRoot;
|
|
1954
|
+
}
|
|
1920
1955
|
return "pnpm install";
|
|
1921
1956
|
}
|
|
1922
1957
|
function hasDependency(pkg, name) {
|
|
@@ -2592,6 +2627,92 @@ function contentGlobToRegExp(glob) {
|
|
|
2592
2627
|
}
|
|
2593
2628
|
return new RegExp(`^${re}$`);
|
|
2594
2629
|
}
|
|
2630
|
+
function leadingParentSegments(p) {
|
|
2631
|
+
const s = p.trim().replace(/\\/g, "/").replace(/^\.\//, "");
|
|
2632
|
+
return (/^(?:\.\.\/)*/.exec(s)?.[0].length ?? 0) / 3;
|
|
2633
|
+
}
|
|
2634
|
+
function isAbsoluteGlob(glob) {
|
|
2635
|
+
const t = glob.trim();
|
|
2636
|
+
return t.startsWith("/") || /^[A-Za-z]:[\\/]/.test(t);
|
|
2637
|
+
}
|
|
2638
|
+
var MAX_BRACE_EXPANSION = 256;
|
|
2639
|
+
function expandBraces(glob) {
|
|
2640
|
+
const open = glob.indexOf("{");
|
|
2641
|
+
if (open === -1) return [glob];
|
|
2642
|
+
let depth = 0;
|
|
2643
|
+
let close = -1;
|
|
2644
|
+
const commas = [];
|
|
2645
|
+
for (let i = open; i < glob.length; i++) {
|
|
2646
|
+
const c = glob[i];
|
|
2647
|
+
if (c === "{") depth++;
|
|
2648
|
+
else if (c === "}") {
|
|
2649
|
+
depth--;
|
|
2650
|
+
if (depth === 0) {
|
|
2651
|
+
close = i;
|
|
2652
|
+
break;
|
|
2653
|
+
}
|
|
2654
|
+
} else if (c === "," && depth === 1) commas.push(i);
|
|
2655
|
+
}
|
|
2656
|
+
const head = glob.slice(0, open + 1);
|
|
2657
|
+
if (close === -1 || commas.length === 0) {
|
|
2658
|
+
return expandBraces(glob.slice(open + 1))?.map((r) => head + r);
|
|
2659
|
+
}
|
|
2660
|
+
const parts = [];
|
|
2661
|
+
let from = open + 1;
|
|
2662
|
+
for (const c of [...commas, close]) {
|
|
2663
|
+
parts.push(glob.slice(from, c));
|
|
2664
|
+
from = c + 1;
|
|
2665
|
+
}
|
|
2666
|
+
const prefix = glob.slice(0, open);
|
|
2667
|
+
const suffix = glob.slice(close + 1);
|
|
2668
|
+
const out = [];
|
|
2669
|
+
for (const part of parts) {
|
|
2670
|
+
const expanded = expandBraces(prefix + part + suffix);
|
|
2671
|
+
if (expanded === void 0) return void 0;
|
|
2672
|
+
out.push(...expanded);
|
|
2673
|
+
if (out.length > MAX_BRACE_EXPANSION) return void 0;
|
|
2674
|
+
}
|
|
2675
|
+
return out;
|
|
2676
|
+
}
|
|
2677
|
+
function realpathPosix(p) {
|
|
2678
|
+
let cur = p;
|
|
2679
|
+
const tail = [];
|
|
2680
|
+
for (let i = 0; i < 64; i++) {
|
|
2681
|
+
try {
|
|
2682
|
+
return [realpathSync(cur), ...tail].join(sep).split(sep).join("/");
|
|
2683
|
+
} catch {
|
|
2684
|
+
const parent = dirname(cur);
|
|
2685
|
+
if (parent === cur) return void 0;
|
|
2686
|
+
tail.unshift(basename(cur));
|
|
2687
|
+
cur = parent;
|
|
2688
|
+
}
|
|
2689
|
+
}
|
|
2690
|
+
return void 0;
|
|
2691
|
+
}
|
|
2692
|
+
function contentGlobBranchCovers(glob, sample, baseDir) {
|
|
2693
|
+
if (isAbsoluteGlob(glob)) {
|
|
2694
|
+
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"));
|
|
2695
|
+
const absSample = resolve(baseDir, sample);
|
|
2696
|
+
if (re.test(absSample.split(sep).join("/"))) return true;
|
|
2697
|
+
const real = realpathPosix(absSample);
|
|
2698
|
+
return real !== void 0 && re.test(real);
|
|
2699
|
+
}
|
|
2700
|
+
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob).test(sample);
|
|
2701
|
+
}
|
|
2702
|
+
function contentGlobCovers(glob, sample, baseDir) {
|
|
2703
|
+
const branches = expandBraces(glob.trim()) ?? [glob];
|
|
2704
|
+
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir));
|
|
2705
|
+
}
|
|
2706
|
+
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";
|
|
2707
|
+
function packageContentTarget(baseDir, name) {
|
|
2708
|
+
const found = isPnpProject(baseDir) ? void 0 : findInstalledPackage(baseDir, name);
|
|
2709
|
+
const rel3 = found === void 0 ? void 0 : relative(baseDir, found.dir);
|
|
2710
|
+
const relDir = rel3 === void 0 || rel3 === "" || isAbsolute(rel3) ? `node_modules/${name}` : rel3.split(sep).join("/");
|
|
2711
|
+
return {
|
|
2712
|
+
sample: `${relDir}/dist/index.js`,
|
|
2713
|
+
suggest: `${relDir.startsWith("../") ? "" : "./"}${relDir}/dist/**/*.{js,mjs}`
|
|
2714
|
+
};
|
|
2715
|
+
}
|
|
2595
2716
|
function balancedSlice(src, start) {
|
|
2596
2717
|
const open = src[start];
|
|
2597
2718
|
const close = open === "[" ? "]" : "}";
|
|
@@ -2653,17 +2774,17 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
2653
2774
|
}
|
|
2654
2775
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
2655
2776
|
if (pkg !== void 0 && hasDependency2(pkg, name) !== void 0) {
|
|
2656
|
-
targets.push({ label: name,
|
|
2777
|
+
targets.push({ label: name, ...packageContentTarget(baseDir, name) });
|
|
2657
2778
|
}
|
|
2658
2779
|
}
|
|
2659
2780
|
if (targets.length === 0) return null;
|
|
2660
2781
|
const read = readTailwindContent(readFileSync2(join(baseDir, configFile), "utf8"));
|
|
2661
|
-
const
|
|
2782
|
+
const globs = (read?.globs ?? []).filter((g) => !g.trim().startsWith("!"));
|
|
2662
2783
|
return {
|
|
2663
2784
|
configFile,
|
|
2664
2785
|
unreadable: read === void 0,
|
|
2665
2786
|
dynamic: read?.dynamic ?? false,
|
|
2666
|
-
targets: targets.map((t) => ({ ...t, covered:
|
|
2787
|
+
targets: targets.map((t) => ({ ...t, covered: globs.some((g) => contentGlobCovers(g, t.sample, baseDir)) }))
|
|
2667
2788
|
};
|
|
2668
2789
|
}
|
|
2669
2790
|
function checkTailwindContent(baseDir) {
|
|
@@ -2678,17 +2799,18 @@ function checkTailwindContent(baseDir) {
|
|
|
2678
2799
|
};
|
|
2679
2800
|
}
|
|
2680
2801
|
const list = missing.map((t) => `${t.label} \u2192 "${t.suggest}"`).join(" \xB7 ");
|
|
2802
|
+
const note = missing.some((t) => t.suggest.startsWith("../")) ? ` (${CONTENT_PARENT_PATH_NOTE})` : "";
|
|
2681
2803
|
if (r.unreadable || r.dynamic) {
|
|
2682
2804
|
return {
|
|
2683
2805
|
name: "tailwind.content",
|
|
2684
2806
|
severity: "warn",
|
|
2685
|
-
message: `${r.configFile}\uC758 content \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${list}`
|
|
2807
|
+
message: `${r.configFile}\uC758 content \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${list}${note}`
|
|
2686
2808
|
};
|
|
2687
2809
|
}
|
|
2688
2810
|
return {
|
|
2689
2811
|
name: "tailwind.content",
|
|
2690
2812
|
severity: "fail",
|
|
2691
|
-
message: `${r.configFile}\uC758 content \uAC00 \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C\uB97C \uB36E\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC74C): ${list}`
|
|
2813
|
+
message: `${r.configFile}\uC758 content \uAC00 \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C\uB97C \uB36E\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC74C): ${list}${note}`
|
|
2692
2814
|
};
|
|
2693
2815
|
}
|
|
2694
2816
|
var ANIMATION_PLUGIN_TAILWIND3 = "tailwindcss-animate";
|
|
@@ -3165,7 +3287,7 @@ import chalk7 from "chalk";
|
|
|
3165
3287
|
// src/theme/brand-core.ts
|
|
3166
3288
|
import { existsSync as existsSync3, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
|
|
3167
3289
|
import { createRequire } from "module";
|
|
3168
|
-
import { dirname, join as join2, relative, resolve as resolve2, sep } from "path";
|
|
3290
|
+
import { dirname as dirname2, join as join2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
|
|
3169
3291
|
var TOKENS_PACKAGE = "@axis-ds/tokens";
|
|
3170
3292
|
var BRAND_NAME_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
3171
3293
|
var MIN_BRAND_TOKENS_VERSION = "1.3.0";
|
|
@@ -3196,7 +3318,7 @@ function findTokensPackageJson(baseDir) {
|
|
|
3196
3318
|
for (; ; ) {
|
|
3197
3319
|
const candidate = join2(dir, "node_modules", TOKENS_PACKAGE, "package.json");
|
|
3198
3320
|
if (existsSync3(candidate)) return candidate;
|
|
3199
|
-
const parent =
|
|
3321
|
+
const parent = dirname2(dir);
|
|
3200
3322
|
if (parent === dir) return void 0;
|
|
3201
3323
|
dir = parent;
|
|
3202
3324
|
}
|
|
@@ -3280,7 +3402,7 @@ function inspectBrandImport(baseDir) {
|
|
|
3280
3402
|
if (!location.path) {
|
|
3281
3403
|
return { ...base, state: "css-missing", imports: [] };
|
|
3282
3404
|
}
|
|
3283
|
-
const cssFile =
|
|
3405
|
+
const cssFile = relative2(root, location.path).split(sep2).join("/");
|
|
3284
3406
|
const imports = [...new Set(findBrandImports(readFileSync3(location.path, "utf8")))];
|
|
3285
3407
|
let state;
|
|
3286
3408
|
if (imports.includes(brand)) state = "match";
|
|
@@ -3396,7 +3518,7 @@ function findBrandActivation(baseDir) {
|
|
|
3396
3518
|
const providerTexts = [];
|
|
3397
3519
|
for (const m of text.matchAll(/from\s+["']\.\/(providers?)["']/g)) {
|
|
3398
3520
|
for (const ext of [".tsx", ".jsx", ".ts", ".js"]) {
|
|
3399
|
-
const rel3 = `${
|
|
3521
|
+
const rel3 = `${dirname2(candidate)}/${m[1]}${ext}`;
|
|
3400
3522
|
const p = join2(root, rel3);
|
|
3401
3523
|
if (isFile2(p)) providerTexts.push({ rel: rel3, text: stripJsLikeComments(readFileSync3(p, "utf8")) });
|
|
3402
3524
|
}
|
|
@@ -3479,6 +3601,16 @@ function declaredAxisPackages(pkg) {
|
|
|
3479
3601
|
}
|
|
3480
3602
|
return out;
|
|
3481
3603
|
}
|
|
3604
|
+
function workspaceRootPackage(baseDir) {
|
|
3605
|
+
const root = findWorkspaceRoot(baseDir);
|
|
3606
|
+
if (root === void 0 || root === baseDir) return void 0;
|
|
3607
|
+
try {
|
|
3608
|
+
const parsed = JSON.parse(readFileSync4(join3(root, "package.json"), "utf8"));
|
|
3609
|
+
return isPlainObject(parsed) ? parsed : void 0;
|
|
3610
|
+
} catch {
|
|
3611
|
+
return void 0;
|
|
3612
|
+
}
|
|
3613
|
+
}
|
|
3482
3614
|
function checkDependencies(baseDirInput) {
|
|
3483
3615
|
const baseDir = resolve3(baseDirInput);
|
|
3484
3616
|
let pkg;
|
|
@@ -3492,13 +3624,17 @@ function checkDependencies(baseDirInput) {
|
|
|
3492
3624
|
}
|
|
3493
3625
|
return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
|
|
3494
3626
|
}
|
|
3495
|
-
const
|
|
3627
|
+
const rootPkg = workspaceRootPackage(baseDir);
|
|
3628
|
+
const fromRoot = (d) => !hasDependency(pkg, d) && rootPkg !== void 0 && Boolean(hasDependency(rootPkg, d));
|
|
3629
|
+
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d) && !fromRoot(d));
|
|
3496
3630
|
if (missingRequired.length > 0) {
|
|
3497
3631
|
return { name: "dependencies", severity: "fail", message: `\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}` };
|
|
3498
3632
|
}
|
|
3499
|
-
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d));
|
|
3633
|
+
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => !hasDependency(pkg, d) && !fromRoot(d));
|
|
3634
|
+
const rootDeclared = [...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => fromRoot(d));
|
|
3635
|
+
const rootNote = rootDeclared.length > 0 ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootDeclared.join(", ")}` : void 0;
|
|
3500
3636
|
const targets = [
|
|
3501
|
-
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => hasDependency(pkg, d) !== void 0),
|
|
3637
|
+
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => hasDependency(pkg, d) !== void 0 || fromRoot(d)),
|
|
3502
3638
|
...declaredAxisPackages(pkg)
|
|
3503
3639
|
];
|
|
3504
3640
|
const pnp = isPnpProject(baseDir);
|
|
@@ -3508,11 +3644,14 @@ function checkDependencies(baseDirInput) {
|
|
|
3508
3644
|
if (notInstalled.length > 0) {
|
|
3509
3645
|
problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalled.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
3510
3646
|
}
|
|
3511
|
-
if (problems.length > 0)
|
|
3647
|
+
if (problems.length > 0) {
|
|
3648
|
+
return { name: "dependencies", severity: "warn", message: problems.join(" / ") + (rootNote ? ` (${rootNote})` : "") };
|
|
3649
|
+
}
|
|
3650
|
+
const note = rootNote ? `, ${rootNote}` : "";
|
|
3512
3651
|
return {
|
|
3513
3652
|
name: "dependencies",
|
|
3514
3653
|
severity: "pass",
|
|
3515
|
-
message: pnp ? `\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uC120\uC5B8\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (Plug'n'Play \uB77C \uC124\uCE58\uBCF8\uC740 \uD655\uC778\uD558\uC9C0 \uC54A\uC74C, ${targets.length}\uAC1C)` : `\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uC120\uC5B8 \xB7 \uC124\uCE58\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (${targets.length}\uAC1C \uD655\uC778)`
|
|
3654
|
+
message: pnp ? `\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uC120\uC5B8\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (Plug'n'Play \uB77C \uC124\uCE58\uBCF8\uC740 \uD655\uC778\uD558\uC9C0 \uC54A\uC74C, ${targets.length}\uAC1C${note})` : `\uD544\uC218 \uBC0F \uAD8C\uC7A5 \uC758\uC874\uC131\uC774 \uC120\uC5B8 \xB7 \uC124\uCE58\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4 (${targets.length}\uAC1C \uD655\uC778${note})`
|
|
3516
3655
|
};
|
|
3517
3656
|
}
|
|
3518
3657
|
|
|
@@ -3775,7 +3914,7 @@ import chalk9 from "chalk";
|
|
|
3775
3914
|
import path13 from "path";
|
|
3776
3915
|
|
|
3777
3916
|
// src/theme/theme-add.ts
|
|
3778
|
-
import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync5, realpathSync, unlinkSync, writeFileSync } from "fs";
|
|
3917
|
+
import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync5, realpathSync as realpathSync2, unlinkSync, writeFileSync } from "fs";
|
|
3779
3918
|
import path12 from "path";
|
|
3780
3919
|
var TOKENS_DEPENDENCY_RANGE = `^${TOKENS_DEPENDENCY_MIN_VERSION}`;
|
|
3781
3920
|
var TAILWIND3_BASE_IMPORTS = [`${TOKENS_PACKAGE}/css`, `${TOKENS_PACKAGE}/css/shadcn`];
|
|
@@ -3872,8 +4011,8 @@ function compareVersions(a, b) {
|
|
|
3872
4011
|
return 0;
|
|
3873
4012
|
}
|
|
3874
4013
|
function realPathInside(baseDir, file) {
|
|
3875
|
-
const realBase =
|
|
3876
|
-
const realPath =
|
|
4014
|
+
const realBase = realpathSync2(baseDir);
|
|
4015
|
+
const realPath = realpathSync2(file);
|
|
3877
4016
|
const relPath = path12.relative(realBase, realPath);
|
|
3878
4017
|
const inside = relPath !== "" && !relPath.startsWith("..") && !path12.isAbsolute(relPath);
|
|
3879
4018
|
return { inside, realPath };
|
|
@@ -4385,6 +4524,7 @@ function renderThemeAdd(plan, written) {
|
|
|
4385
4524
|
)
|
|
4386
4525
|
);
|
|
4387
4526
|
}
|
|
4527
|
+
if (tw.contentMissing.some((t) => t.suggest.startsWith("../"))) lines.push(chalk9.gray(` ${CONTENT_PARENT_PATH_NOTE}`));
|
|
4388
4528
|
}
|
|
4389
4529
|
const act = plan.activation;
|
|
4390
4530
|
lines.push("", chalk9.bold(`\uBE0C\uB79C\uB4DC \uCF1C\uAE30 (ThemeProvider \uB294 ${THEME_PACKAGE} ${THEME_MIN_VERSION} \uC774\uC0C1)`));
|
|
@@ -4766,13 +4906,13 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
4766
4906
|
}
|
|
4767
4907
|
|
|
4768
4908
|
// src/init/init.ts
|
|
4769
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync3, readFileSync as readFileSync6, realpathSync as
|
|
4909
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync3, readFileSync as readFileSync6, realpathSync as realpathSync4, statSync as statSync4, writeFileSync as writeFileSync2 } from "fs";
|
|
4770
4910
|
import path15 from "path";
|
|
4771
4911
|
import chalk10 from "chalk";
|
|
4772
4912
|
import fs12 from "fs-extra";
|
|
4773
4913
|
|
|
4774
4914
|
// ../axis-registry-core/src/add/safe-write.ts
|
|
4775
|
-
import { constants as fsConstants, existsSync as existsSync5, lstatSync as lstatSync2, realpathSync as
|
|
4915
|
+
import { constants as fsConstants, existsSync as existsSync5, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
4776
4916
|
import path14 from "path";
|
|
4777
4917
|
import fs11 from "fs-extra";
|
|
4778
4918
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
@@ -4799,12 +4939,12 @@ function nearestExisting(p) {
|
|
|
4799
4939
|
return cur;
|
|
4800
4940
|
}
|
|
4801
4941
|
function escapeReason(root, target, options = {}) {
|
|
4802
|
-
const realRoot =
|
|
4942
|
+
const realRoot = realpathSync3(root);
|
|
4803
4943
|
if (!isSameOrInside(path14.resolve(root), path14.resolve(target)) || path14.resolve(target) === path14.resolve(root)) {
|
|
4804
4944
|
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
4805
4945
|
}
|
|
4806
4946
|
const anchor = nearestExisting(path14.dirname(target));
|
|
4807
|
-
const realAnchor =
|
|
4947
|
+
const realAnchor = realpathSync3(anchor);
|
|
4808
4948
|
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
4809
4949
|
return `\uC0C1\uC704 \uB514\uB809\uD130\uB9AC\uC758 \uC2E4\uC81C \uC704\uCE58(${realAnchor})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
|
|
4810
4950
|
}
|
|
@@ -4819,7 +4959,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
4819
4959
|
const shown = path14.relative(path14.resolve(root), path14.resolve(target)).split(path14.sep).join("/");
|
|
4820
4960
|
let realTarget;
|
|
4821
4961
|
try {
|
|
4822
|
-
realTarget =
|
|
4962
|
+
realTarget = realpathSync3(target);
|
|
4823
4963
|
} catch {
|
|
4824
4964
|
return `\uAE30\uC874 \uD30C\uC77C ${shown} \uC774 \uAE68\uC9C4 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C \uB530\uB77C\uAC08 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uACE0\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694)`;
|
|
4825
4965
|
}
|
|
@@ -4852,8 +4992,8 @@ function isSymlink(p) {
|
|
|
4852
4992
|
function outsideLinkTarget(root, target) {
|
|
4853
4993
|
if (!isSymlink(target)) return null;
|
|
4854
4994
|
try {
|
|
4855
|
-
const realTarget =
|
|
4856
|
-
return isSameOrInside(
|
|
4995
|
+
const realTarget = realpathSync3(target);
|
|
4996
|
+
return isSameOrInside(realpathSync3(root), realTarget) ? null : realTarget;
|
|
4857
4997
|
} catch {
|
|
4858
4998
|
return null;
|
|
4859
4999
|
}
|
|
@@ -4870,10 +5010,10 @@ function hardLinkMessage(shownPath, nlink) {
|
|
|
4870
5010
|
return `\uAE30\uC874 \uD30C\uC77C ${shownPath} \uC774 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC9C4 \uD30C\uC77C\uC774\uB77C(\uB9C1\uD06C \uC218 ${nlink}) \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uBA74 \uC774\uC5B4\uC9C4 \uB2E4\uB978 \uACBD\uB85C\uC758 \uB0B4\uC6A9\uB3C4 \uBC14\uB01D\uB2C8\uB2E4. \uD558\uB4DC\uB9C1\uD06C\uB97C \uB04A\uC740(\uD30C\uC77C\uC744 \uBCF5\uC0AC\uD574 \uBC14\uAFBC) \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694`;
|
|
4871
5011
|
}
|
|
4872
5012
|
function writtenOutside(root, target) {
|
|
4873
|
-
const realRoot =
|
|
5013
|
+
const realRoot = realpathSync3(root);
|
|
4874
5014
|
let realTarget;
|
|
4875
5015
|
try {
|
|
4876
|
-
realTarget =
|
|
5016
|
+
realTarget = realpathSync3(target);
|
|
4877
5017
|
} catch {
|
|
4878
5018
|
return target;
|
|
4879
5019
|
}
|
|
@@ -4919,8 +5059,8 @@ async function overwriteFollowingLinks(target, content) {
|
|
|
4919
5059
|
}
|
|
4920
5060
|
}
|
|
4921
5061
|
function checkParentInside(root, target) {
|
|
4922
|
-
const realRoot =
|
|
4923
|
-
const realParent =
|
|
5062
|
+
const realRoot = realpathSync3(root);
|
|
5063
|
+
const realParent = realpathSync3(path14.dirname(target));
|
|
4924
5064
|
if (!isSameOrInside(realRoot, realParent)) {
|
|
4925
5065
|
return `\uBD80\uBAA8 \uB514\uB809\uD130\uB9AC\uC758 \uC2E4\uC81C \uC704\uCE58(${realParent})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
|
|
4926
5066
|
}
|
|
@@ -5272,13 +5412,13 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
5272
5412
|
if (st.isSymbolicLink()) {
|
|
5273
5413
|
let real;
|
|
5274
5414
|
try {
|
|
5275
|
-
real =
|
|
5415
|
+
real = realpathSync4(utilsPath);
|
|
5276
5416
|
} catch {
|
|
5277
5417
|
return { action: "reject", reason: `${shown} \uC774 \uAE68\uC9C4 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uACE0\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694` };
|
|
5278
5418
|
}
|
|
5279
5419
|
let outside = null;
|
|
5280
5420
|
try {
|
|
5281
|
-
outside = isSameOrInside(
|
|
5421
|
+
outside = isSameOrInside(realpathSync4(baseDir), real) ? null : real;
|
|
5282
5422
|
} catch {
|
|
5283
5423
|
outside = null;
|
|
5284
5424
|
}
|