@axis-ds/cli 1.5.0 → 1.5.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/{chunk-3WGMHDZL.js → chunk-IQY3WUGG.js} +9 -1
- package/dist/index.js +1125 -565
- package/dist/registry/agentic-streaming-text.json +1 -1
- package/dist/registry/index.json +3 -3
- package/dist/registry/registry.json +3 -3
- package/dist/{registry-client-RMES4CL5.js → registry-client-6WSGKPF2.js} +1 -1
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -9,13 +9,15 @@ import {
|
|
|
9
9
|
registerSyncCommand
|
|
10
10
|
} from "./chunk-QORBOSUA.js";
|
|
11
11
|
import {
|
|
12
|
+
AXIS_QUICK_START_URL,
|
|
13
|
+
AXIS_SITE_URL,
|
|
12
14
|
fetchTemplateDetail,
|
|
13
15
|
fetchTemplateIndex
|
|
14
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-IQY3WUGG.js";
|
|
15
17
|
|
|
16
18
|
// src/index.ts
|
|
17
19
|
import { Command } from "commander";
|
|
18
|
-
import
|
|
20
|
+
import chalk13 from "chalk";
|
|
19
21
|
import { createRequire as createRequire2 } from "module";
|
|
20
22
|
|
|
21
23
|
// src/library/base-collector.ts
|
|
@@ -480,11 +482,11 @@ var ShadcnCollector = class extends BaseCollector {
|
|
|
480
482
|
/**
|
|
481
483
|
* 파일 타입 추론
|
|
482
484
|
*/
|
|
483
|
-
getFileType(
|
|
484
|
-
if (
|
|
485
|
-
if (
|
|
486
|
-
if (
|
|
487
|
-
if (
|
|
485
|
+
getFileType(path18) {
|
|
486
|
+
if (path18.includes("hook") || path18.startsWith("use")) return "hook";
|
|
487
|
+
if (path18.includes("util") || path18.includes("lib")) return "util";
|
|
488
|
+
if (path18.endsWith(".css")) return "style";
|
|
489
|
+
if (path18.endsWith(".d.ts") || path18.includes("types")) return "type";
|
|
488
490
|
return "component";
|
|
489
491
|
}
|
|
490
492
|
};
|
|
@@ -863,9 +865,12 @@ import path2 from "path";
|
|
|
863
865
|
var DEFAULT_PATHS = {
|
|
864
866
|
uiReact: "packages/axis-ui-react/src",
|
|
865
867
|
agenticUi: "packages/axis-agentic-ui/src",
|
|
866
|
-
|
|
867
|
-
|
|
868
|
+
docsApp: "apps/web/src/app/(docs)"
|
|
869
|
+
};
|
|
870
|
+
var DOCS_SLUG_ALIASES = {
|
|
871
|
+
"agentic/approval-card": "agentic/approval-dialog"
|
|
868
872
|
};
|
|
873
|
+
var NON_COMPONENT_FILE = /\.(test|spec|stories)\.tsx?$/;
|
|
869
874
|
var AxisCollector = class extends BaseCollector {
|
|
870
875
|
sourceType = "axis";
|
|
871
876
|
rootDir;
|
|
@@ -875,28 +880,45 @@ var AxisCollector = class extends BaseCollector {
|
|
|
875
880
|
this.rootDir = options.rootDir || process.cwd();
|
|
876
881
|
this.paths = { ...DEFAULT_PATHS, ...options.paths };
|
|
877
882
|
}
|
|
883
|
+
/** 스캔 순서: ui-react 먼저, agentic-ui 다음 (같은 이름이면 앞의 것) */
|
|
884
|
+
packageSources() {
|
|
885
|
+
return [
|
|
886
|
+
{ base: this.paths.uiReact, category: "ui", route: "components" },
|
|
887
|
+
{ base: this.paths.agenticUi, category: "agentic", route: "agentic" }
|
|
888
|
+
];
|
|
889
|
+
}
|
|
878
890
|
/**
|
|
879
891
|
* AXIS 컴포넌트 목록 조회
|
|
880
892
|
*/
|
|
881
893
|
async listComponents() {
|
|
882
894
|
const items = [];
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
895
|
+
const seen = /* @__PURE__ */ new Set();
|
|
896
|
+
for (const pkg of this.packageSources()) {
|
|
897
|
+
for (const slug of await this.listComponentDirs(pkg.base)) {
|
|
898
|
+
const id = `axis-${slug}`;
|
|
899
|
+
if (seen.has(id)) continue;
|
|
900
|
+
seen.add(id);
|
|
901
|
+
const content = await fs2.readFile(
|
|
902
|
+
path2.join(this.rootDir, pkg.base, slug, "index.tsx"),
|
|
903
|
+
"utf-8"
|
|
904
|
+
);
|
|
905
|
+
const name = this.formatName(slug);
|
|
906
|
+
items.push({
|
|
907
|
+
id,
|
|
908
|
+
name,
|
|
909
|
+
description: this.extractDescription(content, slug) || `AXIS ${name} component`,
|
|
910
|
+
category: pkg.category,
|
|
911
|
+
source: "axis"
|
|
912
|
+
});
|
|
891
913
|
}
|
|
892
914
|
}
|
|
893
|
-
return
|
|
915
|
+
return items;
|
|
894
916
|
}
|
|
895
917
|
/**
|
|
896
918
|
* 단일 컴포넌트 수집
|
|
897
919
|
*/
|
|
898
920
|
async collectComponent(id) {
|
|
899
|
-
const slug = id.replace(
|
|
921
|
+
const slug = id.replace(/^axis-/, "");
|
|
900
922
|
const componentInfo = await this.findComponent(slug);
|
|
901
923
|
if (!componentInfo) {
|
|
902
924
|
throw new Error(`AXIS component not found: ${slug}`);
|
|
@@ -913,138 +935,100 @@ var AxisCollector = class extends BaseCollector {
|
|
|
913
935
|
const mainContent = codeFiles.map((f) => f.content).join("\n");
|
|
914
936
|
const meta = this.createBaseMeta(
|
|
915
937
|
componentInfo.name,
|
|
916
|
-
this.extractDescription(mainContent) || `AXIS ${componentInfo.name} component`,
|
|
938
|
+
this.extractDescription(mainContent, slug) || `AXIS ${componentInfo.name} component`,
|
|
917
939
|
codeFiles,
|
|
918
940
|
{
|
|
919
941
|
registry: "@axis",
|
|
920
|
-
url: this.
|
|
942
|
+
url: await this.resolveDocsUrl(slug, componentInfo.route)
|
|
921
943
|
}
|
|
922
944
|
);
|
|
923
945
|
meta.category = componentInfo.category;
|
|
924
946
|
return meta;
|
|
925
947
|
}
|
|
926
948
|
/**
|
|
927
|
-
*
|
|
949
|
+
* 문서 URL 을 정합니다(WI-0057 D3).
|
|
950
|
+
* ① `<docsApp>/<route>/<slug>/page.tsx` 가 있으면 그 경로 ② 없으면 별칭 표의 대상이 실재할 때 그 경로
|
|
951
|
+
* ③ 둘 다 없으면 빈 문자열(library 상세 화면은 빈 URL 이면 문서 링크를 그리지 않습니다).
|
|
928
952
|
*/
|
|
929
|
-
async
|
|
930
|
-
const
|
|
931
|
-
const
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
if (entry.isDirectory()) {
|
|
938
|
-
const componentDir = path2.join(fullPath, entry.name);
|
|
939
|
-
const indexFile = path2.join(componentDir, "index.tsx");
|
|
940
|
-
if (await fs2.pathExists(indexFile)) {
|
|
941
|
-
const content = await fs2.readFile(indexFile, "utf-8");
|
|
942
|
-
const name = this.formatName(entry.name);
|
|
943
|
-
items.push({
|
|
944
|
-
id: `axis-${entry.name}`,
|
|
945
|
-
name,
|
|
946
|
-
description: this.extractDescription(content) || `AXIS ${name} component`,
|
|
947
|
-
category: this.classifyCategory(entry.name, content) || defaultCategory,
|
|
948
|
-
source: "axis"
|
|
949
|
-
});
|
|
950
|
-
}
|
|
951
|
-
} else if (entry.name.endsWith(".tsx") && entry.name !== "index.tsx") {
|
|
952
|
-
const name = entry.name.replace(".tsx", "");
|
|
953
|
-
const filePath = path2.join(fullPath, entry.name);
|
|
954
|
-
const content = await fs2.readFile(filePath, "utf-8");
|
|
955
|
-
items.push({
|
|
956
|
-
id: `axis-${name}`,
|
|
957
|
-
name: this.formatName(name),
|
|
958
|
-
description: this.extractDescription(content) || `AXIS ${name} component`,
|
|
959
|
-
category: this.classifyCategory(name, content) || defaultCategory,
|
|
960
|
-
source: "axis"
|
|
961
|
-
});
|
|
953
|
+
async resolveDocsUrl(slug, route) {
|
|
954
|
+
const direct = `${route}/${slug}`;
|
|
955
|
+
const candidates = [direct];
|
|
956
|
+
const alias = DOCS_SLUG_ALIASES[direct];
|
|
957
|
+
if (alias) candidates.push(alias);
|
|
958
|
+
for (const routePath of candidates) {
|
|
959
|
+
if (await this.docsRouteExists(routePath)) {
|
|
960
|
+
return `${AXIS_SITE_URL}/${routePath}`;
|
|
962
961
|
}
|
|
963
962
|
}
|
|
964
|
-
return
|
|
963
|
+
return "";
|
|
964
|
+
}
|
|
965
|
+
async docsRouteExists(routePath) {
|
|
966
|
+
return fs2.pathExists(path2.join(this.rootDir, this.paths.docsApp, routePath, "page.tsx"));
|
|
965
967
|
}
|
|
966
968
|
/**
|
|
967
|
-
*
|
|
969
|
+
* 패키지 src 바로 아래에서 index.tsx 가 있는 디렉터리 이름(정렬). 단일 파일(a11y.test.tsx 등)과
|
|
970
|
+
* index.tsx 가 없는 디렉터리(constants · test-utils)는 컴포넌트가 아닙니다.
|
|
968
971
|
*/
|
|
969
|
-
async
|
|
970
|
-
const
|
|
971
|
-
const fullPath = path2.join(this.rootDir, webPath);
|
|
972
|
+
async listComponentDirs(packagePath) {
|
|
973
|
+
const fullPath = path2.join(this.rootDir, packagePath);
|
|
972
974
|
if (!await fs2.pathExists(fullPath)) {
|
|
973
|
-
return
|
|
975
|
+
return [];
|
|
974
976
|
}
|
|
975
977
|
const entries = await fs2.readdir(fullPath, { withFileTypes: true });
|
|
978
|
+
const slugs = [];
|
|
976
979
|
for (const entry of entries) {
|
|
977
|
-
if (entry.isDirectory())
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
if (await fs2.pathExists(pageFile)) {
|
|
981
|
-
const content = await fs2.readFile(pageFile, "utf-8");
|
|
982
|
-
const name = this.formatName(entry.name);
|
|
983
|
-
items.push({
|
|
984
|
-
id: `axis-${entry.name}`,
|
|
985
|
-
name,
|
|
986
|
-
description: this.extractDescription(content) || `AXIS ${name} component`,
|
|
987
|
-
category: this.classifyCategory(entry.name, content) || defaultCategory,
|
|
988
|
-
source: "axis"
|
|
989
|
-
});
|
|
990
|
-
}
|
|
980
|
+
if (!entry.isDirectory()) continue;
|
|
981
|
+
if (await fs2.pathExists(path2.join(fullPath, entry.name, "index.tsx"))) {
|
|
982
|
+
slugs.push(entry.name);
|
|
991
983
|
}
|
|
992
984
|
}
|
|
993
|
-
return
|
|
985
|
+
return slugs.sort();
|
|
994
986
|
}
|
|
995
987
|
/**
|
|
996
988
|
* 컴포넌트 찾기
|
|
997
989
|
*/
|
|
998
990
|
async findComponent(slug) {
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
];
|
|
1005
|
-
for (const { base, category } of searchPaths) {
|
|
1006
|
-
const fullBase = path2.join(this.rootDir, base);
|
|
1007
|
-
const dirPath = path2.join(fullBase, slug);
|
|
1008
|
-
if (await fs2.pathExists(dirPath)) {
|
|
1009
|
-
const files = await this.getComponentFiles(dirPath);
|
|
1010
|
-
if (files.length > 0) {
|
|
1011
|
-
return {
|
|
1012
|
-
name: this.formatName(slug),
|
|
1013
|
-
files,
|
|
1014
|
-
baseDir: dirPath,
|
|
1015
|
-
category
|
|
1016
|
-
};
|
|
1017
|
-
}
|
|
1018
|
-
}
|
|
1019
|
-
const filePath = path2.join(fullBase, `${slug}.tsx`);
|
|
1020
|
-
if (await fs2.pathExists(filePath)) {
|
|
991
|
+
for (const pkg of this.packageSources()) {
|
|
992
|
+
const dirPath = path2.join(this.rootDir, pkg.base, slug);
|
|
993
|
+
if (!await fs2.pathExists(path2.join(dirPath, "index.tsx"))) continue;
|
|
994
|
+
const files = await this.getComponentFiles(dirPath);
|
|
995
|
+
if (files.length > 0) {
|
|
1021
996
|
return {
|
|
1022
997
|
name: this.formatName(slug),
|
|
1023
|
-
files
|
|
1024
|
-
baseDir:
|
|
1025
|
-
category
|
|
998
|
+
files,
|
|
999
|
+
baseDir: dirPath,
|
|
1000
|
+
category: pkg.category,
|
|
1001
|
+
route: pkg.route
|
|
1026
1002
|
};
|
|
1027
1003
|
}
|
|
1028
1004
|
}
|
|
1029
1005
|
return null;
|
|
1030
1006
|
}
|
|
1031
1007
|
/**
|
|
1032
|
-
* 컴포넌트
|
|
1008
|
+
* 컴포넌트 디렉터리의 코드 파일(.ts · .tsx, 테스트 · 스토리 제외). 이름순으로 정렬해 결과가 매번 같습니다.
|
|
1033
1009
|
*/
|
|
1034
1010
|
async getComponentFiles(dir) {
|
|
1035
|
-
const files = [];
|
|
1036
1011
|
const entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
}
|
|
1042
|
-
return files;
|
|
1012
|
+
return entries.filter(
|
|
1013
|
+
(entry) => entry.isFile() && (entry.name.endsWith(".tsx") || entry.name.endsWith(".ts")) && !NON_COMPONENT_FILE.test(entry.name)
|
|
1014
|
+
).map((entry) => entry.name).sort().map((name) => path2.join(dir, name));
|
|
1043
1015
|
}
|
|
1044
1016
|
/**
|
|
1045
|
-
* 설명
|
|
1017
|
+
* 설명 추출. 컴포넌트 이름(slug 의 PascalCase)으로 선언된 곳 바로 앞의 JSDoc 첫 줄을 먼저 씁니다
|
|
1018
|
+
* (WI-0057: 파일 첫 JSDoc 은 Props 인터페이스 · 하위 컴포넌트 설명인 경우가 많았습니다).
|
|
1046
1019
|
*/
|
|
1047
|
-
extractDescription(code) {
|
|
1020
|
+
extractDescription(code, slug) {
|
|
1021
|
+
if (slug) {
|
|
1022
|
+
const name = slug.split("-").map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join("");
|
|
1023
|
+
const decl = new RegExp(
|
|
1024
|
+
`/\\*\\*((?:(?!\\*/)[\\s\\S])*)\\*/\\s*(?:export\\s+)?(?:default\\s+)?(?:const|let|function|class)\\s+${name}\\b`
|
|
1025
|
+
);
|
|
1026
|
+
const m = code.match(decl);
|
|
1027
|
+
if (m) {
|
|
1028
|
+
const line = m[1].split("\n").map((l) => l.replace(/^\s*\*?\s?/, "").trim()).find((l) => l && !l.startsWith("@"));
|
|
1029
|
+
if (line) return line;
|
|
1030
|
+
}
|
|
1031
|
+
}
|
|
1048
1032
|
const jsdocMatch = code.match(/\/\*\*\s*\n\s*\*\s*(.+)\n/);
|
|
1049
1033
|
if (jsdocMatch) {
|
|
1050
1034
|
return jsdocMatch[1].trim();
|
|
@@ -1072,14 +1056,6 @@ var AxisCollector = class extends BaseCollector {
|
|
|
1072
1056
|
if (name.endsWith(".d.ts") || name.includes("types")) return "type";
|
|
1073
1057
|
return "component";
|
|
1074
1058
|
}
|
|
1075
|
-
/**
|
|
1076
|
-
* 문서 URL 생성
|
|
1077
|
-
*/
|
|
1078
|
-
getDocsUrl(slug, category) {
|
|
1079
|
-
const baseUrl = "https://axis.minu.best";
|
|
1080
|
-
const route = category === "agentic" ? "agentic" : "components";
|
|
1081
|
-
return `${baseUrl}/${route}/${slug}`;
|
|
1082
|
-
}
|
|
1083
1059
|
};
|
|
1084
1060
|
|
|
1085
1061
|
// src/library/publisher.ts
|
|
@@ -1087,6 +1063,49 @@ import fs3 from "fs-extra";
|
|
|
1087
1063
|
import path3 from "path";
|
|
1088
1064
|
import chalk from "chalk";
|
|
1089
1065
|
import ora from "ora";
|
|
1066
|
+
function toPublicComponent(component) {
|
|
1067
|
+
return {
|
|
1068
|
+
id: component.id,
|
|
1069
|
+
slug: component.slug,
|
|
1070
|
+
name: component.name,
|
|
1071
|
+
description: component.description,
|
|
1072
|
+
category: component.category,
|
|
1073
|
+
source: {
|
|
1074
|
+
type: component.source.type,
|
|
1075
|
+
registry: component.source.registry,
|
|
1076
|
+
url: component.source.url
|
|
1077
|
+
},
|
|
1078
|
+
tags: component.tags,
|
|
1079
|
+
code: component.code,
|
|
1080
|
+
preview: component.preview,
|
|
1081
|
+
status: component.status,
|
|
1082
|
+
updatedAt: component.updatedAt
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
function toIndexEntry(c) {
|
|
1086
|
+
return {
|
|
1087
|
+
id: c.id,
|
|
1088
|
+
slug: c.slug,
|
|
1089
|
+
name: c.name,
|
|
1090
|
+
description: c.description,
|
|
1091
|
+
category: c.category,
|
|
1092
|
+
source: c.source.type,
|
|
1093
|
+
tags: c.tags,
|
|
1094
|
+
status: c.status
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
function toSearchItem(c) {
|
|
1098
|
+
return {
|
|
1099
|
+
id: c.id,
|
|
1100
|
+
slug: c.slug,
|
|
1101
|
+
name: c.name,
|
|
1102
|
+
description: c.description,
|
|
1103
|
+
category: c.category,
|
|
1104
|
+
source: c.source.type,
|
|
1105
|
+
tags: c.tags,
|
|
1106
|
+
url: `/library/${c.category}/${c.slug}`
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1090
1109
|
var Publisher = class {
|
|
1091
1110
|
defaultOutputDir = "apps/web/public/library";
|
|
1092
1111
|
/**
|
|
@@ -1188,55 +1207,20 @@ var Publisher = class {
|
|
|
1188
1207
|
updatedAt: index.updatedAt,
|
|
1189
1208
|
stats: index.stats,
|
|
1190
1209
|
categories: index.categories,
|
|
1191
|
-
components: index.components.map(
|
|
1192
|
-
id: c.id,
|
|
1193
|
-
slug: c.slug,
|
|
1194
|
-
name: c.name,
|
|
1195
|
-
description: c.description,
|
|
1196
|
-
category: c.category,
|
|
1197
|
-
source: c.source.type,
|
|
1198
|
-
tags: c.tags,
|
|
1199
|
-
status: c.status
|
|
1200
|
-
}))
|
|
1210
|
+
components: index.components.map(toIndexEntry)
|
|
1201
1211
|
};
|
|
1202
1212
|
}
|
|
1203
1213
|
/**
|
|
1204
1214
|
* 공개용 컴포넌트 생성
|
|
1205
1215
|
*/
|
|
1206
1216
|
createPublicComponent(component) {
|
|
1207
|
-
return
|
|
1208
|
-
id: component.id,
|
|
1209
|
-
slug: component.slug,
|
|
1210
|
-
name: component.name,
|
|
1211
|
-
description: component.description,
|
|
1212
|
-
category: component.category,
|
|
1213
|
-
source: {
|
|
1214
|
-
type: component.source.type,
|
|
1215
|
-
registry: component.source.registry,
|
|
1216
|
-
url: component.source.url
|
|
1217
|
-
},
|
|
1218
|
-
tags: component.tags,
|
|
1219
|
-
code: component.code,
|
|
1220
|
-
preview: component.preview,
|
|
1221
|
-
dependencies: component.dependencies,
|
|
1222
|
-
status: component.status,
|
|
1223
|
-
updatedAt: component.updatedAt
|
|
1224
|
-
};
|
|
1217
|
+
return toPublicComponent(component);
|
|
1225
1218
|
}
|
|
1226
1219
|
/**
|
|
1227
1220
|
* 검색 인덱스 생성
|
|
1228
1221
|
*/
|
|
1229
1222
|
generateSearchIndex(index) {
|
|
1230
|
-
return index.components.map(
|
|
1231
|
-
id: c.id,
|
|
1232
|
-
slug: c.slug,
|
|
1233
|
-
name: c.name,
|
|
1234
|
-
description: c.description,
|
|
1235
|
-
category: c.category,
|
|
1236
|
-
source: c.source.type,
|
|
1237
|
-
tags: c.tags,
|
|
1238
|
-
url: `/library/${c.category}/${c.slug}`
|
|
1239
|
-
}));
|
|
1223
|
+
return index.components.map(toSearchItem);
|
|
1240
1224
|
}
|
|
1241
1225
|
/**
|
|
1242
1226
|
* JSON 파일 쓰기
|
|
@@ -1278,10 +1262,269 @@ var Publisher = class {
|
|
|
1278
1262
|
};
|
|
1279
1263
|
var publisher = new Publisher();
|
|
1280
1264
|
|
|
1281
|
-
// src/library/
|
|
1265
|
+
// src/library/axis-refresh.ts
|
|
1282
1266
|
import fs4 from "fs-extra";
|
|
1283
1267
|
import path4 from "path";
|
|
1284
1268
|
import chalk2 from "chalk";
|
|
1269
|
+
import { isDeepStrictEqual } from "util";
|
|
1270
|
+
var AXIS = "axis";
|
|
1271
|
+
var META_TAG_LIMIT = 50;
|
|
1272
|
+
function defaultUpdatedAt(now = /* @__PURE__ */ new Date()) {
|
|
1273
|
+
const kst = new Date(now.getTime() + 9 * 60 * 60 * 1e3);
|
|
1274
|
+
return `${kst.toISOString().slice(0, 10)}T00:00:00.000Z`;
|
|
1275
|
+
}
|
|
1276
|
+
function serialize(data) {
|
|
1277
|
+
return JSON.stringify(data, null, 2);
|
|
1278
|
+
}
|
|
1279
|
+
async function readJson(file) {
|
|
1280
|
+
if (!await fs4.pathExists(file)) {
|
|
1281
|
+
throw new Error(`library \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4: ${file}`);
|
|
1282
|
+
}
|
|
1283
|
+
return JSON.parse(await fs4.readFile(file, "utf-8"));
|
|
1284
|
+
}
|
|
1285
|
+
function withoutUpdatedAt(c) {
|
|
1286
|
+
const { updatedAt: _ignored, ...rest } = c;
|
|
1287
|
+
return JSON.parse(serialize(rest));
|
|
1288
|
+
}
|
|
1289
|
+
function computeStats(entries) {
|
|
1290
|
+
const bySource = {};
|
|
1291
|
+
const byCategory = {};
|
|
1292
|
+
for (const e of entries) {
|
|
1293
|
+
bySource[e.source] = (bySource[e.source] || 0) + 1;
|
|
1294
|
+
byCategory[e.category] = (byCategory[e.category] || 0) + 1;
|
|
1295
|
+
}
|
|
1296
|
+
return {
|
|
1297
|
+
total: entries.length,
|
|
1298
|
+
bySource,
|
|
1299
|
+
byCategory
|
|
1300
|
+
};
|
|
1301
|
+
}
|
|
1302
|
+
function aggregateTags(entries) {
|
|
1303
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1304
|
+
for (const e of entries) {
|
|
1305
|
+
for (const tag of e.tags) counts.set(tag, (counts.get(tag) || 0) + 1);
|
|
1306
|
+
}
|
|
1307
|
+
return [...counts.entries()].map(([id, count]) => ({ id, name: id, count })).sort((a, b) => b.count - a.count);
|
|
1308
|
+
}
|
|
1309
|
+
async function refreshAxisLibrary(options) {
|
|
1310
|
+
const libraryDir = options.libraryDir || path4.join(options.rootDir, "apps/web/public/library");
|
|
1311
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(options.updatedAt)) {
|
|
1312
|
+
throw new Error(`updatedAt \uC740 ISO 8601 UTC(\uC608: 2026-10-23T00:00:00.000Z)\uC5EC\uC57C \uD569\uB2C8\uB2E4: ${options.updatedAt}`);
|
|
1313
|
+
}
|
|
1314
|
+
const index = await readJson(path4.join(libraryDir, "index.json"));
|
|
1315
|
+
const searchIndex = await readJson(path4.join(libraryDir, "search-index.json"));
|
|
1316
|
+
const meta = await readJson(path4.join(libraryDir, "meta.json"));
|
|
1317
|
+
const categoryFiles = /* @__PURE__ */ new Map();
|
|
1318
|
+
for (const def of index.categories) {
|
|
1319
|
+
categoryFiles.set(def.id, await readJson(path4.join(libraryDir, "categories", `${def.id}.json`)));
|
|
1320
|
+
}
|
|
1321
|
+
const componentsDir = path4.join(libraryDir, "components");
|
|
1322
|
+
const existingFiles = /* @__PURE__ */ new Map();
|
|
1323
|
+
for (const name of (await fs4.readdir(componentsDir)).filter((n) => n.endsWith(".json")).sort()) {
|
|
1324
|
+
const raw = await fs4.readFile(path4.join(componentsDir, name), "utf-8");
|
|
1325
|
+
existingFiles.set(name.slice(0, -".json".length), { raw, data: JSON.parse(raw) });
|
|
1326
|
+
}
|
|
1327
|
+
const extIndex = /* @__PURE__ */ new Map();
|
|
1328
|
+
const extSearch = /* @__PURE__ */ new Map();
|
|
1329
|
+
const extCategory = /* @__PURE__ */ new Map();
|
|
1330
|
+
const extOrder = [];
|
|
1331
|
+
const remember = (id) => {
|
|
1332
|
+
if (!extOrder.includes(id)) extOrder.push(id);
|
|
1333
|
+
};
|
|
1334
|
+
for (const s of searchIndex) {
|
|
1335
|
+
if (s.source === AXIS) continue;
|
|
1336
|
+
extSearch.set(s.id, s);
|
|
1337
|
+
remember(s.id);
|
|
1338
|
+
}
|
|
1339
|
+
for (const e of index.components) {
|
|
1340
|
+
if (e.source === AXIS) continue;
|
|
1341
|
+
extIndex.set(e.id, e);
|
|
1342
|
+
remember(e.id);
|
|
1343
|
+
}
|
|
1344
|
+
const extCategoryOrder = /* @__PURE__ */ new Map();
|
|
1345
|
+
for (const [catId, file] of categoryFiles) {
|
|
1346
|
+
const ids = [];
|
|
1347
|
+
for (const c of file.components) {
|
|
1348
|
+
if (c.source.type === AXIS) continue;
|
|
1349
|
+
extCategory.set(c.id, c);
|
|
1350
|
+
ids.push(c.id);
|
|
1351
|
+
remember(c.id);
|
|
1352
|
+
}
|
|
1353
|
+
extCategoryOrder.set(catId, ids);
|
|
1354
|
+
}
|
|
1355
|
+
for (const id of extOrder) {
|
|
1356
|
+
const full = extCategory.get(id);
|
|
1357
|
+
const idx = extIndex.get(id);
|
|
1358
|
+
if (!full) {
|
|
1359
|
+
throw new Error(`\uC678\uBD80 \uD56D\uBAA9 ${id} \uAC00 categories/*.json \uC5D0 \uC5C6\uC5B4 \uC815\uD569\uC744 \uB9DE\uCD9C \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
1360
|
+
}
|
|
1361
|
+
if (!idx) extIndex.set(id, toIndexEntry(full));
|
|
1362
|
+
if (!extSearch.has(id)) extSearch.set(id, toSearchItem(full));
|
|
1363
|
+
if (!extCategoryOrder.get(full.category)?.includes(id)) {
|
|
1364
|
+
throw new Error(`\uC678\uBD80 \uD56D\uBAA9 ${id} \uC758 category(${full.category}) \uD30C\uC77C\uC5D0 \uD56D\uBAA9\uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
1365
|
+
}
|
|
1366
|
+
}
|
|
1367
|
+
const collector = options.collector || new AxisCollector({ rootDir: options.rootDir });
|
|
1368
|
+
const axisComponents = [];
|
|
1369
|
+
const added = [];
|
|
1370
|
+
const changed = [];
|
|
1371
|
+
const unchanged = [];
|
|
1372
|
+
const oldAxis = /* @__PURE__ */ new Map();
|
|
1373
|
+
for (const file of categoryFiles.values()) {
|
|
1374
|
+
for (const c of file.components) if (c.source.type === AXIS) oldAxis.set(c.id, c);
|
|
1375
|
+
}
|
|
1376
|
+
for (const f of existingFiles.values()) if (f.data.source?.type === AXIS) oldAxis.set(f.data.id, f.data);
|
|
1377
|
+
for (const item of await collector.listComponents()) {
|
|
1378
|
+
const fresh = toPublicComponent(await collector.collectComponent(item.id));
|
|
1379
|
+
const old = oldAxis.get(fresh.id);
|
|
1380
|
+
if (old && isDeepStrictEqual(withoutUpdatedAt(old), withoutUpdatedAt(fresh))) {
|
|
1381
|
+
fresh.updatedAt = old.updatedAt;
|
|
1382
|
+
unchanged.push(fresh.id);
|
|
1383
|
+
} else {
|
|
1384
|
+
fresh.updatedAt = options.updatedAt;
|
|
1385
|
+
const existedBefore = !!old || index.components.some((e) => e.id === fresh.id) || searchIndex.some((e) => e.id === fresh.id);
|
|
1386
|
+
(existedBefore ? changed : added).push(fresh.id);
|
|
1387
|
+
}
|
|
1388
|
+
axisComponents.push(JSON.parse(serialize(fresh)));
|
|
1389
|
+
}
|
|
1390
|
+
if (axisComponents.length === 0) {
|
|
1391
|
+
throw new Error(`AXIS \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD558\uB098\uB3C4 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(rootDir: ${options.rootDir})`);
|
|
1392
|
+
}
|
|
1393
|
+
const axisIds = new Set(axisComponents.map((c) => c.id));
|
|
1394
|
+
const oldAxisIds = /* @__PURE__ */ new Set();
|
|
1395
|
+
for (const e of index.components) if (e.source === AXIS) oldAxisIds.add(e.id);
|
|
1396
|
+
for (const e of searchIndex) if (e.source === AXIS) oldAxisIds.add(e.id);
|
|
1397
|
+
for (const file of categoryFiles.values()) {
|
|
1398
|
+
for (const c of file.components) if (c.source.type === AXIS) oldAxisIds.add(c.id);
|
|
1399
|
+
}
|
|
1400
|
+
for (const f of existingFiles.values()) if (f.data.source?.type === AXIS) oldAxisIds.add(f.data.id);
|
|
1401
|
+
const removed = [...oldAxisIds].filter((id) => !axisIds.has(id)).sort();
|
|
1402
|
+
const indexEntries = [
|
|
1403
|
+
...extOrder.map((id) => extIndex.get(id)),
|
|
1404
|
+
...axisComponents.map((c) => toIndexEntry(c))
|
|
1405
|
+
];
|
|
1406
|
+
const searchItems = [
|
|
1407
|
+
...extOrder.map((id) => extSearch.get(id)),
|
|
1408
|
+
...axisComponents.map((c) => toSearchItem(c))
|
|
1409
|
+
];
|
|
1410
|
+
const stats = computeStats(indexEntries);
|
|
1411
|
+
const allPublic = [...extOrder.map((id) => extCategory.get(id)), ...axisComponents];
|
|
1412
|
+
const updatedAt = allPublic.map((c) => c.updatedAt).filter(Boolean).sort().at(-1) || index.updatedAt;
|
|
1413
|
+
const outputs = /* @__PURE__ */ new Map();
|
|
1414
|
+
outputs.set(
|
|
1415
|
+
"index.json",
|
|
1416
|
+
serialize({
|
|
1417
|
+
version: index.version,
|
|
1418
|
+
updatedAt,
|
|
1419
|
+
stats,
|
|
1420
|
+
categories: index.categories,
|
|
1421
|
+
components: indexEntries
|
|
1422
|
+
})
|
|
1423
|
+
);
|
|
1424
|
+
outputs.set("search-index.json", serialize(searchItems));
|
|
1425
|
+
outputs.set(
|
|
1426
|
+
"meta.json",
|
|
1427
|
+
serialize({
|
|
1428
|
+
version: meta.version,
|
|
1429
|
+
updatedAt,
|
|
1430
|
+
stats,
|
|
1431
|
+
categories: meta.categories,
|
|
1432
|
+
tags: aggregateTags(indexEntries).slice(0, META_TAG_LIMIT)
|
|
1433
|
+
})
|
|
1434
|
+
);
|
|
1435
|
+
const knownCategories = new Set(index.categories.map((d) => d.id));
|
|
1436
|
+
for (const c of axisComponents) {
|
|
1437
|
+
if (!knownCategories.has(c.category)) {
|
|
1438
|
+
throw new Error(`AXIS \uD56D\uBAA9 ${c.id} \uC758 category(${c.category}) \uAC00 index.json categories \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
1439
|
+
}
|
|
1440
|
+
}
|
|
1441
|
+
for (const def of index.categories) {
|
|
1442
|
+
const old = categoryFiles.get(def.id);
|
|
1443
|
+
const components = [
|
|
1444
|
+
...(extCategoryOrder.get(def.id) || []).map((id) => extCategory.get(id)),
|
|
1445
|
+
...axisComponents.filter((c) => c.category === def.id)
|
|
1446
|
+
];
|
|
1447
|
+
outputs.set(
|
|
1448
|
+
`categories/${def.id}.json`,
|
|
1449
|
+
serialize({
|
|
1450
|
+
category: old.category,
|
|
1451
|
+
name: old.name,
|
|
1452
|
+
description: old.description,
|
|
1453
|
+
icon: old.icon,
|
|
1454
|
+
count: components.length,
|
|
1455
|
+
components
|
|
1456
|
+
})
|
|
1457
|
+
);
|
|
1458
|
+
}
|
|
1459
|
+
const finalSlugs = /* @__PURE__ */ new Set();
|
|
1460
|
+
const axisBySlug = new Map(axisComponents.map((c) => [c.slug, c]));
|
|
1461
|
+
for (const c of allPublic) finalSlugs.add(c.slug);
|
|
1462
|
+
const shadowedAxis = [];
|
|
1463
|
+
for (const slug of [...finalSlugs].sort()) {
|
|
1464
|
+
const axis = axisBySlug.get(slug);
|
|
1465
|
+
const existing = existingFiles.get(slug);
|
|
1466
|
+
const extForSlug = extOrder.map((id) => extCategory.get(id)).filter((c) => c.slug === slug);
|
|
1467
|
+
const existingIsExternal = !!existing && extForSlug.some((c) => c.id === existing.data.id);
|
|
1468
|
+
if (existingIsExternal) {
|
|
1469
|
+
if (axis) shadowedAxis.push(axis.id);
|
|
1470
|
+
continue;
|
|
1471
|
+
}
|
|
1472
|
+
if (axis) {
|
|
1473
|
+
outputs.set(`components/${slug}.json`, serialize(axis));
|
|
1474
|
+
continue;
|
|
1475
|
+
}
|
|
1476
|
+
outputs.set(`components/${slug}.json`, serialize(extForSlug[0]));
|
|
1477
|
+
}
|
|
1478
|
+
const writtenFiles = [];
|
|
1479
|
+
for (const [rel3, content] of outputs) {
|
|
1480
|
+
const file = path4.join(libraryDir, rel3);
|
|
1481
|
+
const before = await fs4.pathExists(file) ? await fs4.readFile(file, "utf-8") : void 0;
|
|
1482
|
+
if (before === content) continue;
|
|
1483
|
+
writtenFiles.push(rel3);
|
|
1484
|
+
if (!options.dryRun) await fs4.writeFile(file, content, "utf-8");
|
|
1485
|
+
}
|
|
1486
|
+
const removedFiles = [];
|
|
1487
|
+
for (const slug of existingFiles.keys()) {
|
|
1488
|
+
if (finalSlugs.has(slug)) continue;
|
|
1489
|
+
const rel3 = `components/${slug}.json`;
|
|
1490
|
+
removedFiles.push(rel3);
|
|
1491
|
+
if (!options.dryRun) await fs4.remove(path4.join(libraryDir, rel3));
|
|
1492
|
+
}
|
|
1493
|
+
return { added, changed, unchanged, removed, shadowedAxis, writtenFiles, removedFiles, stats };
|
|
1494
|
+
}
|
|
1495
|
+
function registerRefreshAxisCommand(libraryCmd2) {
|
|
1496
|
+
libraryCmd2.command("refresh-axis").description("AXIS \uD56D\uBAA9\uB9CC \uC800\uC7A5\uC18C \uC18C\uC2A4\uC5D0\uC11C \uB2E4\uC2DC \uB9CC\uB4E6 (\uC678\uBD80 \uC18C\uC2A4 \uD56D\uBAA9\uC740 \uADF8\uB300\uB85C, \uB124\uD2B8\uC6CC\uD06C \uC5C6\uC74C)").option("--root <dir>", "\uC800\uC7A5\uC18C \uB8E8\uD2B8", process.cwd()).option("-o, --output <dir>", "library \uB514\uB809\uD130\uB9AC (\uB8E8\uD2B8 \uAE30\uC900)", "apps/web/public/library").option("--updated-at <iso>", "\uBC14\uB010 \uD56D\uBAA9\uC5D0 \uAE30\uB85D\uD560 \uC2DC\uAC01 (\uAE30\uBCF8: \uC624\uB298 KST \uB0A0\uC9DC\uC758 00:00:00.000Z)").option("--dry-run", "\uD30C\uC77C\uC744 \uC4F0\uC9C0 \uC54A\uACE0 \uBC14\uB014 \uB0B4\uC6A9\uB9CC \uCD9C\uB825").action(async (opts) => {
|
|
1497
|
+
const rootDir = path4.resolve(opts.root);
|
|
1498
|
+
const result = await refreshAxisLibrary({
|
|
1499
|
+
rootDir,
|
|
1500
|
+
libraryDir: path4.resolve(rootDir, opts.output),
|
|
1501
|
+
updatedAt: opts.updatedAt || defaultUpdatedAt(),
|
|
1502
|
+
dryRun: opts.dryRun
|
|
1503
|
+
});
|
|
1504
|
+
const head = opts.dryRun ? "[dry-run] " : "";
|
|
1505
|
+
console.log(chalk2.blue(`
|
|
1506
|
+
${head}AXIS library \uC7AC\uC0DD\uC131`));
|
|
1507
|
+
console.log(
|
|
1508
|
+
` \uCD94\uAC00 ${result.added.length} \xB7 \uBCC0\uACBD ${result.changed.length} \xB7 \uC720\uC9C0 ${result.unchanged.length} \xB7 \uC0AD\uC81C ${result.removed.length}`
|
|
1509
|
+
);
|
|
1510
|
+
for (const id of result.added) console.log(chalk2.green(` + ${id}`));
|
|
1511
|
+
for (const id of result.changed) console.log(chalk2.yellow(` ~ ${id}`));
|
|
1512
|
+
for (const id of result.removed) console.log(chalk2.red(` - ${id}`));
|
|
1513
|
+
if (result.shadowedAxis.length > 0) {
|
|
1514
|
+
console.log(
|
|
1515
|
+
chalk2.yellow(` slug \uAC00 \uC678\uBD80 \uD56D\uBAA9 \uD30C\uC77C\uACFC \uACB9\uCCD0 \uD30C\uC77C\uC744 \uC4F0\uC9C0 \uC54A\uC74C(E4): ${result.shadowedAxis.join(", ")}`)
|
|
1516
|
+
);
|
|
1517
|
+
}
|
|
1518
|
+
console.log(` \uD30C\uC77C \uC4F0\uAE30 ${result.writtenFiles.length}\uAC1C \xB7 \uC0AD\uC81C ${result.removedFiles.length}\uAC1C`);
|
|
1519
|
+
console.log(` \uC804\uCCB4 ${result.stats.total}\uAC1C ${JSON.stringify(result.stats.bySource)}
|
|
1520
|
+
`);
|
|
1521
|
+
});
|
|
1522
|
+
}
|
|
1523
|
+
|
|
1524
|
+
// src/library/index.ts
|
|
1525
|
+
import fs5 from "fs-extra";
|
|
1526
|
+
import path5 from "path";
|
|
1527
|
+
import chalk3 from "chalk";
|
|
1285
1528
|
import ora2 from "ora";
|
|
1286
1529
|
var DEFAULT_CATEGORIES = [
|
|
1287
1530
|
{ id: "ui", name: "UI", description: "\uAE30\uBCF8 UI \uCEF4\uD3EC\uB10C\uD2B8", icon: "layers", order: 1 },
|
|
@@ -1311,11 +1554,11 @@ var LibraryCurator = class {
|
|
|
1311
1554
|
async collectAll(sources, options) {
|
|
1312
1555
|
const results = /* @__PURE__ */ new Map();
|
|
1313
1556
|
const targetSources = sources || ["shadcn", "monet", "v0", "axis"];
|
|
1314
|
-
console.log(
|
|
1557
|
+
console.log(chalk3.blue("\n\u{1F4E6} Library Curator - \uCEF4\uD3EC\uB10C\uD2B8 \uC218\uC9D1 \uC2DC\uC791\n"));
|
|
1315
1558
|
for (const source of targetSources) {
|
|
1316
1559
|
const collector = this.collectors.get(source);
|
|
1317
1560
|
if (!collector) {
|
|
1318
|
-
console.log(
|
|
1561
|
+
console.log(chalk3.yellow(`\u26A0\uFE0F ${source} collector not found, skipping`));
|
|
1319
1562
|
continue;
|
|
1320
1563
|
}
|
|
1321
1564
|
const spinner = ora2(`${source} \uC218\uC9D1 \uC911...`).start();
|
|
@@ -1326,7 +1569,7 @@ var LibraryCurator = class {
|
|
|
1326
1569
|
results.set(source, result);
|
|
1327
1570
|
if (result.success) {
|
|
1328
1571
|
spinner.succeed(
|
|
1329
|
-
`${source}: ${result.collected}\uAC1C \uC218\uC9D1 \uC644\uB8CC` + (result.failed > 0 ?
|
|
1572
|
+
`${source}: ${result.collected}\uAC1C \uC218\uC9D1 \uC644\uB8CC` + (result.failed > 0 ? chalk3.yellow(` (${result.failed}\uAC1C \uC2E4\uD328)`) : "")
|
|
1330
1573
|
);
|
|
1331
1574
|
} else {
|
|
1332
1575
|
spinner.fail(`${source}: \uC218\uC9D1 \uC2E4\uD328 - ${result.errors[0]?.error}`);
|
|
@@ -1386,15 +1629,15 @@ var LibraryCurator = class {
|
|
|
1386
1629
|
* 인덱스 저장
|
|
1387
1630
|
*/
|
|
1388
1631
|
async saveIndex(index) {
|
|
1389
|
-
await
|
|
1390
|
-
const indexPath =
|
|
1391
|
-
await
|
|
1392
|
-
const categoriesDir =
|
|
1393
|
-
await
|
|
1632
|
+
await fs5.ensureDir(this.dataDir);
|
|
1633
|
+
const indexPath = path5.join(this.dataDir, "components.json");
|
|
1634
|
+
await fs5.writeJSON(indexPath, index, { spaces: 2 });
|
|
1635
|
+
const categoriesDir = path5.join(this.dataDir, "categories");
|
|
1636
|
+
await fs5.ensureDir(categoriesDir);
|
|
1394
1637
|
for (const category of DEFAULT_CATEGORIES) {
|
|
1395
1638
|
const categoryComponents = index.components.filter((c) => c.category === category.id);
|
|
1396
|
-
const categoryPath =
|
|
1397
|
-
await
|
|
1639
|
+
const categoryPath = path5.join(categoriesDir, `${category.id}.json`);
|
|
1640
|
+
await fs5.writeJSON(
|
|
1398
1641
|
categoryPath,
|
|
1399
1642
|
{
|
|
1400
1643
|
category: category.id,
|
|
@@ -1404,17 +1647,17 @@ var LibraryCurator = class {
|
|
|
1404
1647
|
{ spaces: 2 }
|
|
1405
1648
|
);
|
|
1406
1649
|
}
|
|
1407
|
-
console.log(
|
|
1650
|
+
console.log(chalk3.green(`
|
|
1408
1651
|
\u2713 \uC778\uB371\uC2A4 \uC800\uC7A5 \uC644\uB8CC: ${indexPath}`));
|
|
1409
|
-
console.log(
|
|
1652
|
+
console.log(chalk3.gray(` - \uC804\uCCB4: ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
|
|
1410
1653
|
}
|
|
1411
1654
|
/**
|
|
1412
1655
|
* 인덱스 로드
|
|
1413
1656
|
*/
|
|
1414
1657
|
async loadIndex() {
|
|
1415
|
-
const indexPath =
|
|
1416
|
-
if (await
|
|
1417
|
-
return await
|
|
1658
|
+
const indexPath = path5.join(this.dataDir, "components.json");
|
|
1659
|
+
if (await fs5.pathExists(indexPath)) {
|
|
1660
|
+
return await fs5.readJSON(indexPath);
|
|
1418
1661
|
}
|
|
1419
1662
|
return null;
|
|
1420
1663
|
}
|
|
@@ -1469,26 +1712,26 @@ var LibraryCurator = class {
|
|
|
1469
1712
|
async printStats() {
|
|
1470
1713
|
const index = await this.loadIndex();
|
|
1471
1714
|
if (!index) {
|
|
1472
|
-
console.log(
|
|
1473
|
-
console.log(
|
|
1715
|
+
console.log(chalk3.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
1716
|
+
console.log(chalk3.gray(" npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
1474
1717
|
return;
|
|
1475
1718
|
}
|
|
1476
|
-
console.log(
|
|
1477
|
-
console.log(
|
|
1478
|
-
console.log(
|
|
1719
|
+
console.log(chalk3.blue("\n\u{1F4CA} Library Curator - \uD1B5\uACC4\n"));
|
|
1720
|
+
console.log(chalk3.bold("\uC804\uCCB4 \uCEF4\uD3EC\uB10C\uD2B8: ") + chalk3.cyan(`${index.stats.total}\uAC1C`));
|
|
1721
|
+
console.log(chalk3.gray(`\uB9C8\uC9C0\uB9C9 \uC5C5\uB370\uC774\uD2B8: ${index.updatedAt}
|
|
1479
1722
|
`));
|
|
1480
|
-
console.log(
|
|
1723
|
+
console.log(chalk3.bold("\uC18C\uC2A4\uBCC4:"));
|
|
1481
1724
|
for (const [source, count] of Object.entries(index.stats.bySource)) {
|
|
1482
|
-
console.log(` ${
|
|
1725
|
+
console.log(` ${chalk3.cyan(source.padEnd(10))} ${count}\uAC1C`);
|
|
1483
1726
|
}
|
|
1484
|
-
console.log(
|
|
1727
|
+
console.log(chalk3.bold("\n\uCE74\uD14C\uACE0\uB9AC\uBCC4:"));
|
|
1485
1728
|
for (const [category, count] of Object.entries(index.stats.byCategory)) {
|
|
1486
|
-
console.log(` ${
|
|
1729
|
+
console.log(` ${chalk3.cyan(category.padEnd(15))} ${count}\uAC1C`);
|
|
1487
1730
|
}
|
|
1488
|
-
console.log(
|
|
1731
|
+
console.log(chalk3.bold("\n\uC778\uAE30 \uD0DC\uADF8:"));
|
|
1489
1732
|
const topTags = index.tags.slice(0, 10);
|
|
1490
1733
|
for (const tag of topTags) {
|
|
1491
|
-
console.log(` ${
|
|
1734
|
+
console.log(` ${chalk3.cyan(tag.name.padEnd(15))} ${tag.count}\uAC1C`);
|
|
1492
1735
|
}
|
|
1493
1736
|
console.log();
|
|
1494
1737
|
}
|
|
@@ -1496,61 +1739,61 @@ var LibraryCurator = class {
|
|
|
1496
1739
|
var libraryCurator = new LibraryCurator();
|
|
1497
1740
|
|
|
1498
1741
|
// src/template/index.ts
|
|
1499
|
-
import
|
|
1742
|
+
import chalk8 from "chalk";
|
|
1500
1743
|
import ora5 from "ora";
|
|
1501
1744
|
|
|
1502
1745
|
// src/template/template-apply.ts
|
|
1503
|
-
import
|
|
1504
|
-
import
|
|
1505
|
-
import
|
|
1746
|
+
import fs8 from "fs-extra";
|
|
1747
|
+
import path8 from "path";
|
|
1748
|
+
import chalk5 from "chalk";
|
|
1506
1749
|
import ora3 from "ora";
|
|
1507
1750
|
import prompts from "prompts";
|
|
1508
1751
|
|
|
1509
1752
|
// src/template/post-install.ts
|
|
1510
|
-
import
|
|
1511
|
-
import
|
|
1512
|
-
import
|
|
1753
|
+
import fs6 from "fs-extra";
|
|
1754
|
+
import path6 from "path";
|
|
1755
|
+
import chalk4 from "chalk";
|
|
1513
1756
|
async function runPostInstall(patches, baseDir, dryRun = false) {
|
|
1514
1757
|
for (const patch of patches) {
|
|
1515
|
-
const filePath =
|
|
1758
|
+
const filePath = path6.resolve(baseDir, patch.file);
|
|
1516
1759
|
if (dryRun) {
|
|
1517
|
-
console.log(
|
|
1760
|
+
console.log(chalk4.gray(` [dry-run] patch ${patch.type}: ${patch.file}`));
|
|
1518
1761
|
continue;
|
|
1519
1762
|
}
|
|
1520
|
-
if (!await
|
|
1521
|
-
console.log(
|
|
1763
|
+
if (!await fs6.pathExists(filePath)) {
|
|
1764
|
+
console.log(chalk4.yellow(` \uACBD\uACE0: \uD328\uCE58 \uB300\uC0C1 \uD30C\uC77C \uC5C6\uC74C - ${patch.file}`));
|
|
1522
1765
|
continue;
|
|
1523
1766
|
}
|
|
1524
1767
|
switch (patch.type) {
|
|
1525
1768
|
case "replace": {
|
|
1526
1769
|
if (!patch.search || patch.value === void 0) break;
|
|
1527
|
-
let content = await
|
|
1770
|
+
let content = await fs6.readFile(filePath, "utf-8");
|
|
1528
1771
|
content = content.replace(patch.search, patch.value);
|
|
1529
|
-
await
|
|
1530
|
-
console.log(
|
|
1772
|
+
await fs6.writeFile(filePath, content);
|
|
1773
|
+
console.log(chalk4.gray(` patch replace: ${patch.file}`));
|
|
1531
1774
|
break;
|
|
1532
1775
|
}
|
|
1533
1776
|
case "append": {
|
|
1534
1777
|
if (patch.value === void 0) break;
|
|
1535
|
-
const content = await
|
|
1536
|
-
await
|
|
1537
|
-
console.log(
|
|
1778
|
+
const content = await fs6.readFile(filePath, "utf-8");
|
|
1779
|
+
await fs6.writeFile(filePath, content + patch.value);
|
|
1780
|
+
console.log(chalk4.gray(` patch append: ${patch.file}`));
|
|
1538
1781
|
break;
|
|
1539
1782
|
}
|
|
1540
1783
|
case "prepend": {
|
|
1541
1784
|
if (patch.value === void 0) break;
|
|
1542
|
-
const content = await
|
|
1543
|
-
await
|
|
1544
|
-
console.log(
|
|
1785
|
+
const content = await fs6.readFile(filePath, "utf-8");
|
|
1786
|
+
await fs6.writeFile(filePath, patch.value + content);
|
|
1787
|
+
console.log(chalk4.gray(` patch prepend: ${patch.file}`));
|
|
1545
1788
|
break;
|
|
1546
1789
|
}
|
|
1547
1790
|
case "json-merge": {
|
|
1548
1791
|
if (!patch.merge) break;
|
|
1549
|
-
const raw = await
|
|
1792
|
+
const raw = await fs6.readFile(filePath, "utf-8");
|
|
1550
1793
|
const json = JSON.parse(raw);
|
|
1551
1794
|
deepMerge(json, patch.merge);
|
|
1552
|
-
await
|
|
1553
|
-
console.log(
|
|
1795
|
+
await fs6.writeJSON(filePath, json, { spaces: 2 });
|
|
1796
|
+
console.log(chalk4.gray(` patch json-merge: ${patch.file}`));
|
|
1554
1797
|
break;
|
|
1555
1798
|
}
|
|
1556
1799
|
}
|
|
@@ -1568,10 +1811,10 @@ function deepMerge(target, source) {
|
|
|
1568
1811
|
}
|
|
1569
1812
|
}
|
|
1570
1813
|
|
|
1571
|
-
// src/config/axis-config.ts
|
|
1572
|
-
import
|
|
1573
|
-
import
|
|
1574
|
-
var AXIS_CONFIG_SCHEMA_URL =
|
|
1814
|
+
// ../axis-registry-core/src/config/axis-config.ts
|
|
1815
|
+
import fs7 from "fs-extra";
|
|
1816
|
+
import path7 from "path";
|
|
1817
|
+
var AXIS_CONFIG_SCHEMA_URL = `${AXIS_SITE_URL}/schema.json`;
|
|
1575
1818
|
var AXIS_CONFIG_FILE = "axis.config.json";
|
|
1576
1819
|
function createInitConfig(answers, registry) {
|
|
1577
1820
|
return {
|
|
@@ -1593,9 +1836,9 @@ function createTemplateConfig(template) {
|
|
|
1593
1836
|
};
|
|
1594
1837
|
}
|
|
1595
1838
|
async function readAxisConfig(baseDir) {
|
|
1596
|
-
const configPath =
|
|
1597
|
-
if (!await
|
|
1598
|
-
return await
|
|
1839
|
+
const configPath = path7.join(baseDir, AXIS_CONFIG_FILE);
|
|
1840
|
+
if (!await fs7.pathExists(configPath)) return null;
|
|
1841
|
+
return await fs7.readJSON(configPath);
|
|
1599
1842
|
}
|
|
1600
1843
|
|
|
1601
1844
|
// src/template/template-apply.ts
|
|
@@ -1609,19 +1852,19 @@ async function applyTemplate(slug, options) {
|
|
|
1609
1852
|
spinner.fail(err.message);
|
|
1610
1853
|
process.exit(1);
|
|
1611
1854
|
}
|
|
1612
|
-
const baseDir =
|
|
1855
|
+
const baseDir = path8.resolve(options.dir || ".");
|
|
1613
1856
|
const conflicts = [];
|
|
1614
1857
|
for (const file of detail.files) {
|
|
1615
|
-
const dest =
|
|
1616
|
-
if (await
|
|
1858
|
+
const dest = path8.join(baseDir, file.path);
|
|
1859
|
+
if (await fs8.pathExists(dest)) {
|
|
1617
1860
|
conflicts.push(file.path);
|
|
1618
1861
|
}
|
|
1619
1862
|
}
|
|
1620
1863
|
if (conflicts.length > 0 && !options.yes && !options.dryRun) {
|
|
1621
|
-
console.log(
|
|
1864
|
+
console.log(chalk5.yellow(`
|
|
1622
1865
|
\uAE30\uC874 \uD30C\uC77C\uACFC \uCDA9\uB3CC\uD558\uB294 ${conflicts.length}\uAC1C \uD30C\uC77C:`));
|
|
1623
1866
|
for (const c of conflicts) {
|
|
1624
|
-
console.log(
|
|
1867
|
+
console.log(chalk5.gray(` - ${c}`));
|
|
1625
1868
|
}
|
|
1626
1869
|
const { proceed } = await prompts({
|
|
1627
1870
|
type: "confirm",
|
|
@@ -1630,59 +1873,59 @@ async function applyTemplate(slug, options) {
|
|
|
1630
1873
|
initial: false
|
|
1631
1874
|
});
|
|
1632
1875
|
if (!proceed) {
|
|
1633
|
-
console.log(
|
|
1876
|
+
console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
1634
1877
|
return;
|
|
1635
1878
|
}
|
|
1636
1879
|
}
|
|
1637
1880
|
if (options.dryRun) {
|
|
1638
|
-
console.log(
|
|
1881
|
+
console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
|
|
1639
1882
|
for (const file of detail.files) {
|
|
1640
|
-
const dest =
|
|
1883
|
+
const dest = path8.join(baseDir, file.path);
|
|
1641
1884
|
const exists = conflicts.includes(file.path);
|
|
1642
|
-
const label = exists ?
|
|
1885
|
+
const label = exists ? chalk5.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk5.green("\uC0DD\uC131");
|
|
1643
1886
|
console.log(` ${label} ${dest}`);
|
|
1644
1887
|
}
|
|
1645
1888
|
if (detail.postInstall?.length) {
|
|
1646
|
-
console.log(
|
|
1889
|
+
console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] postInstall \uD328\uCE58:"));
|
|
1647
1890
|
for (const p of detail.postInstall) {
|
|
1648
|
-
console.log(
|
|
1891
|
+
console.log(chalk5.gray(` ${p.type}: ${p.file}`));
|
|
1649
1892
|
}
|
|
1650
1893
|
}
|
|
1651
1894
|
return;
|
|
1652
1895
|
}
|
|
1653
1896
|
const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
|
|
1654
1897
|
for (const file of detail.files) {
|
|
1655
|
-
const dest =
|
|
1656
|
-
await
|
|
1657
|
-
await
|
|
1898
|
+
const dest = path8.join(baseDir, file.path);
|
|
1899
|
+
await fs8.ensureDir(path8.dirname(dest));
|
|
1900
|
+
await fs8.writeFile(dest, file.content);
|
|
1658
1901
|
}
|
|
1659
1902
|
writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
|
|
1660
1903
|
if (detail.postInstall?.length) {
|
|
1661
|
-
console.log(
|
|
1904
|
+
console.log(chalk5.blue("\npostInstall \uD328\uCE58 \uC2E4\uD589 \uC911..."));
|
|
1662
1905
|
await runPostInstall(detail.postInstall, baseDir);
|
|
1663
1906
|
}
|
|
1664
1907
|
if (!options.skipDeps) {
|
|
1665
1908
|
const allDeps = { ...detail.dependencies, ...detail.devDependencies };
|
|
1666
1909
|
const depList = Object.entries(allDeps);
|
|
1667
1910
|
if (depList.length > 0) {
|
|
1668
|
-
console.log(
|
|
1911
|
+
console.log(chalk5.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
|
|
1669
1912
|
const deps = Object.entries(detail.dependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
|
|
1670
1913
|
const devDeps = Object.entries(detail.devDependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
|
|
1671
1914
|
if (deps) {
|
|
1672
|
-
console.log(
|
|
1915
|
+
console.log(chalk5.cyan(` pnpm add ${deps}`));
|
|
1673
1916
|
}
|
|
1674
1917
|
if (devDeps) {
|
|
1675
|
-
console.log(
|
|
1918
|
+
console.log(chalk5.cyan(` pnpm add -D ${devDeps}`));
|
|
1676
1919
|
}
|
|
1677
1920
|
}
|
|
1678
1921
|
}
|
|
1679
|
-
console.log(
|
|
1922
|
+
console.log(chalk5.green(`
|
|
1680
1923
|
'${detail.name}' \uD15C\uD50C\uB9BF \uC801\uC6A9 \uC644\uB8CC!`));
|
|
1681
1924
|
}
|
|
1682
1925
|
async function initTemplate(slug, options) {
|
|
1683
1926
|
let selectedSlug = slug;
|
|
1684
1927
|
if (!selectedSlug) {
|
|
1685
|
-
const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-
|
|
1928
|
+
const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-6WSGKPF2.js");
|
|
1686
1929
|
const index = await fetchTemplateIndex2();
|
|
1687
1930
|
const { choice } = await prompts({
|
|
1688
1931
|
type: "select",
|
|
@@ -1695,7 +1938,7 @@ async function initTemplate(slug, options) {
|
|
|
1695
1938
|
}))
|
|
1696
1939
|
});
|
|
1697
1940
|
if (!choice) {
|
|
1698
|
-
console.log(
|
|
1941
|
+
console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
1699
1942
|
return;
|
|
1700
1943
|
}
|
|
1701
1944
|
selectedSlug = choice;
|
|
@@ -1709,14 +1952,14 @@ async function initTemplate(slug, options) {
|
|
|
1709
1952
|
initial: selectedSlug
|
|
1710
1953
|
});
|
|
1711
1954
|
if (!dir) {
|
|
1712
|
-
console.log(
|
|
1955
|
+
console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
1713
1956
|
return;
|
|
1714
1957
|
}
|
|
1715
1958
|
targetDir = dir;
|
|
1716
1959
|
}
|
|
1717
|
-
const resolved =
|
|
1718
|
-
if (await
|
|
1719
|
-
const entries = await
|
|
1960
|
+
const resolved = path8.resolve(targetDir);
|
|
1961
|
+
if (await fs8.pathExists(resolved)) {
|
|
1962
|
+
const entries = await fs8.readdir(resolved);
|
|
1720
1963
|
if (entries.length > 0) {
|
|
1721
1964
|
const { proceed } = await prompts({
|
|
1722
1965
|
type: "confirm",
|
|
@@ -1727,26 +1970,26 @@ async function initTemplate(slug, options) {
|
|
|
1727
1970
|
if (!proceed) return;
|
|
1728
1971
|
}
|
|
1729
1972
|
} else {
|
|
1730
|
-
await
|
|
1973
|
+
await fs8.ensureDir(resolved);
|
|
1731
1974
|
}
|
|
1732
1975
|
await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
|
|
1733
|
-
const configPath =
|
|
1734
|
-
if (!await
|
|
1976
|
+
const configPath = path8.join(resolved, "axis.config.json");
|
|
1977
|
+
if (!await fs8.pathExists(configPath)) {
|
|
1735
1978
|
const axisConfig = createTemplateConfig(selectedSlug);
|
|
1736
|
-
await
|
|
1737
|
-
console.log(
|
|
1979
|
+
await fs8.writeJSON(configPath, axisConfig, { spaces: 2 });
|
|
1980
|
+
console.log(chalk5.green("axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
|
|
1738
1981
|
}
|
|
1739
|
-
console.log(
|
|
1982
|
+
console.log(chalk5.blue(`
|
|
1740
1983
|
\uB2E4\uC74C \uB2E8\uACC4:`));
|
|
1741
|
-
console.log(
|
|
1742
|
-
console.log(
|
|
1743
|
-
console.log(
|
|
1984
|
+
console.log(chalk5.cyan(` cd ${targetDir}`));
|
|
1985
|
+
console.log(chalk5.cyan(` pnpm install`));
|
|
1986
|
+
console.log(chalk5.cyan(` pnpm dev`));
|
|
1744
1987
|
}
|
|
1745
1988
|
|
|
1746
1989
|
// src/template/template-diff.ts
|
|
1747
|
-
import
|
|
1748
|
-
import
|
|
1749
|
-
import
|
|
1990
|
+
import fs9 from "fs-extra";
|
|
1991
|
+
import path9 from "path";
|
|
1992
|
+
import chalk6 from "chalk";
|
|
1750
1993
|
import ora4 from "ora";
|
|
1751
1994
|
async function diffTemplate(slug, options) {
|
|
1752
1995
|
const spinner = ora4(`'${slug}' \uD15C\uD50C\uB9BF \uAC00\uC838\uC624\uB294 \uC911...`).start();
|
|
@@ -1758,15 +2001,15 @@ async function diffTemplate(slug, options) {
|
|
|
1758
2001
|
spinner.fail(err.message);
|
|
1759
2002
|
process.exit(1);
|
|
1760
2003
|
}
|
|
1761
|
-
const baseDir =
|
|
2004
|
+
const baseDir = path9.resolve(options.dir || ".");
|
|
1762
2005
|
const entries = [];
|
|
1763
2006
|
for (const file of detail.files) {
|
|
1764
|
-
const localPath =
|
|
1765
|
-
if (!await
|
|
2007
|
+
const localPath = path9.join(baseDir, file.path);
|
|
2008
|
+
if (!await fs9.pathExists(localPath)) {
|
|
1766
2009
|
entries.push({ path: file.path, status: "added" });
|
|
1767
2010
|
continue;
|
|
1768
2011
|
}
|
|
1769
|
-
const localContent = await
|
|
2012
|
+
const localContent = await fs9.readFile(localPath, "utf-8");
|
|
1770
2013
|
if (localContent === file.content) {
|
|
1771
2014
|
entries.push({ path: file.path, status: "unchanged" });
|
|
1772
2015
|
} else {
|
|
@@ -1787,14 +2030,14 @@ async function diffTemplate(slug, options) {
|
|
|
1787
2030
|
}
|
|
1788
2031
|
}
|
|
1789
2032
|
}
|
|
1790
|
-
console.log(
|
|
2033
|
+
console.log(chalk6.blue(`
|
|
1791
2034
|
'${detail.name}' \uD15C\uD50C\uB9BF diff \uACB0\uACFC:
|
|
1792
2035
|
`));
|
|
1793
2036
|
const statusIcon = {
|
|
1794
|
-
added:
|
|
1795
|
-
modified:
|
|
1796
|
-
unchanged:
|
|
1797
|
-
extra:
|
|
2037
|
+
added: chalk6.green("+ \uCD94\uAC00 \uD544\uC694"),
|
|
2038
|
+
modified: chalk6.yellow("~ \uBCC0\uACBD\uB428"),
|
|
2039
|
+
unchanged: chalk6.gray("= \uB3D9\uC77C"),
|
|
2040
|
+
extra: chalk6.cyan("? \uB85C\uCEEC \uC804\uC6A9")
|
|
1798
2041
|
};
|
|
1799
2042
|
let added = 0;
|
|
1800
2043
|
let modified = 0;
|
|
@@ -1805,7 +2048,7 @@ async function diffTemplate(slug, options) {
|
|
|
1805
2048
|
console.log(` ${icon.padEnd(28)} ${entry.path}`);
|
|
1806
2049
|
if (entry.status === "modified" && options.verbose) {
|
|
1807
2050
|
console.log(
|
|
1808
|
-
|
|
2051
|
+
chalk6.gray(
|
|
1809
2052
|
` \uB85C\uCEEC ${entry.localLines}\uC904 / \uC6D0\uBCF8 ${entry.remoteLines}\uC904`
|
|
1810
2053
|
)
|
|
1811
2054
|
);
|
|
@@ -1825,9 +2068,9 @@ async function diffTemplate(slug, options) {
|
|
|
1825
2068
|
break;
|
|
1826
2069
|
}
|
|
1827
2070
|
}
|
|
1828
|
-
console.log(
|
|
2071
|
+
console.log(chalk6.blue("\n\uC694\uC57D:"));
|
|
1829
2072
|
console.log(
|
|
1830
|
-
` \uCD94\uAC00 \uD544\uC694: ${
|
|
2073
|
+
` \uCD94\uAC00 \uD544\uC694: ${chalk6.green(String(added))} | \uBCC0\uACBD\uB428: ${chalk6.yellow(String(modified))} | \uB3D9\uC77C: ${chalk6.gray(String(unchanged))}${extra > 0 ? ` | \uB85C\uCEEC \uC804\uC6A9: ${chalk6.cyan(String(extra))}` : ""}`
|
|
1831
2074
|
);
|
|
1832
2075
|
}
|
|
1833
2076
|
async function collectLocalFiles(dir, base) {
|
|
@@ -1836,27 +2079,27 @@ async function collectLocalFiles(dir, base) {
|
|
|
1836
2079
|
const results = [];
|
|
1837
2080
|
let entries;
|
|
1838
2081
|
try {
|
|
1839
|
-
entries = await
|
|
2082
|
+
entries = await fs9.readdir(dir, { withFileTypes: true });
|
|
1840
2083
|
} catch {
|
|
1841
2084
|
return results;
|
|
1842
2085
|
}
|
|
1843
2086
|
for (const entry of entries) {
|
|
1844
2087
|
if (ignore.has(entry.name)) continue;
|
|
1845
|
-
const fullPath =
|
|
2088
|
+
const fullPath = path9.join(dir, entry.name);
|
|
1846
2089
|
if (entry.isDirectory()) {
|
|
1847
2090
|
const nested = await collectLocalFiles(fullPath, root);
|
|
1848
2091
|
results.push(...nested);
|
|
1849
2092
|
} else {
|
|
1850
|
-
results.push(
|
|
2093
|
+
results.push(path9.relative(root, fullPath).replace(/\\/g, "/"));
|
|
1851
2094
|
}
|
|
1852
2095
|
}
|
|
1853
2096
|
return results;
|
|
1854
2097
|
}
|
|
1855
2098
|
|
|
1856
2099
|
// src/template/template-check.ts
|
|
1857
|
-
import
|
|
1858
|
-
import
|
|
1859
|
-
import
|
|
2100
|
+
import fs10 from "fs-extra";
|
|
2101
|
+
import path10 from "path";
|
|
2102
|
+
import chalk7 from "chalk";
|
|
1860
2103
|
|
|
1861
2104
|
// src/theme/brand-core.ts
|
|
1862
2105
|
import { existsSync, readFileSync, statSync } from "fs";
|
|
@@ -2102,7 +2345,7 @@ function getBrand(baseDir, name) {
|
|
|
2102
2345
|
};
|
|
2103
2346
|
}
|
|
2104
2347
|
|
|
2105
|
-
// src/template/tailwind-core.ts
|
|
2348
|
+
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
2106
2349
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
2107
2350
|
import { join as join2, resolve as resolve2 } from "path";
|
|
2108
2351
|
function hasDependency(pkg, name) {
|
|
@@ -2523,9 +2766,9 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2523
2766
|
return { name: "tailwind.config", severity: "warn", message: "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
|
|
2524
2767
|
}
|
|
2525
2768
|
for (const file of otherFiles) {
|
|
2526
|
-
const
|
|
2527
|
-
if (existsSync2(
|
|
2528
|
-
if (hasTokensPresetReference(readFileSync2(
|
|
2769
|
+
const path18 = join2(baseDir, file);
|
|
2770
|
+
if (existsSync2(path18)) {
|
|
2771
|
+
if (hasTokensPresetReference(readFileSync2(path18, "utf8"))) {
|
|
2529
2772
|
return { name: "tailwind.config", severity: "pass", message: `${file}${PRESET_PASS_SUFFIX}` };
|
|
2530
2773
|
}
|
|
2531
2774
|
return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
|
|
@@ -2536,12 +2779,12 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2536
2779
|
|
|
2537
2780
|
// src/template/template-check.ts
|
|
2538
2781
|
var SEVERITY_ICON = {
|
|
2539
|
-
pass:
|
|
2540
|
-
warn:
|
|
2541
|
-
fail:
|
|
2782
|
+
pass: chalk7.green("PASS"),
|
|
2783
|
+
warn: chalk7.yellow("WARN"),
|
|
2784
|
+
fail: chalk7.red("FAIL")
|
|
2542
2785
|
};
|
|
2543
2786
|
async function collectCheckResults(dir) {
|
|
2544
|
-
const baseDir =
|
|
2787
|
+
const baseDir = path10.resolve(dir || ".");
|
|
2545
2788
|
const results = [];
|
|
2546
2789
|
results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
|
|
2547
2790
|
results.push(checkTailwindSetup(baseDir));
|
|
@@ -2554,7 +2797,7 @@ async function collectCheckResults(dir) {
|
|
|
2554
2797
|
}
|
|
2555
2798
|
async function runCheck(dir) {
|
|
2556
2799
|
const results = await collectCheckResults(dir);
|
|
2557
|
-
console.log(
|
|
2800
|
+
console.log(chalk7.blue("\nAXIS \uD504\uB85C\uC81D\uD2B8 \uAC80\uC99D \uACB0\uACFC:\n"));
|
|
2558
2801
|
let passCount = 0;
|
|
2559
2802
|
let warnCount = 0;
|
|
2560
2803
|
let failCount = 0;
|
|
@@ -2574,19 +2817,19 @@ async function runCheck(dir) {
|
|
|
2574
2817
|
}
|
|
2575
2818
|
console.log();
|
|
2576
2819
|
console.log(
|
|
2577
|
-
` \uACB0\uACFC: ${
|
|
2820
|
+
` \uACB0\uACFC: ${chalk7.green(`${passCount} pass`)} / ${chalk7.yellow(`${warnCount} warn`)} / ${chalk7.red(`${failCount} fail`)}`
|
|
2578
2821
|
);
|
|
2579
2822
|
if (failCount > 0) {
|
|
2580
|
-
console.log(
|
|
2823
|
+
console.log(chalk7.red("\n\uC77C\uBD80 \uD544\uC218 \uD56D\uBAA9\uC774 \uB204\uB77D\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC704 \uC548\uB0B4\uB97C \uD655\uC778\uD558\uC138\uC694."));
|
|
2581
2824
|
} else if (warnCount > 0) {
|
|
2582
|
-
console.log(
|
|
2825
|
+
console.log(chalk7.yellow("\n\uAD8C\uC7A5 \uD56D\uBAA9\uC744 \uD655\uC778\uD558\uC138\uC694."));
|
|
2583
2826
|
} else {
|
|
2584
|
-
console.log(
|
|
2827
|
+
console.log(chalk7.green("\n\uBAA8\uB4E0 \uAC80\uC99D\uC744 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4!"));
|
|
2585
2828
|
}
|
|
2586
2829
|
return { pass: passCount, warn: warnCount, fail: failCount };
|
|
2587
2830
|
}
|
|
2588
2831
|
async function checkFileExists(baseDir, fileName, label) {
|
|
2589
|
-
const exists = await
|
|
2832
|
+
const exists = await fs10.pathExists(path10.join(baseDir, fileName));
|
|
2590
2833
|
return {
|
|
2591
2834
|
name: label,
|
|
2592
2835
|
severity: exists ? "pass" : "fail",
|
|
@@ -2602,9 +2845,9 @@ async function checkUtils(baseDir) {
|
|
|
2602
2845
|
"utils.ts"
|
|
2603
2846
|
];
|
|
2604
2847
|
for (const candidate of candidates) {
|
|
2605
|
-
const fullPath =
|
|
2606
|
-
if (await
|
|
2607
|
-
const content = await
|
|
2848
|
+
const fullPath = path10.join(baseDir, candidate);
|
|
2849
|
+
if (await fs10.pathExists(fullPath)) {
|
|
2850
|
+
const content = await fs10.readFile(fullPath, "utf-8");
|
|
2608
2851
|
const hasCn = content.includes("function cn");
|
|
2609
2852
|
return {
|
|
2610
2853
|
name: "utils.ts",
|
|
@@ -2620,15 +2863,15 @@ async function checkUtils(baseDir) {
|
|
|
2620
2863
|
};
|
|
2621
2864
|
}
|
|
2622
2865
|
async function checkDependencies(baseDir) {
|
|
2623
|
-
const pkgPath =
|
|
2624
|
-
if (!await
|
|
2866
|
+
const pkgPath = path10.join(baseDir, "package.json");
|
|
2867
|
+
if (!await fs10.pathExists(pkgPath)) {
|
|
2625
2868
|
return {
|
|
2626
2869
|
name: "package.json",
|
|
2627
2870
|
severity: "fail",
|
|
2628
2871
|
message: "package.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
2629
2872
|
};
|
|
2630
2873
|
}
|
|
2631
|
-
const pkg = await
|
|
2874
|
+
const pkg = await fs10.readJSON(pkgPath);
|
|
2632
2875
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
2633
2876
|
const required = ["tailwindcss"];
|
|
2634
2877
|
const recommended = ["clsx", "tailwind-merge"];
|
|
@@ -2702,10 +2945,10 @@ function registerTemplateCommand(program2) {
|
|
|
2702
2945
|
templates = templates.filter((t) => t.category === options.category);
|
|
2703
2946
|
}
|
|
2704
2947
|
if (templates.length === 0) {
|
|
2705
|
-
console.log(
|
|
2948
|
+
console.log(chalk8.yellow("\n\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD15C\uD50C\uB9BF\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2706
2949
|
return;
|
|
2707
2950
|
}
|
|
2708
|
-
console.log(
|
|
2951
|
+
console.log(chalk8.blue(`
|
|
2709
2952
|
\u{1F4E6} AXIS \uD15C\uD50C\uB9BF (${templates.length}\uAC1C)
|
|
2710
2953
|
`));
|
|
2711
2954
|
const byCategory = /* @__PURE__ */ new Map();
|
|
@@ -2716,16 +2959,16 @@ function registerTemplateCommand(program2) {
|
|
|
2716
2959
|
byCategory.get(t.category).push(t);
|
|
2717
2960
|
}
|
|
2718
2961
|
for (const [category, items] of byCategory) {
|
|
2719
|
-
console.log(
|
|
2962
|
+
console.log(chalk8.bold(` ${category}`));
|
|
2720
2963
|
for (const t of items) {
|
|
2721
2964
|
console.log(
|
|
2722
|
-
` ${
|
|
2965
|
+
` ${chalk8.cyan(t.slug.padEnd(20))} ${chalk8.gray(t.description.slice(0, 50))}`
|
|
2723
2966
|
);
|
|
2724
2967
|
}
|
|
2725
2968
|
console.log();
|
|
2726
2969
|
}
|
|
2727
|
-
console.log(
|
|
2728
|
-
console.log(
|
|
2970
|
+
console.log(chalk8.gray("\uC0AC\uC6A9\uBC95: axis template info <name>"));
|
|
2971
|
+
console.log(chalk8.gray(" axis template apply <name>\n"));
|
|
2729
2972
|
} catch (err) {
|
|
2730
2973
|
spinner.fail(err.message);
|
|
2731
2974
|
process.exit(1);
|
|
@@ -2736,30 +2979,30 @@ function registerTemplateCommand(program2) {
|
|
|
2736
2979
|
try {
|
|
2737
2980
|
const detail = await fetchTemplateDetail(name);
|
|
2738
2981
|
spinner.stop();
|
|
2739
|
-
console.log(
|
|
2982
|
+
console.log(chalk8.blue(`
|
|
2740
2983
|
\u{1F4CB} ${detail.name}
|
|
2741
2984
|
`));
|
|
2742
|
-
console.log(` ${
|
|
2743
|
-
console.log(` ${
|
|
2744
|
-
console.log(` ${
|
|
2985
|
+
console.log(` ${chalk8.bold("\uC124\uBA85")}: ${detail.description}`);
|
|
2986
|
+
console.log(` ${chalk8.bold("\uCE74\uD14C\uACE0\uB9AC")}: ${detail.category}`);
|
|
2987
|
+
console.log(` ${chalk8.bold("\uBC84\uC804")}: ${detail.version}`);
|
|
2745
2988
|
if (detail.tags.length > 0) {
|
|
2746
|
-
console.log(` ${
|
|
2989
|
+
console.log(` ${chalk8.bold("\uD0DC\uADF8")}: ${detail.tags.join(", ")}`);
|
|
2747
2990
|
}
|
|
2748
2991
|
if (detail.features.length > 0) {
|
|
2749
|
-
console.log(
|
|
2992
|
+
console.log(chalk8.bold("\n \uAE30\uB2A5:"));
|
|
2750
2993
|
for (const f of detail.features) {
|
|
2751
2994
|
console.log(` - ${f}`);
|
|
2752
2995
|
}
|
|
2753
2996
|
}
|
|
2754
|
-
console.log(
|
|
2997
|
+
console.log(chalk8.bold(`
|
|
2755
2998
|
\uD30C\uC77C (${detail.files.length}\uAC1C):`));
|
|
2756
2999
|
for (const f of detail.files) {
|
|
2757
|
-
console.log(` ${
|
|
3000
|
+
console.log(` ${chalk8.cyan(f.path)} ${chalk8.gray(`(${f.type})`)}`);
|
|
2758
3001
|
}
|
|
2759
3002
|
const deps = Object.keys(detail.dependencies || {});
|
|
2760
3003
|
const devDeps = Object.keys(detail.devDependencies || {});
|
|
2761
3004
|
if (deps.length > 0 || devDeps.length > 0) {
|
|
2762
|
-
console.log(
|
|
3005
|
+
console.log(chalk8.bold("\n \uC758\uC874\uC131:"));
|
|
2763
3006
|
if (deps.length > 0) {
|
|
2764
3007
|
console.log(` dependencies: ${deps.join(", ")}`);
|
|
2765
3008
|
}
|
|
@@ -2767,7 +3010,7 @@ function registerTemplateCommand(program2) {
|
|
|
2767
3010
|
console.log(` devDependencies: ${devDeps.join(", ")}`);
|
|
2768
3011
|
}
|
|
2769
3012
|
}
|
|
2770
|
-
console.log(
|
|
3013
|
+
console.log(chalk8.gray(`
|
|
2771
3014
|
\uC0AC\uC6A9\uBC95: axis template apply ${name}
|
|
2772
3015
|
`));
|
|
2773
3016
|
} catch (err) {
|
|
@@ -2793,16 +3036,40 @@ function registerCheckCommand(program2) {
|
|
|
2793
3036
|
}
|
|
2794
3037
|
|
|
2795
3038
|
// src/theme/index.ts
|
|
2796
|
-
import
|
|
3039
|
+
import chalk9 from "chalk";
|
|
3040
|
+
import path13 from "path";
|
|
3041
|
+
|
|
3042
|
+
// src/theme/theme-add.ts
|
|
3043
|
+
import { accessSync, constants, existsSync as existsSync4, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
|
|
3044
|
+
import path12 from "path";
|
|
3045
|
+
|
|
3046
|
+
// ../axis-registry-core/src/project.ts
|
|
3047
|
+
import { existsSync as existsSync3 } from "fs";
|
|
2797
3048
|
import path11 from "path";
|
|
3049
|
+
function detectInstallCommand(baseDir) {
|
|
3050
|
+
if (existsSync3(path11.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
|
|
3051
|
+
if (existsSync3(path11.join(baseDir, "yarn.lock"))) return "yarn install";
|
|
3052
|
+
if (existsSync3(path11.join(baseDir, "package-lock.json"))) return "npm install";
|
|
3053
|
+
return "pnpm install";
|
|
3054
|
+
}
|
|
3055
|
+
function hasDependency2(pkg, name) {
|
|
3056
|
+
for (const field of ["dependencies", "devDependencies"]) {
|
|
3057
|
+
const deps = pkg[field];
|
|
3058
|
+
if (typeof deps === "object" && deps !== null && name in deps) {
|
|
3059
|
+
return String(deps[name]);
|
|
3060
|
+
}
|
|
3061
|
+
}
|
|
3062
|
+
return void 0;
|
|
3063
|
+
}
|
|
3064
|
+
function isPlainObject2(value) {
|
|
3065
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3066
|
+
}
|
|
2798
3067
|
|
|
2799
3068
|
// src/theme/theme-add.ts
|
|
2800
|
-
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
|
|
2801
|
-
import path10 from "path";
|
|
2802
3069
|
var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
|
|
2803
3070
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
2804
3071
|
function readText(file) {
|
|
2805
|
-
return
|
|
3072
|
+
return existsSync4(file) ? readFileSync3(file, "utf8") : null;
|
|
2806
3073
|
}
|
|
2807
3074
|
function eolOf(text) {
|
|
2808
3075
|
return text.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -2870,33 +3137,15 @@ function compareVersions(a, b) {
|
|
|
2870
3137
|
function realPathInside(baseDir, file) {
|
|
2871
3138
|
const realBase = realpathSync(baseDir);
|
|
2872
3139
|
const realPath = realpathSync(file);
|
|
2873
|
-
const relPath =
|
|
2874
|
-
const inside = relPath !== "" && !relPath.startsWith("..") && !
|
|
3140
|
+
const relPath = path12.relative(realBase, realPath);
|
|
3141
|
+
const inside = relPath !== "" && !relPath.startsWith("..") && !path12.isAbsolute(relPath);
|
|
2875
3142
|
return { inside, realPath };
|
|
2876
3143
|
}
|
|
2877
3144
|
function isStylesheet(realPath) {
|
|
2878
|
-
return
|
|
2879
|
-
}
|
|
2880
|
-
function detectInstallCommand(baseDir) {
|
|
2881
|
-
if (existsSync3(path10.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
|
|
2882
|
-
if (existsSync3(path10.join(baseDir, "yarn.lock"))) return "yarn install";
|
|
2883
|
-
if (existsSync3(path10.join(baseDir, "package-lock.json"))) return "npm install";
|
|
2884
|
-
return "pnpm install";
|
|
2885
|
-
}
|
|
2886
|
-
function hasDependency2(pkg, name) {
|
|
2887
|
-
for (const field of ["dependencies", "devDependencies"]) {
|
|
2888
|
-
const deps = pkg[field];
|
|
2889
|
-
if (typeof deps === "object" && deps !== null && name in deps) {
|
|
2890
|
-
return String(deps[name]);
|
|
2891
|
-
}
|
|
2892
|
-
}
|
|
2893
|
-
return void 0;
|
|
2894
|
-
}
|
|
2895
|
-
function isPlainObject2(value) {
|
|
2896
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3145
|
+
return path12.extname(realPath).toLowerCase() === ".css";
|
|
2897
3146
|
}
|
|
2898
3147
|
function planThemeAdd(baseDirInput, brand) {
|
|
2899
|
-
const baseDir =
|
|
3148
|
+
const baseDir = path12.resolve(baseDirInput);
|
|
2900
3149
|
const plan = {
|
|
2901
3150
|
baseDir,
|
|
2902
3151
|
brand,
|
|
@@ -2908,7 +3157,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2908
3157
|
installCommand: detectInstallCommand(baseDir),
|
|
2909
3158
|
writes: []
|
|
2910
3159
|
};
|
|
2911
|
-
const configFile =
|
|
3160
|
+
const configFile = path12.join(baseDir, AXIS_CONFIG_FILE);
|
|
2912
3161
|
const configText = readText(configFile);
|
|
2913
3162
|
if (configText === null) {
|
|
2914
3163
|
plan.errors.push({ kind: "no-config" });
|
|
@@ -2974,7 +3223,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2974
3223
|
} else {
|
|
2975
3224
|
plan.css = { configuredMissing: location.configuredMissing, action: "manual", otherBrands: [] };
|
|
2976
3225
|
}
|
|
2977
|
-
const pkgFile =
|
|
3226
|
+
const pkgFile = path12.join(baseDir, "package.json");
|
|
2978
3227
|
const pkgText = readText(pkgFile);
|
|
2979
3228
|
const installed = plan.tokens.version;
|
|
2980
3229
|
const upgrade = installed !== void 0 && (compareVersions(installed, MIN_BRAND_TOKENS_VERSION) ?? 0) < 0;
|
|
@@ -3034,8 +3283,8 @@ function applyThemeAdd(plan) {
|
|
|
3034
3283
|
if (current !== w.before) {
|
|
3035
3284
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
3036
3285
|
}
|
|
3037
|
-
const where = realPathInside(plan.baseDir, w.before === null ?
|
|
3038
|
-
if (!where.inside && !(w.before === null &&
|
|
3286
|
+
const where = realPathInside(plan.baseDir, w.before === null ? path12.dirname(w.file) : w.file);
|
|
3287
|
+
if (!where.inside && !(w.before === null && path12.dirname(w.file) === plan.baseDir)) {
|
|
3039
3288
|
throw new Error(`${w.file} \uC758 \uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`);
|
|
3040
3289
|
}
|
|
3041
3290
|
if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
|
|
@@ -3047,7 +3296,7 @@ function applyThemeAdd(plan) {
|
|
|
3047
3296
|
throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3048
3297
|
}
|
|
3049
3298
|
try {
|
|
3050
|
-
accessSync(w.before === null ?
|
|
3299
|
+
accessSync(w.before === null ? path12.dirname(w.file) : w.file, constants.W_OK);
|
|
3051
3300
|
} catch (err) {
|
|
3052
3301
|
throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
|
|
3053
3302
|
}
|
|
@@ -3086,22 +3335,22 @@ function tokensStatusGuide(status, version) {
|
|
|
3086
3335
|
switch (status) {
|
|
3087
3336
|
case "not-installed":
|
|
3088
3337
|
return [
|
|
3089
|
-
|
|
3090
|
-
` \uC124\uCE58: ${
|
|
3338
|
+
chalk9.yellow(`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`),
|
|
3339
|
+
` \uC124\uCE58: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
|
|
3091
3340
|
];
|
|
3092
3341
|
case "unsupported":
|
|
3093
3342
|
return [
|
|
3094
|
-
|
|
3343
|
+
chalk9.yellow(
|
|
3095
3344
|
`${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).`
|
|
3096
3345
|
),
|
|
3097
|
-
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${
|
|
3346
|
+
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
|
|
3098
3347
|
];
|
|
3099
3348
|
case "not-built":
|
|
3100
3349
|
return [
|
|
3101
|
-
|
|
3350
|
+
chalk9.yellow(
|
|
3102
3351
|
`${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.`
|
|
3103
3352
|
),
|
|
3104
|
-
` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${
|
|
3353
|
+
` \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 ${chalk9.cyan(`pnpm --filter ${TOKENS_PACKAGE} build`)}, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
|
|
3105
3354
|
];
|
|
3106
3355
|
}
|
|
3107
3356
|
}
|
|
@@ -3111,22 +3360,22 @@ function renderThemeList(result) {
|
|
|
3111
3360
|
}
|
|
3112
3361
|
if (result.brands.length === 0) {
|
|
3113
3362
|
return {
|
|
3114
|
-
lines: ["",
|
|
3363
|
+
lines: ["", chalk9.yellow(`\uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uBE0C\uB79C\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`), ""],
|
|
3115
3364
|
exitCode: 0
|
|
3116
3365
|
};
|
|
3117
3366
|
}
|
|
3118
3367
|
const width = Math.max(...result.brands.map((b) => b.name.length));
|
|
3119
3368
|
const lines = [
|
|
3120
3369
|
"",
|
|
3121
|
-
|
|
3370
|
+
chalk9.blue(`AXIS \uBE0C\uB79C\uB4DC (${result.brands.length}\uAC1C, ${TOKENS_PACKAGE} ${result.version ?? ""})`),
|
|
3122
3371
|
""
|
|
3123
3372
|
];
|
|
3124
3373
|
for (const b of result.brands) {
|
|
3125
3374
|
lines.push(
|
|
3126
|
-
` ${
|
|
3375
|
+
` ${chalk9.cyan(b.name.padEnd(width))} ${b.description} ${chalk9.gray(`(${b.themes.join(" \xB7 ")})`)}`
|
|
3127
3376
|
);
|
|
3128
3377
|
}
|
|
3129
|
-
lines.push("",
|
|
3378
|
+
lines.push("", chalk9.gray("\uC0AC\uC6A9\uBC95: axis theme info <brand>"), "");
|
|
3130
3379
|
return { lines, exitCode: 0 };
|
|
3131
3380
|
}
|
|
3132
3381
|
function a11yValue(value) {
|
|
@@ -3142,13 +3391,13 @@ function tokenTable(brand) {
|
|
|
3142
3391
|
const header = ["\uD1A0\uD070", "\uB77C\uC774\uD2B8", "\uB2E4\uD06C"];
|
|
3143
3392
|
const w0 = Math.max(header[0].length, ...rows.map((r) => r[0].length));
|
|
3144
3393
|
const w1 = Math.max(header[1].length, ...rows.map((r) => r[1].length));
|
|
3145
|
-
lines.push(
|
|
3394
|
+
lines.push(chalk9.gray(` ${header[0].padEnd(w0)} ${header[1].padEnd(w1)} ${header[2]}`));
|
|
3146
3395
|
for (const [k, l, d] of rows) {
|
|
3147
3396
|
lines.push(` ${k.padEnd(w0)} ${l.padEnd(w1)} ${d}`);
|
|
3148
3397
|
}
|
|
3149
3398
|
}
|
|
3150
3399
|
if (missing.length > 0) {
|
|
3151
|
-
lines.push(
|
|
3400
|
+
lines.push(chalk9.gray(` \uBE0C\uB79C\uB4DC\uAC00 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC74C: ${missing.join(", ")}`));
|
|
3152
3401
|
}
|
|
3153
3402
|
return lines;
|
|
3154
3403
|
}
|
|
@@ -3161,9 +3410,9 @@ function renderThemeInfo(result, name) {
|
|
|
3161
3410
|
return {
|
|
3162
3411
|
lines: [
|
|
3163
3412
|
"",
|
|
3164
|
-
|
|
3413
|
+
chalk9.red(`\uBE0C\uB79C\uB4DC '${name}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
|
|
3165
3414
|
` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${result.available.length > 0 ? result.available.join(", ") : "(\uC5C6\uC74C)"}`,
|
|
3166
|
-
|
|
3415
|
+
chalk9.gray(" \uBAA9\uB85D: axis theme list"),
|
|
3167
3416
|
""
|
|
3168
3417
|
],
|
|
3169
3418
|
exitCode: 1
|
|
@@ -3171,34 +3420,34 @@ function renderThemeInfo(result, name) {
|
|
|
3171
3420
|
}
|
|
3172
3421
|
const lines = [
|
|
3173
3422
|
"",
|
|
3174
|
-
|
|
3423
|
+
chalk9.blue(`\uBE0C\uB79C\uB4DC ${brand.name}`),
|
|
3175
3424
|
` \uC124\uBA85: ${brand.description}`,
|
|
3176
3425
|
` \uD14C\uB9C8: ${brand.themes.join(" \xB7 ")}`,
|
|
3177
3426
|
"",
|
|
3178
|
-
|
|
3427
|
+
chalk9.bold("Import (globals.css, @charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)"),
|
|
3179
3428
|
` @import "${brand.importPath}";`,
|
|
3180
3429
|
"",
|
|
3181
|
-
|
|
3430
|
+
chalk9.bold("Provider (@axis-ds/theme 1.3.0 \uC774\uC0C1)"),
|
|
3182
3431
|
...brand.providerExample.split("\n").map((l) => l ? ` ${l}` : ""),
|
|
3183
|
-
|
|
3432
|
+
chalk9.gray(
|
|
3184
3433
|
` ThemeProvider \uB098 <html data-brand="${brand.name}"> \uAC00 \uC5C6\uC73C\uBA74 import \uB9CC\uC73C\uB85C\uB294 \uD654\uBA74\uC774 \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`
|
|
3185
3434
|
),
|
|
3186
3435
|
"",
|
|
3187
|
-
|
|
3436
|
+
chalk9.bold("\uC8FC\uC694 \uD1A0\uD070"),
|
|
3188
3437
|
...tokenTable(brand),
|
|
3189
3438
|
"",
|
|
3190
|
-
|
|
3439
|
+
chalk9.bold("\uBCF4\uC815 \uB0B4\uC5ED"),
|
|
3191
3440
|
` a11y \uC0C1\uD0DC: ${a11yValue(brand.adjustments.a11y.status)}`,
|
|
3192
3441
|
` \uC810\uAC80\uC77C: ${a11yValue(brand.adjustments.a11y.checkedAt)}`,
|
|
3193
3442
|
` \uAC8C\uC774\uD2B8: ${a11yValue(brand.adjustments.a11y.gate)}`,
|
|
3194
3443
|
` \uADFC\uAC70 \uBB38\uC11C: ${brand.adjustments.reference}`,
|
|
3195
|
-
|
|
3444
|
+
chalk9.gray(" \uBCF4\uC815 \uC804 \xB7 \uD6C4 \uAC12\uC740 \uC774 \uBC84\uC804\uC5D0\uC11C \uCD9C\uB825\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."),
|
|
3196
3445
|
""
|
|
3197
3446
|
];
|
|
3198
3447
|
return { lines, exitCode: 0 };
|
|
3199
3448
|
}
|
|
3200
3449
|
function rel(plan, file) {
|
|
3201
|
-
return
|
|
3450
|
+
return path13.relative(plan.baseDir, file) || file;
|
|
3202
3451
|
}
|
|
3203
3452
|
function renderThemeAdd(plan, written) {
|
|
3204
3453
|
const error = plan.errors[0];
|
|
@@ -3207,24 +3456,24 @@ function renderThemeAdd(plan, written) {
|
|
|
3207
3456
|
switch (error.kind) {
|
|
3208
3457
|
case "no-config":
|
|
3209
3458
|
lines2.push(
|
|
3210
|
-
|
|
3211
|
-
` \uBA3C\uC800 ${
|
|
3459
|
+
chalk9.red("axis.config.json \uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."),
|
|
3460
|
+
` \uBA3C\uC800 ${chalk9.cyan("axis init")} \uC744 \uC2E4\uD589\uD558\uC138\uC694.`
|
|
3212
3461
|
);
|
|
3213
3462
|
break;
|
|
3214
3463
|
case "invalid-config":
|
|
3215
|
-
lines2.push(
|
|
3464
|
+
lines2.push(chalk9.red(`axis.config.json \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${error.message}). \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
|
|
3216
3465
|
break;
|
|
3217
3466
|
case "invalid-package-json":
|
|
3218
|
-
lines2.push(
|
|
3467
|
+
lines2.push(chalk9.red(`package.json \uC744 \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${error.message}). \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
|
|
3219
3468
|
break;
|
|
3220
3469
|
case "invalid-name":
|
|
3221
3470
|
lines2.push(
|
|
3222
|
-
|
|
3471
|
+
chalk9.red(`\uBE0C\uB79C\uB4DC \uC774\uB984 '${error.brand}' \uAC00 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508, \uC608: ontology)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`)
|
|
3223
3472
|
);
|
|
3224
3473
|
break;
|
|
3225
3474
|
case "css-outside-project":
|
|
3226
3475
|
lines2.push(
|
|
3227
|
-
|
|
3476
|
+
chalk9.red(
|
|
3228
3477
|
`CSS \uD30C\uC77C ${error.file} \uC758 \uC2E4\uC81C \uC704\uCE58(${error.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`
|
|
3229
3478
|
),
|
|
3230
3479
|
` axis.config.json \uC758 globalCss \uB97C \uD504\uB85C\uC81D\uD2B8 \uC548 \uD30C\uC77C\uB85C \uACE0\uCE58\uAC70\uB098, \uADF8 \uD30C\uC77C\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
|
|
@@ -3232,25 +3481,25 @@ function renderThemeAdd(plan, written) {
|
|
|
3232
3481
|
break;
|
|
3233
3482
|
case "css-not-stylesheet":
|
|
3234
3483
|
lines2.push(
|
|
3235
|
-
|
|
3484
|
+
chalk9.red(`${error.file} \uC758 \uC2E4\uC81C \uB300\uC0C1(${error.realPath})\uC774 CSS \uD30C\uC77C(.css)\uC774 \uC544\uB2D9\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`),
|
|
3236
3485
|
` axis.config.json \uC758 globalCss \uB97C \uC804\uC5ED CSS \uD30C\uC77C\uB85C \uACE0\uCE58\uAC70\uB098, \uADF8 \uD30C\uC77C\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
|
|
3237
3486
|
);
|
|
3238
3487
|
break;
|
|
3239
3488
|
case "unknown-brand":
|
|
3240
3489
|
lines2.push(
|
|
3241
|
-
|
|
3490
|
+
chalk9.red(`\uBE0C\uB79C\uB4DC '${error.brand}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${error.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
|
|
3242
3491
|
` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${error.available.length > 0 ? error.available.join(", ") : "(\uC5C6\uC74C)"}`,
|
|
3243
|
-
|
|
3492
|
+
chalk9.gray(" \uBAA9\uB85D: axis theme list")
|
|
3244
3493
|
);
|
|
3245
3494
|
break;
|
|
3246
3495
|
}
|
|
3247
3496
|
lines2.push("");
|
|
3248
3497
|
return { lines: lines2, exitCode: 1 };
|
|
3249
3498
|
}
|
|
3250
|
-
const lines = ["",
|
|
3499
|
+
const lines = ["", chalk9.blue(`\uBE0C\uB79C\uB4DC ${plan.brand} \uC801\uC6A9`), ""];
|
|
3251
3500
|
if (plan.unverifiedBrand) {
|
|
3252
3501
|
lines.push(
|
|
3253
|
-
|
|
3502
|
+
chalk9.yellow(
|
|
3254
3503
|
` ! ${TOKENS_PACKAGE} \uB97C \uC77D\uC744 \uC218 \uC5C6\uC5B4(${plan.tokens.status}) \uC774\uB984 \uADDC\uCE59\uB9CC \uD655\uC778\uD588\uC2B5\uB2C8\uB2E4. \uC124\uCE58 \uD6C4 axis theme list \uB85C '${plan.brand}' \uAC00 \uC788\uB294\uC9C0 \uD655\uC778\uD558\uC138\uC694.`
|
|
3255
3504
|
)
|
|
3256
3505
|
);
|
|
@@ -3258,24 +3507,24 @@ function renderThemeAdd(plan, written) {
|
|
|
3258
3507
|
const css = plan.css;
|
|
3259
3508
|
if (css?.configuredMissing) {
|
|
3260
3509
|
lines.push(
|
|
3261
|
-
|
|
3510
|
+
chalk9.yellow(
|
|
3262
3511
|
css.file ? ` ! axis.config.json \uC758 globalCss(${css.configuredMissing})\uAC00 \uC5C6\uC5B4 ${rel(plan, css.file)} \uC5D0 \uCD94\uAC00\uD569\uB2C8\uB2E4.` : ` ! axis.config.json \uC758 globalCss(${css.configuredMissing})\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`
|
|
3263
3512
|
)
|
|
3264
3513
|
);
|
|
3265
3514
|
}
|
|
3266
3515
|
if (css?.action === "add" && css.file) {
|
|
3267
|
-
lines.push(` ${
|
|
3516
|
+
lines.push(` ${chalk9.green("\u2713")} ${rel(plan, css.file)}: @import "${plan.importPath}"; \uCD94\uAC00`);
|
|
3268
3517
|
} else if (css?.action === "exists" && css.file) {
|
|
3269
|
-
lines.push(` ${
|
|
3518
|
+
lines.push(` ${chalk9.gray("-")} ${rel(plan, css.file)}: import \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uAC74\uB108\uB700`);
|
|
3270
3519
|
} else {
|
|
3271
3520
|
lines.push(
|
|
3272
|
-
|
|
3521
|
+
chalk9.yellow(" ! CSS \uC9C4\uC785\uC810(globalCss \xB7 app/globals.css \xB7 src/app/globals.css \xB7 globals.css)\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4."),
|
|
3273
3522
|
` \uC804\uC5ED CSS \uB9E8 \uC55E(@charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
|
|
3274
3523
|
);
|
|
3275
3524
|
}
|
|
3276
3525
|
if (css && css.otherBrands.length > 0) {
|
|
3277
3526
|
lines.push(
|
|
3278
|
-
|
|
3527
|
+
chalk9.yellow(
|
|
3279
3528
|
` ! \uB2E4\uB978 \uBE0C\uB79C\uB4DC import(${css.otherBrands.join(", ")})\uB294 \uADF8\uB300\uB85C \uB450\uC5C8\uC2B5\uB2C8\uB2E4. \uC4F0\uC9C0 \uC54A\uC73C\uBA74 \uC774\uC804 \uBE0C\uB79C\uB4DC import \uB97C \uC9C0\uC6CC\uB3C4 \uB429\uB2C8\uB2E4.`
|
|
3280
3529
|
)
|
|
3281
3530
|
);
|
|
@@ -3283,60 +3532,60 @@ function renderThemeAdd(plan, written) {
|
|
|
3283
3532
|
const dep = plan.dependency;
|
|
3284
3533
|
if (dep?.action === "add") {
|
|
3285
3534
|
lines.push(
|
|
3286
|
-
` ${
|
|
3287
|
-
` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${
|
|
3535
|
+
` ${chalk9.green("\u2713")} package.json: dependencies \uC5D0 "${TOKENS_PACKAGE}": "${TOKENS_DEPENDENCY_RANGE}" \uCD94\uAC00`,
|
|
3536
|
+
` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk9.cyan(plan.installCommand)}`
|
|
3288
3537
|
);
|
|
3289
3538
|
} else if (dep?.action === "present") {
|
|
3290
|
-
lines.push(` ${
|
|
3539
|
+
lines.push(` ${chalk9.gray("-")} package.json: ${TOKENS_PACKAGE} ${dep.declaredRange} \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uBC94\uC704\uB97C \uBC14\uAFB8\uC9C0 \uC54A\uC74C`);
|
|
3291
3540
|
} else if (dep?.action === "no-package-json") {
|
|
3292
3541
|
lines.push(
|
|
3293
|
-
|
|
3542
|
+
chalk9.yellow(` ! package.json \uC774 \uC5C6\uC5B4 \uC758\uC874\uC131\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${TOKENS_INSTALL_COMMAND}`)
|
|
3294
3543
|
);
|
|
3295
3544
|
}
|
|
3296
3545
|
if (dep?.upgrade) {
|
|
3297
3546
|
lines.push(
|
|
3298
|
-
|
|
3547
|
+
chalk9.yellow(
|
|
3299
3548
|
` ! \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${plan.tokens.version} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`
|
|
3300
3549
|
),
|
|
3301
|
-
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${
|
|
3550
|
+
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
|
|
3302
3551
|
);
|
|
3303
3552
|
}
|
|
3304
3553
|
if (plan.configChanged) {
|
|
3305
|
-
lines.push(` ${
|
|
3554
|
+
lines.push(` ${chalk9.green("\u2713")} axis.config.json: "brand": "${plan.brand}" \uAE30\uB85D`);
|
|
3306
3555
|
} else {
|
|
3307
|
-
lines.push(` ${
|
|
3556
|
+
lines.push(` ${chalk9.gray("-")} axis.config.json: brand \uAC00 \uC774\uBBF8 "${plan.brand}"`);
|
|
3308
3557
|
}
|
|
3309
3558
|
lines.push(
|
|
3310
3559
|
"",
|
|
3311
|
-
|
|
3560
|
+
chalk9.bold(`Provider (${THEME_PACKAGE} 1.3.0 \uC774\uC0C1)`),
|
|
3312
3561
|
...providerExample(plan.brand).split("\n").map((l) => l ? ` ${l}` : ""),
|
|
3313
|
-
|
|
3562
|
+
chalk9.gray(
|
|
3314
3563
|
` ThemeProvider \uB098 <html data-brand="${plan.brand}"> \uAC00 \uC5C6\uC73C\uBA74 import \uB9CC\uC73C\uB85C\uB294 \uD654\uBA74\uC774 \uBC14\uB00C\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.`
|
|
3315
3564
|
)
|
|
3316
3565
|
);
|
|
3317
3566
|
if (dep?.themeMissing) {
|
|
3318
|
-
lines.push(` ${THEME_PACKAGE} \uC124\uCE58: ${
|
|
3567
|
+
lines.push(` ${THEME_PACKAGE} \uC124\uCE58: ${chalk9.cyan(`pnpm add ${THEME_PACKAGE}@^1.3.0`)}`);
|
|
3319
3568
|
}
|
|
3320
|
-
lines.push("",
|
|
3569
|
+
lines.push("", chalk9.gray(written.length > 0 ? `\uD30C\uC77C ${written.length}\uAC1C\uB97C \uBC14\uAFE8\uC2B5\uB2C8\uB2E4.` : "\uBC14\uAFBC \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4."), "");
|
|
3321
3570
|
return { lines, exitCode: 0 };
|
|
3322
3571
|
}
|
|
3323
3572
|
function renderThemeAddFailure(plan, err) {
|
|
3324
3573
|
const lines = [""];
|
|
3325
3574
|
if (err instanceof ThemeApplyError) {
|
|
3326
|
-
lines.push(
|
|
3575
|
+
lines.push(chalk9.red(err.message));
|
|
3327
3576
|
if (err.restored.length > 0) {
|
|
3328
3577
|
lines.push(` \uBA3C\uC800 \uC4F4 \uD30C\uC77C\uC740 \uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4: ${err.restored.map((f) => rel(plan, f)).join(", ")}`);
|
|
3329
3578
|
}
|
|
3330
3579
|
if (err.restoreFailed.length > 0) {
|
|
3331
3580
|
lines.push(
|
|
3332
|
-
|
|
3581
|
+
chalk9.red(` \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD574 \uBC14\uB010 \uCC44 \uB0A8\uC740 \uD30C\uC77C: ${err.restoreFailed.map((f) => rel(plan, f)).join(", ")}`)
|
|
3333
3582
|
);
|
|
3334
3583
|
}
|
|
3335
3584
|
if (err.restored.length === 0 && err.restoreFailed.length === 0) {
|
|
3336
3585
|
lines.push(" \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
3337
3586
|
}
|
|
3338
3587
|
} else {
|
|
3339
|
-
lines.push(
|
|
3588
|
+
lines.push(chalk9.red(err instanceof Error ? err.message : String(err)), " \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
3340
3589
|
}
|
|
3341
3590
|
lines.push("");
|
|
3342
3591
|
return { lines, exitCode: 1 };
|
|
@@ -3348,15 +3597,15 @@ function print(output) {
|
|
|
3348
3597
|
function registerThemeCommand(program2) {
|
|
3349
3598
|
const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
|
|
3350
3599
|
themeCmd.command("list").alias("ls").description("\uC124\uCE58\uB41C @axis-ds/tokens \uC758 \uBE0C\uB79C\uB4DC \uBAA9\uB85D").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((options) => {
|
|
3351
|
-
const baseDir =
|
|
3600
|
+
const baseDir = path13.resolve(options.dir || ".");
|
|
3352
3601
|
print(renderThemeList(listBrands(baseDir)));
|
|
3353
3602
|
});
|
|
3354
3603
|
themeCmd.command("info <brand>").description("\uBE0C\uB79C\uB4DC \uC0C1\uC138: import \uACBD\uB85C \xB7 Provider \uC608\uC2DC \xB7 \uC8FC\uC694 \uD1A0\uD070 \xB7 \uBCF4\uC815 \uB0B4\uC5ED").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((name, options) => {
|
|
3355
|
-
const baseDir =
|
|
3604
|
+
const baseDir = path13.resolve(options.dir || ".");
|
|
3356
3605
|
print(renderThemeInfo(getBrand(baseDir, name), name));
|
|
3357
3606
|
});
|
|
3358
3607
|
themeCmd.command("add <brand>").description("\uBE0C\uB79C\uB4DC \uC801\uC6A9: CSS import \xB7 package.json \uC758\uC874\uC131 \xB7 axis.config.json brand (\uC124\uCE58\uB294 \uC548\uB0B4\uB9CC)").option("-d, --dir <path>", "\uB300\uC0C1 \uB514\uB809\uD1A0\uB9AC").action((name, options) => {
|
|
3359
|
-
const baseDir =
|
|
3608
|
+
const baseDir = path13.resolve(options.dir || ".");
|
|
3360
3609
|
const plan = planThemeAdd(baseDir, name);
|
|
3361
3610
|
let written = [];
|
|
3362
3611
|
if (plan.errors.length === 0) {
|
|
@@ -3372,17 +3621,17 @@ function registerThemeCommand(program2) {
|
|
|
3372
3621
|
}
|
|
3373
3622
|
|
|
3374
3623
|
// src/init/index.ts
|
|
3375
|
-
import
|
|
3624
|
+
import chalk11 from "chalk";
|
|
3376
3625
|
import prompts2 from "prompts";
|
|
3377
3626
|
|
|
3378
|
-
// src/registry/schema.ts
|
|
3627
|
+
// ../axis-registry-core/src/registry/schema.ts
|
|
3379
3628
|
import { createHash } from "crypto";
|
|
3380
3629
|
var REGISTRY_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3381
3630
|
var REGISTRY_NAME_MAX_LENGTH = 64;
|
|
3382
3631
|
function isValidRegistryName(name) {
|
|
3383
3632
|
return typeof name === "string" && name.length > 0 && name.length <= REGISTRY_NAME_MAX_LENGTH && REGISTRY_NAME_PATTERN.test(name);
|
|
3384
3633
|
}
|
|
3385
|
-
var REGISTRY_PUBLIC_BASE_URL =
|
|
3634
|
+
var REGISTRY_PUBLIC_BASE_URL = `${AXIS_SITE_URL}/r`;
|
|
3386
3635
|
function redactRegistryUrl(raw) {
|
|
3387
3636
|
return maskQueryAndHash(redactUserinfo(raw));
|
|
3388
3637
|
}
|
|
@@ -3579,7 +3828,7 @@ function checkItemSha256(item, entry, where = `${item.name}.json`) {
|
|
|
3579
3828
|
}
|
|
3580
3829
|
}
|
|
3581
3830
|
|
|
3582
|
-
// src/registry/remote.ts
|
|
3831
|
+
// ../axis-registry-core/src/registry/remote.ts
|
|
3583
3832
|
var DEFAULT_REGISTRY_URL = REGISTRY_PUBLIC_BASE_URL;
|
|
3584
3833
|
var DEFAULT_REGISTRY_TIMEOUT_MS = 5e3;
|
|
3585
3834
|
var LEGACY_DEFAULT_REGISTRY_URL = "https://axis.minu.best/r";
|
|
@@ -3648,10 +3897,18 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
3648
3897
|
try {
|
|
3649
3898
|
let res;
|
|
3650
3899
|
try {
|
|
3651
|
-
res = await fetchImpl(url, {
|
|
3900
|
+
res = await fetchImpl(url, {
|
|
3901
|
+
signal: controller.signal,
|
|
3902
|
+
headers: { accept: "application/json" },
|
|
3903
|
+
...options.rejectRedirects ? { redirect: "manual" } : {}
|
|
3904
|
+
});
|
|
3652
3905
|
} catch (error) {
|
|
3653
3906
|
throw describe(error);
|
|
3654
3907
|
}
|
|
3908
|
+
if (options.rejectRedirects && (res.type === "opaqueredirect" || res.status >= 300 && res.status < 400 || res.status === 0)) {
|
|
3909
|
+
await res.text().catch(() => void 0);
|
|
3910
|
+
throw new RegistryAccessError(`${shown}: \uB9AC\uB2E4\uC774\uB809\uD2B8(HTTP ${res.status})\uB97C \uB530\uB77C\uAC00\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
|
|
3911
|
+
}
|
|
3655
3912
|
if (!res.ok) {
|
|
3656
3913
|
await res.text().catch(() => void 0);
|
|
3657
3914
|
throw new RegistryAccessError(`${shown}: HTTP ${res.status}`);
|
|
@@ -3668,15 +3925,15 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
3668
3925
|
}
|
|
3669
3926
|
|
|
3670
3927
|
// src/init/init.ts
|
|
3671
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as
|
|
3672
|
-
import
|
|
3673
|
-
import
|
|
3674
|
-
import
|
|
3928
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync2, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
3929
|
+
import path15 from "path";
|
|
3930
|
+
import chalk10 from "chalk";
|
|
3931
|
+
import fs12 from "fs-extra";
|
|
3675
3932
|
|
|
3676
|
-
// src/add/safe-write.ts
|
|
3677
|
-
import { constants as fsConstants, existsSync as
|
|
3678
|
-
import
|
|
3679
|
-
import
|
|
3933
|
+
// ../axis-registry-core/src/add/safe-write.ts
|
|
3934
|
+
import { constants as fsConstants, existsSync as existsSync5, lstatSync, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
|
|
3935
|
+
import path14 from "path";
|
|
3936
|
+
import fs11 from "fs-extra";
|
|
3680
3937
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
3681
3938
|
var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
|
|
3682
3939
|
var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
|
|
@@ -3686,15 +3943,15 @@ function codedError(code, message) {
|
|
|
3686
3943
|
e.code = code;
|
|
3687
3944
|
return e;
|
|
3688
3945
|
}
|
|
3689
|
-
function isSameOrInside(parent, child, impl =
|
|
3946
|
+
function isSameOrInside(parent, child, impl = path14) {
|
|
3690
3947
|
const rel3 = impl.relative(parent, child);
|
|
3691
3948
|
if (rel3 === "") return true;
|
|
3692
3949
|
return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
|
|
3693
3950
|
}
|
|
3694
3951
|
function nearestExisting(p) {
|
|
3695
3952
|
let cur = p;
|
|
3696
|
-
while (!
|
|
3697
|
-
const up =
|
|
3953
|
+
while (!existsSync5(cur)) {
|
|
3954
|
+
const up = path14.dirname(cur);
|
|
3698
3955
|
if (up === cur) return cur;
|
|
3699
3956
|
cur = up;
|
|
3700
3957
|
}
|
|
@@ -3702,10 +3959,10 @@ function nearestExisting(p) {
|
|
|
3702
3959
|
}
|
|
3703
3960
|
function escapeReason(root, target, options = {}) {
|
|
3704
3961
|
const realRoot = realpathSync2(root);
|
|
3705
|
-
if (!isSameOrInside(
|
|
3962
|
+
if (!isSameOrInside(path14.resolve(root), path14.resolve(target)) || path14.resolve(target) === path14.resolve(root)) {
|
|
3706
3963
|
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
3707
3964
|
}
|
|
3708
|
-
const anchor = nearestExisting(
|
|
3965
|
+
const anchor = nearestExisting(path14.dirname(target));
|
|
3709
3966
|
const realAnchor = realpathSync2(anchor);
|
|
3710
3967
|
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
3711
3968
|
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`;
|
|
@@ -3718,7 +3975,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
3718
3975
|
}
|
|
3719
3976
|
if (st) {
|
|
3720
3977
|
if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
|
|
3721
|
-
const shown =
|
|
3978
|
+
const shown = path14.relative(path14.resolve(root), path14.resolve(target)).split(path14.sep).join("/");
|
|
3722
3979
|
let realTarget;
|
|
3723
3980
|
try {
|
|
3724
3981
|
realTarget = realpathSync2(target);
|
|
@@ -3786,50 +4043,50 @@ async function writeNoFollow(target, content, mode) {
|
|
|
3786
4043
|
let fd;
|
|
3787
4044
|
if (mode === "overwrite") {
|
|
3788
4045
|
try {
|
|
3789
|
-
fd = await
|
|
4046
|
+
fd = await fs11.open(target, OVERWRITE_FLAGS);
|
|
3790
4047
|
} catch (e) {
|
|
3791
4048
|
if (e.code !== "ENOENT") throw e;
|
|
3792
4049
|
actual = "new";
|
|
3793
|
-
fd = await
|
|
4050
|
+
fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
|
|
3794
4051
|
}
|
|
3795
4052
|
} else {
|
|
3796
|
-
fd = await
|
|
4053
|
+
fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
|
|
3797
4054
|
}
|
|
3798
4055
|
try {
|
|
3799
4056
|
if (actual === "overwrite") {
|
|
3800
|
-
const st = await
|
|
4057
|
+
const st = await fs11.fstat(fd);
|
|
3801
4058
|
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3802
4059
|
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
3803
|
-
await
|
|
4060
|
+
await fs11.ftruncate(fd, 0);
|
|
3804
4061
|
}
|
|
3805
|
-
await
|
|
4062
|
+
await fs11.writeFile(fd, content);
|
|
3806
4063
|
} finally {
|
|
3807
|
-
await
|
|
4064
|
+
await fs11.close(fd);
|
|
3808
4065
|
}
|
|
3809
4066
|
return actual;
|
|
3810
4067
|
}
|
|
3811
4068
|
async function overwriteFollowingLinks(target, content) {
|
|
3812
|
-
const fd = await
|
|
4069
|
+
const fd = await fs11.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
|
|
3813
4070
|
try {
|
|
3814
|
-
const st = await
|
|
4071
|
+
const st = await fs11.fstat(fd);
|
|
3815
4072
|
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3816
4073
|
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
3817
|
-
await
|
|
3818
|
-
await
|
|
4074
|
+
await fs11.ftruncate(fd, 0);
|
|
4075
|
+
await fs11.writeFile(fd, content);
|
|
3819
4076
|
} finally {
|
|
3820
|
-
await
|
|
4077
|
+
await fs11.close(fd);
|
|
3821
4078
|
}
|
|
3822
4079
|
}
|
|
3823
4080
|
function checkParentInside(root, target) {
|
|
3824
4081
|
const realRoot = realpathSync2(root);
|
|
3825
|
-
const realParent = realpathSync2(
|
|
4082
|
+
const realParent = realpathSync2(path14.dirname(target));
|
|
3826
4083
|
if (!isSameOrInside(realRoot, realParent)) {
|
|
3827
4084
|
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`;
|
|
3828
4085
|
}
|
|
3829
4086
|
return escapeReason(root, target);
|
|
3830
4087
|
}
|
|
3831
4088
|
|
|
3832
|
-
// src/
|
|
4089
|
+
// ../axis-registry-core/src/utils-deps.ts
|
|
3833
4090
|
var CLSX_RANGE = "^2.1.1";
|
|
3834
4091
|
var TAILWIND_MERGE_RANGES = {
|
|
3835
4092
|
tailwind4: "^3.4.0",
|
|
@@ -3841,6 +4098,8 @@ function selectUtilsDependencies(tailwind) {
|
|
|
3841
4098
|
"tailwind-merge": tailwind.major !== void 0 && tailwind.major >= 4 ? TAILWIND_MERGE_RANGES.tailwind4 : TAILWIND_MERGE_RANGES.tailwind3
|
|
3842
4099
|
};
|
|
3843
4100
|
}
|
|
4101
|
+
|
|
4102
|
+
// src/init/init.ts
|
|
3844
4103
|
function tailwindWarnings(tailwind, installCommand) {
|
|
3845
4104
|
const out = [];
|
|
3846
4105
|
if (tailwind.source === "none" && tailwind.value !== void 0) {
|
|
@@ -3904,7 +4163,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
|
|
|
3904
4163
|
var TAILWIND4_CONFLICT_LINE = " ! create-next-app \uAE30\uBCF8 globals.css \uC758 :root \xB7 @theme inline \xB7 @media (prefers-color-scheme: dark) \xB7 body \uBE14\uB85D\uC740 AXIS \uC640 \uAC19\uC740 \uC774\uB984(--background \xB7 --foreground \xB7 --color-background \xB7 --font-sans \xB7 --font-mono)\uC744 \uB2E4\uB978 \uAC12\uC73C\uB85C \uC815\uC758\uD569\uB2C8\uB2E4. \uC774 \uBE14\uB85D\uB4E4\uC744 \uC9C0\uC6B0\uC138\uC694.";
|
|
3905
4164
|
function readPackageJsonSafe(baseDir) {
|
|
3906
4165
|
try {
|
|
3907
|
-
const text = readFileSync4(
|
|
4166
|
+
const text = readFileSync4(path15.join(baseDir, "package.json"), "utf8");
|
|
3908
4167
|
const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
|
|
3909
4168
|
return isPlainObject2(parsed) ? parsed : void 0;
|
|
3910
4169
|
} catch {
|
|
@@ -3969,7 +4228,7 @@ function addCommandFor(installCommand, deps) {
|
|
|
3969
4228
|
return `pnpm add ${specs}`;
|
|
3970
4229
|
}
|
|
3971
4230
|
function planUtilsDependencies(baseDirInput) {
|
|
3972
|
-
const baseDir =
|
|
4231
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
3973
4232
|
const installCommand = detectInstallCommand(baseDir);
|
|
3974
4233
|
const tailwind0 = detectTailwind(baseDir);
|
|
3975
4234
|
const ranges0 = selectUtilsDependencies(tailwind0);
|
|
@@ -3982,8 +4241,8 @@ function planUtilsDependencies(baseDirInput) {
|
|
|
3982
4241
|
installCommand,
|
|
3983
4242
|
addCommand: addCommandFor(installCommand, ranges0)
|
|
3984
4243
|
};
|
|
3985
|
-
const pkgFile =
|
|
3986
|
-
if (!
|
|
4244
|
+
const pkgFile = path15.join(baseDir, "package.json");
|
|
4245
|
+
if (!existsSync6(pkgFile)) return plan;
|
|
3987
4246
|
const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
|
|
3988
4247
|
let where;
|
|
3989
4248
|
try {
|
|
@@ -4036,8 +4295,8 @@ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
|
|
|
4036
4295
|
function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
|
|
4037
4296
|
const w = plan.write;
|
|
4038
4297
|
if (plan.action !== "add" || !w) return false;
|
|
4039
|
-
const baseDir =
|
|
4040
|
-
const current =
|
|
4298
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
4299
|
+
const current = existsSync6(w.file) ? readFileSync4(w.file, "utf8") : null;
|
|
4041
4300
|
if (current !== w.before) {
|
|
4042
4301
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
4043
4302
|
}
|
|
@@ -4066,25 +4325,25 @@ function reportDependencies(plan, log) {
|
|
|
4066
4325
|
const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
|
|
4067
4326
|
const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
|
|
4068
4327
|
const logBasis = () => {
|
|
4069
|
-
log(
|
|
4070
|
-
for (const w of tailwindWarnings(plan.tailwind, plan.installCommand)) log(
|
|
4328
|
+
log(chalk10.gray(basis));
|
|
4329
|
+
for (const w of tailwindWarnings(plan.tailwind, plan.installCommand)) log(chalk10.yellow(` ${w}`));
|
|
4071
4330
|
};
|
|
4072
4331
|
if (plan.action === "add") {
|
|
4073
4332
|
const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
|
|
4074
|
-
log(
|
|
4075
|
-
if (plan.present.length > 0) log(
|
|
4333
|
+
log(chalk10.green(`\u2713 package.json dependencies \uC5D0 \uCD94\uAC00: ${addedText}`));
|
|
4334
|
+
if (plan.present.length > 0) log(chalk10.gray(` \uC774\uBBF8 \uC788\uC74C(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
|
|
4076
4335
|
if (plan.added.includes("tailwind-merge")) logBasis();
|
|
4077
|
-
log(
|
|
4336
|
+
log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
|
|
4078
4337
|
} else if (plan.action === "present") {
|
|
4079
|
-
log(
|
|
4080
|
-
log(
|
|
4338
|
+
log(chalk10.green(`\u2713 utils.ts \uC758\uC874\uC131\uC774 package.json \uC5D0 \uC774\uBBF8 \uC788\uC2B5\uB2C8\uB2E4(\uBC84\uC804 \uC720\uC9C0): ${presentText}`));
|
|
4339
|
+
log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
|
|
4081
4340
|
} else if (plan.action === "no-package-json") {
|
|
4082
|
-
log(
|
|
4083
|
-
log(
|
|
4341
|
+
log(chalk10.yellow("! package.json \uC774 \uC5C6\uC5B4 utils.ts \uC758\uC874\uC131(clsx, tailwind-merge)\uC744 \uCD94\uAC00\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4."));
|
|
4342
|
+
log(chalk10.yellow(` \uC124\uCE58: ${chalk10.cyan(plan.addCommand)}`));
|
|
4084
4343
|
logBasis();
|
|
4085
4344
|
} else {
|
|
4086
|
-
log(
|
|
4087
|
-
log(
|
|
4345
|
+
log(chalk10.yellow(`! package.json \uC744 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(${plan.reason}).`));
|
|
4346
|
+
log(chalk10.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk10.cyan(plan.addCommand)}`));
|
|
4088
4347
|
if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
|
|
4089
4348
|
}
|
|
4090
4349
|
}
|
|
@@ -4107,8 +4366,8 @@ function errCode(e) {
|
|
|
4107
4366
|
return e.code ?? e.message;
|
|
4108
4367
|
}
|
|
4109
4368
|
function planUtilsWrite(baseDirInput, utilsPath) {
|
|
4110
|
-
const baseDir =
|
|
4111
|
-
const shown =
|
|
4369
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
4370
|
+
const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
|
|
4112
4371
|
let st;
|
|
4113
4372
|
try {
|
|
4114
4373
|
st = lstatSync2(utilsPath);
|
|
@@ -4169,7 +4428,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
4169
4428
|
return { action: "overwrite" };
|
|
4170
4429
|
}
|
|
4171
4430
|
async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
4172
|
-
const baseDir =
|
|
4431
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
4173
4432
|
const current = await existingConfig(baseDir);
|
|
4174
4433
|
const existingRegistry = nonEmptyString(current?.registry);
|
|
4175
4434
|
const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
|
|
@@ -4186,13 +4445,13 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4186
4445
|
},
|
|
4187
4446
|
registry
|
|
4188
4447
|
);
|
|
4189
|
-
const configPath =
|
|
4448
|
+
const configPath = path15.join(baseDir, "axis.config.json");
|
|
4190
4449
|
const nextText = `${JSON.stringify(axisConfig, null, 2)}
|
|
4191
4450
|
`;
|
|
4192
4451
|
const rejects = [];
|
|
4193
4452
|
let previousText = null;
|
|
4194
4453
|
try {
|
|
4195
|
-
previousText = await
|
|
4454
|
+
previousText = await fs12.readFile(configPath, "utf8");
|
|
4196
4455
|
} catch (e) {
|
|
4197
4456
|
if (e.code !== "ENOENT") {
|
|
4198
4457
|
rejects.push(`\uAE30\uC874 axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})`);
|
|
@@ -4205,79 +4464,79 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4205
4464
|
} catch {
|
|
4206
4465
|
}
|
|
4207
4466
|
}
|
|
4208
|
-
const utilsPath =
|
|
4467
|
+
const utilsPath = path15.resolve(baseDir, answers.componentsDir, "utils.ts");
|
|
4209
4468
|
const utilsPlan = planUtilsWrite(baseDir, utilsPath);
|
|
4210
4469
|
if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
|
|
4211
4470
|
if (rejects.length > 0) {
|
|
4212
|
-
log(
|
|
4213
|
-
for (const r of rejects) log(
|
|
4471
|
+
log(chalk10.red("\u2717 \uC4F8 \uC218 \uC5C6\uB294 \uD30C\uC77C\uC774 \uC788\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(axis.config.json \xB7 utils.ts \xB7 package.json \uADF8\uB300\uB85C)."));
|
|
4472
|
+
for (const r of rejects) log(chalk10.red(` - ${r}`));
|
|
4214
4473
|
process.exitCode = 1;
|
|
4215
4474
|
return;
|
|
4216
4475
|
}
|
|
4217
4476
|
let configState;
|
|
4218
4477
|
if (previousText === null) {
|
|
4219
4478
|
try {
|
|
4220
|
-
await
|
|
4479
|
+
await fs12.writeFile(configPath, nextText, { flag: "wx" });
|
|
4221
4480
|
} catch (err) {
|
|
4222
4481
|
const reason = err.code === "EEXIST" ? "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uAC19\uC740 \uC774\uB984\uC758 \uD30C\uC77C\uC774 \uC0DD\uACBC\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569)" : err.message;
|
|
4223
|
-
log(
|
|
4482
|
+
log(chalk10.red(`\u2717 axis.config.json \uC744 \uB9CC\uB4E4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
|
|
4224
4483
|
process.exitCode = 1;
|
|
4225
4484
|
return;
|
|
4226
4485
|
}
|
|
4227
4486
|
configState = "created";
|
|
4228
|
-
log(
|
|
4487
|
+
log(chalk10.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
|
|
4229
4488
|
} else if (previousText === nextText) {
|
|
4230
4489
|
configState = "kept";
|
|
4231
|
-
log(
|
|
4490
|
+
log(chalk10.green("\u2713 axis.config.json \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
|
|
4232
4491
|
} else {
|
|
4233
4492
|
try {
|
|
4234
4493
|
await overwriteFollowingLinks(configPath, nextText);
|
|
4235
4494
|
} catch (err) {
|
|
4236
4495
|
const reason = err.code === HARDLINK_ERROR_CODE ? `\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC84C\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569, D19)` : err.message;
|
|
4237
|
-
log(
|
|
4496
|
+
log(chalk10.red(`\u2717 axis.config.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`));
|
|
4238
4497
|
process.exitCode = 1;
|
|
4239
4498
|
return;
|
|
4240
4499
|
}
|
|
4241
4500
|
configState = "updated";
|
|
4242
4501
|
const registryNote = migratedRegistry ? "registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C\uB85C \uAC31\uC2E0" : existingRegistry !== void 0 ? "registry \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "registry \uB294 \uAE30\uBCF8\uAC12";
|
|
4243
4502
|
const agenticNote = existingAgenticDir !== void 0 ? ", agenticDir \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "";
|
|
4244
|
-
log(
|
|
4503
|
+
log(chalk10.green(`\u2713 axis.config.json \uAC31\uC2E0(\uAE30\uC874 \uD30C\uC77C\uC744 init \uAC12\uC73C\uB85C \uB2E4\uC2DC \uC500, ${registryNote}${agenticNote})`));
|
|
4245
4504
|
if (migratedRegistry && existingRegistry !== void 0) {
|
|
4246
4505
|
log(
|
|
4247
|
-
|
|
4506
|
+
chalk10.yellow(
|
|
4248
4507
|
` registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C(${redactRegistryUrl(registry)})\uB85C \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4(\uC885\uC804 axis.minu.best: ${redactRegistryUrl(existingRegistry)}).`
|
|
4249
4508
|
)
|
|
4250
4509
|
);
|
|
4251
4510
|
}
|
|
4252
4511
|
const dropped = current ? Object.keys(current).filter((k) => !(k in axisConfig) && current[k] !== void 0) : [];
|
|
4253
4512
|
if (dropped.length > 0) {
|
|
4254
|
-
log(
|
|
4513
|
+
log(chalk10.yellow(` \uAE30\uC874 \uC124\uC815\uC5D0\uC11C \uBE60\uC9C4 \uD0A4: ${dropped.join(", ")} (\uD544\uC694\uD558\uBA74 axis.config.json \uC5D0 \uB2E4\uC2DC \uC801\uC5B4 \uC8FC\uC138\uC694)`));
|
|
4255
4514
|
}
|
|
4256
4515
|
}
|
|
4257
4516
|
let utilsStateNote = "utils.ts \uB294 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9).";
|
|
4258
4517
|
if (utilsPlan.action === "keep") {
|
|
4259
|
-
if (utilsPlan.link === void 0) log(
|
|
4260
|
-
else if (utilsPlan.link.outside === null) log(
|
|
4261
|
-
else log(
|
|
4518
|
+
if (utilsPlan.link === void 0) log(chalk10.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
|
|
4519
|
+
else if (utilsPlan.link.outside === null) log(chalk10.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C)"));
|
|
4520
|
+
else log(chalk10.green(`\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16: ${utilsPlan.link.outside})`));
|
|
4262
4521
|
} else {
|
|
4263
4522
|
let actual;
|
|
4264
4523
|
try {
|
|
4265
|
-
await
|
|
4524
|
+
await fs12.ensureDir(path15.dirname(utilsPath));
|
|
4266
4525
|
actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
|
|
4267
4526
|
} catch (err) {
|
|
4268
4527
|
const code = err.code;
|
|
4269
4528
|
const reason = code === HARDLINK_ERROR_CODE ? "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC84C\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569, D19)" : code === "ELOOP" || code === "EEXIST" ? "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uAC19\uC740 \uC774\uB984\uC758 \uD30C\uC77C \xB7 \uB9C1\uD06C\uAC00 \uC0DD\uACBC\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569)" : err.message;
|
|
4270
4529
|
log(
|
|
4271
|
-
|
|
4530
|
+
chalk10.red(
|
|
4272
4531
|
utilsPlan.action === "create" ? `\u2717 utils.ts \uB97C \uB9CC\uB4E4\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}.` : `\u2717 utils.ts \uB97C \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${reason}. \uADF8 \uD30C\uC77C\uC740 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.`
|
|
4273
4532
|
)
|
|
4274
4533
|
);
|
|
4275
|
-
log(
|
|
4534
|
+
log(chalk10.yellow(` ${configStateNote(configState)}`));
|
|
4276
4535
|
process.exitCode = 1;
|
|
4277
4536
|
return;
|
|
4278
4537
|
}
|
|
4279
4538
|
log(
|
|
4280
|
-
|
|
4539
|
+
chalk10.green(
|
|
4281
4540
|
actual === "new" ? "\u2713 utils.ts \uC0DD\uC131 \uC644\uB8CC" : "\u2713 utils.ts \uB36E\uC5B4\uC500(\uAE30\uC874 \uB0B4\uC6A9\uACFC \uB2EC\uB77C init \uC758 utils \uB85C \uB2E4\uC2DC \uC500)"
|
|
4282
4541
|
)
|
|
4283
4542
|
);
|
|
@@ -4286,9 +4545,9 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4286
4545
|
try {
|
|
4287
4546
|
applyUtilsDependencies(baseDir, plan);
|
|
4288
4547
|
} catch (err) {
|
|
4289
|
-
log(
|
|
4290
|
-
log(
|
|
4291
|
-
log(
|
|
4548
|
+
log(chalk10.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
|
|
4549
|
+
log(chalk10.yellow(` ${configStateNote(configState)} ${utilsStateNote}`));
|
|
4550
|
+
log(chalk10.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk10.cyan(plan.addCommand)}`));
|
|
4292
4551
|
process.exitCode = 1;
|
|
4293
4552
|
return;
|
|
4294
4553
|
}
|
|
@@ -4300,19 +4559,19 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4300
4559
|
answers.globalCss,
|
|
4301
4560
|
baseDir
|
|
4302
4561
|
);
|
|
4303
|
-
log(
|
|
4562
|
+
log(chalk10.blue(`
|
|
4304
4563
|
${head}`));
|
|
4305
|
-
for (const line of rest) log(line.startsWith(" !") ?
|
|
4564
|
+
for (const line of rest) log(line.startsWith(" !") ? chalk10.yellow(line) : chalk10.cyan(line));
|
|
4306
4565
|
}
|
|
4307
|
-
log(
|
|
4308
|
-
log(
|
|
4566
|
+
log(chalk10.blue("\n\uCD08\uAE30\uD654 \uC644\uB8CC! \uC774\uC81C \uB2E4\uC74C \uBA85\uB839\uC5B4\uB85C \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCD94\uAC00\uD558\uC138\uC694:"));
|
|
4567
|
+
log(chalk10.cyan(` ${INIT_NEXT_STEP_COMMAND}
|
|
4309
4568
|
`));
|
|
4310
4569
|
}
|
|
4311
4570
|
|
|
4312
4571
|
// src/init/index.ts
|
|
4313
4572
|
function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
|
|
4314
4573
|
program2.command("init").description("\uD504\uB85C\uC81D\uD2B8\uC5D0 AXIS Design System \uCD08\uAE30\uD654").option("-y, --yes", "\uAE30\uBCF8\uAC12\uC73C\uB85C \uC790\uB3D9 \uC124\uC815").action(async (options) => {
|
|
4315
|
-
console.log(
|
|
4574
|
+
console.log(chalk11.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
|
|
4316
4575
|
const tailwind4 = isTailwind4(planUtilsDependencies(process.cwd()).tailwind);
|
|
4317
4576
|
const config = options.yes ? { ...INIT_DEFAULTS } : await prompts2([
|
|
4318
4577
|
{
|
|
@@ -4339,27 +4598,27 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
|
|
|
4339
4598
|
}
|
|
4340
4599
|
|
|
4341
4600
|
// src/add/index.ts
|
|
4342
|
-
import
|
|
4601
|
+
import chalk12 from "chalk";
|
|
4343
4602
|
import prompts3 from "prompts";
|
|
4344
4603
|
|
|
4345
|
-
// src/add/add.ts
|
|
4346
|
-
import { existsSync as
|
|
4347
|
-
import
|
|
4348
|
-
import
|
|
4604
|
+
// ../axis-registry-core/src/add/add.ts
|
|
4605
|
+
import { existsSync as existsSync8, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
|
|
4606
|
+
import path17 from "path";
|
|
4607
|
+
import fs13 from "fs-extra";
|
|
4349
4608
|
|
|
4350
|
-
// src/registry/bundled.ts
|
|
4351
|
-
import { existsSync as
|
|
4352
|
-
import
|
|
4609
|
+
// ../axis-registry-core/src/registry/bundled.ts
|
|
4610
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
4611
|
+
import path16 from "path";
|
|
4353
4612
|
import { fileURLToPath } from "url";
|
|
4354
4613
|
function findBundledRegistryDir(moduleUrl = import.meta.url) {
|
|
4355
|
-
const here =
|
|
4356
|
-
for (const dir of [
|
|
4357
|
-
if (
|
|
4614
|
+
const here = path16.dirname(fileURLToPath(moduleUrl));
|
|
4615
|
+
for (const dir of [path16.join(here, "registry"), path16.join(here, "..", "registry")]) {
|
|
4616
|
+
if (existsSync7(path16.join(dir, "index.json"))) return dir;
|
|
4358
4617
|
}
|
|
4359
4618
|
return null;
|
|
4360
4619
|
}
|
|
4361
4620
|
function readBundledJson(dir, fileName) {
|
|
4362
|
-
const file =
|
|
4621
|
+
const file = path16.join(dir, fileName);
|
|
4363
4622
|
let text;
|
|
4364
4623
|
try {
|
|
4365
4624
|
text = readFileSync5(file, "utf8");
|
|
@@ -4369,7 +4628,238 @@ function readBundledJson(dir, fileName) {
|
|
|
4369
4628
|
return parseJsonText(text, `\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC ${fileName}`);
|
|
4370
4629
|
}
|
|
4371
4630
|
|
|
4372
|
-
// src/registry/
|
|
4631
|
+
// ../axis-registry-core/src/registry/host-guard.ts
|
|
4632
|
+
import { lookup as dnsLookup } from "dns/promises";
|
|
4633
|
+
import { isIP } from "net";
|
|
4634
|
+
var defaultLookupAll = (hostname) => dnsLookup(hostname, { all: true, verbatim: true });
|
|
4635
|
+
function ipv4Octets(ip) {
|
|
4636
|
+
const parts = ip.split(".");
|
|
4637
|
+
if (parts.length !== 4) return null;
|
|
4638
|
+
const nums = parts.map((p) => /^\d{1,3}$/.test(p) ? Number(p) : NaN);
|
|
4639
|
+
return nums.every((n) => n >= 0 && n <= 255) ? nums : null;
|
|
4640
|
+
}
|
|
4641
|
+
var BLOCKED_V4 = [
|
|
4642
|
+
["0.0.0.0", 8, "\uBBF8\uC9C0\uC815 \uC8FC\uC18C(0.0.0.0/8)"],
|
|
4643
|
+
["10.0.0.0", 8, "\uC0AC\uC124 \uC8FC\uC18C(10.0.0.0/8)"],
|
|
4644
|
+
["100.64.0.0", 10, "\uACF5\uC720 \uC8FC\uC18C(100.64.0.0/10)"],
|
|
4645
|
+
["127.0.0.0", 8, "\uB8E8\uD504\uBC31 \uC8FC\uC18C(127.0.0.0/8)"],
|
|
4646
|
+
["169.254.0.0", 16, "\uB9C1\uD06C\uB85C\uCEEC \uC8FC\uC18C(169.254.0.0/16)"],
|
|
4647
|
+
["172.16.0.0", 12, "\uC0AC\uC124 \uC8FC\uC18C(172.16.0.0/12)"],
|
|
4648
|
+
["192.0.0.0", 24, "IETF \uD504\uB85C\uD1A0\uCF5C \uD560\uB2F9 \uC8FC\uC18C(192.0.0.0/24)"],
|
|
4649
|
+
["192.0.2.0", 24, "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(192.0.2.0/24)"],
|
|
4650
|
+
["192.88.99.0", 24, "6to4 \uB9B4\uB808\uC774 \uC8FC\uC18C(192.88.99.0/24)"],
|
|
4651
|
+
["192.168.0.0", 16, "\uC0AC\uC124 \uC8FC\uC18C(192.168.0.0/16)"],
|
|
4652
|
+
["198.18.0.0", 15, "\uBCA4\uCE58\uB9C8\uD06C \uC8FC\uC18C(198.18.0.0/15)"],
|
|
4653
|
+
["198.51.100.0", 24, "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(198.51.100.0/24)"],
|
|
4654
|
+
["203.0.113.0", 24, "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(203.0.113.0/24)"],
|
|
4655
|
+
["224.0.0.0", 4, "\uBA40\uD2F0\uCE90\uC2A4\uD2B8 \uC8FC\uC18C(224.0.0.0/4)"],
|
|
4656
|
+
["240.0.0.0", 4, "\uC608\uC57D \uC8FC\uC18C(240.0.0.0/4)"]
|
|
4657
|
+
];
|
|
4658
|
+
function ipv4ToInt(o) {
|
|
4659
|
+
return (o[0] << 24 | o[1] << 16 | o[2] << 8 | o[3]) >>> 0;
|
|
4660
|
+
}
|
|
4661
|
+
function blockedIpv4Reason(ip) {
|
|
4662
|
+
const o = ipv4Octets(ip);
|
|
4663
|
+
if (!o) return "IPv4 \uC8FC\uC18C \uD615\uC2DD\uC774 \uC544\uB2D8";
|
|
4664
|
+
const n = ipv4ToInt(o);
|
|
4665
|
+
for (const [base, len, name] of BLOCKED_V4) {
|
|
4666
|
+
const mask = len === 0 ? 0 : 4294967295 << 32 - len >>> 0;
|
|
4667
|
+
if ((n & mask) >>> 0 === (ipv4ToInt(ipv4Octets(base)) & mask) >>> 0) return name;
|
|
4668
|
+
}
|
|
4669
|
+
return null;
|
|
4670
|
+
}
|
|
4671
|
+
function parseIpv6(ip) {
|
|
4672
|
+
let s = ip.toLowerCase();
|
|
4673
|
+
const zone = s.indexOf("%");
|
|
4674
|
+
if (zone >= 0) s = s.slice(0, zone);
|
|
4675
|
+
const lastColon = s.lastIndexOf(":");
|
|
4676
|
+
if (lastColon >= 0 && s.slice(lastColon + 1).includes(".")) {
|
|
4677
|
+
const o = ipv4Octets(s.slice(lastColon + 1));
|
|
4678
|
+
if (!o) return null;
|
|
4679
|
+
s = `${s.slice(0, lastColon + 1)}${(o[0] << 8 | o[1]).toString(16)}:${(o[2] << 8 | o[3]).toString(16)}`;
|
|
4680
|
+
}
|
|
4681
|
+
const halves = s.split("::");
|
|
4682
|
+
if (halves.length > 2) return null;
|
|
4683
|
+
const toGroups = (part) => part === "" ? [] : part.split(":");
|
|
4684
|
+
const parseGroup = (g) => /^[0-9a-f]{1,4}$/.test(g) ? parseInt(g, 16) : NaN;
|
|
4685
|
+
let groups = toGroups(halves[0]).map(parseGroup);
|
|
4686
|
+
const restNums = halves.length === 2 ? toGroups(halves[1]).map(parseGroup) : [];
|
|
4687
|
+
const total = groups.length + restNums.length;
|
|
4688
|
+
if (halves.length === 2) {
|
|
4689
|
+
if (total > 7) return null;
|
|
4690
|
+
groups = [...groups, ...new Array(8 - total).fill(0), ...restNums];
|
|
4691
|
+
} else if (total !== 8) {
|
|
4692
|
+
return null;
|
|
4693
|
+
}
|
|
4694
|
+
return groups.every((g) => Number.isInteger(g) && g >= 0 && g <= 65535) ? groups : null;
|
|
4695
|
+
}
|
|
4696
|
+
function groupsToIpv4(hi, lo) {
|
|
4697
|
+
return `${hi >> 8}.${hi & 255}.${lo >> 8}.${lo & 255}`;
|
|
4698
|
+
}
|
|
4699
|
+
function blockedIpv6Reason(ip) {
|
|
4700
|
+
const g = parseIpv6(ip);
|
|
4701
|
+
if (!g) return "IPv6 \uC8FC\uC18C \uD615\uC2DD\uC774 \uC544\uB2D8";
|
|
4702
|
+
const zeros = (from, to) => g.slice(from, to).every((x) => x === 0);
|
|
4703
|
+
const embeddedTail = () => groupsToIpv4(g[6], g[7]);
|
|
4704
|
+
const viaEmbedded = (v4, what) => {
|
|
4705
|
+
const r = blockedIpv4Reason(v4);
|
|
4706
|
+
return r ? `${what}\uC774 \uD488\uC740 ${v4}: ${r}` : null;
|
|
4707
|
+
};
|
|
4708
|
+
if (zeros(0, 8)) return "\uBBF8\uC9C0\uC815 \uC8FC\uC18C(::)";
|
|
4709
|
+
if (zeros(0, 7) && g[7] === 1) return "\uB8E8\uD504\uBC31 \uC8FC\uC18C(::1)";
|
|
4710
|
+
if (zeros(0, 5) && g[5] === 65535) return viaEmbedded(embeddedTail(), "IPv4 \uB9E4\uD551 \uC8FC\uC18C(::ffff:0:0/96)");
|
|
4711
|
+
if (zeros(0, 6)) return viaEmbedded(embeddedTail(), "IPv4 \uD638\uD658 \uC8FC\uC18C(::/96)");
|
|
4712
|
+
if (g[0] === 100 && g[1] === 65435 && zeros(2, 6)) return viaEmbedded(embeddedTail(), "NAT64 \uC8FC\uC18C(64:ff9b::/96)");
|
|
4713
|
+
if (g[0] === 100 && g[1] === 65435 && g[2] === 1) return "\uB85C\uCEEC NAT64 \uC8FC\uC18C(64:ff9b:1::/48)";
|
|
4714
|
+
if (g[0] === 256 && zeros(1, 4)) return "\uD3D0\uAE30 \uC804\uC6A9 \uC8FC\uC18C(100::/64)";
|
|
4715
|
+
if (g[0] === 256 && zeros(1, 3) && g[3] === 1) return "\uB354\uBBF8 \uC811\uB450 \uC8FC\uC18C(100:0:0:1::/64)";
|
|
4716
|
+
if (g[0] === 8193 && g[1] === 0) {
|
|
4717
|
+
const server = groupsToIpv4(g[2], g[3]);
|
|
4718
|
+
const client = groupsToIpv4(~g[6] & 65535, ~g[7] & 65535);
|
|
4719
|
+
return viaEmbedded(server, "Teredo \uC8FC\uC18C(2001::/32) \uC11C\uBC84") ?? viaEmbedded(client, "Teredo \uC8FC\uC18C(2001::/32) \uD074\uB77C\uC774\uC5B8\uD2B8");
|
|
4720
|
+
}
|
|
4721
|
+
if (g[0] === 8193 && g[1] < 512) return "IETF \uD504\uB85C\uD1A0\uCF5C \uD560\uB2F9 \uC8FC\uC18C(2001::/23)";
|
|
4722
|
+
if (g[0] === 8193 && g[1] === 3512) return "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(2001:db8::/32)";
|
|
4723
|
+
if ((g[0] & 65520) === 16368) return "\uBB38\uC11C\uC6A9 \uC8FC\uC18C(3fff::/20)";
|
|
4724
|
+
if (g[0] === 8194) return viaEmbedded(groupsToIpv4(g[1], g[2]), "6to4 \uC8FC\uC18C(2002::/16)");
|
|
4725
|
+
if (g[0] === 24320) return "SRv6 SID \uC8FC\uC18C(5f00::/16)";
|
|
4726
|
+
if ((g[0] & 65024) === 64512) return "\uC0AC\uC124 \uC8FC\uC18C(fc00::/7)";
|
|
4727
|
+
if ((g[0] & 65472) === 65152) return "\uB9C1\uD06C\uB85C\uCEEC \uC8FC\uC18C(fe80::/10)";
|
|
4728
|
+
if ((g[0] & 65472) === 65216) return "\uC0AC\uC774\uD2B8\uB85C\uCEEC \uC8FC\uC18C(fec0::/10)";
|
|
4729
|
+
if ((g[0] & 65280) === 65280) return "\uBA40\uD2F0\uCE90\uC2A4\uD2B8 \uC8FC\uC18C(ff00::/8)";
|
|
4730
|
+
return null;
|
|
4731
|
+
}
|
|
4732
|
+
function blockedAddressReason(address) {
|
|
4733
|
+
const v = isIP(address.split("%")[0]);
|
|
4734
|
+
if (v === 4) return blockedIpv4Reason(address);
|
|
4735
|
+
if (v === 6) return blockedIpv6Reason(address);
|
|
4736
|
+
return "IP \uC8FC\uC18C \uD615\uC2DD\uC774 \uC544\uB2D8";
|
|
4737
|
+
}
|
|
4738
|
+
async function publicRegistryUrlProblem(raw, lookupAll = defaultLookupAll) {
|
|
4739
|
+
let parsed;
|
|
4740
|
+
try {
|
|
4741
|
+
parsed = new URL(raw.trim());
|
|
4742
|
+
} catch {
|
|
4743
|
+
return "URL \uD615\uC2DD\uC774 \uC544\uB2D8";
|
|
4744
|
+
}
|
|
4745
|
+
if (parsed.protocol !== "https:") return `https \uAC00 \uC544\uB2D8(${parsed.protocol.replace(/:$/, "")})`;
|
|
4746
|
+
let host = parsed.hostname.toLowerCase();
|
|
4747
|
+
if (host.startsWith("[") && host.endsWith("]")) host = host.slice(1, -1);
|
|
4748
|
+
host = host.replace(/\.+$/, "");
|
|
4749
|
+
if (host === "") return "\uD638\uC2A4\uD2B8\uAC00 \uC5C6\uC74C";
|
|
4750
|
+
if (isIP(host)) {
|
|
4751
|
+
const r = blockedAddressReason(host);
|
|
4752
|
+
return r ? `${r}\uB97C \uAC00\uB9AC\uD0B4` : null;
|
|
4753
|
+
}
|
|
4754
|
+
if (host === "localhost" || host.endsWith(".localhost")) return "localhost \uC774\uB984";
|
|
4755
|
+
if (host.endsWith(".local")) return "\uB85C\uCEEC \uB124\uD2B8\uC6CC\uD06C \uC774\uB984(.local)";
|
|
4756
|
+
let addresses;
|
|
4757
|
+
try {
|
|
4758
|
+
addresses = await lookupAll(host);
|
|
4759
|
+
} catch (error) {
|
|
4760
|
+
const code = error.code;
|
|
4761
|
+
return `\uD638\uC2A4\uD2B8 \uC8FC\uC18C\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD568(${code ?? error.message})`;
|
|
4762
|
+
}
|
|
4763
|
+
if (addresses.length === 0) return "\uD638\uC2A4\uD2B8 \uC8FC\uC18C\uB97C \uD655\uC778\uD558\uC9C0 \uBABB\uD568(\uACB0\uACFC \uC5C6\uC74C)";
|
|
4764
|
+
for (const { address } of addresses) {
|
|
4765
|
+
const r = blockedAddressReason(address);
|
|
4766
|
+
if (r) return `${host} \uAC00 ${address}(${r})\uB85C \uD480\uB9BC`;
|
|
4767
|
+
}
|
|
4768
|
+
return null;
|
|
4769
|
+
}
|
|
4770
|
+
|
|
4771
|
+
// ../axis-registry-core/src/registry/pinned-fetch.ts
|
|
4772
|
+
import { request as httpsRequest } from "https";
|
|
4773
|
+
var PINNED_FETCH_MAX_BYTES = 4 * 1024 * 1024;
|
|
4774
|
+
var BLOCKED_CONNECT_CODE = "EAXISBLOCKEDADDR";
|
|
4775
|
+
function guardedLookup(lookupAll, judge) {
|
|
4776
|
+
return (hostname, options, callback) => {
|
|
4777
|
+
lookupAll(hostname).then(
|
|
4778
|
+
(addresses) => {
|
|
4779
|
+
if (addresses.length === 0) {
|
|
4780
|
+
callback(Object.assign(new Error(`${hostname} \uC758 \uC8FC\uC18C\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`), { code: "ENOTFOUND" }), "", 0);
|
|
4781
|
+
return;
|
|
4782
|
+
}
|
|
4783
|
+
for (const { address } of addresses) {
|
|
4784
|
+
const reason = judge(address);
|
|
4785
|
+
if (reason) {
|
|
4786
|
+
const err = Object.assign(
|
|
4787
|
+
new Error(`\uC5F0\uACB0 \uB2E8\uACC4\uC5D0\uC11C ${hostname} \uAC00 ${address}(${reason})\uB85C \uD480\uB824 \uC5F0\uACB0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`),
|
|
4788
|
+
{ code: BLOCKED_CONNECT_CODE }
|
|
4789
|
+
);
|
|
4790
|
+
callback(err, "", 0);
|
|
4791
|
+
return;
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
const family = options?.family === 4 || options?.family === 6 ? options.family : 0;
|
|
4795
|
+
const usable = family ? addresses.filter((a) => a.family === family) : addresses;
|
|
4796
|
+
if (usable.length === 0) {
|
|
4797
|
+
callback(Object.assign(new Error(`${hostname} \uC5D0 IPv${family} \uC8FC\uC18C\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`), { code: "ENOTFOUND" }), "", 0);
|
|
4798
|
+
return;
|
|
4799
|
+
}
|
|
4800
|
+
if (options?.all) callback(null, usable.map((a) => ({ address: a.address, family: a.family })));
|
|
4801
|
+
else callback(null, usable[0].address, usable[0].family);
|
|
4802
|
+
},
|
|
4803
|
+
(error) => callback(error, "", 0)
|
|
4804
|
+
);
|
|
4805
|
+
};
|
|
4806
|
+
}
|
|
4807
|
+
function createPinnedFetch(options = {}) {
|
|
4808
|
+
const lookupAll = options.lookupAll ?? defaultLookupAll;
|
|
4809
|
+
const judge = options.judge ?? blockedAddressReason;
|
|
4810
|
+
const send = options.request ?? httpsRequest;
|
|
4811
|
+
const maxBytes = options.maxBytes ?? PINNED_FETCH_MAX_BYTES;
|
|
4812
|
+
return (input, init) => new Promise((resolve3, reject) => {
|
|
4813
|
+
let url;
|
|
4814
|
+
try {
|
|
4815
|
+
url = new URL(input);
|
|
4816
|
+
} catch (error) {
|
|
4817
|
+
reject(error);
|
|
4818
|
+
return;
|
|
4819
|
+
}
|
|
4820
|
+
const host = url.hostname.startsWith("[") ? url.hostname.slice(1, -1) : url.hostname;
|
|
4821
|
+
const req = send(
|
|
4822
|
+
{
|
|
4823
|
+
hostname: host,
|
|
4824
|
+
port: options.port ?? (url.port ? Number(url.port) : void 0),
|
|
4825
|
+
path: `${url.pathname}${url.search}`,
|
|
4826
|
+
method: "GET",
|
|
4827
|
+
headers: init?.headers ?? {},
|
|
4828
|
+
servername: host,
|
|
4829
|
+
lookup: guardedLookup(lookupAll, judge),
|
|
4830
|
+
...init?.signal ? { signal: init.signal } : {}
|
|
4831
|
+
},
|
|
4832
|
+
(res) => {
|
|
4833
|
+
const chunks = [];
|
|
4834
|
+
let size = 0;
|
|
4835
|
+
let failed = false;
|
|
4836
|
+
res.on("data", (chunk) => {
|
|
4837
|
+
size += chunk.length;
|
|
4838
|
+
if (size > maxBytes && !failed) {
|
|
4839
|
+
failed = true;
|
|
4840
|
+
res.destroy();
|
|
4841
|
+
reject(new Error(`\uC751\uB2F5\uC774 ${maxBytes} \uBC14\uC774\uD2B8\uB97C \uB118\uC5B4 \uC77D\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`));
|
|
4842
|
+
return;
|
|
4843
|
+
}
|
|
4844
|
+
chunks.push(chunk);
|
|
4845
|
+
});
|
|
4846
|
+
res.on("error", (error) => {
|
|
4847
|
+
if (!failed) reject(error);
|
|
4848
|
+
});
|
|
4849
|
+
res.on("end", () => {
|
|
4850
|
+
if (failed) return;
|
|
4851
|
+
const body = Buffer.concat(chunks).toString("utf8");
|
|
4852
|
+
const status = res.statusCode ?? 0;
|
|
4853
|
+
resolve3({ ok: status >= 200 && status < 300, status, text: async () => body });
|
|
4854
|
+
});
|
|
4855
|
+
}
|
|
4856
|
+
);
|
|
4857
|
+
req.on("error", reject);
|
|
4858
|
+
req.end();
|
|
4859
|
+
});
|
|
4860
|
+
}
|
|
4861
|
+
|
|
4862
|
+
// ../axis-registry-core/src/registry/index.ts
|
|
4373
4863
|
var RegistryError = class extends Error {
|
|
4374
4864
|
constructor(code, message) {
|
|
4375
4865
|
super(message);
|
|
@@ -4377,15 +4867,16 @@ var RegistryError = class extends Error {
|
|
|
4377
4867
|
this.name = "RegistryError";
|
|
4378
4868
|
}
|
|
4379
4869
|
};
|
|
4380
|
-
|
|
4870
|
+
var DEFAULT_BUNDLED_LABEL = "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC";
|
|
4871
|
+
function bundledFallbackMessage(version, reason, kind = "access", label = DEFAULT_BUNDLED_LABEL) {
|
|
4381
4872
|
const lead = kind === "invalid" ? "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uC751\uB2F5\uC774 \uD615\uC2DD \uAC80\uC99D\uC744 \uD1B5\uACFC\uD558\uC9C0 \uBABB\uD574" : "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC811\uADFC\uD558\uC9C0 \uBABB\uD574";
|
|
4382
|
-
return `${lead}
|
|
4873
|
+
return `${lead} ${label}(version ${version})\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. (\uC6D0\uC778: ${reason})`;
|
|
4383
4874
|
}
|
|
4384
4875
|
function fallbackKindOf(error) {
|
|
4385
4876
|
return error instanceof RegistryAccessError ? "access" : "invalid";
|
|
4386
4877
|
}
|
|
4387
|
-
function versionMismatchMessage(remoteVersion, bundledVersion) {
|
|
4388
|
-
return `\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${remoteVersion})\uC640
|
|
4878
|
+
function versionMismatchMessage(remoteVersion, bundledVersion, label = DEFAULT_BUNDLED_LABEL) {
|
|
4879
|
+
return `\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${remoteVersion})\uC640 ${label}(version ${bundledVersion})\uC758 version \uC774 \uB2E4\uB985\uB2C8\uB2E4. \uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC6B0\uC120 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.`;
|
|
4389
4880
|
}
|
|
4390
4881
|
function messageOf(error) {
|
|
4391
4882
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -4397,6 +4888,10 @@ var RegistryClient = class {
|
|
|
4397
4888
|
timeoutMs;
|
|
4398
4889
|
fetchImpl;
|
|
4399
4890
|
notify;
|
|
4891
|
+
bundledLabel;
|
|
4892
|
+
rawUrl;
|
|
4893
|
+
urlSource;
|
|
4894
|
+
rejectRedirects;
|
|
4400
4895
|
mode = null;
|
|
4401
4896
|
indexPromise = null;
|
|
4402
4897
|
bundledIndex = null;
|
|
@@ -4419,6 +4914,15 @@ var RegistryClient = class {
|
|
|
4419
4914
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_REGISTRY_TIMEOUT_MS;
|
|
4420
4915
|
this.fetchImpl = options.fetchImpl;
|
|
4421
4916
|
this.notify = options.notify ?? ((message) => console.warn(message));
|
|
4917
|
+
this.bundledLabel = options.bundledLabel ?? DEFAULT_BUNDLED_LABEL;
|
|
4918
|
+
this.rawUrl = options.url;
|
|
4919
|
+
this.urlSource = options.urlSource;
|
|
4920
|
+
this.rejectRedirects = options.rejectRedirects === true;
|
|
4921
|
+
}
|
|
4922
|
+
/** 원격 주소(가림 적용)와 그 출처. 표시용입니다(WI-0055 D13) */
|
|
4923
|
+
get remote() {
|
|
4924
|
+
const url = this.baseUrl ?? this.rawUrl;
|
|
4925
|
+
return { url: url === null ? null : redactRegistryUrl(url), source: this.urlSource };
|
|
4422
4926
|
}
|
|
4423
4927
|
/** 지금 쓰는 출처. index 를 읽기 전에는 null 입니다 */
|
|
4424
4928
|
get origin() {
|
|
@@ -4462,7 +4966,11 @@ var RegistryClient = class {
|
|
|
4462
4966
|
return bases;
|
|
4463
4967
|
}
|
|
4464
4968
|
fetchOptions() {
|
|
4465
|
-
return {
|
|
4969
|
+
return {
|
|
4970
|
+
timeoutMs: this.timeoutMs,
|
|
4971
|
+
...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {},
|
|
4972
|
+
...this.rejectRedirects ? { rejectRedirects: true } : {}
|
|
4973
|
+
};
|
|
4466
4974
|
}
|
|
4467
4975
|
async loadIndex() {
|
|
4468
4976
|
let remoteError;
|
|
@@ -4486,7 +4994,7 @@ var RegistryClient = class {
|
|
|
4486
4994
|
/** 동봉본 index 를 읽습니다(성공하면 한 번만). 실패하면 이유를 돌려줍니다 */
|
|
4487
4995
|
loadBundledIndex() {
|
|
4488
4996
|
if (this.bundledIndex) return { index: this.bundledIndex };
|
|
4489
|
-
if (!this.bundledDir) return { error:
|
|
4997
|
+
if (!this.bundledDir) return { error: `${this.bundledLabel}\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4` };
|
|
4490
4998
|
try {
|
|
4491
4999
|
this.bundledIndex = validateRegistryIndex(readBundledJson(this.bundledDir, "index.json"), "\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC index.json");
|
|
4492
5000
|
return { index: this.bundledIndex };
|
|
@@ -4497,7 +5005,7 @@ var RegistryClient = class {
|
|
|
4497
5005
|
warnVersionMismatch(remoteVersion) {
|
|
4498
5006
|
const bundled = this.loadBundledIndex();
|
|
4499
5007
|
if ("index" in bundled && bundled.index.version !== remoteVersion) {
|
|
4500
|
-
this.notify(versionMismatchMessage(remoteVersion, bundled.index.version));
|
|
5008
|
+
this.notify(versionMismatchMessage(remoteVersion, bundled.index.version, this.bundledLabel));
|
|
4501
5009
|
}
|
|
4502
5010
|
}
|
|
4503
5011
|
async switchToBundled(reason, kind = "access") {
|
|
@@ -4512,7 +5020,7 @@ var RegistryClient = class {
|
|
|
4512
5020
|
this.indexPromise = Promise.resolve(bundled.index);
|
|
4513
5021
|
if (!this.fallbackAnnounced) {
|
|
4514
5022
|
this.fallbackAnnounced = true;
|
|
4515
|
-
this.notify(bundledFallbackMessage(bundled.index.version, reason, kind));
|
|
5023
|
+
this.notify(bundledFallbackMessage(bundled.index.version, reason, kind, this.bundledLabel));
|
|
4516
5024
|
}
|
|
4517
5025
|
return bundled.index;
|
|
4518
5026
|
}
|
|
@@ -4522,7 +5030,7 @@ var RegistryClient = class {
|
|
|
4522
5030
|
if (!index || !entry || !this.bundledDir) {
|
|
4523
5031
|
throw new RegistryError(
|
|
4524
5032
|
"not-found",
|
|
4525
|
-
`'${name}' \uD56D\uBAA9\uC774
|
|
5033
|
+
`'${name}' \uD56D\uBAA9\uC774 ${this.bundledLabel}(version ${index?.version ?? "\uC54C \uC218 \uC5C6\uC74C"})\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
4526
5034
|
);
|
|
4527
5035
|
}
|
|
4528
5036
|
try {
|
|
@@ -4530,18 +5038,23 @@ var RegistryClient = class {
|
|
|
4530
5038
|
checkItemSha256(item, entry);
|
|
4531
5039
|
return item;
|
|
4532
5040
|
} catch (error) {
|
|
4533
|
-
throw new RegistryError("unavailable",
|
|
5041
|
+
throw new RegistryError("unavailable", `${this.bundledLabel}\uC758 '${name}' \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${messageOf(error)}`);
|
|
4534
5042
|
}
|
|
4535
5043
|
}
|
|
4536
5044
|
};
|
|
4537
5045
|
|
|
4538
|
-
// src/add/add.ts
|
|
5046
|
+
// ../axis-registry-core/src/add/add.ts
|
|
4539
5047
|
var AGENTIC_PREFIX = "agentic-";
|
|
5048
|
+
var CLI_ADD_HINTS = {
|
|
5049
|
+
listCommand: "npx @axis-ds/cli list",
|
|
5050
|
+
overwrite: "--overwrite",
|
|
5051
|
+
agenticFlag: true
|
|
5052
|
+
};
|
|
4540
5053
|
function applyAgenticAlias(name, agentic) {
|
|
4541
5054
|
if (!agentic || name.startsWith(AGENTIC_PREFIX)) return name;
|
|
4542
5055
|
return `${AGENTIC_PREFIX}${name}`;
|
|
4543
5056
|
}
|
|
4544
|
-
function describeMissingName(requested, resolved, index, agentic) {
|
|
5057
|
+
function describeMissingName(requested, resolved, index, agentic, agenticFlag = true) {
|
|
4545
5058
|
const names = new Set(index.items.map((it) => it.name));
|
|
4546
5059
|
if (!isValidRegistryName(resolved)) {
|
|
4547
5060
|
return `'${requested}': \uC774\uB984 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
@@ -4550,6 +5063,9 @@ function describeMissingName(requested, resolved, index, agentic) {
|
|
|
4550
5063
|
return `'${requested}': Agentic UI \uC5D0 '${resolved}' \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. '${requested}' \uB294 Core UI \uD56D\uBAA9\uC774\uB2C8 --agentic \uC5C6\uC774 \uC2E4\uD589\uD558\uC138\uC694`;
|
|
4551
5064
|
}
|
|
4552
5065
|
if (!agentic && names.has(`${AGENTIC_PREFIX}${requested}`)) {
|
|
5066
|
+
if (!agenticFlag) {
|
|
5067
|
+
return `'${requested}': \uC5C6\uC2B5\uB2C8\uB2E4. Agentic UI \uD56D\uBAA9\uC744 \uB73B\uD588\uB2E4\uBA74 \uC804\uCCB4 \uC774\uB984 '${AGENTIC_PREFIX}${requested}' \uB97C \uC4F0\uC138\uC694`;
|
|
5068
|
+
}
|
|
4553
5069
|
return `'${requested}': \uC5C6\uC2B5\uB2C8\uB2E4. Agentic UI \uD56D\uBAA9 '${AGENTIC_PREFIX}${requested}' \uB97C \uB73B\uD588\uB2E4\uBA74 \uC804\uCCB4 \uC774\uB984\uC744 \uC4F0\uAC70\uB098 --agentic \uC744 \uBD99\uC774\uC138\uC694`;
|
|
4554
5070
|
}
|
|
4555
5071
|
return `'${requested}': \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`;
|
|
@@ -4564,10 +5080,10 @@ function layoutFromConfig(root, config) {
|
|
|
4564
5080
|
throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
|
|
4565
5081
|
}
|
|
4566
5082
|
const componentsDir = componentsRaw.replace(/\\/g, "/");
|
|
4567
|
-
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") :
|
|
4568
|
-
return { root:
|
|
5083
|
+
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path17.posix.join(path17.posix.dirname(componentsDir), "agentic");
|
|
5084
|
+
return { root: path17.resolve(root), componentsDir, agenticDir };
|
|
4569
5085
|
}
|
|
4570
|
-
function toPosix(p, impl =
|
|
5086
|
+
function toPosix(p, impl = path17) {
|
|
4571
5087
|
return p.split(impl.sep).join("/");
|
|
4572
5088
|
}
|
|
4573
5089
|
function itemKind(item) {
|
|
@@ -4589,12 +5105,12 @@ function placeFile(layout, item, filePath, target) {
|
|
|
4589
5105
|
const problem = registryPathProblem(p);
|
|
4590
5106
|
if (problem) throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(p)}, ${problem})`);
|
|
4591
5107
|
}
|
|
4592
|
-
const base =
|
|
5108
|
+
const base = path17.posix.basename(filePath);
|
|
4593
5109
|
if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
|
|
4594
5110
|
throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(filePath)}, \uD30C\uC77C \uC774\uB984\uC740 .ts \xB7 .tsx \uB9CC \uC124\uCE58\uD569\uB2C8\uB2E4)`);
|
|
4595
5111
|
}
|
|
4596
5112
|
const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
|
|
4597
|
-
return
|
|
5113
|
+
return path17.resolve(layout.root, dir, base);
|
|
4598
5114
|
}
|
|
4599
5115
|
function stripExt(p) {
|
|
4600
5116
|
return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
|
|
@@ -4605,7 +5121,7 @@ function buildImportTargets(entries) {
|
|
|
4605
5121
|
for (const { item, file, target } of entries) {
|
|
4606
5122
|
const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
|
|
4607
5123
|
exact.set(`@/${rel3}`, target);
|
|
4608
|
-
if (itemKind(item) === "lib") lib.set(
|
|
5124
|
+
if (itemKind(item) === "lib") lib.set(path17.posix.basename(rel3), target);
|
|
4609
5125
|
}
|
|
4610
5126
|
return { exact, lib };
|
|
4611
5127
|
}
|
|
@@ -4681,7 +5197,7 @@ function insideRanges(ranges, at) {
|
|
|
4681
5197
|
}
|
|
4682
5198
|
var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
|
|
4683
5199
|
var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
|
|
4684
|
-
function relativeSpecifier(fromFile, toFile, impl =
|
|
5200
|
+
function relativeSpecifier(fromFile, toFile, impl = path17) {
|
|
4685
5201
|
let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
|
|
4686
5202
|
if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
|
|
4687
5203
|
return rel3;
|
|
@@ -4709,7 +5225,7 @@ function rewriteImports(content, fileTarget, targets) {
|
|
|
4709
5225
|
}
|
|
4710
5226
|
var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
|
|
4711
5227
|
function relativeSpecifierResolves(fromFile, spec) {
|
|
4712
|
-
const base =
|
|
5228
|
+
const base = path17.resolve(path17.dirname(fromFile), spec);
|
|
4713
5229
|
return RESOLVE_EXTS.some((ext) => {
|
|
4714
5230
|
try {
|
|
4715
5231
|
return statSync4(base + ext).isFile();
|
|
@@ -4761,7 +5277,7 @@ function planFiles(layout, items) {
|
|
|
4761
5277
|
}
|
|
4762
5278
|
const prev = byTarget.get(target);
|
|
4763
5279
|
if (prev !== void 0) {
|
|
4764
|
-
errors.push(`${item.name}: ${toPosix(
|
|
5280
|
+
errors.push(`${item.name}: ${toPosix(path17.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
|
|
4765
5281
|
continue;
|
|
4766
5282
|
}
|
|
4767
5283
|
byTarget.set(target, item.name);
|
|
@@ -4787,7 +5303,7 @@ function missingDependencies(root, items) {
|
|
|
4787
5303
|
const installCommand = detectInstallCommand(root);
|
|
4788
5304
|
let pkg;
|
|
4789
5305
|
try {
|
|
4790
|
-
const text = readFileSync6(
|
|
5306
|
+
const text = readFileSync6(path17.join(root, "package.json"), "utf8").replace(/^/, "");
|
|
4791
5307
|
const parsed = JSON.parse(text);
|
|
4792
5308
|
pkg = isPlainObject2(parsed) ? parsed : void 0;
|
|
4793
5309
|
} catch {
|
|
@@ -4819,15 +5335,16 @@ function addCommandForSpecs(installCommand, specs) {
|
|
|
4819
5335
|
return `pnpm add ${args}`;
|
|
4820
5336
|
}
|
|
4821
5337
|
function rel2(root, p) {
|
|
4822
|
-
return toPosix(
|
|
5338
|
+
return toPosix(path17.relative(root, p));
|
|
4823
5339
|
}
|
|
4824
5340
|
async function runAdd(cwd, requested, options, ctx) {
|
|
4825
5341
|
const log = ctx.log ?? console.log;
|
|
4826
5342
|
const error = ctx.error ?? console.error;
|
|
4827
|
-
const
|
|
5343
|
+
const hints = { ...CLI_ADD_HINTS, ...ctx.hints };
|
|
5344
|
+
const root = path17.resolve(cwd);
|
|
4828
5345
|
const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
|
|
4829
5346
|
if (requested.length === 0) {
|
|
4830
|
-
error(
|
|
5347
|
+
error(`\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: ${hints.listCommand}`);
|
|
4831
5348
|
return result;
|
|
4832
5349
|
}
|
|
4833
5350
|
let config;
|
|
@@ -4837,9 +5354,16 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4837
5354
|
error(`axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`);
|
|
4838
5355
|
return result;
|
|
4839
5356
|
}
|
|
5357
|
+
if (!config && ctx.fallbackConfig) {
|
|
5358
|
+
config = ctx.fallbackConfig;
|
|
5359
|
+
result.usedFallbackConfig = true;
|
|
5360
|
+
log(`axis.config.json \uC774 \uC5C6\uC5B4 \uAE30\uBCF8 \uBC30\uCE58(componentsDir ${config.componentsDir ?? "(\uC5C6\uC74C)"})\uB85C \uC124\uCE58\uD569\uB2C8\uB2E4`);
|
|
5361
|
+
}
|
|
4840
5362
|
if (!config) {
|
|
4841
5363
|
error(
|
|
4842
|
-
|
|
5364
|
+
`axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
5365
|
+
\uD574\uACB0: \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0\uC11C 'npx @axis-ds/cli init'\uC744 \uC2E4\uD589\uD558\uC138\uC694.
|
|
5366
|
+
\uCC38\uACE0: ${AXIS_QUICK_START_URL}`
|
|
4843
5367
|
);
|
|
4844
5368
|
return result;
|
|
4845
5369
|
}
|
|
@@ -4862,13 +5386,13 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4862
5386
|
const missing = [];
|
|
4863
5387
|
for (const req of requested) {
|
|
4864
5388
|
const name = applyAgenticAlias(req, options.agentic);
|
|
4865
|
-
if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic));
|
|
5389
|
+
if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic, hints.agenticFlag));
|
|
4866
5390
|
else if (!resolved.includes(name)) resolved.push(name);
|
|
4867
5391
|
}
|
|
4868
5392
|
if (missing.length > 0) {
|
|
4869
5393
|
error(`\uCEF4\uD3EC\uB10C\uD2B8\uB97C \uCC3E\uC744 \uC218 \uC5C6\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC124\uCE58\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uB808\uC9C0\uC2A4\uD2B8\uB9AC version ${index.version}).`);
|
|
4870
5394
|
for (const m of missing) error(` - ${m}`);
|
|
4871
|
-
error(
|
|
5395
|
+
error(` \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: ${hints.listCommand}`);
|
|
4872
5396
|
return result;
|
|
4873
5397
|
}
|
|
4874
5398
|
let items;
|
|
@@ -4880,6 +5404,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4880
5404
|
return result;
|
|
4881
5405
|
}
|
|
4882
5406
|
items = collected.items;
|
|
5407
|
+
result.items = items.map((it) => it.name);
|
|
4883
5408
|
} catch (e) {
|
|
4884
5409
|
const msg = e instanceof RegistryError ? e.message : `\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`;
|
|
4885
5410
|
error(msg);
|
|
@@ -4894,7 +5419,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4894
5419
|
const existing = /* @__PURE__ */ new Map();
|
|
4895
5420
|
const readErrors = [];
|
|
4896
5421
|
for (const file of plan.files) {
|
|
4897
|
-
if (!
|
|
5422
|
+
if (!existsSync8(file.target)) {
|
|
4898
5423
|
existing.set(file, null);
|
|
4899
5424
|
continue;
|
|
4900
5425
|
}
|
|
@@ -4973,7 +5498,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4973
5498
|
try {
|
|
4974
5499
|
const before = escapeReason(root, d.file.target);
|
|
4975
5500
|
if (before) return stopWriting(p, before);
|
|
4976
|
-
await
|
|
5501
|
+
await fs13.ensureDir(path17.dirname(d.file.target));
|
|
4977
5502
|
const after = checkParentInside(root, d.file.target);
|
|
4978
5503
|
if (after) return stopWriting(p, after);
|
|
4979
5504
|
actual = await writeNoFollow(d.file.target, d.file.content, actual);
|
|
@@ -5029,7 +5554,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
5029
5554
|
log(outsideRel.has(p) ? ` = ${p} (\uAC19\uC740 \uB0B4\uC6A9\uC774\uB77C \uAC74\uB108\uB700, \uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` = ${p} (\uAC19\uC740 \uB0B4\uC6A9\uC774\uB77C \uAC74\uB108\uB700)`);
|
|
5030
5555
|
}
|
|
5031
5556
|
if (result.skipped.length > 0) {
|
|
5032
|
-
log(`\uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C ${result.skipped.length}\uAC1C\uB97C \uAC74\uB108\uB6F0\uC5C8\uC2B5\uB2C8\uB2E4(\uB36E\uC5B4\uC4F0\uB824\uBA74
|
|
5557
|
+
log(`\uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C ${result.skipped.length}\uAC1C\uB97C \uAC74\uB108\uB6F0\uC5C8\uC2B5\uB2C8\uB2E4(\uB36E\uC5B4\uC4F0\uB824\uBA74 ${hints.overwrite}):`);
|
|
5033
5558
|
for (const p of result.skipped) log(outsideRel.has(p) ? ` - ${p} (\uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` - ${p}`);
|
|
5034
5559
|
}
|
|
5035
5560
|
if (broken.length > 0) {
|
|
@@ -5039,8 +5564,9 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
5039
5564
|
}
|
|
5040
5565
|
const deps = missingDependencies(root, items);
|
|
5041
5566
|
if (Object.keys(deps.specs).length > 0) {
|
|
5567
|
+
result.dependencyCommand = addCommandForSpecs(deps.installCommand, deps.specs);
|
|
5042
5568
|
log("\npackage.json \uC5D0 \uC5C6\uB294 \uC758\uC874\uC131(\uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4):");
|
|
5043
|
-
log(` ${
|
|
5569
|
+
log(` ${result.dependencyCommand}`);
|
|
5044
5570
|
}
|
|
5045
5571
|
return { ...result, exitCode: 0 };
|
|
5046
5572
|
}
|
|
@@ -5055,17 +5581,50 @@ function groupIndex(index) {
|
|
|
5055
5581
|
}
|
|
5056
5582
|
return { ui, agentic };
|
|
5057
5583
|
}
|
|
5058
|
-
async function createClientFor(cwd, notify, env = process.env) {
|
|
5584
|
+
async function createClientFor(cwd, notify, env = process.env, clientOptions = {}) {
|
|
5585
|
+
const { guardConfigRegistry, ...options } = clientOptions;
|
|
5059
5586
|
let config = null;
|
|
5060
5587
|
try {
|
|
5061
|
-
config = await readAxisConfig(
|
|
5588
|
+
config = await readAxisConfig(path17.resolve(cwd));
|
|
5062
5589
|
} catch {
|
|
5063
5590
|
config = null;
|
|
5064
5591
|
}
|
|
5065
|
-
|
|
5592
|
+
let resolved = resolveRegistryUrl({ config, env });
|
|
5066
5593
|
const say = notify ?? ((message) => console.warn(message));
|
|
5067
5594
|
if (resolved.migratedFrom !== void 0) say(LEGACY_REGISTRY_NOTICE);
|
|
5068
|
-
|
|
5595
|
+
let rejectRedirects = false;
|
|
5596
|
+
if (guardConfigRegistry && resolved.source === "config" && resolved.migratedFrom === void 0 && !isDefaultRegistry(resolved.url)) {
|
|
5597
|
+
const problem = await publicRegistryUrlProblem(resolved.url, guardConfigRegistry.lookup);
|
|
5598
|
+
if (problem !== null) {
|
|
5599
|
+
say(configRegistryRejectedMessage(resolved.url, problem));
|
|
5600
|
+
resolved = { url: DEFAULT_REGISTRY_URL, source: "default" };
|
|
5601
|
+
} else {
|
|
5602
|
+
rejectRedirects = true;
|
|
5603
|
+
if (!options.fetchImpl) {
|
|
5604
|
+
options.fetchImpl = createPinnedFetch({
|
|
5605
|
+
...guardConfigRegistry.lookup ? { lookupAll: guardConfigRegistry.lookup } : {},
|
|
5606
|
+
...guardConfigRegistry.connect
|
|
5607
|
+
});
|
|
5608
|
+
}
|
|
5609
|
+
}
|
|
5610
|
+
}
|
|
5611
|
+
return new RegistryClient({
|
|
5612
|
+
...options,
|
|
5613
|
+
url: resolved.url,
|
|
5614
|
+
urlSource: resolved.source,
|
|
5615
|
+
...rejectRedirects ? { rejectRedirects: true } : {},
|
|
5616
|
+
...notify ? { notify } : {}
|
|
5617
|
+
});
|
|
5618
|
+
}
|
|
5619
|
+
function isDefaultRegistry(url) {
|
|
5620
|
+
try {
|
|
5621
|
+
return normalizeRegistryBaseUrl(url.trim()) === DEFAULT_REGISTRY_URL;
|
|
5622
|
+
} catch {
|
|
5623
|
+
return false;
|
|
5624
|
+
}
|
|
5625
|
+
}
|
|
5626
|
+
function configRegistryRejectedMessage(url, problem) {
|
|
5627
|
+
return `axis.config.json \uC758 registry(${redactRegistryUrl(url)})\uB97C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4: ${problem}. config \uC758 registry \uB294 \uACF5\uAC1C https \uC8FC\uC18C\uC77C \uB54C\uB9CC \uC501\uB2C8\uB2E4(\uB8E8\uD504\uBC31 \xB7 \uC0AC\uC124 \xB7 \uB9C1\uD06C\uB85C\uCEEC \uC8FC\uC18C \uC81C\uC678). \uAE30\uBCF8 \uC8FC\uC18C(${DEFAULT_REGISTRY_URL})\uB85C \uC870\uD68C\uD569\uB2C8\uB2E4`;
|
|
5069
5628
|
}
|
|
5070
5629
|
|
|
5071
5630
|
// src/add/index.ts
|
|
@@ -5076,7 +5635,7 @@ function createConfirm(interactive) {
|
|
|
5076
5635
|
return overwrite === true;
|
|
5077
5636
|
};
|
|
5078
5637
|
}
|
|
5079
|
-
var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(
|
|
5638
|
+
var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk12.yellow(m)));
|
|
5080
5639
|
function registerAddCommand(program2, deps = {}) {
|
|
5081
5640
|
program2.command("add <components...>").description("\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uCEF4\uD3EC\uB10C\uD2B8\uB97C \uD504\uB85C\uC81D\uD2B8\uC5D0 \uBCF5\uC0AC(registryDependencies \uD3EC\uD568)").option("--agentic", "\uC774\uB984 \uC55E\uC5D0 agentic- \uB97C \uBD99\uC5EC \uCC3E\uC74C(\uC804\uCCB4 \uC774\uB984\uB3C4 \uD5C8\uC6A9)").option("-y, --yes", "\uBB3B\uC9C0 \uC54A\uACE0 \uC9C4\uD589. \uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C\uC740 \uAC74\uB108\uB700").option("--overwrite", "\uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 \uD30C\uC77C\uC744 \uB36E\uC5B4\uC500").action(async (components, options) => {
|
|
5082
5641
|
const client = await (deps.createClient ?? defaultCreateClient)(process.cwd());
|
|
@@ -5084,7 +5643,7 @@ function registerAddCommand(program2, deps = {}) {
|
|
|
5084
5643
|
const result = await runAdd(process.cwd(), components, options, {
|
|
5085
5644
|
client,
|
|
5086
5645
|
log: (...a) => console.log(...a),
|
|
5087
|
-
error: (...a) => console.error(
|
|
5646
|
+
error: (...a) => console.error(chalk12.red(a.map(String).join(" "))),
|
|
5088
5647
|
...confirm ? { confirm } : {}
|
|
5089
5648
|
});
|
|
5090
5649
|
process.exitCode = result.exitCode;
|
|
@@ -5093,7 +5652,7 @@ function registerAddCommand(program2, deps = {}) {
|
|
|
5093
5652
|
function registerListCommand(program2, deps = {}) {
|
|
5094
5653
|
program2.command("list").description("\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("--category <type>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130 (ui, agentic)").action(async (options) => {
|
|
5095
5654
|
if (options.category !== void 0 && options.category !== "ui" && options.category !== "agentic") {
|
|
5096
|
-
console.error(
|
|
5655
|
+
console.error(chalk12.red(`--category \uB294 ui \uB610\uB294 agentic \uC785\uB2C8\uB2E4(\uBC1B\uC740 \uAC12: ${options.category})`));
|
|
5097
5656
|
process.exitCode = 1;
|
|
5098
5657
|
return;
|
|
5099
5658
|
}
|
|
@@ -5105,26 +5664,26 @@ function registerListCommand(program2, deps = {}) {
|
|
|
5105
5664
|
groups = groupIndex(index);
|
|
5106
5665
|
version = index.version;
|
|
5107
5666
|
} catch (e) {
|
|
5108
|
-
console.error(
|
|
5667
|
+
console.error(chalk12.red(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`));
|
|
5109
5668
|
process.exitCode = 1;
|
|
5110
5669
|
return;
|
|
5111
5670
|
}
|
|
5112
5671
|
const total = groups.ui.length + groups.agentic.length;
|
|
5113
5672
|
const origin = client.origin === "bundled" ? "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC" : "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC";
|
|
5114
|
-
console.log(
|
|
5673
|
+
console.log(chalk12.blue(`
|
|
5115
5674
|
\u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8 ${total}\uAC1C (${origin}, version ${version})
|
|
5116
5675
|
`));
|
|
5117
5676
|
const show = (label, items) => {
|
|
5118
|
-
console.log(
|
|
5677
|
+
console.log(chalk12.bold(`${label} (${items.length})`));
|
|
5119
5678
|
for (const c of items) {
|
|
5120
|
-
console.log(` ${
|
|
5679
|
+
console.log(` ${chalk12.cyan(c.name.padEnd(32))} ${chalk12.gray(c.description ?? c.title ?? "")}`);
|
|
5121
5680
|
}
|
|
5122
5681
|
console.log();
|
|
5123
5682
|
};
|
|
5124
5683
|
if (!options.category || options.category === "ui") show("Core UI", groups.ui);
|
|
5125
5684
|
if (!options.category || options.category === "agentic") show("Agentic UI", groups.agentic);
|
|
5126
|
-
console.log(
|
|
5127
|
-
console.log(
|
|
5685
|
+
console.log(chalk12.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <\uC774\uB984...> (\uC608: add button input card)"));
|
|
5686
|
+
console.log(chalk12.gray("Agentic: npx @axis-ds/cli add run-progress --agentic (= add agentic-run-progress)\n"));
|
|
5128
5687
|
});
|
|
5129
5688
|
}
|
|
5130
5689
|
|
|
@@ -5153,24 +5712,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
|
|
|
5153
5712
|
await client.importFromClipboard();
|
|
5154
5713
|
});
|
|
5155
5714
|
monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
|
|
5156
|
-
console.log(
|
|
5157
|
-
console.log(
|
|
5158
|
-
console.log(
|
|
5159
|
-
console.log(
|
|
5160
|
-
console.log(
|
|
5161
|
-
console.log(
|
|
5162
|
-
console.log(
|
|
5163
|
-
console.log(
|
|
5715
|
+
console.log(chalk13.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
|
|
5716
|
+
console.log(chalk13.bold("1. API \uD0A4 \uBC1C\uAE09:"));
|
|
5717
|
+
console.log(chalk13.cyan(" https://monet.design/mcp\n"));
|
|
5718
|
+
console.log(chalk13.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
|
|
5719
|
+
console.log(chalk13.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
|
|
5720
|
+
console.log(chalk13.cyan(" MONET_API_KEY=your-api-key-here\n"));
|
|
5721
|
+
console.log(chalk13.bold("3. Claude Code MCP \uC124\uC815:"));
|
|
5722
|
+
console.log(chalk13.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
|
|
5164
5723
|
console.log(
|
|
5165
|
-
|
|
5724
|
+
chalk13.cyan(` "monet": {
|
|
5166
5725
|
"url": "https://www.monet.design/api/remote/mcp",
|
|
5167
5726
|
"headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
|
|
5168
5727
|
"disabled": false
|
|
5169
5728
|
}
|
|
5170
5729
|
`)
|
|
5171
5730
|
);
|
|
5172
|
-
console.log(
|
|
5173
|
-
console.log(
|
|
5731
|
+
console.log(chalk13.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
|
|
5732
|
+
console.log(chalk13.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
|
|
5174
5733
|
});
|
|
5175
5734
|
var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
|
|
5176
5735
|
v0Cmd.command("convert <file>").alias("c").description("V0 \uCF54\uB4DC\uB97C AXIS \uC2A4\uD0C0\uC77C\uB85C \uBCC0\uD658").option("-o, --output <path>", "\uCD9C\uB825 \uD30C\uC77C \uACBD\uB85C").action(async (file, options) => {
|
|
@@ -5207,18 +5766,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
|
|
|
5207
5766
|
total += result.collected;
|
|
5208
5767
|
failed += result.failed;
|
|
5209
5768
|
}
|
|
5210
|
-
console.log(
|
|
5769
|
+
console.log(chalk13.blue(`
|
|
5211
5770
|
\u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
|
|
5212
5771
|
if (failed > 0) {
|
|
5213
|
-
console.log(
|
|
5772
|
+
console.log(chalk13.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
|
|
5214
5773
|
}
|
|
5215
5774
|
});
|
|
5216
5775
|
libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9AC \uCEF4\uD3EC\uB10C\uD2B8 \uBAA9\uB85D").option("-c, --category <category>", "\uCE74\uD14C\uACE0\uB9AC \uD544\uD130").option("-s, --source <source>", "\uC18C\uC2A4 \uD544\uD130").action(async (options) => {
|
|
5217
5776
|
const curator = new LibraryCurator();
|
|
5218
5777
|
const index = await curator.loadIndex();
|
|
5219
5778
|
if (!index) {
|
|
5220
|
-
console.log(
|
|
5221
|
-
console.log(
|
|
5779
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
5780
|
+
console.log(chalk13.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
5222
5781
|
return;
|
|
5223
5782
|
}
|
|
5224
5783
|
let components = index.components;
|
|
@@ -5228,7 +5787,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
5228
5787
|
if (options.source) {
|
|
5229
5788
|
components = components.filter((c) => c.source.type === options.source);
|
|
5230
5789
|
}
|
|
5231
|
-
console.log(
|
|
5790
|
+
console.log(chalk13.blue(`
|
|
5232
5791
|
\u{1F4E6} Library Components (${components.length}\uAC1C)
|
|
5233
5792
|
`));
|
|
5234
5793
|
const byCategory = /* @__PURE__ */ new Map();
|
|
@@ -5240,14 +5799,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
5240
5799
|
byCategory.get(cat).push(comp);
|
|
5241
5800
|
}
|
|
5242
5801
|
for (const [category, items] of byCategory) {
|
|
5243
|
-
console.log(
|
|
5802
|
+
console.log(chalk13.bold(`${category} (${items.length})`));
|
|
5244
5803
|
for (const item of items.slice(0, 10)) {
|
|
5245
5804
|
console.log(
|
|
5246
|
-
` ${
|
|
5805
|
+
` ${chalk13.cyan(item.name.padEnd(25))} ${chalk13.gray(item.source.type.padEnd(8))} ${chalk13.gray(item.description.slice(0, 40))}`
|
|
5247
5806
|
);
|
|
5248
5807
|
}
|
|
5249
5808
|
if (items.length > 10) {
|
|
5250
|
-
console.log(
|
|
5809
|
+
console.log(chalk13.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
|
|
5251
5810
|
}
|
|
5252
5811
|
console.log();
|
|
5253
5812
|
}
|
|
@@ -5259,21 +5818,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
|
|
|
5259
5818
|
source: options.source
|
|
5260
5819
|
});
|
|
5261
5820
|
if (results.length === 0) {
|
|
5262
|
-
console.log(
|
|
5821
|
+
console.log(chalk13.yellow(`
|
|
5263
5822
|
'${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
5264
5823
|
`));
|
|
5265
5824
|
return;
|
|
5266
5825
|
}
|
|
5267
|
-
console.log(
|
|
5826
|
+
console.log(chalk13.blue(`
|
|
5268
5827
|
\u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
|
|
5269
5828
|
`));
|
|
5270
5829
|
for (const comp of results.slice(0, 20)) {
|
|
5271
5830
|
console.log(
|
|
5272
|
-
` ${
|
|
5831
|
+
` ${chalk13.cyan(comp.name.padEnd(25))} ${chalk13.gray(comp.source.type.padEnd(8))} ${chalk13.gray(comp.category.padEnd(12))} ${chalk13.gray(comp.description.slice(0, 30))}`
|
|
5273
5832
|
);
|
|
5274
5833
|
}
|
|
5275
5834
|
if (results.length > 20) {
|
|
5276
|
-
console.log(
|
|
5835
|
+
console.log(chalk13.gray(`
|
|
5277
5836
|
... \uC678 ${results.length - 20}\uAC1C`));
|
|
5278
5837
|
}
|
|
5279
5838
|
console.log();
|
|
@@ -5287,12 +5846,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
5287
5846
|
const publisher2 = new Publisher();
|
|
5288
5847
|
const index = await curator.loadIndex();
|
|
5289
5848
|
if (!index) {
|
|
5290
|
-
console.log(
|
|
5291
|
-
console.log(
|
|
5849
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
5850
|
+
console.log(chalk13.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
5292
5851
|
return;
|
|
5293
5852
|
}
|
|
5294
|
-
console.log(
|
|
5295
|
-
console.log(
|
|
5853
|
+
console.log(chalk13.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
|
|
5854
|
+
console.log(chalk13.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
|
|
5296
5855
|
`));
|
|
5297
5856
|
if (options.clean) {
|
|
5298
5857
|
await publisher2.clean(options.output);
|
|
@@ -5303,21 +5862,22 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
5303
5862
|
generateSearchIndex: true
|
|
5304
5863
|
});
|
|
5305
5864
|
if (result.success) {
|
|
5306
|
-
console.log(
|
|
5865
|
+
console.log(chalk13.green(`
|
|
5307
5866
|
\u2713 \uBC30\uCE58 \uC644\uB8CC`));
|
|
5308
|
-
console.log(
|
|
5309
|
-
console.log(
|
|
5310
|
-
console.log(
|
|
5311
|
-
console.log(
|
|
5867
|
+
console.log(chalk13.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
|
|
5868
|
+
console.log(chalk13.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
|
|
5869
|
+
console.log(chalk13.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
|
|
5870
|
+
console.log(chalk13.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
|
|
5312
5871
|
} else {
|
|
5313
|
-
console.log(
|
|
5872
|
+
console.log(chalk13.red(`
|
|
5314
5873
|
\u2717 \uBC30\uCE58 \uC2E4\uD328`));
|
|
5315
5874
|
for (const error of result.errors) {
|
|
5316
|
-
console.log(
|
|
5875
|
+
console.log(chalk13.red(` - ${error}`));
|
|
5317
5876
|
}
|
|
5318
5877
|
}
|
|
5319
5878
|
console.log();
|
|
5320
5879
|
});
|
|
5880
|
+
registerRefreshAxisCommand(libraryCmd);
|
|
5321
5881
|
registerSyncCommand(program);
|
|
5322
5882
|
registerTemplateCommand(program);
|
|
5323
5883
|
registerCheckCommand(program);
|