@axis-ds/mcp 1.4.6 → 1.4.8
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 +756 -83
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -42,6 +42,7 @@ Claude Desktop 또는 기타 MCP 호환 클라이언트에서 설정:
|
|
|
42
42
|
- `targetDir` 는 이미 있는 프로젝트 루트입니다(상대 경로는 서버의 현재 디렉터리 기준). `axis.config.json` 이 있으면 그 `componentsDir` · `agenticDir` 에, 없으면 `components/ui` · `components/agentic` 에 설치하고 그 사실을 알립니다. 프로젝트 밖으로 나가는 경로는 아무것도 쓰지 않고 실패합니다.
|
|
43
43
|
- 내용이 다른 기존 파일은 덮어쓰지 않고 건너뛰며 응답 첫머리에 건너뛴 수를 적습니다. `overwrite: true` 일 때만 덮어씁니다.
|
|
44
44
|
- 의존성은 설치하지 않고 lockfile 에 맞는 명령(`pnpm add` · `npm install` · `yarn add`)만 안내합니다. lockfile 이 없으면 `package.json` 의 `packageManager` 를 봅니다(1.4.2 부터). `axis.apply_template` 의 「필요한 의존성」 · `axis.list_brands` · `axis.get_brand` 의 설치 안내도 1.4.2 부터 같은 방식으로 `targetDir` 의 매니저를 따릅니다(1.4.1 까지는 `pnpm` 고정).
|
|
45
|
+
- `axis.apply_template` 은 `targetDir` 에 이미 있는 `package.json` · `axis.config.json`(템플릿 루트의 것)을 덮어쓰지 않고 CLI `axis template apply` 와 같은 규칙으로 합칩니다(WI-0088). `packageManager` 등 사용자 필드가 남고, 결과의 파일 목록에 「합치기」로 표시합니다. 파일을 쓰는 도중 실패하면 건드린 파일을 되돌리고 오류로 응답합니다. 템플릿 경로가 `targetDir` 밖(절대 경로 · `..` · 밖을 가리키는 심볼릭 링크 경유)이면 `axis.apply_template` · `axis.diff_template` 은 아무 파일도 쓰거나 읽지 않고 오류로 응답합니다.
|
|
45
46
|
|
|
46
47
|
## 토큰 도구
|
|
47
48
|
|
package/dist/index.js
CHANGED
|
@@ -58,8 +58,8 @@ function listTokens(category) {
|
|
|
58
58
|
}
|
|
59
59
|
return tokens;
|
|
60
60
|
}
|
|
61
|
-
function getToken(
|
|
62
|
-
const q =
|
|
61
|
+
function getToken(path12) {
|
|
62
|
+
const q = path12.trim().toLowerCase();
|
|
63
63
|
return loadTokens().tokens.find(
|
|
64
64
|
(t) => t.path.toLowerCase() === q || (t.aliases ?? []).some((a) => a.toLowerCase() === q) || t.cssVariable.toLowerCase() === q
|
|
65
65
|
);
|
|
@@ -237,8 +237,8 @@ function validateRegistryIndex(data, where = "index.json") {
|
|
|
237
237
|
if (!isValidRegistryName(raw.name)) throw new Error(`${at}: name \uC774 slug \uADDC\uCE59\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
|
|
238
238
|
if (seen.has(raw.name)) throw new Error(`${at}: name '${raw.name}' \uAC00 \uC911\uBCF5\uC785\uB2C8\uB2E4`);
|
|
239
239
|
seen.add(raw.name);
|
|
240
|
-
const
|
|
241
|
-
if (
|
|
240
|
+
const sha2562 = optionalString(raw, "sha256", at);
|
|
241
|
+
if (sha2562 !== void 0 && !/^[0-9a-f]{64}$/.test(sha2562)) {
|
|
242
242
|
throw new Error(`${at}: sha256 \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
243
243
|
}
|
|
244
244
|
return {
|
|
@@ -246,7 +246,7 @@ function validateRegistryIndex(data, where = "index.json") {
|
|
|
246
246
|
type: requireType(raw, at),
|
|
247
247
|
title: optionalString(raw, "title", at),
|
|
248
248
|
description: optionalString(raw, "description", at),
|
|
249
|
-
...
|
|
249
|
+
...sha2562 !== void 0 ? { sha256: sha2562 } : {}
|
|
250
250
|
};
|
|
251
251
|
});
|
|
252
252
|
return {
|
|
@@ -1020,6 +1020,9 @@ function dependencyInstallGuide(baseDirInput, name, range) {
|
|
|
1020
1020
|
...base
|
|
1021
1021
|
};
|
|
1022
1022
|
}
|
|
1023
|
+
function installCommandPhrase(installCommand, rootDeclared) {
|
|
1024
|
+
return rootDeclared && packageManagerOf(installCommand) === "npm" ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${installCommand}` : installCommand;
|
|
1025
|
+
}
|
|
1023
1026
|
function isPlainObject(value) {
|
|
1024
1027
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1025
1028
|
}
|
|
@@ -1062,6 +1065,13 @@ function isFile(file) {
|
|
|
1062
1065
|
return false;
|
|
1063
1066
|
}
|
|
1064
1067
|
}
|
|
1068
|
+
function isDirectory(dir) {
|
|
1069
|
+
try {
|
|
1070
|
+
return statSync(dir).isDirectory();
|
|
1071
|
+
} catch {
|
|
1072
|
+
return false;
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1065
1075
|
function selectGlobalCss(baseDir, configured, candidates, options = {}) {
|
|
1066
1076
|
const result = {};
|
|
1067
1077
|
if (typeof configured === "string" && configured.trim() !== "") {
|
|
@@ -1181,6 +1191,144 @@ function outsideCssPackageResolution(baseDir, cssDir, name, file) {
|
|
|
1181
1191
|
if (!usable(findInstalledPackage(baseDir, name))) return "unknown";
|
|
1182
1192
|
return usable(findInstalledPackage(cssDir, name)) ? "resolved" : "unresolved";
|
|
1183
1193
|
}
|
|
1194
|
+
var CSS_EXPORT_CONDITIONS = /* @__PURE__ */ new Set(["style", "default"]);
|
|
1195
|
+
function splitPackageSpec(spec) {
|
|
1196
|
+
const parts = spec.split("/");
|
|
1197
|
+
const n = spec.startsWith("@") ? 2 : 1;
|
|
1198
|
+
if (parts.length < n || parts.slice(0, n).some((p) => p === "" || p === "." || p === "..")) return void 0;
|
|
1199
|
+
return { name: parts.slice(0, n).join("/"), rest: parts.slice(n).join("/") };
|
|
1200
|
+
}
|
|
1201
|
+
function resolveExportTarget(value, conditions = CSS_EXPORT_CONDITIONS) {
|
|
1202
|
+
if (typeof value === "string") return value;
|
|
1203
|
+
if (Array.isArray(value)) {
|
|
1204
|
+
for (const v of value) {
|
|
1205
|
+
const r = resolveExportTarget(v, conditions);
|
|
1206
|
+
if (r !== void 0) return r;
|
|
1207
|
+
}
|
|
1208
|
+
return void 0;
|
|
1209
|
+
}
|
|
1210
|
+
if (isPlainObject(value)) {
|
|
1211
|
+
for (const [key, v] of Object.entries(value)) {
|
|
1212
|
+
if (!conditions.has(key)) continue;
|
|
1213
|
+
if (v === null) return void 0;
|
|
1214
|
+
const r = resolveExportTarget(v, conditions);
|
|
1215
|
+
if (r !== void 0) return r;
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
return void 0;
|
|
1219
|
+
}
|
|
1220
|
+
function cssFileCandidates(p) {
|
|
1221
|
+
return [p, `${p}.css`, path3.join(p, "index.css")];
|
|
1222
|
+
}
|
|
1223
|
+
function exportsTarget(exportsField, subpath, conditions = CSS_EXPORT_CONDITIONS) {
|
|
1224
|
+
const map = isPlainObject(exportsField) && Object.keys(exportsField).some((k) => k.startsWith(".")) ? exportsField : { ".": exportsField };
|
|
1225
|
+
if (Object.prototype.hasOwnProperty.call(map, subpath)) {
|
|
1226
|
+
const t = resolveExportTarget(map[subpath], conditions);
|
|
1227
|
+
if (t === void 0) return void 0;
|
|
1228
|
+
return t.includes("*") || !t.startsWith("./") ? "?" : t;
|
|
1229
|
+
}
|
|
1230
|
+
if (Object.keys(map).some((k) => k.includes("*") || k.endsWith("/") && subpath.startsWith(k))) return "?";
|
|
1231
|
+
return void 0;
|
|
1232
|
+
}
|
|
1233
|
+
function resolveCssPackageImport(fromDir, spec) {
|
|
1234
|
+
return resolvePackageSubpath(fromDir, spec, CSS_EXPORT_CONDITIONS, cssFileCandidates);
|
|
1235
|
+
}
|
|
1236
|
+
function resolvePackageSubpath(fromDir, spec, conditions, candidates) {
|
|
1237
|
+
const parsed = splitPackageSpec(spec);
|
|
1238
|
+
if (parsed === void 0 || parsed.rest === "") return { kind: "unknown" };
|
|
1239
|
+
const subpath = `./${parsed.rest}`;
|
|
1240
|
+
let dir = resolveBaseDir(fromDir);
|
|
1241
|
+
for (; ; ) {
|
|
1242
|
+
const pkgDir = path3.join(dir, "node_modules", ...parsed.name.split("/"));
|
|
1243
|
+
if (isDirectory(pkgDir)) {
|
|
1244
|
+
let manifest;
|
|
1245
|
+
try {
|
|
1246
|
+
const raw = JSON.parse(readFileSync3(path3.join(pkgDir, "package.json"), "utf8"));
|
|
1247
|
+
manifest = isPlainObject(raw) ? raw : void 0;
|
|
1248
|
+
} catch {
|
|
1249
|
+
manifest = void 0;
|
|
1250
|
+
}
|
|
1251
|
+
if (manifest !== void 0 && manifest.exports) {
|
|
1252
|
+
const version = exactVersionOf(manifest.version);
|
|
1253
|
+
const target = exportsTarget(manifest.exports, subpath, conditions);
|
|
1254
|
+
if (target === "?") return { kind: "unknown" };
|
|
1255
|
+
if (target === void 0) {
|
|
1256
|
+
return version !== void 0 ? { kind: "not-exported", pkgDir, subpath, version } : { kind: "not-exported", pkgDir, subpath };
|
|
1257
|
+
}
|
|
1258
|
+
const file = candidates(path3.join(pkgDir, target)).find(isFile);
|
|
1259
|
+
if (file !== void 0) return { kind: "resolved", pkgDir, file };
|
|
1260
|
+
return version !== void 0 ? { kind: "target-missing", pkgDir, subpath, target, version } : { kind: "target-missing", pkgDir, subpath, target };
|
|
1261
|
+
}
|
|
1262
|
+
const bare = candidates(path3.join(pkgDir, parsed.rest)).find(isFile);
|
|
1263
|
+
if (bare !== void 0) return { kind: "resolved", pkgDir, file: bare };
|
|
1264
|
+
}
|
|
1265
|
+
const parent = path3.dirname(dir);
|
|
1266
|
+
if (parent === dir) return { kind: "not-found" };
|
|
1267
|
+
dir = parent;
|
|
1268
|
+
}
|
|
1269
|
+
}
|
|
1270
|
+
function installBase(pkgDir, name) {
|
|
1271
|
+
let base = pkgDir;
|
|
1272
|
+
for (let i = 0; i < name.split("/").length + 1; i++) base = path3.dirname(base);
|
|
1273
|
+
try {
|
|
1274
|
+
return realpathSync(base);
|
|
1275
|
+
} catch {
|
|
1276
|
+
return path3.resolve(base);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
function isAncestorInstall(hit, app, name) {
|
|
1280
|
+
const h = installBase(hit, name);
|
|
1281
|
+
const a = installBase(app, name);
|
|
1282
|
+
return a !== h && a.startsWith(h.endsWith(path3.sep) ? h : h + path3.sep);
|
|
1283
|
+
}
|
|
1284
|
+
function sameRealDir(a, b) {
|
|
1285
|
+
const real = (p) => {
|
|
1286
|
+
try {
|
|
1287
|
+
return realpathSync(p);
|
|
1288
|
+
} catch {
|
|
1289
|
+
return path3.resolve(p);
|
|
1290
|
+
}
|
|
1291
|
+
};
|
|
1292
|
+
return real(a) === real(b);
|
|
1293
|
+
}
|
|
1294
|
+
function cssPackageLineResolution(baseDir, lineDir, spec, otherDirs = []) {
|
|
1295
|
+
if (isPnpProject(baseDir)) return { kind: "ok" };
|
|
1296
|
+
const parsed = splitPackageSpec(spec);
|
|
1297
|
+
if (parsed === void 0) return { kind: "ok" };
|
|
1298
|
+
const r = resolveCssPackageImport(lineDir, spec);
|
|
1299
|
+
if (r.kind === "resolved" || r.kind === "unknown") return { kind: "ok" };
|
|
1300
|
+
const app = findInstalledPackage(baseDir, parsed.name);
|
|
1301
|
+
if (r.kind === "not-exported" || r.kind === "target-missing") {
|
|
1302
|
+
if (app !== void 0 && sameRealDir(app.dir, r.pkgDir)) return { kind: "ok" };
|
|
1303
|
+
if (app !== void 0 && isAncestorInstall(r.pkgDir, app.dir, parsed.name)) return { kind: "ok" };
|
|
1304
|
+
return r.kind === "not-exported" ? { ...r, kind: "shadow-not-exported" } : { ...r, kind: "shadow-target-missing" };
|
|
1305
|
+
}
|
|
1306
|
+
if (app !== void 0) return { kind: "ok" };
|
|
1307
|
+
for (const other of typeof otherDirs === "function" ? otherDirs() : otherDirs) {
|
|
1308
|
+
const o = resolveCssPackageImport(other, spec);
|
|
1309
|
+
if (o.kind === "resolved") return { kind: "not-visible", pkgDir: o.pkgDir, fromDir: resolveBaseDir(other) };
|
|
1310
|
+
}
|
|
1311
|
+
return { kind: "ok" };
|
|
1312
|
+
}
|
|
1313
|
+
var JS_REQUIRE_CONDITIONS = /* @__PURE__ */ new Set(["require", "node", "module-sync", "default"]);
|
|
1314
|
+
var JS_IMPORT_CONDITIONS = /* @__PURE__ */ new Set(["import", "node", "module-sync", "default"]);
|
|
1315
|
+
function jsFileCandidates(p) {
|
|
1316
|
+
return [p, `${p}.js`, `${p}.json`, `${p}.node`, path3.join(p, "index.js"), path3.join(p, "index.json"), path3.join(p, "index.node")];
|
|
1317
|
+
}
|
|
1318
|
+
function tailwindConfigImportResolution(baseDir, spec, refs) {
|
|
1319
|
+
if (isPnpProject(baseDir)) return { kind: "ok" };
|
|
1320
|
+
const blocked = (conditions) => {
|
|
1321
|
+
const r = resolvePackageSubpath(baseDir, spec, conditions, jsFileCandidates);
|
|
1322
|
+
return r.kind === "not-exported" ? r : void 0;
|
|
1323
|
+
};
|
|
1324
|
+
const viaRequire = refs.require || refs.import ? blocked(JS_REQUIRE_CONDITIONS) : void 0;
|
|
1325
|
+
if (refs.require && viaRequire !== void 0) return viaRequire;
|
|
1326
|
+
if (refs.import && viaRequire !== void 0) {
|
|
1327
|
+
const viaImport = blocked(JS_IMPORT_CONDITIONS);
|
|
1328
|
+
if (viaImport !== void 0) return viaImport;
|
|
1329
|
+
}
|
|
1330
|
+
return { kind: "ok" };
|
|
1331
|
+
}
|
|
1184
1332
|
function findPnpUnpluggedPackages(baseDirInput, name, range) {
|
|
1185
1333
|
const root = pnpProjectRoot(baseDirInput);
|
|
1186
1334
|
if (root === void 0) return [];
|
|
@@ -1205,6 +1353,17 @@ function findPnpUnpluggedPackages(baseDirInput, name, range) {
|
|
|
1205
1353
|
}
|
|
1206
1354
|
return found;
|
|
1207
1355
|
}
|
|
1356
|
+
var PNP_REAL_DIR_RANGE = /^(?:workspace|portal|link):/;
|
|
1357
|
+
function pnpComponentSourceHidden(baseDirInput, name, range) {
|
|
1358
|
+
if (!isPnpProject(baseDirInput)) return false;
|
|
1359
|
+
const r = range.trim();
|
|
1360
|
+
if (PNP_REAL_DIR_RANGE.test(r)) return false;
|
|
1361
|
+
const probe = versionSatisfiesRange("0.0.0", r) === void 0 ? "*" : r;
|
|
1362
|
+
return findPnpUnpluggedPackages(baseDirInput, name, probe).length === 0;
|
|
1363
|
+
}
|
|
1364
|
+
function pnpUnplugSetupPhrase(name) {
|
|
1365
|
+
return `Plug'n'Play \uB8E8\uD2B8(.pnp.cjs \uAC00 \uC788\uB294 \uACF3) package.json \uC758 dependenciesMeta \uC5D0 "${name}": { "unplugged": true } \uB97C \uB450\uACE0 yarn install`;
|
|
1366
|
+
}
|
|
1208
1367
|
function parsePartialVersion(token) {
|
|
1209
1368
|
const m = /^v?(\d+|[xX*])(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(token.trim());
|
|
1210
1369
|
if (!m) return void 0;
|
|
@@ -1618,12 +1777,12 @@ function outsideCssDir(selection) {
|
|
|
1618
1777
|
function outsideCssUnresolvedIssue(spec, name) {
|
|
1619
1778
|
return `${spec} import \uAC00 \uC788\uC9C0\uB9CC \uC774 \uD30C\uC77C \uC704\uCE58\uC5D0\uC11C ${name} \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC124\uCE58\uBCF8\uC774 \uC571 \uCABD node_modules \uC5D0\uB9CC \uC788\uC74C) \u2192 \uC774 \uD30C\uC77C\uC758 \uC0C1\uC704 node_modules(\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uB4F1)\uC5D0 \uC124\uCE58\uD558\uAC70\uB098 globalCss \uB97C \uC571 \uC548 \uD30C\uC77C\uB85C \uBC14\uAFB8\uC138\uC694`;
|
|
1620
1779
|
}
|
|
1621
|
-
function tokensInstallPhrase(baseDir) {
|
|
1622
|
-
const g = dependencyInstallGuide(baseDir, TOKENS_PACKAGE_NAME,
|
|
1780
|
+
function tokensInstallPhrase(baseDir, range = `^${TAILWIND4_MIN_AXIS_VERSION}`) {
|
|
1781
|
+
const g = dependencyInstallGuide(baseDir, TOKENS_PACKAGE_NAME, range);
|
|
1623
1782
|
if (g.kind === "install-at-root") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${g.installCommand}`;
|
|
1624
1783
|
return g.kind === "install" ? g.installCommand : g.addCommand;
|
|
1625
1784
|
}
|
|
1626
|
-
function tokensCssUnresolvedIssue(baseDir, pkg, spec, cssDir) {
|
|
1785
|
+
function tokensCssUnresolvedIssue(baseDir, pkg, spec, cssDir, lineIssue) {
|
|
1627
1786
|
const r = tokensCssResolution(baseDir, pkg, TOKENS_PACKAGE_NAME);
|
|
1628
1787
|
const head = `${spec} import \uAC00 \uC788\uC9C0\uB9CC`;
|
|
1629
1788
|
if (r.kind === "pnp-root-only") return `${head} ${TOKENS_PACKAGE_NAME} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`;
|
|
@@ -1633,7 +1792,42 @@ function tokensCssUnresolvedIssue(baseDir, pkg, spec, cssDir) {
|
|
|
1633
1792
|
if (cssDir !== void 0 && outsideCssPackageResolution(baseDir, cssDir, TOKENS_PACKAGE_NAME) === "unresolved") {
|
|
1634
1793
|
return outsideCssUnresolvedIssue(spec, TOKENS_PACKAGE_NAME);
|
|
1635
1794
|
}
|
|
1636
|
-
return
|
|
1795
|
+
return lineIssue?.();
|
|
1796
|
+
}
|
|
1797
|
+
function packageNameOfSpec(spec) {
|
|
1798
|
+
const parts = spec.split("/");
|
|
1799
|
+
return parts.slice(0, spec.startsWith("@") ? 2 : 1).join("/");
|
|
1800
|
+
}
|
|
1801
|
+
function displayRel(baseDir, p) {
|
|
1802
|
+
return relative(baseDir, p).split(sep).join("/");
|
|
1803
|
+
}
|
|
1804
|
+
function packageLineShadowIssue(baseDir, expanded, origin, spec, opts = {}) {
|
|
1805
|
+
const name = packageNameOfSpec(spec);
|
|
1806
|
+
const lineDir = dirname2(origin.path);
|
|
1807
|
+
const others = () => [...new Set(expanded.files.map((f) => dirname2(f.path)))].filter((d) => d !== lineDir);
|
|
1808
|
+
const r = cssPackageLineResolution(baseDir, lineDir, spec, others);
|
|
1809
|
+
const head = `${spec} import \uAC00 \uC788\uC9C0\uB9CC \uADF8 \uC904\uC774 \uC788\uB294 \uD30C\uC77C \uC704\uCE58\uC5D0\uC11C`;
|
|
1810
|
+
const label = (pkgDir, version) => `${displayRel(baseDir, pkgDir)}(${version ?? "\uBC84\uC804 \uBAA8\uB984"})`;
|
|
1811
|
+
if (opts.tailwind3 === true && r.kind !== "shadow-not-exported") return void 0;
|
|
1812
|
+
switch (r.kind) {
|
|
1813
|
+
case "ok":
|
|
1814
|
+
return void 0;
|
|
1815
|
+
case "shadow-not-exported": {
|
|
1816
|
+
const current = opts.tailwind3 === true || r.version !== void 0 && (compareExactVersions(r.version, TAILWIND4_MIN_AXIS_VERSION) ?? -1) >= 0;
|
|
1817
|
+
const todo = current ? "\uB2E4\uC2DC \uC124\uCE58\uD558\uC138\uC694" : `${TAILWIND4_MIN_AXIS_VERSION} \uC774\uC0C1\uC73C\uB85C \uB9DE\uCD94\uC138\uC694`;
|
|
1818
|
+
return `${head} \uBA3C\uC800 \uC7A1\uD788\uB294 ${label(r.pkgDir, r.version)}\uAC00 ${r.subpath} \uB97C \uB0B4\uBCF4\uB0B4\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uADF8 \uC911\uCCA9 node_modules \uC758 ${name} \uB97C \uC9C0\uC6B0\uAC70\uB098 ${todo}`;
|
|
1819
|
+
}
|
|
1820
|
+
case "shadow-target-missing":
|
|
1821
|
+
return `${head} \uBA3C\uC800 \uC7A1\uD788\uB294 ${label(r.pkgDir, r.version)}\uC5D0 \uB0B4\uBCF4\uB0B8 \uD30C\uC77C(${r.target})\uC774 \uC5C6\uC5B4 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uADF8 \uC911\uCCA9 node_modules \uC758 ${name} \uB97C \uC9C0\uC6B0\uAC70\uB098 \uB2E4\uC2DC \uC124\uCE58\uD558\uC138\uC694`;
|
|
1822
|
+
case "not-visible": {
|
|
1823
|
+
const there = expanded.files.find((f) => dirname2(f.path) === r.fromDir);
|
|
1824
|
+
const move = there !== void 0 ? `\uC774 \uC904(${origin.rel})\uC744 ${there.rel} \uB85C \uC62E\uAE30\uC138\uC694` : `\uC774 \uC904(${origin.rel})\uC744 \uADF8 \uC704\uCE58\uC758 CSS \uD30C\uC77C\uB85C \uC62E\uAE30\uC138\uC694`;
|
|
1825
|
+
return `${head} ${name} \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC124\uCE58\uBCF8\uC774 ${displayRel(baseDir, r.pkgDir)} \uC5D0\uB9CC \uC788\uC74C) \u2192 \uC571 \uB610\uB294 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC124\uCE58\uD558\uAC70\uB098 ${move}`;
|
|
1826
|
+
}
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
function isOutsideEntry(origin) {
|
|
1830
|
+
return origin.depth === 0 && origin.cssDir !== void 0;
|
|
1637
1831
|
}
|
|
1638
1832
|
function checkGlobalsCss(baseDirInput) {
|
|
1639
1833
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
@@ -1661,7 +1855,21 @@ function judgeGlobalsCss(baseDir, selection, candidate, expanded) {
|
|
|
1661
1855
|
if (imported !== void 0) {
|
|
1662
1856
|
const origin = evidenceOrigin(expanded, (f) => findTokensCssImport(f) === imported);
|
|
1663
1857
|
via = cssImportViaNote(viaFiles([origin]));
|
|
1664
|
-
const
|
|
1858
|
+
const tailwind4 = (detectTailwind(baseDir, pkg).major ?? 0) >= 4;
|
|
1859
|
+
const inside = origin !== void 0 && !isOutsideEntry(origin);
|
|
1860
|
+
const issue = tailwind4 && inside ? tokensCssUnresolvedIssue(
|
|
1861
|
+
baseDir,
|
|
1862
|
+
pkg,
|
|
1863
|
+
imported,
|
|
1864
|
+
void 0,
|
|
1865
|
+
() => packageLineShadowIssue(baseDir, expanded, origin, imported)
|
|
1866
|
+
) : tokensCssUnresolvedIssue(
|
|
1867
|
+
baseDir,
|
|
1868
|
+
pkg,
|
|
1869
|
+
imported,
|
|
1870
|
+
origin !== void 0 ? origin.cssDir : outsideCssDir(selection),
|
|
1871
|
+
inside ? () => packageLineShadowIssue(baseDir, expanded, origin, imported, { tailwind3: true }) : void 0
|
|
1872
|
+
);
|
|
1665
1873
|
if (issue !== void 0) unresolved = `${candidate}\uC5D0 ${issue}`;
|
|
1666
1874
|
else pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${imported} import)`;
|
|
1667
1875
|
} else if (AXIS_VARIABLE_DEFINITION.test(stripCssComments(expanded.evidence))) {
|
|
@@ -1865,6 +2073,8 @@ function stripJsComments(src) {
|
|
|
1865
2073
|
}
|
|
1866
2074
|
var TOKENS_TAILWIND3_PRESET = "@axis-ds/tokens/tailwind";
|
|
1867
2075
|
var PRESET_REFERENCE = /(?:\brequire\s*\(\s*|\bimport\s*\(\s*|\bfrom\s*|\bimport\s+)(["'])@axis-ds\/tokens\/tailwind\1/;
|
|
2076
|
+
var PRESET_REQUIRE_REFERENCE = /\brequire\s*\(\s*(["'])@axis-ds\/tokens\/tailwind\1/;
|
|
2077
|
+
var PRESET_IMPORT_REFERENCE = /(?:\bimport\s*\(\s*|\bfrom\s*|\bimport\s+)(["'])@axis-ds\/tokens\/tailwind\1/;
|
|
1868
2078
|
function hasTokensPresetReference(source) {
|
|
1869
2079
|
return PRESET_REFERENCE.test(stripJsComments(source));
|
|
1870
2080
|
}
|
|
@@ -1892,6 +2102,25 @@ function hasBareCjsPresetRequire(code) {
|
|
|
1892
2102
|
function isCommonJsConfig(file, source) {
|
|
1893
2103
|
return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
|
|
1894
2104
|
}
|
|
2105
|
+
function presetTokensUnresolvedMessage(baseDir, pkg, file, bareCjs, code) {
|
|
2106
|
+
const r = tokensCssResolution(baseDir, pkg, TOKENS_PACKAGE_NAME);
|
|
2107
|
+
const head = `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC ${TOKENS_PACKAGE_NAME} \uAC00`;
|
|
2108
|
+
if (r.kind === "not-installed") {
|
|
2109
|
+
return `${head} \uC124\uCE58\uB418\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC124\uCE58(${tokensInstallPhrase(baseDir, `^${TOKENS_CJS_PRESET_FIXED_VERSION}`)})`;
|
|
2110
|
+
}
|
|
2111
|
+
if (r.kind === "pnp-root-only" && !bareCjs) {
|
|
2112
|
+
return `${head} ${PNP_ROOT_ONLY_NOTE}(\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uC120\uC5B8 ${r.range}) \u2192 \uC571 package.json \uC5D0 ${TOKENS_PACKAGE_NAME} \uB97C \uC120\uC5B8\uD558\uC138\uC694`;
|
|
2113
|
+
}
|
|
2114
|
+
const e = tailwindConfigImportResolution(baseDir, TOKENS_TAILWIND3_PRESET, {
|
|
2115
|
+
require: PRESET_REQUIRE_REFERENCE.test(code),
|
|
2116
|
+
import: PRESET_IMPORT_REFERENCE.test(code)
|
|
2117
|
+
});
|
|
2118
|
+
if (e.kind === "not-exported") {
|
|
2119
|
+
const label = `${displayRel(baseDir, e.pkgDir)}(${e.version ?? "\uBC84\uC804 \uBAA8\uB984"})`;
|
|
2120
|
+
return `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC \uBA3C\uC800 \uC7A1\uD788\uB294 ${label}\uAC00 ${e.subpath} \uB97C \uB0B4\uBCF4\uB0B4\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uADF8 node_modules \uC758 ${TOKENS_PACKAGE_NAME} \uB97C \uC9C0\uC6B0\uAC70\uB098 \uB2E4\uC2DC \uC124\uCE58\uD558\uC138\uC694`;
|
|
2121
|
+
}
|
|
2122
|
+
return void 0;
|
|
2123
|
+
}
|
|
1895
2124
|
function packageVersionGate(baseDirInput, pkg, name, min, options = {}) {
|
|
1896
2125
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1897
2126
|
if (!isPnpProject(baseDir)) {
|
|
@@ -1944,7 +2173,8 @@ function tailwind4Issues(input, pkg, versions, baseDir) {
|
|
|
1944
2173
|
const r = resolutions.get(name);
|
|
1945
2174
|
if (r.kind === "undeclared" || r.kind === "app-lockfile") continue;
|
|
1946
2175
|
if (hasComponentTailwindImport(evidence, name) || hasComponentSource(evidence, name)) continue;
|
|
1947
|
-
if (
|
|
2176
|
+
if (r.kind === "app" && pnpComponentSourceHidden(baseDir, name, r.range)) unresolvedMissing.push(componentCssPnpMissingIssue(name));
|
|
2177
|
+
else if (componentCssResolvable(r)) missing.push(name);
|
|
1948
2178
|
else unresolvedMissing.push(componentCssMissingIssue(baseDir, name, r));
|
|
1949
2179
|
}
|
|
1950
2180
|
if (missing.length > 0) {
|
|
@@ -1960,12 +2190,28 @@ function tailwind4Issues(input, pkg, versions, baseDir) {
|
|
|
1960
2190
|
}
|
|
1961
2191
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1962
2192
|
if (!hasComponentTailwindImport(evidence, name)) continue;
|
|
1963
|
-
const
|
|
1964
|
-
const
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
issues.push(
|
|
1968
|
-
|
|
2193
|
+
const r = resolutions.get(name);
|
|
2194
|
+
const unresolved = componentCssPresentIssue(baseDir, name, r);
|
|
2195
|
+
const spec = `${name}/tailwind.css`;
|
|
2196
|
+
if (unresolved !== void 0) {
|
|
2197
|
+
issues.push(unresolved);
|
|
2198
|
+
continue;
|
|
2199
|
+
}
|
|
2200
|
+
if (r.kind === "app" && pnpComponentSourceHidden(baseDir, name, r.range)) {
|
|
2201
|
+
issues.push(componentCssPnpPresentIssue(name));
|
|
2202
|
+
continue;
|
|
2203
|
+
}
|
|
2204
|
+
const shadow = input.lineIssue === void 0 ? false : input.lineIssue(spec);
|
|
2205
|
+
let lineProblem;
|
|
2206
|
+
if (shadow !== false) lineProblem = shadow;
|
|
2207
|
+
else {
|
|
2208
|
+
const componentDir = cssDirOf(spec);
|
|
2209
|
+
if (componentDir !== void 0 && outsideCssPackageResolution(baseDir, componentDir, name, "tailwind.css") === "unresolved") {
|
|
2210
|
+
lineProblem = outsideCssUnresolvedIssue(spec, name);
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
if (lineProblem !== void 0) issues.push(lineProblem);
|
|
2214
|
+
else if (versions.some((v) => v.name === name)) issues.push(`${name}/tailwind.css import \uAC00 \uC788\uC9C0\uB9CC ${name} \uBC84\uC804 \uD655\uC778\uC774 \uD544\uC694\uD569\uB2C8\uB2E4`);
|
|
1969
2215
|
}
|
|
1970
2216
|
return issues;
|
|
1971
2217
|
}
|
|
@@ -1973,6 +2219,13 @@ function componentInstallPhrase(baseDir, name, range) {
|
|
|
1973
2219
|
const g = dependencyInstallGuide(baseDir, name, range);
|
|
1974
2220
|
return g.kind === "install-at-root" ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${g.installCommand}` : g.installCommand;
|
|
1975
2221
|
}
|
|
2222
|
+
var PNP_ZIP_SOURCE_NOTE = `Plug'n'Play \uC5D0\uC11C @source "./dist" \uAC00 .yarn/cache zip \uC548\uC744 \uAC00\uB9AC\uCF1C \uCEF4\uD3EC\uB10C\uD2B8 \uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
2223
|
+
function componentCssPnpMissingIssue(name) {
|
|
2224
|
+
return `${name} \uC758 tailwind.css \uB294 ${PNP_ZIP_SOURCE_NOTE} \u2192 ${pnpUnplugSetupPhrase(name)} \uB4A4 ${componentTailwindImportLine(name)}`;
|
|
2225
|
+
}
|
|
2226
|
+
function componentCssPnpPresentIssue(name) {
|
|
2227
|
+
return `${name}/tailwind.css import \uAC00 \uC788\uC9C0\uB9CC ${PNP_ZIP_SOURCE_NOTE} \u2192 ${pnpUnplugSetupPhrase(name)} \uD558\uC138\uC694`;
|
|
2228
|
+
}
|
|
1976
2229
|
function componentCssMissingIssue(baseDir, name, r) {
|
|
1977
2230
|
const line = componentTailwindImportLine(name);
|
|
1978
2231
|
switch (r.kind) {
|
|
@@ -2033,7 +2286,17 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2033
2286
|
);
|
|
2034
2287
|
const versions = axisPackagesBelowTailwind4(pkg, baseDir);
|
|
2035
2288
|
const issues = tailwind4Issues(
|
|
2036
|
-
{
|
|
2289
|
+
{
|
|
2290
|
+
entry: expanded.entry,
|
|
2291
|
+
evidence: expanded.evidence,
|
|
2292
|
+
cssDirOf: (spec) => packageLineCssDir(expanded, spec),
|
|
2293
|
+
lineIssue: (spec) => {
|
|
2294
|
+
const line = expanded.packageLines.find((l) => l.spec === spec);
|
|
2295
|
+
const origin = line !== void 0 ? expanded.files.find((f) => f.rel === line.file) : void 0;
|
|
2296
|
+
if (origin === void 0 || isOutsideEntry(origin)) return false;
|
|
2297
|
+
return packageLineShadowIssue(baseDir, expanded, origin, spec);
|
|
2298
|
+
}
|
|
2299
|
+
},
|
|
2037
2300
|
pkg,
|
|
2038
2301
|
versions,
|
|
2039
2302
|
baseDir
|
|
@@ -2058,12 +2321,15 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2058
2321
|
};
|
|
2059
2322
|
}
|
|
2060
2323
|
for (const file of TAILWIND_CONFIG_FILES) {
|
|
2061
|
-
const
|
|
2062
|
-
if (!existsSync3(
|
|
2063
|
-
const content = readFileSync4(
|
|
2324
|
+
const path12 = join2(baseDir, file);
|
|
2325
|
+
if (!existsSync3(path12)) continue;
|
|
2326
|
+
const content = readFileSync4(path12, "utf8");
|
|
2064
2327
|
if (hasTokensPresetReference(content)) {
|
|
2065
2328
|
const code = stripJsComments(content);
|
|
2066
|
-
|
|
2329
|
+
const bareCjs = isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code);
|
|
2330
|
+
const unresolved = presetTokensUnresolvedMessage(baseDir, pkg, file, bareCjs, code);
|
|
2331
|
+
if (unresolved !== void 0) return { name: "tailwind.config", severity: "warn", message: unresolved };
|
|
2332
|
+
if (bareCjs) {
|
|
2067
2333
|
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION, { appOnlyInPnp: true });
|
|
2068
2334
|
if (gate.status === "unresolved") {
|
|
2069
2335
|
return {
|
|
@@ -3491,11 +3757,11 @@ async function handleGetComponent(params, deps = {}) {
|
|
|
3491
3757
|
return { component, source: describeOrigin(client, latest.version), notices };
|
|
3492
3758
|
}
|
|
3493
3759
|
function handleGetToken(params) {
|
|
3494
|
-
const { path:
|
|
3495
|
-
if (!
|
|
3760
|
+
const { path: path12 } = params;
|
|
3761
|
+
if (!path12 || path12.trim() === "") {
|
|
3496
3762
|
throw new Error("\uD1A0\uD070 \uACBD\uB85C(path)\uB294 \uD544\uC218\uC785\uB2C8\uB2E4.");
|
|
3497
3763
|
}
|
|
3498
|
-
const token = getToken(
|
|
3764
|
+
const token = getToken(path12);
|
|
3499
3765
|
if (!token) {
|
|
3500
3766
|
return null;
|
|
3501
3767
|
}
|
|
@@ -3576,9 +3842,9 @@ function cssUsage(token) {
|
|
|
3576
3842
|
const shadcnColor = !token.cssVariable.startsWith("--axis-") && token.value.startsWith("hsl(");
|
|
3577
3843
|
return shadcnColor ? `hsl(var(${token.cssVariable}))` : `var(${token.cssVariable})`;
|
|
3578
3844
|
}
|
|
3579
|
-
function formatTokenNotFound(
|
|
3845
|
+
function formatTokenNotFound(path12) {
|
|
3580
3846
|
return [
|
|
3581
|
-
`\uD1A0\uD070\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: \`${
|
|
3847
|
+
`\uD1A0\uD070\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: \`${path12}\``,
|
|
3582
3848
|
"",
|
|
3583
3849
|
"- \uACBD\uB85C\uB294 `axis.list_tokens` \uB85C \uD655\uC778\uD558\uC138\uC694. \uACBD\uB85C \xB7 tokens \uC774\uB984 \uAE30\uBC18 \uACBD\uB85C(\uC608: `control.h.md`) \xB7 CSS \uBCC0\uC218 \uC774\uB984(\uC608: `--axis-control-h-md`)\uC744 \uBC1B\uC2B5\uB2C8\uB2E4.",
|
|
3584
3850
|
"- \uBE0C\uB79C\uB4DC \uAC12\uC740 `axis.list_brands` \xB7 `axis.get_brand` \uB85C \uC870\uD68C\uD558\uC138\uC694."
|
|
@@ -5276,12 +5542,14 @@ function formatSaveResult(result) {
|
|
|
5276
5542
|
// src/tools/template.ts
|
|
5277
5543
|
import fetch from "node-fetch";
|
|
5278
5544
|
import fs6 from "fs-extra";
|
|
5279
|
-
import
|
|
5545
|
+
import path10 from "path";
|
|
5280
5546
|
|
|
5281
5547
|
// src/tools/brand-core.ts
|
|
5548
|
+
import { createHash as createHash2 } from "crypto";
|
|
5282
5549
|
import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
5283
5550
|
import { createRequire } from "module";
|
|
5284
5551
|
import { dirname as dirname4, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
|
|
5552
|
+
import { MessageChannel, Worker, receiveMessageOnPort } from "worker_threads";
|
|
5285
5553
|
var TOKENS_PACKAGE = "@axis-ds/tokens";
|
|
5286
5554
|
var MIN_BRAND_TOKENS_VERSION = "1.3.0";
|
|
5287
5555
|
var TOKENS_DEPENDENCY_MIN_VERSION = "1.6.0";
|
|
@@ -5306,13 +5574,15 @@ function readJsonFile(file) {
|
|
|
5306
5574
|
function errorCode(err) {
|
|
5307
5575
|
return typeof err === "object" && err !== null && "code" in err ? String(err.code) : void 0;
|
|
5308
5576
|
}
|
|
5309
|
-
function
|
|
5577
|
+
function tokensPackageJsonCandidates(baseDir) {
|
|
5578
|
+
const candidates = [];
|
|
5310
5579
|
let dir = resolve3(baseDir);
|
|
5311
5580
|
for (; ; ) {
|
|
5312
5581
|
const candidate = join4(dir, "node_modules", TOKENS_PACKAGE, "package.json");
|
|
5313
|
-
|
|
5582
|
+
candidates.push(candidate);
|
|
5583
|
+
if (existsSync8(candidate)) return { found: candidate, candidates };
|
|
5314
5584
|
const parent = dirname4(dir);
|
|
5315
|
-
if (parent === dir) return
|
|
5585
|
+
if (parent === dir) return { candidates };
|
|
5316
5586
|
dir = parent;
|
|
5317
5587
|
}
|
|
5318
5588
|
}
|
|
@@ -5322,18 +5592,195 @@ function projectRequire(baseDir) {
|
|
|
5322
5592
|
function tokensSpecifier(subpath) {
|
|
5323
5593
|
return `${TOKENS_PACKAGE}/${subpath.replace(/^\.\//, "")}`;
|
|
5324
5594
|
}
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
|
|
5329
|
-
|
|
5595
|
+
var nodeSeenStates = /* @__PURE__ */ new Map();
|
|
5596
|
+
var ABSENT = "absent";
|
|
5597
|
+
var UNKNOWN = "unknown";
|
|
5598
|
+
var isolationDisabled = false;
|
|
5599
|
+
var isolatedStats = { workers: 0, resolves: 0, fallbacks: 0 };
|
|
5600
|
+
var ISOLATED_RESOLVE_TIMEOUT_MS = 5e3;
|
|
5601
|
+
var ISOLATED_RESOLVE_SOURCE = `
|
|
5602
|
+
const { workerData } = require("node:worker_threads");
|
|
5603
|
+
const { createRequire } = require("node:module");
|
|
5604
|
+
const { port, signal, from } = workerData;
|
|
5605
|
+
const req = createRequire(from);
|
|
5606
|
+
port.on("message", (spec) => {
|
|
5607
|
+
let reply;
|
|
5330
5608
|
try {
|
|
5331
|
-
|
|
5332
|
-
|
|
5609
|
+
reply = { path: req.resolve(spec) };
|
|
5610
|
+
} catch (err) {
|
|
5611
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : undefined;
|
|
5612
|
+
reply = { code, message: err && err.message ? String(err.message) : String(err) };
|
|
5613
|
+
}
|
|
5614
|
+
port.postMessage(reply);
|
|
5615
|
+
Atomics.store(signal, 0, 1);
|
|
5616
|
+
Atomics.notify(signal, 0);
|
|
5617
|
+
});
|
|
5618
|
+
`;
|
|
5619
|
+
var IsolationFailure = class extends Error {
|
|
5620
|
+
};
|
|
5621
|
+
function createWorkerResolveSession(from, source, timeoutMs) {
|
|
5622
|
+
const { port1, port2 } = new MessageChannel();
|
|
5623
|
+
const signal = new Int32Array(new SharedArrayBuffer(4));
|
|
5624
|
+
const worker = new Worker(source, {
|
|
5625
|
+
eval: true,
|
|
5626
|
+
workerData: { port: port2, signal, from },
|
|
5627
|
+
transferList: [port2]
|
|
5628
|
+
});
|
|
5629
|
+
worker.on("error", () => {
|
|
5630
|
+
});
|
|
5631
|
+
worker.unref();
|
|
5632
|
+
return {
|
|
5633
|
+
resolve(spec) {
|
|
5634
|
+
Atomics.store(signal, 0, 0);
|
|
5635
|
+
port1.postMessage(spec);
|
|
5636
|
+
const waited = Atomics.wait(signal, 0, 0, timeoutMs);
|
|
5637
|
+
const received = receiveMessageOnPort(port1);
|
|
5638
|
+
if (waited === "timed-out" || !received) throw new IsolationFailure("\uACA9\uB9AC \uD574\uC11D\uC774 \uC751\uB2F5\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
5639
|
+
const reply = received.message;
|
|
5640
|
+
if (typeof reply.path === "string") return reply.path;
|
|
5641
|
+
throw Object.assign(new Error(reply.message ?? spec), reply.code === void 0 ? {} : { code: reply.code });
|
|
5642
|
+
},
|
|
5643
|
+
close() {
|
|
5644
|
+
port1.close();
|
|
5645
|
+
void worker.terminate();
|
|
5646
|
+
}
|
|
5647
|
+
};
|
|
5648
|
+
}
|
|
5649
|
+
function workerResolveSession(from) {
|
|
5650
|
+
return createWorkerResolveSession(from, ISOLATED_RESOLVE_SOURCE, ISOLATED_RESOLVE_TIMEOUT_MS);
|
|
5651
|
+
}
|
|
5652
|
+
var isolatedFactory = workerResolveSession;
|
|
5653
|
+
function sha256(text) {
|
|
5654
|
+
return createHash2("sha256").update(text).digest("hex");
|
|
5655
|
+
}
|
|
5656
|
+
function openTokensResolver(baseDir, candidates, pkgJson, pkgText) {
|
|
5657
|
+
const nodeRequire = projectRequire(baseDir);
|
|
5658
|
+
const key = sha256(pkgText);
|
|
5659
|
+
const current = candidates.map((c) => c === pkgJson ? key : ABSENT);
|
|
5660
|
+
const changed = candidates.some((c, i) => {
|
|
5661
|
+
const seen = nodeSeenStates.get(c);
|
|
5662
|
+
return seen !== void 0 && seen !== current[i];
|
|
5663
|
+
});
|
|
5664
|
+
let mode = changed ? "isolated" : "node";
|
|
5665
|
+
if (mode === "node") {
|
|
5666
|
+
candidates.forEach((c, i) => {
|
|
5667
|
+
if (!nodeSeenStates.has(c)) nodeSeenStates.set(c, current[i]);
|
|
5668
|
+
});
|
|
5669
|
+
}
|
|
5670
|
+
let session = null;
|
|
5671
|
+
let stale = false;
|
|
5672
|
+
let raced = false;
|
|
5673
|
+
let postChecked = false;
|
|
5674
|
+
const markStale = () => {
|
|
5675
|
+
if (!stale) isolatedStats.fallbacks += 1;
|
|
5676
|
+
stale = true;
|
|
5677
|
+
};
|
|
5678
|
+
const fallBack = () => {
|
|
5679
|
+
markStale();
|
|
5680
|
+
isolationDisabled = true;
|
|
5681
|
+
session?.close();
|
|
5682
|
+
session = null;
|
|
5683
|
+
};
|
|
5684
|
+
const startIsolation = () => {
|
|
5685
|
+
if (isolationDisabled) {
|
|
5686
|
+
markStale();
|
|
5687
|
+
return;
|
|
5688
|
+
}
|
|
5689
|
+
try {
|
|
5690
|
+
session = isolatedFactory(join4(resolve3(baseDir), "package.json"));
|
|
5691
|
+
isolatedStats.workers += 1;
|
|
5692
|
+
} catch {
|
|
5693
|
+
fallBack();
|
|
5694
|
+
}
|
|
5695
|
+
};
|
|
5696
|
+
if (mode === "isolated") startIsolation();
|
|
5697
|
+
const isolatedResolve = (spec) => {
|
|
5698
|
+
if (session) {
|
|
5699
|
+
try {
|
|
5700
|
+
const resolved = session.resolve(spec);
|
|
5701
|
+
isolatedStats.resolves += 1;
|
|
5702
|
+
return resolved;
|
|
5703
|
+
} catch (err) {
|
|
5704
|
+
if (!(err instanceof IsolationFailure)) {
|
|
5705
|
+
isolatedStats.resolves += 1;
|
|
5706
|
+
throw err;
|
|
5707
|
+
}
|
|
5708
|
+
fallBack();
|
|
5709
|
+
}
|
|
5710
|
+
}
|
|
5711
|
+
return nodeRequire.resolve(spec);
|
|
5712
|
+
};
|
|
5713
|
+
return {
|
|
5714
|
+
resolve(spec) {
|
|
5715
|
+
if (mode === "isolated") return isolatedResolve(spec);
|
|
5716
|
+
let resolved;
|
|
5717
|
+
let failure;
|
|
5718
|
+
let failed = false;
|
|
5719
|
+
try {
|
|
5720
|
+
resolved = nodeRequire.resolve(spec);
|
|
5721
|
+
} catch (err) {
|
|
5722
|
+
failed = true;
|
|
5723
|
+
failure = err;
|
|
5724
|
+
}
|
|
5725
|
+
if (!postChecked) {
|
|
5726
|
+
postChecked = true;
|
|
5727
|
+
let after;
|
|
5728
|
+
try {
|
|
5729
|
+
after = sha256(readFileSync8(pkgJson, "utf8"));
|
|
5730
|
+
} catch {
|
|
5731
|
+
after = UNKNOWN;
|
|
5732
|
+
}
|
|
5733
|
+
if (after !== key) {
|
|
5734
|
+
nodeSeenStates.set(pkgJson, UNKNOWN);
|
|
5735
|
+
raced = true;
|
|
5736
|
+
mode = "isolated";
|
|
5737
|
+
startIsolation();
|
|
5738
|
+
return isolatedResolve(spec);
|
|
5739
|
+
}
|
|
5740
|
+
}
|
|
5741
|
+
if (failed) throw failure;
|
|
5742
|
+
return resolved;
|
|
5743
|
+
},
|
|
5744
|
+
get stale() {
|
|
5745
|
+
return stale;
|
|
5746
|
+
},
|
|
5747
|
+
get raced() {
|
|
5748
|
+
return raced;
|
|
5749
|
+
},
|
|
5750
|
+
close() {
|
|
5751
|
+
session?.close();
|
|
5752
|
+
session = null;
|
|
5753
|
+
}
|
|
5754
|
+
};
|
|
5755
|
+
}
|
|
5756
|
+
function readVersion(pkgText) {
|
|
5757
|
+
const pkg = JSON.parse(pkgText);
|
|
5758
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
5759
|
+
}
|
|
5760
|
+
function openTokens(baseDir) {
|
|
5761
|
+
const { found: pkgJson, candidates } = tokensPackageJsonCandidates(baseDir);
|
|
5762
|
+
if (!pkgJson) return { resolution: { status: "not-installed" } };
|
|
5763
|
+
const pkgText = readFileSync8(pkgJson, "utf8");
|
|
5764
|
+
let version = readVersion(pkgText);
|
|
5765
|
+
const resolver = openTokensResolver(baseDir, candidates, pkgJson, pkgText);
|
|
5766
|
+
const finish = (status, indexPath) => {
|
|
5767
|
+
if (resolver.raced) {
|
|
5768
|
+
try {
|
|
5769
|
+
version = readVersion(readFileSync8(pkgJson, "utf8"));
|
|
5770
|
+
} catch {
|
|
5771
|
+
}
|
|
5772
|
+
}
|
|
5773
|
+
const resolution = indexPath === void 0 ? { status, version } : { status, version, indexPath };
|
|
5774
|
+
return { resolution: resolver.stale ? { ...resolution, stale: true } : resolution, resolver };
|
|
5775
|
+
};
|
|
5776
|
+
try {
|
|
5777
|
+
const indexPath = resolver.resolve(tokensSpecifier("./brands"));
|
|
5778
|
+
return finish("ok", indexPath);
|
|
5333
5779
|
} catch (err) {
|
|
5334
5780
|
const code = errorCode(err);
|
|
5335
|
-
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") return
|
|
5336
|
-
if (code === "MODULE_NOT_FOUND") return
|
|
5781
|
+
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") return finish("unsupported");
|
|
5782
|
+
if (code === "MODULE_NOT_FOUND") return finish("not-built");
|
|
5783
|
+
resolver.close();
|
|
5337
5784
|
throw err;
|
|
5338
5785
|
}
|
|
5339
5786
|
}
|
|
@@ -5402,8 +5849,8 @@ function readBrandIndex(indexPath) {
|
|
|
5402
5849
|
}
|
|
5403
5850
|
return data.brands;
|
|
5404
5851
|
}
|
|
5405
|
-
function readSummary(
|
|
5406
|
-
const metaPath =
|
|
5852
|
+
function readSummary(resolver, entry) {
|
|
5853
|
+
const metaPath = resolver.resolve(tokensSpecifier(entry.meta));
|
|
5407
5854
|
const meta = readJsonFile(metaPath);
|
|
5408
5855
|
return {
|
|
5409
5856
|
name: entry.name,
|
|
@@ -5414,20 +5861,33 @@ function readSummary(baseDir, entry) {
|
|
|
5414
5861
|
};
|
|
5415
5862
|
}
|
|
5416
5863
|
function listBrands(baseDir) {
|
|
5417
|
-
const tokens =
|
|
5418
|
-
|
|
5864
|
+
const { resolution: tokens, resolver } = openTokens(baseDir);
|
|
5865
|
+
try {
|
|
5866
|
+
return withStaleOf(resolver, listBrandsWith(tokens, resolver));
|
|
5867
|
+
} finally {
|
|
5868
|
+
resolver?.close();
|
|
5869
|
+
}
|
|
5870
|
+
}
|
|
5871
|
+
function listBrandsWith(tokens, resolver) {
|
|
5872
|
+
if (tokens.status !== "ok" || !tokens.indexPath || !resolver) {
|
|
5419
5873
|
return { status: tokens.status, version: tokens.version, brands: [] };
|
|
5420
5874
|
}
|
|
5421
5875
|
const entries = readBrandIndex(tokens.indexPath);
|
|
5422
|
-
|
|
5423
|
-
|
|
5424
|
-
|
|
5425
|
-
|
|
5426
|
-
|
|
5427
|
-
|
|
5876
|
+
const brands = [];
|
|
5877
|
+
for (const entry of entries) {
|
|
5878
|
+
try {
|
|
5879
|
+
brands.push(readSummary(resolver, entry));
|
|
5880
|
+
} catch (err) {
|
|
5881
|
+
if (isMissingBuildFile(err)) return { status: "not-built", version: tokens.version, brands: [] };
|
|
5882
|
+
if (resolver.stale && errorCode(err) === "ERR_PACKAGE_PATH_NOT_EXPORTED") continue;
|
|
5883
|
+
throw err;
|
|
5884
|
+
}
|
|
5428
5885
|
}
|
|
5429
5886
|
return { status: "ok", version: tokens.version, brands };
|
|
5430
5887
|
}
|
|
5888
|
+
function withStaleOf(resolver, result) {
|
|
5889
|
+
return resolver?.stale ? { ...result, stale: true } : result;
|
|
5890
|
+
}
|
|
5431
5891
|
function stripComments(css) {
|
|
5432
5892
|
return css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
5433
5893
|
}
|
|
@@ -5539,8 +5999,15 @@ function readProjectPackageJson(baseDir) {
|
|
|
5539
5999
|
}
|
|
5540
6000
|
}
|
|
5541
6001
|
function getBrand(baseDir, name) {
|
|
5542
|
-
const tokens =
|
|
5543
|
-
|
|
6002
|
+
const { resolution: tokens, resolver } = openTokens(baseDir);
|
|
6003
|
+
try {
|
|
6004
|
+
return withStaleOf(resolver, getBrandWith(tokens, resolver, name));
|
|
6005
|
+
} finally {
|
|
6006
|
+
resolver?.close();
|
|
6007
|
+
}
|
|
6008
|
+
}
|
|
6009
|
+
function getBrandWith(tokens, resolver, name) {
|
|
6010
|
+
if (tokens.status !== "ok" || !tokens.indexPath || !resolver) {
|
|
5544
6011
|
return { status: tokens.status, version: tokens.version, brand: null, available: [] };
|
|
5545
6012
|
}
|
|
5546
6013
|
const entries = readBrandIndex(tokens.indexPath);
|
|
@@ -5552,11 +6019,14 @@ function getBrand(baseDir, name) {
|
|
|
5552
6019
|
let summary;
|
|
5553
6020
|
let parsed;
|
|
5554
6021
|
try {
|
|
5555
|
-
summary = readSummary(
|
|
5556
|
-
const cssPath =
|
|
6022
|
+
summary = readSummary(resolver, entry);
|
|
6023
|
+
const cssPath = resolver.resolve(summary.importPath);
|
|
5557
6024
|
parsed = parseBrandCss(readFileSync8(cssPath, "utf8"), name);
|
|
5558
6025
|
} catch (err) {
|
|
5559
6026
|
if (isMissingBuildFile(err)) return { status: "not-built", version: tokens.version, brand: null, available: [] };
|
|
6027
|
+
if (resolver.stale && errorCode(err) === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
6028
|
+
return { status: "ok", version: tokens.version, brand: null, available: available.filter((n) => n !== name) };
|
|
6029
|
+
}
|
|
5560
6030
|
throw err;
|
|
5561
6031
|
}
|
|
5562
6032
|
return {
|
|
@@ -5632,11 +6102,15 @@ function checkDependencies(baseDirInput) {
|
|
|
5632
6102
|
if (missingRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 \uB204\uB77D: ${missingRecommended.join(", ")}`);
|
|
5633
6103
|
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`);
|
|
5634
6104
|
if (pnpRootAxis.length > 0) problems.push(`${pnpRootAxis.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
6105
|
+
const installCommand = detectInstallCommand(baseDir);
|
|
5635
6106
|
if (notInstalledOther.length > 0) {
|
|
5636
|
-
|
|
6107
|
+
const phrase = installCommandPhrase(installCommand, notInstalledOther.some((d) => fromRoot(d)));
|
|
6108
|
+
problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalledOther.join(", ")} \u2192 ${phrase}`);
|
|
5637
6109
|
}
|
|
5638
6110
|
if (notInstalledRoot.length > 0) {
|
|
5639
|
-
problems.push(
|
|
6111
|
+
problems.push(
|
|
6112
|
+
`\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 ${installCommandPhrase(installCommand, true)}`
|
|
6113
|
+
);
|
|
5640
6114
|
}
|
|
5641
6115
|
if (problems.length > 0) {
|
|
5642
6116
|
return { name: "dependencies", severity: "warn", message: problems.join(" / ") + (rootNote ? ` (${rootNote})` : "") };
|
|
@@ -5649,6 +6123,192 @@ function checkDependencies(baseDirInput) {
|
|
|
5649
6123
|
};
|
|
5650
6124
|
}
|
|
5651
6125
|
|
|
6126
|
+
// ../axis-registry-core/src/template/apply-files.ts
|
|
6127
|
+
import { existsSync as existsSync9, lstatSync as lstatSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync10, readdirSync as readdirSync3, realpathSync as realpathSync4, rmdirSync, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
6128
|
+
import path9 from "path";
|
|
6129
|
+
var TemplatePathError = class extends Error {
|
|
6130
|
+
constructor(relPath, reason) {
|
|
6131
|
+
super(`\uD15C\uD50C\uB9BF \uACBD\uB85C '${relPath}' \uAC00 \uB300\uC0C1 \uB514\uB809\uD130\uB9AC \uBC16\uC744 \uAC00\uB9AC\uCF1C(${reason}) \uC911\uB2E8\uD588\uC2B5\uB2C8\uB2E4. \uC544\uBB34 \uD30C\uC77C\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4`);
|
|
6132
|
+
this.relPath = relPath;
|
|
6133
|
+
this.reason = reason;
|
|
6134
|
+
this.name = "TemplatePathError";
|
|
6135
|
+
}
|
|
6136
|
+
};
|
|
6137
|
+
function realpathOfExisting(p) {
|
|
6138
|
+
const rest = [];
|
|
6139
|
+
let cur = p;
|
|
6140
|
+
for (; ; ) {
|
|
6141
|
+
try {
|
|
6142
|
+
lstatSync3(cur);
|
|
6143
|
+
break;
|
|
6144
|
+
} catch {
|
|
6145
|
+
const parent = path9.dirname(cur);
|
|
6146
|
+
if (parent === cur) break;
|
|
6147
|
+
rest.unshift(path9.basename(cur));
|
|
6148
|
+
cur = parent;
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
try {
|
|
6152
|
+
return path9.join(realpathSync4(cur), ...rest);
|
|
6153
|
+
} catch {
|
|
6154
|
+
return void 0;
|
|
6155
|
+
}
|
|
6156
|
+
}
|
|
6157
|
+
function isInside(root, target) {
|
|
6158
|
+
const rel2 = path9.relative(root, target);
|
|
6159
|
+
return rel2 !== "" && !rel2.startsWith("..") && !path9.isAbsolute(rel2);
|
|
6160
|
+
}
|
|
6161
|
+
function resolveTemplatePath(baseDir, relPath) {
|
|
6162
|
+
if (typeof relPath !== "string" || relPath === "" || relPath.includes("\0")) {
|
|
6163
|
+
throw new TemplatePathError(String(relPath), "\uBE48 \uACBD\uB85C \uB610\uB294 \uC798\uBABB\uB41C \uBB38\uC790");
|
|
6164
|
+
}
|
|
6165
|
+
if (path9.isAbsolute(relPath) || path9.win32.isAbsolute(relPath)) throw new TemplatePathError(relPath, "\uC808\uB300 \uACBD\uB85C");
|
|
6166
|
+
const base = path9.resolve(baseDir);
|
|
6167
|
+
const dest = path9.resolve(base, relPath);
|
|
6168
|
+
if (!isInside(base, dest)) throw new TemplatePathError(relPath, "\uC0C1\uC704 \uB514\uB809\uD130\uB9AC\uB85C \uB098\uAC10");
|
|
6169
|
+
const baseReal = realpathOfExisting(base);
|
|
6170
|
+
const destReal = realpathOfExisting(dest);
|
|
6171
|
+
if (!baseReal || !destReal || !isInside(baseReal, destReal)) {
|
|
6172
|
+
throw new TemplatePathError(relPath, "\uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uAC00 \uB300\uC0C1 \uB514\uB809\uD130\uB9AC \uBC16\uC744 \uAC00\uB9AC\uD0B4");
|
|
6173
|
+
}
|
|
6174
|
+
return dest;
|
|
6175
|
+
}
|
|
6176
|
+
function assertTemplatePaths(baseDir, relPaths) {
|
|
6177
|
+
for (const p of relPaths) resolveTemplatePath(baseDir, p);
|
|
6178
|
+
}
|
|
6179
|
+
var PACKAGE_JSON_MERGED_MAPS = [
|
|
6180
|
+
"scripts",
|
|
6181
|
+
"dependencies",
|
|
6182
|
+
"devDependencies",
|
|
6183
|
+
"peerDependencies",
|
|
6184
|
+
"optionalDependencies"
|
|
6185
|
+
];
|
|
6186
|
+
function isPlainObject3(v) {
|
|
6187
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
6188
|
+
}
|
|
6189
|
+
function parseObject(text) {
|
|
6190
|
+
try {
|
|
6191
|
+
const v = JSON.parse(text);
|
|
6192
|
+
return isPlainObject3(v) ? v : void 0;
|
|
6193
|
+
} catch {
|
|
6194
|
+
return void 0;
|
|
6195
|
+
}
|
|
6196
|
+
}
|
|
6197
|
+
function mergePackageJson(user, template) {
|
|
6198
|
+
const maps = new Set(PACKAGE_JSON_MERGED_MAPS);
|
|
6199
|
+
const out = {};
|
|
6200
|
+
for (const [key, value] of Object.entries(user)) {
|
|
6201
|
+
const tpl = template[key];
|
|
6202
|
+
if (maps.has(key) && isPlainObject3(tpl)) {
|
|
6203
|
+
out[key] = isPlainObject3(value) ? { ...value, ...tpl } : tpl;
|
|
6204
|
+
} else {
|
|
6205
|
+
out[key] = value;
|
|
6206
|
+
}
|
|
6207
|
+
}
|
|
6208
|
+
for (const [key, value] of Object.entries(template)) {
|
|
6209
|
+
if (!(key in out)) out[key] = value;
|
|
6210
|
+
}
|
|
6211
|
+
return out;
|
|
6212
|
+
}
|
|
6213
|
+
function mergeAxisConfigJson(user, template) {
|
|
6214
|
+
return { ...user, ...template };
|
|
6215
|
+
}
|
|
6216
|
+
function detectJsonIndent(text) {
|
|
6217
|
+
const m = /^([ \t]+)\S/m.exec(text);
|
|
6218
|
+
if (!m) return 2;
|
|
6219
|
+
return m[1].startsWith(" ") ? " " : m[1].length;
|
|
6220
|
+
}
|
|
6221
|
+
function serializeLike(before, value) {
|
|
6222
|
+
const crlf = before.includes("\r\n");
|
|
6223
|
+
const trailing = /\r?\n$/.test(before);
|
|
6224
|
+
let text = JSON.stringify(value, null, detectJsonIndent(before));
|
|
6225
|
+
if (trailing) text += "\n";
|
|
6226
|
+
return crlf ? text.replace(/\n/g, "\r\n") : text;
|
|
6227
|
+
}
|
|
6228
|
+
var MERGERS = {
|
|
6229
|
+
"package.json": mergePackageJson,
|
|
6230
|
+
"axis.config.json": mergeAxisConfigJson
|
|
6231
|
+
};
|
|
6232
|
+
function planTemplateFileContent(relPath, templateContent, before) {
|
|
6233
|
+
if (before === void 0) return { action: "created", content: templateContent };
|
|
6234
|
+
const merger = MERGERS[relPath.replace(/^\.\//, "")];
|
|
6235
|
+
if (!merger) return { action: "overwritten", content: templateContent };
|
|
6236
|
+
const user = parseObject(before);
|
|
6237
|
+
const template = parseObject(templateContent);
|
|
6238
|
+
if (!user || !template) {
|
|
6239
|
+
return {
|
|
6240
|
+
action: "overwritten",
|
|
6241
|
+
content: templateContent,
|
|
6242
|
+
note: `\uAE30\uC874 ${relPath} \uC744 JSON \uAC1D\uCCB4\uB85C \uC77D\uC744 \uC218 \uC5C6\uC5B4 \uD15C\uD50C\uB9BF \uB0B4\uC6A9\uC73C\uB85C \uB36E\uC5B4\uC501\uB2C8\uB2E4`
|
|
6243
|
+
};
|
|
6244
|
+
}
|
|
6245
|
+
return { action: "merged", content: serializeLike(before, merger(user, template)) };
|
|
6246
|
+
}
|
|
6247
|
+
function planTemplateFiles(baseDir, files, extraPaths = []) {
|
|
6248
|
+
const dests = files.map((file) => resolveTemplatePath(baseDir, file.path));
|
|
6249
|
+
assertTemplatePaths(baseDir, extraPaths);
|
|
6250
|
+
return files.map((file, i) => {
|
|
6251
|
+
const dest = dests[i];
|
|
6252
|
+
const before = existsSync9(dest) ? readFileSync10(dest, "utf8") : void 0;
|
|
6253
|
+
return { path: file.path, dest, before, ...planTemplateFileContent(file.path, file.content, before) };
|
|
6254
|
+
});
|
|
6255
|
+
}
|
|
6256
|
+
var TemplateApplyError = class extends Error {
|
|
6257
|
+
constructor(message, restored, unrestored) {
|
|
6258
|
+
super(message);
|
|
6259
|
+
this.restored = restored;
|
|
6260
|
+
this.unrestored = unrestored;
|
|
6261
|
+
this.name = "TemplateApplyError";
|
|
6262
|
+
}
|
|
6263
|
+
};
|
|
6264
|
+
function writeTemplateFiles(plan) {
|
|
6265
|
+
const done = [];
|
|
6266
|
+
const madeDirs = [];
|
|
6267
|
+
try {
|
|
6268
|
+
for (const item of plan) {
|
|
6269
|
+
const dir = path9.dirname(item.dest);
|
|
6270
|
+
if (!existsSync9(dir)) {
|
|
6271
|
+
const fresh = [];
|
|
6272
|
+
for (let d = dir; !existsSync9(d); d = path9.dirname(d)) fresh.unshift(d);
|
|
6273
|
+
mkdirSync2(dir, { recursive: true });
|
|
6274
|
+
madeDirs.push(...fresh);
|
|
6275
|
+
}
|
|
6276
|
+
writeFileSync2(item.dest, item.content);
|
|
6277
|
+
done.push(item);
|
|
6278
|
+
}
|
|
6279
|
+
} catch (err) {
|
|
6280
|
+
const restored = [];
|
|
6281
|
+
const unrestored = [];
|
|
6282
|
+
const failed = plan[done.length];
|
|
6283
|
+
const targets = failed ? [...done, failed] : done;
|
|
6284
|
+
for (const item of targets.reverse()) {
|
|
6285
|
+
try {
|
|
6286
|
+
if (item.before === void 0) {
|
|
6287
|
+
if (existsSync9(item.dest)) unlinkSync(item.dest);
|
|
6288
|
+
} else {
|
|
6289
|
+
writeFileSync2(item.dest, item.before);
|
|
6290
|
+
}
|
|
6291
|
+
restored.push(item.path);
|
|
6292
|
+
} catch {
|
|
6293
|
+
unrestored.push(item.path);
|
|
6294
|
+
}
|
|
6295
|
+
}
|
|
6296
|
+
for (const d of madeDirs.reverse()) {
|
|
6297
|
+
try {
|
|
6298
|
+
if (existsSync9(d) && readdirSync3(d).length === 0) rmdirSync(d);
|
|
6299
|
+
} catch {
|
|
6300
|
+
}
|
|
6301
|
+
}
|
|
6302
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
6303
|
+
const tail = unrestored.length > 0 ? ` \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD55C \uD30C\uC77C: ${unrestored.join(", ")}` : "";
|
|
6304
|
+
throw new TemplateApplyError(
|
|
6305
|
+
`\uD15C\uD50C\uB9BF \uD30C\uC77C\uC744 \uC4F0\uB294 \uB3C4\uC911 \uC2E4\uD328\uD574 \uAC74\uB4DC\uB9B0 \uD30C\uC77C ${restored.length}\uAC1C\uB97C \uC6D0\uB798\uB300\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4(${reason}).${tail}`,
|
|
6306
|
+
restored.reverse(),
|
|
6307
|
+
unrestored
|
|
6308
|
+
);
|
|
6309
|
+
}
|
|
6310
|
+
}
|
|
6311
|
+
|
|
5652
6312
|
// src/site.ts
|
|
5653
6313
|
var AXIS_SITE_URL2 = "https://axis-design-system.pages.dev";
|
|
5654
6314
|
|
|
@@ -5702,24 +6362,18 @@ async function handleGetTemplate(params) {
|
|
|
5702
6362
|
}
|
|
5703
6363
|
async function handleApplyTemplate(params) {
|
|
5704
6364
|
const detail = await fetchTemplateDetail(params.name);
|
|
5705
|
-
const baseDir =
|
|
6365
|
+
const baseDir = path10.resolve(params.targetDir);
|
|
5706
6366
|
const installCommand = detectInstallCommand(baseDir);
|
|
5707
|
-
const
|
|
5708
|
-
|
|
5709
|
-
|
|
5710
|
-
|
|
5711
|
-
|
|
5712
|
-
|
|
5713
|
-
|
|
5714
|
-
}
|
|
5715
|
-
files.push({
|
|
5716
|
-
path: file.path,
|
|
5717
|
-
action: exists ? "overwritten" : "created"
|
|
5718
|
-
});
|
|
5719
|
-
}
|
|
6367
|
+
const plan = planTemplateFiles(baseDir, detail.files, (detail.postInstall ?? []).map((p) => p.file));
|
|
6368
|
+
if (!params.dryRun) writeTemplateFiles(plan);
|
|
6369
|
+
const files = plan.map((item) => ({
|
|
6370
|
+
path: item.path,
|
|
6371
|
+
action: item.action,
|
|
6372
|
+
...item.note ? { note: item.note } : {}
|
|
6373
|
+
}));
|
|
5720
6374
|
if (!params.dryRun && detail.postInstall?.length) {
|
|
5721
6375
|
for (const patch of detail.postInstall) {
|
|
5722
|
-
const target =
|
|
6376
|
+
const target = resolveTemplatePath(baseDir, patch.file);
|
|
5723
6377
|
if (!await fs6.pathExists(target)) continue;
|
|
5724
6378
|
if (patch.type === "replace" && patch.search && patch.value) {
|
|
5725
6379
|
const content = await fs6.readFile(target, "utf-8");
|
|
@@ -5747,10 +6401,11 @@ async function handleApplyTemplate(params) {
|
|
|
5747
6401
|
}
|
|
5748
6402
|
async function handleDiffTemplate(params) {
|
|
5749
6403
|
const detail = await fetchTemplateDetail(params.name);
|
|
5750
|
-
const baseDir =
|
|
6404
|
+
const baseDir = path10.resolve(params.targetDir || ".");
|
|
5751
6405
|
const entries = [];
|
|
5752
|
-
|
|
5753
|
-
|
|
6406
|
+
const localPaths = detail.files.map((file) => resolveTemplatePath(baseDir, file.path));
|
|
6407
|
+
for (const [i, file] of detail.files.entries()) {
|
|
6408
|
+
const localPath = localPaths[i];
|
|
5754
6409
|
if (!await fs6.pathExists(localPath)) {
|
|
5755
6410
|
entries.push({ path: file.path, status: "added" });
|
|
5756
6411
|
continue;
|
|
@@ -5838,9 +6493,9 @@ function brandActivationResult(check) {
|
|
|
5838
6493
|
};
|
|
5839
6494
|
}
|
|
5840
6495
|
async function handleCheckProject(params) {
|
|
5841
|
-
const baseDir =
|
|
6496
|
+
const baseDir = path10.resolve(params.targetDir || ".");
|
|
5842
6497
|
const results = [];
|
|
5843
|
-
const configExists = await fs6.pathExists(
|
|
6498
|
+
const configExists = await fs6.pathExists(path10.join(baseDir, "axis.config.json"));
|
|
5844
6499
|
results.push({
|
|
5845
6500
|
name: "axis.config.json",
|
|
5846
6501
|
severity: configExists ? "pass" : "fail",
|
|
@@ -5857,7 +6512,7 @@ async function handleCheckProject(params) {
|
|
|
5857
6512
|
];
|
|
5858
6513
|
let utilsFound = false;
|
|
5859
6514
|
for (const candidate of utilsCandidates) {
|
|
5860
|
-
const fullPath =
|
|
6515
|
+
const fullPath = path10.join(baseDir, candidate);
|
|
5861
6516
|
if (await fs6.pathExists(fullPath)) {
|
|
5862
6517
|
const content2 = await fs6.readFile(fullPath, "utf-8");
|
|
5863
6518
|
const hasCn = content2.includes("function cn");
|
|
@@ -5948,9 +6603,15 @@ function formatApplyTemplateResult(result) {
|
|
|
5948
6603
|
`);
|
|
5949
6604
|
if (result.files.length > 0) {
|
|
5950
6605
|
lines.push("### \uD30C\uC77C", "");
|
|
6606
|
+
const label = {
|
|
6607
|
+
created: "\uC0DD\uC131",
|
|
6608
|
+
overwritten: "\uB36E\uC5B4\uC4F0\uAE30",
|
|
6609
|
+
merged: "\uD569\uCE58\uAE30: \uAE30\uC874 \uD544\uB4DC\uB97C \uB450\uACE0 \uD15C\uD50C\uB9BF \uD0A4\uB97C \uD569\uCE68"
|
|
6610
|
+
};
|
|
5951
6611
|
for (const f of result.files) {
|
|
5952
6612
|
const icon = f.action === "created" ? "+" : "~";
|
|
5953
|
-
lines.push(`- ${icon} ${f.path} (${f.action
|
|
6613
|
+
lines.push(`- ${icon} ${f.path} (${label[f.action]})`);
|
|
6614
|
+
if (f.note) lines.push(` - ! ${f.note}`);
|
|
5954
6615
|
}
|
|
5955
6616
|
}
|
|
5956
6617
|
const deps = Object.entries(result.dependencies);
|
|
@@ -6002,10 +6663,10 @@ function formatCheckProjectResult(result) {
|
|
|
6002
6663
|
}
|
|
6003
6664
|
|
|
6004
6665
|
// src/tools/brand.ts
|
|
6005
|
-
import
|
|
6666
|
+
import path11 from "path";
|
|
6006
6667
|
var TOKENS_INSTALL_COMMAND = addCommandFor("pnpm install", { [TOKENS_PACKAGE]: `^${TOKENS_DEPENDENCY_MIN_VERSION}` });
|
|
6007
6668
|
function baseDirOf(targetDir) {
|
|
6008
|
-
return
|
|
6669
|
+
return path11.resolve(targetDir || process.cwd());
|
|
6009
6670
|
}
|
|
6010
6671
|
function tokensInstallGuideFor(targetDir) {
|
|
6011
6672
|
return dependencyInstallGuide(baseDirOf(targetDir), TOKENS_PACKAGE, `^${TOKENS_DEPENDENCY_MIN_VERSION}`);
|
|
@@ -6043,7 +6704,16 @@ function formatTokensStatusGuide(status, version, installCommand = TOKENS_INSTAL
|
|
|
6043
6704
|
].join("\n");
|
|
6044
6705
|
}
|
|
6045
6706
|
}
|
|
6707
|
+
var STALE_TOKENS_NOTE = `- \uC8FC\uC758: \uC774 MCP \uC11C\uBC84\uAC00 ${TOKENS_PACKAGE} \uB97C \uCC98\uC74C \uC77D\uC740 \uB4A4 \uB0B4\uC6A9\uC774 \uBC14\uB00C\uC5C8\uB294\uB370 \uC0C8 \uC0C1\uD0DC\uB97C \uB2E4\uC2DC \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC704 \uACB0\uACFC\uB294 \uC774\uC804 \uC124\uCE58 \uAE30\uC900\uC77C \uC218 \uC788\uC73C\uB2C8 MCP \uC11C\uBC84\uB97C \uB2E4\uC2DC \uC2DC\uC791\uD558\uC138\uC694.`;
|
|
6708
|
+
function withStaleNote(text, result) {
|
|
6709
|
+
return result.stale ? `${text}
|
|
6710
|
+
|
|
6711
|
+
${STALE_TOKENS_NOTE}` : text;
|
|
6712
|
+
}
|
|
6046
6713
|
function formatListBrandsResult(result, installCommand) {
|
|
6714
|
+
return withStaleNote(listBrandsText(result, installCommand), result);
|
|
6715
|
+
}
|
|
6716
|
+
function listBrandsText(result, installCommand) {
|
|
6047
6717
|
const lines = ["## AXIS \uBE0C\uB79C\uB4DC\n"];
|
|
6048
6718
|
if (result.status !== "ok") {
|
|
6049
6719
|
lines.push(formatTokensStatusGuide(result.status, result.version, installCommand));
|
|
@@ -6081,6 +6751,9 @@ function tokenTable(brand) {
|
|
|
6081
6751
|
return lines;
|
|
6082
6752
|
}
|
|
6083
6753
|
function formatGetBrandResult(result, name, installCommand) {
|
|
6754
|
+
return withStaleNote(getBrandText(result, name, installCommand), result);
|
|
6755
|
+
}
|
|
6756
|
+
function getBrandText(result, name, installCommand) {
|
|
6084
6757
|
if (result.status !== "ok") {
|
|
6085
6758
|
return [`## \uBE0C\uB79C\uB4DC: ${name}
|
|
6086
6759
|
`, formatTokensStatusGuide(result.status, result.version, installCommand)].join("\n");
|
|
@@ -6281,10 +6954,10 @@ server.tool(
|
|
|
6281
6954
|
{
|
|
6282
6955
|
path: z.string().describe("\uD1A0\uD070 \uACBD\uB85C (\uC608: colors.primary, spacing.4, control.h.md) \uB610\uB294 CSS \uBCC0\uC218 \uC774\uB984 (\uC608: --axis-control-h-md)")
|
|
6283
6956
|
},
|
|
6284
|
-
async ({ path:
|
|
6957
|
+
async ({ path: path12 }) => {
|
|
6285
6958
|
try {
|
|
6286
|
-
const token = handleGetToken({ path:
|
|
6287
|
-
const formatted = formatTokenDetail(token,
|
|
6959
|
+
const token = handleGetToken({ path: path12 });
|
|
6960
|
+
const formatted = formatTokenDetail(token, path12);
|
|
6288
6961
|
return {
|
|
6289
6962
|
content: [
|
|
6290
6963
|
{
|