@axis-ds/mcp 1.4.1 → 1.4.2
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 +153 -86
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ Claude Desktop 또는 기타 MCP 호환 클라이언트에서 설정:
|
|
|
41
41
|
- 이름은 레지스트리 이름 그대로입니다. Agentic UI 는 `agentic-` 접두를 붙입니다(예: `agentic-run-progress`). 의존 항목(`utils` · `agentic-a11y-labels`)은 함께 설치됩니다.
|
|
42
42
|
- `targetDir` 는 이미 있는 프로젝트 루트입니다(상대 경로는 서버의 현재 디렉터리 기준). `axis.config.json` 이 있으면 그 `componentsDir` · `agenticDir` 에, 없으면 `components/ui` · `components/agentic` 에 설치하고 그 사실을 알립니다. 프로젝트 밖으로 나가는 경로는 아무것도 쓰지 않고 실패합니다.
|
|
43
43
|
- 내용이 다른 기존 파일은 덮어쓰지 않고 건너뛰며 응답 첫머리에 건너뛴 수를 적습니다. `overwrite: true` 일 때만 덮어씁니다.
|
|
44
|
-
- 의존성은 설치하지 않고 lockfile 에 맞는 명령(`pnpm add` · `npm install` · `yarn add`)만 안내합니다.
|
|
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
45
|
|
|
46
46
|
## 토큰 도구
|
|
47
47
|
|
package/dist/index.js
CHANGED
|
@@ -603,7 +603,7 @@ function createPinnedFetch(options = {}) {
|
|
|
603
603
|
const judge = options.judge ?? blockedAddressReason;
|
|
604
604
|
const send = options.request ?? httpsRequest;
|
|
605
605
|
const maxBytes = options.maxBytes ?? PINNED_FETCH_MAX_BYTES;
|
|
606
|
-
return (input, init) => new Promise((
|
|
606
|
+
return (input, init) => new Promise((resolve4, reject) => {
|
|
607
607
|
let url;
|
|
608
608
|
try {
|
|
609
609
|
url = new URL(input);
|
|
@@ -644,7 +644,7 @@ function createPinnedFetch(options = {}) {
|
|
|
644
644
|
if (failed) return;
|
|
645
645
|
const body = Buffer.concat(chunks).toString("utf8");
|
|
646
646
|
const status = res.statusCode ?? 0;
|
|
647
|
-
|
|
647
|
+
resolve4({ ok: status >= 200 && status < 300, status, text: async () => body });
|
|
648
648
|
});
|
|
649
649
|
}
|
|
650
650
|
);
|
|
@@ -871,8 +871,16 @@ var RegistryClient = class {
|
|
|
871
871
|
};
|
|
872
872
|
|
|
873
873
|
// ../axis-registry-core/src/project.ts
|
|
874
|
-
import { existsSync as existsSync2, readFileSync as readFileSync3, statSync } from "fs";
|
|
874
|
+
import { existsSync as existsSync2, readFileSync as readFileSync3, realpathSync, statSync } from "fs";
|
|
875
875
|
import path3 from "path";
|
|
876
|
+
function resolveBaseDir(baseDirInput) {
|
|
877
|
+
const resolved = path3.resolve(baseDirInput);
|
|
878
|
+
try {
|
|
879
|
+
return realpathSync(resolved);
|
|
880
|
+
} catch {
|
|
881
|
+
return resolved;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
876
884
|
var LOCKFILE_COMMANDS = [
|
|
877
885
|
["pnpm-lock.yaml", "pnpm install"],
|
|
878
886
|
["yarn.lock", "yarn install"],
|
|
@@ -894,7 +902,7 @@ function isWorkspaceRootDir(dir) {
|
|
|
894
902
|
return Array.isArray(ws) || isPlainObject(ws) && Array.isArray(ws.packages);
|
|
895
903
|
}
|
|
896
904
|
function findWorkspaceRoot(baseDirInput) {
|
|
897
|
-
let dir =
|
|
905
|
+
let dir = resolveBaseDir(baseDirInput);
|
|
898
906
|
for (; ; ) {
|
|
899
907
|
if (isWorkspaceRootDir(dir)) return dir;
|
|
900
908
|
if (existsSync2(path3.join(dir, ".git"))) return void 0;
|
|
@@ -903,17 +911,45 @@ function findWorkspaceRoot(baseDirInput) {
|
|
|
903
911
|
dir = parent;
|
|
904
912
|
}
|
|
905
913
|
}
|
|
914
|
+
var PACKAGE_MANAGER_COMMANDS = {
|
|
915
|
+
pnpm: "pnpm install",
|
|
916
|
+
yarn: "yarn install",
|
|
917
|
+
npm: "npm install"
|
|
918
|
+
};
|
|
919
|
+
function packageManagerCommandAt(dir) {
|
|
920
|
+
let parsed;
|
|
921
|
+
try {
|
|
922
|
+
parsed = JSON.parse(readFileSync3(path3.join(dir, "package.json"), "utf8"));
|
|
923
|
+
} catch {
|
|
924
|
+
return void 0;
|
|
925
|
+
}
|
|
926
|
+
if (!isPlainObject(parsed) || typeof parsed.packageManager !== "string") return void 0;
|
|
927
|
+
const name = /^(pnpm|yarn|npm)@/.exec(parsed.packageManager.trim())?.[1];
|
|
928
|
+
return name !== void 0 ? PACKAGE_MANAGER_COMMANDS[name] : void 0;
|
|
929
|
+
}
|
|
906
930
|
function detectInstallCommand(baseDirInput) {
|
|
907
|
-
const baseDir =
|
|
931
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
908
932
|
const own = lockfileCommandAt(baseDir);
|
|
909
933
|
if (own !== void 0) return own;
|
|
910
|
-
const
|
|
911
|
-
|
|
934
|
+
const found = findWorkspaceRoot(baseDir);
|
|
935
|
+
const root = found !== void 0 && found !== baseDir ? found : void 0;
|
|
936
|
+
if (root !== void 0) {
|
|
912
937
|
const fromRoot = lockfileCommandAt(root);
|
|
913
938
|
if (fromRoot !== void 0) return fromRoot;
|
|
914
939
|
}
|
|
940
|
+
const ownManager = packageManagerCommandAt(baseDir);
|
|
941
|
+
if (ownManager !== void 0) return ownManager;
|
|
942
|
+
if (root !== void 0) {
|
|
943
|
+
const rootManager = packageManagerCommandAt(root);
|
|
944
|
+
if (rootManager !== void 0) return rootManager;
|
|
945
|
+
}
|
|
915
946
|
return "pnpm install";
|
|
916
947
|
}
|
|
948
|
+
function packageManagerOf(command) {
|
|
949
|
+
if (command.startsWith("yarn")) return "yarn";
|
|
950
|
+
if (command.startsWith("npm")) return "npm";
|
|
951
|
+
return "pnpm";
|
|
952
|
+
}
|
|
917
953
|
function hasDependency(pkg, name) {
|
|
918
954
|
for (const field of ["dependencies", "devDependencies"]) {
|
|
919
955
|
const deps = pkg[field];
|
|
@@ -923,14 +959,52 @@ function hasDependency(pkg, name) {
|
|
|
923
959
|
}
|
|
924
960
|
return void 0;
|
|
925
961
|
}
|
|
962
|
+
function workspaceRootPackage(baseDirInput) {
|
|
963
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
964
|
+
const root = findWorkspaceRoot(baseDir);
|
|
965
|
+
if (root === void 0 || root === baseDir) return void 0;
|
|
966
|
+
try {
|
|
967
|
+
const parsed = JSON.parse(readFileSync3(path3.join(root, "package.json"), "utf8"));
|
|
968
|
+
return isPlainObject(parsed) ? parsed : void 0;
|
|
969
|
+
} catch {
|
|
970
|
+
return void 0;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
function declaredDependency(baseDir, pkg, name, rootPkg) {
|
|
974
|
+
if (pkg === void 0) return void 0;
|
|
975
|
+
const own = hasDependency(pkg, name);
|
|
976
|
+
if (own !== void 0) return { range: own, source: "app" };
|
|
977
|
+
const root = rootPkg === void 0 ? workspaceRootPackage(baseDir) : rootPkg ?? void 0;
|
|
978
|
+
const fromRoot = root !== void 0 ? hasDependency(root, name) : void 0;
|
|
979
|
+
return fromRoot !== void 0 ? { range: fromRoot, source: "root" } : void 0;
|
|
980
|
+
}
|
|
926
981
|
function isPlainObject(value) {
|
|
927
982
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
928
983
|
}
|
|
929
|
-
function
|
|
984
|
+
function addCommandPrefix(installCommand, options = {}) {
|
|
985
|
+
const dev = options.dev ? " -D" : "";
|
|
986
|
+
switch (packageManagerOf(installCommand)) {
|
|
987
|
+
case "yarn":
|
|
988
|
+
return `yarn add${dev}`;
|
|
989
|
+
case "npm":
|
|
990
|
+
return `npm install${dev}`;
|
|
991
|
+
default:
|
|
992
|
+
return `pnpm add${dev}`;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
function addCommandFor(installCommand, deps, options = {}) {
|
|
930
996
|
const specs = Object.entries(deps).map(([name, range]) => `"${name}@${range}"`).join(" ");
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
997
|
+
return `${addCommandPrefix(installCommand, options)} ${specs}`;
|
|
998
|
+
}
|
|
999
|
+
function workspaceRunCommand(installCommand, pkg, script) {
|
|
1000
|
+
switch (packageManagerOf(installCommand)) {
|
|
1001
|
+
case "yarn":
|
|
1002
|
+
return `yarn workspace ${pkg} ${script}`;
|
|
1003
|
+
case "npm":
|
|
1004
|
+
return `npm run ${script} -w ${pkg}`;
|
|
1005
|
+
default:
|
|
1006
|
+
return `pnpm --filter ${pkg} ${script}`;
|
|
1007
|
+
}
|
|
934
1008
|
}
|
|
935
1009
|
var GLOBAL_CSS_CANDIDATES = [
|
|
936
1010
|
"app/globals.css",
|
|
@@ -969,7 +1043,7 @@ function exactVersionOf(version) {
|
|
|
969
1043
|
return v;
|
|
970
1044
|
}
|
|
971
1045
|
function findInstalledPackage(baseDirInput, name) {
|
|
972
|
-
let dir =
|
|
1046
|
+
let dir = resolveBaseDir(baseDirInput);
|
|
973
1047
|
for (; ; ) {
|
|
974
1048
|
const pkgDir = path3.join(dir, "node_modules", ...name.split("/"));
|
|
975
1049
|
const file = path3.join(pkgDir, "package.json");
|
|
@@ -989,7 +1063,7 @@ function findInstalledPackage(baseDirInput, name) {
|
|
|
989
1063
|
}
|
|
990
1064
|
}
|
|
991
1065
|
function isPnpProject(baseDirInput) {
|
|
992
|
-
let dir =
|
|
1066
|
+
let dir = resolveBaseDir(baseDirInput);
|
|
993
1067
|
for (; ; ) {
|
|
994
1068
|
if (isFile(path3.join(dir, ".pnp.cjs")) || isFile(path3.join(dir, ".pnp.js"))) return true;
|
|
995
1069
|
const parent = path3.dirname(dir);
|
|
@@ -1010,16 +1084,10 @@ function compareExactVersions(a, b) {
|
|
|
1010
1084
|
}
|
|
1011
1085
|
|
|
1012
1086
|
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
1013
|
-
import { existsSync as existsSync3, lstatSync, readdirSync, readFileSync as readFileSync4, realpathSync } from "fs";
|
|
1087
|
+
import { existsSync as existsSync3, lstatSync, readdirSync, readFileSync as readFileSync4, realpathSync as realpathSync2 } from "fs";
|
|
1014
1088
|
import { basename, dirname as dirname2, extname, isAbsolute, join as join2, relative, resolve, sep } from "path";
|
|
1015
|
-
function
|
|
1016
|
-
|
|
1017
|
-
const deps = pkg[field];
|
|
1018
|
-
if (typeof deps === "object" && deps !== null && name in deps) {
|
|
1019
|
-
return String(deps[name]);
|
|
1020
|
-
}
|
|
1021
|
-
}
|
|
1022
|
-
return void 0;
|
|
1089
|
+
function declaredRange(baseDir, pkg, name) {
|
|
1090
|
+
return declaredDependency(baseDir, pkg, name)?.range;
|
|
1023
1091
|
}
|
|
1024
1092
|
function isPlainObject2(value) {
|
|
1025
1093
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1092,8 +1160,8 @@ function majorFromVersion(version) {
|
|
|
1092
1160
|
return Number(m[1]);
|
|
1093
1161
|
}
|
|
1094
1162
|
function detectTailwind(baseDirInput, pkg) {
|
|
1095
|
-
const baseDir =
|
|
1096
|
-
const declared = pkg ?
|
|
1163
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1164
|
+
const declared = pkg ? declaredRange(baseDir, pkg, "tailwindcss") : void 0;
|
|
1097
1165
|
const bounds = declared !== void 0 ? tailwindMajorBounds(declared) : void 0;
|
|
1098
1166
|
const declaredMajor = bounds?.lower;
|
|
1099
1167
|
const version = isPnpProject(baseDir) ? void 0 : findInstalledPackage(baseDir, "tailwindcss")?.version;
|
|
@@ -1144,7 +1212,7 @@ function findTokensCssImport(css) {
|
|
|
1144
1212
|
var TOKENS_CSS_JS_IMPORT = /(?:\bimport\s+|\bfrom\s+|\brequire\s*\(\s*)(["'])(@axis-ds\/tokens\/css(?:\/shadcn|\/tailwind4)?)\1/;
|
|
1145
1213
|
var AXIS_VARIABLE_DEFINITION = /(?<![\w-])--axis-[\w-]+\s*:/;
|
|
1146
1214
|
function findLayoutTokensCssImport(baseDirInput) {
|
|
1147
|
-
const baseDir =
|
|
1215
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1148
1216
|
for (const candidate of ROOT_LAYOUT_FILES) {
|
|
1149
1217
|
const file = join2(baseDir, candidate);
|
|
1150
1218
|
if (!existsSync3(file)) continue;
|
|
@@ -1160,7 +1228,7 @@ function findLayoutTokensCssImport(baseDirInput) {
|
|
|
1160
1228
|
return void 0;
|
|
1161
1229
|
}
|
|
1162
1230
|
function checkGlobalsCss(baseDirInput) {
|
|
1163
|
-
const baseDir =
|
|
1231
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1164
1232
|
for (const candidate of TAILWIND_CSS_CANDIDATES) {
|
|
1165
1233
|
const file = join2(baseDir, candidate);
|
|
1166
1234
|
if (!existsSync3(file)) continue;
|
|
@@ -1252,11 +1320,11 @@ function installedAxisVersion(baseDir, name) {
|
|
|
1252
1320
|
}
|
|
1253
1321
|
function axisPackagesBelowTailwind4(pkg, baseDirInput) {
|
|
1254
1322
|
if (!pkg) return [];
|
|
1255
|
-
const baseDir = baseDirInput !== void 0 ?
|
|
1323
|
+
const baseDir = baseDirInput !== void 0 ? resolveBaseDir(baseDirInput) : void 0;
|
|
1256
1324
|
const out = [];
|
|
1257
1325
|
const min = lowerOf(TAILWIND4_MIN_AXIS_VERSION);
|
|
1258
1326
|
for (const name of TAILWIND4_AXIS_PACKAGES) {
|
|
1259
|
-
const range =
|
|
1327
|
+
const range = baseDir !== void 0 ? declaredRange(baseDir, pkg, name) : hasDependency(pkg, name);
|
|
1260
1328
|
if (range === void 0 || range.trim().startsWith("workspace:")) continue;
|
|
1261
1329
|
const installed = baseDir !== void 0 ? installedAxisVersion(baseDir, name) : void 0;
|
|
1262
1330
|
const installedLower = installed !== void 0 ? lowerOf(installed) : void 0;
|
|
@@ -1396,7 +1464,7 @@ function isCommonJsConfig(file, source) {
|
|
|
1396
1464
|
return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
|
|
1397
1465
|
}
|
|
1398
1466
|
function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
1399
|
-
const baseDir =
|
|
1467
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1400
1468
|
if (!isPnpProject(baseDir)) {
|
|
1401
1469
|
const installed = findInstalledPackage(baseDir, name)?.version;
|
|
1402
1470
|
if (installed !== void 0) {
|
|
@@ -1404,7 +1472,7 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
1404
1472
|
if (cmp !== void 0) return { status: cmp >= 0 ? "ok" : "below", source: "installed", value: installed };
|
|
1405
1473
|
}
|
|
1406
1474
|
}
|
|
1407
|
-
const declared = pkg ?
|
|
1475
|
+
const declared = pkg ? declaredRange(baseDir, pkg, name) : void 0;
|
|
1408
1476
|
if (declared !== void 0) {
|
|
1409
1477
|
const atLeast = rangeLowerAtLeast(declared, min);
|
|
1410
1478
|
if (atLeast !== void 0) return { status: atLeast ? "ok" : "below", source: "declared", value: declared };
|
|
@@ -1425,12 +1493,12 @@ function readPackageJson(baseDir) {
|
|
|
1425
1493
|
return void 0;
|
|
1426
1494
|
}
|
|
1427
1495
|
}
|
|
1428
|
-
function tailwind4Issues(css, pkg, versions) {
|
|
1496
|
+
function tailwind4Issues(css, pkg, versions, baseDir) {
|
|
1429
1497
|
const issues = [];
|
|
1430
1498
|
const hasEntry = hasTokensTailwind4Import(css);
|
|
1431
1499
|
if (!hasEntry) issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${TOKENS_TAILWIND4_IMPORT_LINE}`);
|
|
1432
1500
|
const missing = TAILWIND4_COMPONENT_PACKAGES.filter(
|
|
1433
|
-
(name) =>
|
|
1501
|
+
(name) => declaredRange(baseDir, pkg, name) !== void 0 && !hasComponentTailwindImport(css, name) && !hasComponentSource(css, name)
|
|
1434
1502
|
);
|
|
1435
1503
|
if (missing.length > 0) {
|
|
1436
1504
|
issues.push(`\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C(tailwind.css)\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${missing.map(componentTailwindImportLine).join(" ")}`);
|
|
@@ -1450,7 +1518,7 @@ function tailwind4Issues(css, pkg, versions) {
|
|
|
1450
1518
|
return issues;
|
|
1451
1519
|
}
|
|
1452
1520
|
function checkTailwindSetup(baseDirInput) {
|
|
1453
|
-
const baseDir =
|
|
1521
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1454
1522
|
const pkg = readPackageJson(baseDir);
|
|
1455
1523
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
1456
1524
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
@@ -1467,7 +1535,7 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
1467
1535
|
};
|
|
1468
1536
|
}
|
|
1469
1537
|
const versions = axisPackagesBelowTailwind4(pkg, baseDir);
|
|
1470
|
-
const issues = tailwind4Issues(css, pkg, versions);
|
|
1538
|
+
const issues = tailwind4Issues(css, pkg, versions, baseDir);
|
|
1471
1539
|
if (issues.length > 0) {
|
|
1472
1540
|
return {
|
|
1473
1541
|
name: "tailwind.config",
|
|
@@ -1606,7 +1674,7 @@ function realpathPosix(p) {
|
|
|
1606
1674
|
const tail = [];
|
|
1607
1675
|
for (let i = 0; i < 64; i++) {
|
|
1608
1676
|
try {
|
|
1609
|
-
return [
|
|
1677
|
+
return [realpathSync2(cur), ...tail].join(sep).split(sep).join("/");
|
|
1610
1678
|
} catch {
|
|
1611
1679
|
const parent = dirname2(cur);
|
|
1612
1680
|
if (parent === cur) return void 0;
|
|
@@ -1626,7 +1694,8 @@ function contentGlobBranchCovers(glob, sample, baseDir) {
|
|
|
1626
1694
|
}
|
|
1627
1695
|
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob).test(sample);
|
|
1628
1696
|
}
|
|
1629
|
-
function contentGlobCovers(glob, sample,
|
|
1697
|
+
function contentGlobCovers(glob, sample, baseDirInput) {
|
|
1698
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1630
1699
|
const branches = expandBraces(glob.trim()) ?? [glob];
|
|
1631
1700
|
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir));
|
|
1632
1701
|
}
|
|
@@ -1687,7 +1756,7 @@ function normalizeRel(p) {
|
|
|
1687
1756
|
return s;
|
|
1688
1757
|
}
|
|
1689
1758
|
function inspectTailwindContent(baseDirInput) {
|
|
1690
|
-
const baseDir =
|
|
1759
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1691
1760
|
const pkg = readPackageJson(baseDir);
|
|
1692
1761
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
1693
1762
|
if (tailwind.major !== void 0 && tailwind.major >= 4) return null;
|
|
@@ -1700,7 +1769,7 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
1700
1769
|
targets.push({ label: `componentsDir(${componentsDir})`, sample: `${rel2}/button.tsx`, suggest: `./${rel2}/**/*.{ts,tsx}` });
|
|
1701
1770
|
}
|
|
1702
1771
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1703
|
-
if (
|
|
1772
|
+
if (declaredRange(baseDir, pkg, name) !== void 0) {
|
|
1704
1773
|
targets.push({ label: name, ...packageContentTarget(baseDir, name) });
|
|
1705
1774
|
}
|
|
1706
1775
|
}
|
|
@@ -1778,10 +1847,10 @@ function componentsUseAnimation(baseDir, componentsDir) {
|
|
|
1778
1847
|
return false;
|
|
1779
1848
|
}
|
|
1780
1849
|
function checkAnimationPlugin(baseDirInput) {
|
|
1781
|
-
const baseDir =
|
|
1850
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1782
1851
|
const pkg = readPackageJson(baseDir);
|
|
1783
1852
|
const config = readAxisConfigLike(baseDir);
|
|
1784
|
-
const declared =
|
|
1853
|
+
const declared = declaredRange(baseDir, pkg, "@axis-ds/ui-react") !== void 0;
|
|
1785
1854
|
const copied = typeof config?.componentsDir === "string" && componentsUseAnimation(baseDir, config.componentsDir);
|
|
1786
1855
|
if (!declared && !copied) return null;
|
|
1787
1856
|
const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
|
|
@@ -1799,7 +1868,7 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
1799
1868
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync3(join2(baseDir, f)));
|
|
1800
1869
|
const source = configFile !== void 0 ? stripJsComments(readFileSync4(join2(baseDir, configFile), "utf8")) : "";
|
|
1801
1870
|
const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
|
|
1802
|
-
const pluginDeclared =
|
|
1871
|
+
const pluginDeclared = declaredRange(baseDir, pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0;
|
|
1803
1872
|
const pluginInstalled = pluginDeclared && (isPnpProject(baseDir) || findInstalledPackage(baseDir, ANIMATION_PLUGIN_TAILWIND3) !== void 0);
|
|
1804
1873
|
if (plugins === "found" && pluginDeclared && pluginInstalled) {
|
|
1805
1874
|
return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
@@ -1891,7 +1960,7 @@ function selectUtilsDependencies(tailwind) {
|
|
|
1891
1960
|
}
|
|
1892
1961
|
|
|
1893
1962
|
// ../axis-registry-core/src/add/safe-write.ts
|
|
1894
|
-
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as
|
|
1963
|
+
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as statSync2 } from "fs";
|
|
1895
1964
|
import path4 from "path";
|
|
1896
1965
|
import fs2 from "fs-extra";
|
|
1897
1966
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
@@ -1918,12 +1987,12 @@ function nearestExisting(p) {
|
|
|
1918
1987
|
return cur;
|
|
1919
1988
|
}
|
|
1920
1989
|
function escapeReason(root, target, options = {}) {
|
|
1921
|
-
const realRoot =
|
|
1990
|
+
const realRoot = realpathSync3(root);
|
|
1922
1991
|
if (!isSameOrInside(path4.resolve(root), path4.resolve(target)) || path4.resolve(target) === path4.resolve(root)) {
|
|
1923
1992
|
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
1924
1993
|
}
|
|
1925
1994
|
const anchor = nearestExisting(path4.dirname(target));
|
|
1926
|
-
const realAnchor =
|
|
1995
|
+
const realAnchor = realpathSync3(anchor);
|
|
1927
1996
|
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
1928
1997
|
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`;
|
|
1929
1998
|
}
|
|
@@ -1938,7 +2007,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
1938
2007
|
const shown = path4.relative(path4.resolve(root), path4.resolve(target)).split(path4.sep).join("/");
|
|
1939
2008
|
let realTarget;
|
|
1940
2009
|
try {
|
|
1941
|
-
realTarget =
|
|
2010
|
+
realTarget = realpathSync3(target);
|
|
1942
2011
|
} catch {
|
|
1943
2012
|
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)`;
|
|
1944
2013
|
}
|
|
@@ -1971,8 +2040,8 @@ function isSymlink(p) {
|
|
|
1971
2040
|
function outsideLinkTarget(root, target) {
|
|
1972
2041
|
if (!isSymlink(target)) return null;
|
|
1973
2042
|
try {
|
|
1974
|
-
const realTarget =
|
|
1975
|
-
return isSameOrInside(
|
|
2043
|
+
const realTarget = realpathSync3(target);
|
|
2044
|
+
return isSameOrInside(realpathSync3(root), realTarget) ? null : realTarget;
|
|
1976
2045
|
} catch {
|
|
1977
2046
|
return null;
|
|
1978
2047
|
}
|
|
@@ -1989,10 +2058,10 @@ function hardLinkMessage(shownPath, nlink) {
|
|
|
1989
2058
|
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`;
|
|
1990
2059
|
}
|
|
1991
2060
|
function writtenOutside(root, target) {
|
|
1992
|
-
const realRoot =
|
|
2061
|
+
const realRoot = realpathSync3(root);
|
|
1993
2062
|
let realTarget;
|
|
1994
2063
|
try {
|
|
1995
|
-
realTarget =
|
|
2064
|
+
realTarget = realpathSync3(target);
|
|
1996
2065
|
} catch {
|
|
1997
2066
|
return target;
|
|
1998
2067
|
}
|
|
@@ -2026,8 +2095,8 @@ async function writeNoFollow(target, content, mode) {
|
|
|
2026
2095
|
return actual;
|
|
2027
2096
|
}
|
|
2028
2097
|
function checkParentInside(root, target) {
|
|
2029
|
-
const realRoot =
|
|
2030
|
-
const realParent =
|
|
2098
|
+
const realRoot = realpathSync3(root);
|
|
2099
|
+
const realParent = realpathSync3(path4.dirname(target));
|
|
2031
2100
|
if (!isSameOrInside(realRoot, realParent)) {
|
|
2032
2101
|
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`;
|
|
2033
2102
|
}
|
|
@@ -2301,11 +2370,12 @@ function missingDependencies(root, items) {
|
|
|
2301
2370
|
pkg = void 0;
|
|
2302
2371
|
}
|
|
2303
2372
|
const ranges = selectUtilsDependencies(detectTailwind(root, pkg));
|
|
2373
|
+
const rootPkg = pkg !== void 0 ? workspaceRootPackage(root) ?? null : null;
|
|
2304
2374
|
const specs = {};
|
|
2305
2375
|
for (const item of items) {
|
|
2306
2376
|
for (const dep of item.dependencies) {
|
|
2307
2377
|
const name = dependencyName(dep);
|
|
2308
|
-
if (
|
|
2378
|
+
if (declaredDependency(root, pkg, name, rootPkg) !== void 0) continue;
|
|
2309
2379
|
if (name in specs) continue;
|
|
2310
2380
|
const explicit = dep.length > name.length ? dep.slice(name.length + 1) : void 0;
|
|
2311
2381
|
specs[name] = explicit ?? ranges[name];
|
|
@@ -2321,9 +2391,7 @@ function dependencyName(spec) {
|
|
|
2321
2391
|
}
|
|
2322
2392
|
function addCommandForSpecs(installCommand, specs) {
|
|
2323
2393
|
const args = Object.entries(specs).map(([name, range]) => range ? `"${name}@${range}"` : name).join(" ");
|
|
2324
|
-
|
|
2325
|
-
if (installCommand.startsWith("npm")) return `npm install ${args}`;
|
|
2326
|
-
return `pnpm add ${args}`;
|
|
2394
|
+
return `${addCommandPrefix(installCommand)} ${args}`;
|
|
2327
2395
|
}
|
|
2328
2396
|
function rel(root, p) {
|
|
2329
2397
|
return toPosix(path5.relative(root, p));
|
|
@@ -4850,7 +4918,7 @@ function getBrand(baseDir, name) {
|
|
|
4850
4918
|
|
|
4851
4919
|
// ../axis-registry-core/src/template/dependencies-core.ts
|
|
4852
4920
|
import { readFileSync as readFileSync9 } from "fs";
|
|
4853
|
-
import { join as join5
|
|
4921
|
+
import { join as join5 } from "path";
|
|
4854
4922
|
var REQUIRED_DEPENDENCIES = ["tailwindcss"];
|
|
4855
4923
|
var RECOMMENDED_DEPENDENCIES = ["clsx", "tailwind-merge"];
|
|
4856
4924
|
function declaredAxisPackages(pkg) {
|
|
@@ -4862,18 +4930,8 @@ function declaredAxisPackages(pkg) {
|
|
|
4862
4930
|
}
|
|
4863
4931
|
return out;
|
|
4864
4932
|
}
|
|
4865
|
-
function workspaceRootPackage(baseDir) {
|
|
4866
|
-
const root = findWorkspaceRoot(baseDir);
|
|
4867
|
-
if (root === void 0 || root === baseDir) return void 0;
|
|
4868
|
-
try {
|
|
4869
|
-
const parsed = JSON.parse(readFileSync9(join5(root, "package.json"), "utf8"));
|
|
4870
|
-
return isPlainObject(parsed) ? parsed : void 0;
|
|
4871
|
-
} catch {
|
|
4872
|
-
return void 0;
|
|
4873
|
-
}
|
|
4874
|
-
}
|
|
4875
4933
|
function checkDependencies(baseDirInput) {
|
|
4876
|
-
const baseDir =
|
|
4934
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
4877
4935
|
let pkg;
|
|
4878
4936
|
try {
|
|
4879
4937
|
const parsed = JSON.parse(readFileSync9(join5(baseDir, "package.json"), "utf8"));
|
|
@@ -4885,17 +4943,18 @@ function checkDependencies(baseDirInput) {
|
|
|
4885
4943
|
}
|
|
4886
4944
|
return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
|
|
4887
4945
|
}
|
|
4888
|
-
const rootPkg = workspaceRootPackage(baseDir);
|
|
4889
|
-
const
|
|
4890
|
-
const
|
|
4946
|
+
const rootPkg = workspaceRootPackage(baseDir) ?? null;
|
|
4947
|
+
const declared = (d) => declaredDependency(baseDir, pkg, d, rootPkg);
|
|
4948
|
+
const fromRoot = (d) => declared(d)?.source === "root";
|
|
4949
|
+
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0);
|
|
4891
4950
|
if (missingRequired.length > 0) {
|
|
4892
4951
|
return { name: "dependencies", severity: "fail", message: `\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}` };
|
|
4893
4952
|
}
|
|
4894
|
-
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) =>
|
|
4953
|
+
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => declared(d) === void 0);
|
|
4895
4954
|
const rootDeclared = [...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => fromRoot(d));
|
|
4896
4955
|
const rootNote = rootDeclared.length > 0 ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootDeclared.join(", ")}` : void 0;
|
|
4897
4956
|
const targets = [
|
|
4898
|
-
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) =>
|
|
4957
|
+
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => declared(d) !== void 0),
|
|
4899
4958
|
...declaredAxisPackages(pkg)
|
|
4900
4959
|
];
|
|
4901
4960
|
const pnp = isPnpProject(baseDir);
|
|
@@ -4970,6 +5029,7 @@ async function handleGetTemplate(params) {
|
|
|
4970
5029
|
async function handleApplyTemplate(params) {
|
|
4971
5030
|
const detail = await fetchTemplateDetail(params.name);
|
|
4972
5031
|
const baseDir = path9.resolve(params.targetDir);
|
|
5032
|
+
const installCommand = detectInstallCommand(baseDir);
|
|
4973
5033
|
const files = [];
|
|
4974
5034
|
for (const file of detail.files) {
|
|
4975
5035
|
const dest = path9.join(baseDir, file.path);
|
|
@@ -5007,7 +5067,8 @@ async function handleApplyTemplate(params) {
|
|
|
5007
5067
|
files,
|
|
5008
5068
|
dependencies: detail.dependencies || {},
|
|
5009
5069
|
devDependencies: detail.devDependencies || {},
|
|
5010
|
-
dryRun: !!params.dryRun
|
|
5070
|
+
dryRun: !!params.dryRun,
|
|
5071
|
+
installCommand
|
|
5011
5072
|
};
|
|
5012
5073
|
}
|
|
5013
5074
|
async function handleDiffTemplate(params) {
|
|
@@ -5214,11 +5275,12 @@ function formatApplyTemplateResult(result) {
|
|
|
5214
5275
|
const devDeps = Object.entries(result.devDependencies);
|
|
5215
5276
|
if (deps.length > 0 || devDeps.length > 0) {
|
|
5216
5277
|
lines.push("", "### \uD544\uC694\uD55C \uC758\uC874\uC131", "");
|
|
5278
|
+
const installCommand = result.installCommand ?? "pnpm install";
|
|
5217
5279
|
if (deps.length > 0) {
|
|
5218
|
-
lines.push(
|
|
5280
|
+
lines.push(`\`${addCommandFor(installCommand, result.dependencies)}\``);
|
|
5219
5281
|
}
|
|
5220
5282
|
if (devDeps.length > 0) {
|
|
5221
|
-
lines.push(
|
|
5283
|
+
lines.push(`\`${addCommandFor(installCommand, result.devDependencies, { dev: true })}\``);
|
|
5222
5284
|
}
|
|
5223
5285
|
}
|
|
5224
5286
|
return lines.join("\n");
|
|
@@ -5263,6 +5325,11 @@ var TOKENS_INSTALL_COMMAND = addCommandFor("pnpm install", { [TOKENS_PACKAGE]: `
|
|
|
5263
5325
|
function baseDirOf(targetDir) {
|
|
5264
5326
|
return path10.resolve(targetDir || process.cwd());
|
|
5265
5327
|
}
|
|
5328
|
+
function tokensInstallCommandFor(targetDir) {
|
|
5329
|
+
return addCommandFor(detectInstallCommand(baseDirOf(targetDir)), {
|
|
5330
|
+
[TOKENS_PACKAGE]: `^${TOKENS_DEPENDENCY_MIN_VERSION}`
|
|
5331
|
+
});
|
|
5332
|
+
}
|
|
5266
5333
|
async function handleListBrands(params) {
|
|
5267
5334
|
return listBrands(baseDirOf(params.targetDir));
|
|
5268
5335
|
}
|
|
@@ -5273,32 +5340,32 @@ async function handleGetBrand(params) {
|
|
|
5273
5340
|
}
|
|
5274
5341
|
return getBrand(baseDirOf(params.targetDir), name);
|
|
5275
5342
|
}
|
|
5276
|
-
function formatTokensStatusGuide(status, version) {
|
|
5343
|
+
function formatTokensStatusGuide(status, version, installCommand = TOKENS_INSTALL_COMMAND) {
|
|
5277
5344
|
switch (status) {
|
|
5278
5345
|
case "not-installed":
|
|
5279
5346
|
return [
|
|
5280
5347
|
`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`,
|
|
5281
5348
|
"",
|
|
5282
|
-
`- \uC124\uCE58: \`${
|
|
5349
|
+
`- \uC124\uCE58: \`${installCommand}\``
|
|
5283
5350
|
].join("\n");
|
|
5284
5351
|
case "unsupported":
|
|
5285
5352
|
return [
|
|
5286
5353
|
`${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).`,
|
|
5287
5354
|
"",
|
|
5288
|
-
`- \uC5C5\uADF8\uB808\uC774\uB4DC: \`${
|
|
5355
|
+
`- \uC5C5\uADF8\uB808\uC774\uB4DC: \`${installCommand}\``
|
|
5289
5356
|
].join("\n");
|
|
5290
5357
|
case "not-built":
|
|
5291
5358
|
return [
|
|
5292
5359
|
`${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.`,
|
|
5293
5360
|
"",
|
|
5294
|
-
`- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74
|
|
5361
|
+
`- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 \`${workspaceRunCommand(installCommand, TOKENS_PACKAGE, "build")}\`, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: \`${installCommand}\``
|
|
5295
5362
|
].join("\n");
|
|
5296
5363
|
}
|
|
5297
5364
|
}
|
|
5298
|
-
function formatListBrandsResult(result) {
|
|
5365
|
+
function formatListBrandsResult(result, installCommand) {
|
|
5299
5366
|
const lines = ["## AXIS \uBE0C\uB79C\uB4DC\n"];
|
|
5300
5367
|
if (result.status !== "ok") {
|
|
5301
|
-
lines.push(formatTokensStatusGuide(result.status, result.version));
|
|
5368
|
+
lines.push(formatTokensStatusGuide(result.status, result.version, installCommand));
|
|
5302
5369
|
return lines.join("\n");
|
|
5303
5370
|
}
|
|
5304
5371
|
if (result.brands.length === 0) {
|
|
@@ -5332,10 +5399,10 @@ function tokenTable(brand) {
|
|
|
5332
5399
|
}
|
|
5333
5400
|
return lines;
|
|
5334
5401
|
}
|
|
5335
|
-
function formatGetBrandResult(result, name) {
|
|
5402
|
+
function formatGetBrandResult(result, name, installCommand) {
|
|
5336
5403
|
if (result.status !== "ok") {
|
|
5337
5404
|
return [`## \uBE0C\uB79C\uB4DC: ${name}
|
|
5338
|
-
`, formatTokensStatusGuide(result.status, result.version)].join("\n");
|
|
5405
|
+
`, formatTokensStatusGuide(result.status, result.version, installCommand)].join("\n");
|
|
5339
5406
|
}
|
|
5340
5407
|
const brand = result.brand;
|
|
5341
5408
|
if (!brand) {
|
|
@@ -5949,7 +6016,7 @@ server.tool(
|
|
|
5949
6016
|
async ({ targetDir }) => {
|
|
5950
6017
|
try {
|
|
5951
6018
|
const result = await handleListBrands({ targetDir });
|
|
5952
|
-
const formatted = formatListBrandsResult(result);
|
|
6019
|
+
const formatted = formatListBrandsResult(result, tokensInstallCommandFor(targetDir));
|
|
5953
6020
|
return {
|
|
5954
6021
|
content: [
|
|
5955
6022
|
{
|
|
@@ -5974,7 +6041,7 @@ server.tool(
|
|
|
5974
6041
|
);
|
|
5975
6042
|
server.tool(
|
|
5976
6043
|
"axis.get_brand",
|
|
5977
|
-
"\uBE0C\uB79C\uB4DC \uD558\uB098\uC758 import \uACBD\uB85C \xB7
|
|
6044
|
+
"\uBE0C\uB79C\uB4DC \uD558\uB098\uC758 import \uACBD\uB85C \xB7 \uBE0C\uB79C\uB4DC \uCF1C\uAE30 \uC608\uC2DC(<html data-brand> \xB7 ThemeProvider setBrand) \xB7 \uC8FC\uC694 \uD1A0\uD070 \xB7 \uBCF4\uC815 \uB0B4\uC5ED\uC744 \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
5978
6045
|
{
|
|
5979
6046
|
name: z.string().describe("\uBE0C\uB79C\uB4DC \uC774\uB984 (\uC608: ontology)"),
|
|
5980
6047
|
targetDir: z.string().optional().describe("\uB300\uC0C1 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD1A0\uB9AC (\uAE30\uBCF8: \uD604\uC7AC \uB514\uB809\uD1A0\uB9AC)")
|
|
@@ -5982,7 +6049,7 @@ server.tool(
|
|
|
5982
6049
|
async ({ name, targetDir }) => {
|
|
5983
6050
|
try {
|
|
5984
6051
|
const result = await handleGetBrand({ name, targetDir });
|
|
5985
|
-
const formatted = formatGetBrandResult(result, name);
|
|
6052
|
+
const formatted = formatGetBrandResult(result, name, tokensInstallCommandFor(targetDir));
|
|
5986
6053
|
return {
|
|
5987
6054
|
content: [
|
|
5988
6055
|
{
|