@axis-ds/cli 1.5.1 → 1.5.3
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/dist/{chunk-NVGENR3K.js → chunk-IQY3WUGG.js} +1 -1
- package/dist/index.js +1154 -565
- package/dist/registry/agentic-streaming-text.json +1 -1
- package/dist/registry/index.json +2 -2
- package/dist/registry/registry.json +2 -2
- package/dist/{registry-client-BJ2XYT73.js → registry-client-6WSGKPF2.js} +1 -1
- package/package.json +3 -2
package/dist/index.js
CHANGED
|
@@ -13,11 +13,11 @@ import {
|
|
|
13
13
|
AXIS_SITE_URL,
|
|
14
14
|
fetchTemplateDetail,
|
|
15
15
|
fetchTemplateIndex
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-IQY3WUGG.js";
|
|
17
17
|
|
|
18
18
|
// src/index.ts
|
|
19
19
|
import { Command } from "commander";
|
|
20
|
-
import
|
|
20
|
+
import chalk13 from "chalk";
|
|
21
21
|
import { createRequire as createRequire2 } from "module";
|
|
22
22
|
|
|
23
23
|
// src/library/base-collector.ts
|
|
@@ -482,11 +482,11 @@ var ShadcnCollector = class extends BaseCollector {
|
|
|
482
482
|
/**
|
|
483
483
|
* 파일 타입 추론
|
|
484
484
|
*/
|
|
485
|
-
getFileType(
|
|
486
|
-
if (
|
|
487
|
-
if (
|
|
488
|
-
if (
|
|
489
|
-
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";
|
|
490
490
|
return "component";
|
|
491
491
|
}
|
|
492
492
|
};
|
|
@@ -865,9 +865,12 @@ import path2 from "path";
|
|
|
865
865
|
var DEFAULT_PATHS = {
|
|
866
866
|
uiReact: "packages/axis-ui-react/src",
|
|
867
867
|
agenticUi: "packages/axis-agentic-ui/src",
|
|
868
|
-
|
|
869
|
-
|
|
868
|
+
docsApp: "apps/web/src/app/(docs)"
|
|
869
|
+
};
|
|
870
|
+
var DOCS_SLUG_ALIASES = {
|
|
871
|
+
"agentic/approval-card": "agentic/approval-dialog"
|
|
870
872
|
};
|
|
873
|
+
var NON_COMPONENT_FILE = /\.(test|spec|stories)\.tsx?$/;
|
|
871
874
|
var AxisCollector = class extends BaseCollector {
|
|
872
875
|
sourceType = "axis";
|
|
873
876
|
rootDir;
|
|
@@ -877,28 +880,45 @@ var AxisCollector = class extends BaseCollector {
|
|
|
877
880
|
this.rootDir = options.rootDir || process.cwd();
|
|
878
881
|
this.paths = { ...DEFAULT_PATHS, ...options.paths };
|
|
879
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
|
+
}
|
|
880
890
|
/**
|
|
881
891
|
* AXIS 컴포넌트 목록 조회
|
|
882
892
|
*/
|
|
883
893
|
async listComponents() {
|
|
884
894
|
const items = [];
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
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
|
+
});
|
|
893
913
|
}
|
|
894
914
|
}
|
|
895
|
-
return
|
|
915
|
+
return items;
|
|
896
916
|
}
|
|
897
917
|
/**
|
|
898
918
|
* 단일 컴포넌트 수집
|
|
899
919
|
*/
|
|
900
920
|
async collectComponent(id) {
|
|
901
|
-
const slug = id.replace(
|
|
921
|
+
const slug = id.replace(/^axis-/, "");
|
|
902
922
|
const componentInfo = await this.findComponent(slug);
|
|
903
923
|
if (!componentInfo) {
|
|
904
924
|
throw new Error(`AXIS component not found: ${slug}`);
|
|
@@ -915,138 +935,100 @@ var AxisCollector = class extends BaseCollector {
|
|
|
915
935
|
const mainContent = codeFiles.map((f) => f.content).join("\n");
|
|
916
936
|
const meta = this.createBaseMeta(
|
|
917
937
|
componentInfo.name,
|
|
918
|
-
this.extractDescription(mainContent) || `AXIS ${componentInfo.name} component`,
|
|
938
|
+
this.extractDescription(mainContent, slug) || `AXIS ${componentInfo.name} component`,
|
|
919
939
|
codeFiles,
|
|
920
940
|
{
|
|
921
941
|
registry: "@axis",
|
|
922
|
-
url: this.
|
|
942
|
+
url: await this.resolveDocsUrl(slug, componentInfo.route)
|
|
923
943
|
}
|
|
924
944
|
);
|
|
925
945
|
meta.category = componentInfo.category;
|
|
926
946
|
return meta;
|
|
927
947
|
}
|
|
928
948
|
/**
|
|
929
|
-
*
|
|
949
|
+
* 문서 URL 을 정합니다(WI-0057 D3).
|
|
950
|
+
* ① `<docsApp>/<route>/<slug>/page.tsx` 가 있으면 그 경로 ② 없으면 별칭 표의 대상이 실재할 때 그 경로
|
|
951
|
+
* ③ 둘 다 없으면 빈 문자열(library 상세 화면은 빈 URL 이면 문서 링크를 그리지 않습니다).
|
|
930
952
|
*/
|
|
931
|
-
async
|
|
932
|
-
const
|
|
933
|
-
const
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
if (entry.isDirectory()) {
|
|
940
|
-
const componentDir = path2.join(fullPath, entry.name);
|
|
941
|
-
const indexFile = path2.join(componentDir, "index.tsx");
|
|
942
|
-
if (await fs2.pathExists(indexFile)) {
|
|
943
|
-
const content = await fs2.readFile(indexFile, "utf-8");
|
|
944
|
-
const name = this.formatName(entry.name);
|
|
945
|
-
items.push({
|
|
946
|
-
id: `axis-${entry.name}`,
|
|
947
|
-
name,
|
|
948
|
-
description: this.extractDescription(content) || `AXIS ${name} component`,
|
|
949
|
-
category: this.classifyCategory(entry.name, content) || defaultCategory,
|
|
950
|
-
source: "axis"
|
|
951
|
-
});
|
|
952
|
-
}
|
|
953
|
-
} else if (entry.name.endsWith(".tsx") && entry.name !== "index.tsx") {
|
|
954
|
-
const name = entry.name.replace(".tsx", "");
|
|
955
|
-
const filePath = path2.join(fullPath, entry.name);
|
|
956
|
-
const content = await fs2.readFile(filePath, "utf-8");
|
|
957
|
-
items.push({
|
|
958
|
-
id: `axis-${name}`,
|
|
959
|
-
name: this.formatName(name),
|
|
960
|
-
description: this.extractDescription(content) || `AXIS ${name} component`,
|
|
961
|
-
category: this.classifyCategory(name, content) || defaultCategory,
|
|
962
|
-
source: "axis"
|
|
963
|
-
});
|
|
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}`;
|
|
964
961
|
}
|
|
965
962
|
}
|
|
966
|
-
return
|
|
963
|
+
return "";
|
|
964
|
+
}
|
|
965
|
+
async docsRouteExists(routePath) {
|
|
966
|
+
return fs2.pathExists(path2.join(this.rootDir, this.paths.docsApp, routePath, "page.tsx"));
|
|
967
967
|
}
|
|
968
968
|
/**
|
|
969
|
-
*
|
|
969
|
+
* 패키지 src 바로 아래에서 index.tsx 가 있는 디렉터리 이름(정렬). 단일 파일(a11y.test.tsx 등)과
|
|
970
|
+
* index.tsx 가 없는 디렉터리(constants · test-utils)는 컴포넌트가 아닙니다.
|
|
970
971
|
*/
|
|
971
|
-
async
|
|
972
|
-
const
|
|
973
|
-
const fullPath = path2.join(this.rootDir, webPath);
|
|
972
|
+
async listComponentDirs(packagePath) {
|
|
973
|
+
const fullPath = path2.join(this.rootDir, packagePath);
|
|
974
974
|
if (!await fs2.pathExists(fullPath)) {
|
|
975
|
-
return
|
|
975
|
+
return [];
|
|
976
976
|
}
|
|
977
977
|
const entries = await fs2.readdir(fullPath, { withFileTypes: true });
|
|
978
|
+
const slugs = [];
|
|
978
979
|
for (const entry of entries) {
|
|
979
|
-
if (entry.isDirectory())
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
if (await fs2.pathExists(pageFile)) {
|
|
983
|
-
const content = await fs2.readFile(pageFile, "utf-8");
|
|
984
|
-
const name = this.formatName(entry.name);
|
|
985
|
-
items.push({
|
|
986
|
-
id: `axis-${entry.name}`,
|
|
987
|
-
name,
|
|
988
|
-
description: this.extractDescription(content) || `AXIS ${name} component`,
|
|
989
|
-
category: this.classifyCategory(entry.name, content) || defaultCategory,
|
|
990
|
-
source: "axis"
|
|
991
|
-
});
|
|
992
|
-
}
|
|
980
|
+
if (!entry.isDirectory()) continue;
|
|
981
|
+
if (await fs2.pathExists(path2.join(fullPath, entry.name, "index.tsx"))) {
|
|
982
|
+
slugs.push(entry.name);
|
|
993
983
|
}
|
|
994
984
|
}
|
|
995
|
-
return
|
|
985
|
+
return slugs.sort();
|
|
996
986
|
}
|
|
997
987
|
/**
|
|
998
988
|
* 컴포넌트 찾기
|
|
999
989
|
*/
|
|
1000
990
|
async findComponent(slug) {
|
|
1001
|
-
const
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
];
|
|
1007
|
-
for (const { base, category } of searchPaths) {
|
|
1008
|
-
const fullBase = path2.join(this.rootDir, base);
|
|
1009
|
-
const dirPath = path2.join(fullBase, slug);
|
|
1010
|
-
if (await fs2.pathExists(dirPath)) {
|
|
1011
|
-
const files = await this.getComponentFiles(dirPath);
|
|
1012
|
-
if (files.length > 0) {
|
|
1013
|
-
return {
|
|
1014
|
-
name: this.formatName(slug),
|
|
1015
|
-
files,
|
|
1016
|
-
baseDir: dirPath,
|
|
1017
|
-
category
|
|
1018
|
-
};
|
|
1019
|
-
}
|
|
1020
|
-
}
|
|
1021
|
-
const filePath = path2.join(fullBase, `${slug}.tsx`);
|
|
1022
|
-
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) {
|
|
1023
996
|
return {
|
|
1024
997
|
name: this.formatName(slug),
|
|
1025
|
-
files
|
|
1026
|
-
baseDir:
|
|
1027
|
-
category
|
|
998
|
+
files,
|
|
999
|
+
baseDir: dirPath,
|
|
1000
|
+
category: pkg.category,
|
|
1001
|
+
route: pkg.route
|
|
1028
1002
|
};
|
|
1029
1003
|
}
|
|
1030
1004
|
}
|
|
1031
1005
|
return null;
|
|
1032
1006
|
}
|
|
1033
1007
|
/**
|
|
1034
|
-
* 컴포넌트
|
|
1008
|
+
* 컴포넌트 디렉터리의 코드 파일(.ts · .tsx, 테스트 · 스토리 제외). 이름순으로 정렬해 결과가 매번 같습니다.
|
|
1035
1009
|
*/
|
|
1036
1010
|
async getComponentFiles(dir) {
|
|
1037
|
-
const files = [];
|
|
1038
1011
|
const entries = await fs2.readdir(dir, { withFileTypes: true });
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
}
|
|
1043
|
-
}
|
|
1044
|
-
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));
|
|
1045
1015
|
}
|
|
1046
1016
|
/**
|
|
1047
|
-
* 설명
|
|
1017
|
+
* 설명 추출. 컴포넌트 이름(slug 의 PascalCase)으로 선언된 곳 바로 앞의 JSDoc 첫 줄을 먼저 씁니다
|
|
1018
|
+
* (WI-0057: 파일 첫 JSDoc 은 Props 인터페이스 · 하위 컴포넌트 설명인 경우가 많았습니다).
|
|
1048
1019
|
*/
|
|
1049
|
-
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
|
+
}
|
|
1050
1032
|
const jsdocMatch = code.match(/\/\*\*\s*\n\s*\*\s*(.+)\n/);
|
|
1051
1033
|
if (jsdocMatch) {
|
|
1052
1034
|
return jsdocMatch[1].trim();
|
|
@@ -1074,14 +1056,6 @@ var AxisCollector = class extends BaseCollector {
|
|
|
1074
1056
|
if (name.endsWith(".d.ts") || name.includes("types")) return "type";
|
|
1075
1057
|
return "component";
|
|
1076
1058
|
}
|
|
1077
|
-
/**
|
|
1078
|
-
* 문서 URL 생성
|
|
1079
|
-
*/
|
|
1080
|
-
getDocsUrl(slug, category) {
|
|
1081
|
-
const baseUrl = AXIS_SITE_URL;
|
|
1082
|
-
const route = category === "agentic" ? "agentic" : "components";
|
|
1083
|
-
return `${baseUrl}/${route}/${slug}`;
|
|
1084
|
-
}
|
|
1085
1059
|
};
|
|
1086
1060
|
|
|
1087
1061
|
// src/library/publisher.ts
|
|
@@ -1089,6 +1063,49 @@ import fs3 from "fs-extra";
|
|
|
1089
1063
|
import path3 from "path";
|
|
1090
1064
|
import chalk from "chalk";
|
|
1091
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
|
+
}
|
|
1092
1109
|
var Publisher = class {
|
|
1093
1110
|
defaultOutputDir = "apps/web/public/library";
|
|
1094
1111
|
/**
|
|
@@ -1190,55 +1207,20 @@ var Publisher = class {
|
|
|
1190
1207
|
updatedAt: index.updatedAt,
|
|
1191
1208
|
stats: index.stats,
|
|
1192
1209
|
categories: index.categories,
|
|
1193
|
-
components: index.components.map(
|
|
1194
|
-
id: c.id,
|
|
1195
|
-
slug: c.slug,
|
|
1196
|
-
name: c.name,
|
|
1197
|
-
description: c.description,
|
|
1198
|
-
category: c.category,
|
|
1199
|
-
source: c.source.type,
|
|
1200
|
-
tags: c.tags,
|
|
1201
|
-
status: c.status
|
|
1202
|
-
}))
|
|
1210
|
+
components: index.components.map(toIndexEntry)
|
|
1203
1211
|
};
|
|
1204
1212
|
}
|
|
1205
1213
|
/**
|
|
1206
1214
|
* 공개용 컴포넌트 생성
|
|
1207
1215
|
*/
|
|
1208
1216
|
createPublicComponent(component) {
|
|
1209
|
-
return
|
|
1210
|
-
id: component.id,
|
|
1211
|
-
slug: component.slug,
|
|
1212
|
-
name: component.name,
|
|
1213
|
-
description: component.description,
|
|
1214
|
-
category: component.category,
|
|
1215
|
-
source: {
|
|
1216
|
-
type: component.source.type,
|
|
1217
|
-
registry: component.source.registry,
|
|
1218
|
-
url: component.source.url
|
|
1219
|
-
},
|
|
1220
|
-
tags: component.tags,
|
|
1221
|
-
code: component.code,
|
|
1222
|
-
preview: component.preview,
|
|
1223
|
-
dependencies: component.dependencies,
|
|
1224
|
-
status: component.status,
|
|
1225
|
-
updatedAt: component.updatedAt
|
|
1226
|
-
};
|
|
1217
|
+
return toPublicComponent(component);
|
|
1227
1218
|
}
|
|
1228
1219
|
/**
|
|
1229
1220
|
* 검색 인덱스 생성
|
|
1230
1221
|
*/
|
|
1231
1222
|
generateSearchIndex(index) {
|
|
1232
|
-
return index.components.map(
|
|
1233
|
-
id: c.id,
|
|
1234
|
-
slug: c.slug,
|
|
1235
|
-
name: c.name,
|
|
1236
|
-
description: c.description,
|
|
1237
|
-
category: c.category,
|
|
1238
|
-
source: c.source.type,
|
|
1239
|
-
tags: c.tags,
|
|
1240
|
-
url: `/library/${c.category}/${c.slug}`
|
|
1241
|
-
}));
|
|
1223
|
+
return index.components.map(toSearchItem);
|
|
1242
1224
|
}
|
|
1243
1225
|
/**
|
|
1244
1226
|
* JSON 파일 쓰기
|
|
@@ -1280,10 +1262,269 @@ var Publisher = class {
|
|
|
1280
1262
|
};
|
|
1281
1263
|
var publisher = new Publisher();
|
|
1282
1264
|
|
|
1283
|
-
// src/library/
|
|
1265
|
+
// src/library/axis-refresh.ts
|
|
1284
1266
|
import fs4 from "fs-extra";
|
|
1285
1267
|
import path4 from "path";
|
|
1286
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";
|
|
1287
1528
|
import ora2 from "ora";
|
|
1288
1529
|
var DEFAULT_CATEGORIES = [
|
|
1289
1530
|
{ id: "ui", name: "UI", description: "\uAE30\uBCF8 UI \uCEF4\uD3EC\uB10C\uD2B8", icon: "layers", order: 1 },
|
|
@@ -1313,11 +1554,11 @@ var LibraryCurator = class {
|
|
|
1313
1554
|
async collectAll(sources, options) {
|
|
1314
1555
|
const results = /* @__PURE__ */ new Map();
|
|
1315
1556
|
const targetSources = sources || ["shadcn", "monet", "v0", "axis"];
|
|
1316
|
-
console.log(
|
|
1557
|
+
console.log(chalk3.blue("\n\u{1F4E6} Library Curator - \uCEF4\uD3EC\uB10C\uD2B8 \uC218\uC9D1 \uC2DC\uC791\n"));
|
|
1317
1558
|
for (const source of targetSources) {
|
|
1318
1559
|
const collector = this.collectors.get(source);
|
|
1319
1560
|
if (!collector) {
|
|
1320
|
-
console.log(
|
|
1561
|
+
console.log(chalk3.yellow(`\u26A0\uFE0F ${source} collector not found, skipping`));
|
|
1321
1562
|
continue;
|
|
1322
1563
|
}
|
|
1323
1564
|
const spinner = ora2(`${source} \uC218\uC9D1 \uC911...`).start();
|
|
@@ -1328,7 +1569,7 @@ var LibraryCurator = class {
|
|
|
1328
1569
|
results.set(source, result);
|
|
1329
1570
|
if (result.success) {
|
|
1330
1571
|
spinner.succeed(
|
|
1331
|
-
`${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)`) : "")
|
|
1332
1573
|
);
|
|
1333
1574
|
} else {
|
|
1334
1575
|
spinner.fail(`${source}: \uC218\uC9D1 \uC2E4\uD328 - ${result.errors[0]?.error}`);
|
|
@@ -1388,15 +1629,15 @@ var LibraryCurator = class {
|
|
|
1388
1629
|
* 인덱스 저장
|
|
1389
1630
|
*/
|
|
1390
1631
|
async saveIndex(index) {
|
|
1391
|
-
await
|
|
1392
|
-
const indexPath =
|
|
1393
|
-
await
|
|
1394
|
-
const categoriesDir =
|
|
1395
|
-
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);
|
|
1396
1637
|
for (const category of DEFAULT_CATEGORIES) {
|
|
1397
1638
|
const categoryComponents = index.components.filter((c) => c.category === category.id);
|
|
1398
|
-
const categoryPath =
|
|
1399
|
-
await
|
|
1639
|
+
const categoryPath = path5.join(categoriesDir, `${category.id}.json`);
|
|
1640
|
+
await fs5.writeJSON(
|
|
1400
1641
|
categoryPath,
|
|
1401
1642
|
{
|
|
1402
1643
|
category: category.id,
|
|
@@ -1406,17 +1647,17 @@ var LibraryCurator = class {
|
|
|
1406
1647
|
{ spaces: 2 }
|
|
1407
1648
|
);
|
|
1408
1649
|
}
|
|
1409
|
-
console.log(
|
|
1650
|
+
console.log(chalk3.green(`
|
|
1410
1651
|
\u2713 \uC778\uB371\uC2A4 \uC800\uC7A5 \uC644\uB8CC: ${indexPath}`));
|
|
1411
|
-
console.log(
|
|
1652
|
+
console.log(chalk3.gray(` - \uC804\uCCB4: ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
|
|
1412
1653
|
}
|
|
1413
1654
|
/**
|
|
1414
1655
|
* 인덱스 로드
|
|
1415
1656
|
*/
|
|
1416
1657
|
async loadIndex() {
|
|
1417
|
-
const indexPath =
|
|
1418
|
-
if (await
|
|
1419
|
-
return await
|
|
1658
|
+
const indexPath = path5.join(this.dataDir, "components.json");
|
|
1659
|
+
if (await fs5.pathExists(indexPath)) {
|
|
1660
|
+
return await fs5.readJSON(indexPath);
|
|
1420
1661
|
}
|
|
1421
1662
|
return null;
|
|
1422
1663
|
}
|
|
@@ -1471,26 +1712,26 @@ var LibraryCurator = class {
|
|
|
1471
1712
|
async printStats() {
|
|
1472
1713
|
const index = await this.loadIndex();
|
|
1473
1714
|
if (!index) {
|
|
1474
|
-
console.log(
|
|
1475
|
-
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"));
|
|
1476
1717
|
return;
|
|
1477
1718
|
}
|
|
1478
|
-
console.log(
|
|
1479
|
-
console.log(
|
|
1480
|
-
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}
|
|
1481
1722
|
`));
|
|
1482
|
-
console.log(
|
|
1723
|
+
console.log(chalk3.bold("\uC18C\uC2A4\uBCC4:"));
|
|
1483
1724
|
for (const [source, count] of Object.entries(index.stats.bySource)) {
|
|
1484
|
-
console.log(` ${
|
|
1725
|
+
console.log(` ${chalk3.cyan(source.padEnd(10))} ${count}\uAC1C`);
|
|
1485
1726
|
}
|
|
1486
|
-
console.log(
|
|
1727
|
+
console.log(chalk3.bold("\n\uCE74\uD14C\uACE0\uB9AC\uBCC4:"));
|
|
1487
1728
|
for (const [category, count] of Object.entries(index.stats.byCategory)) {
|
|
1488
|
-
console.log(` ${
|
|
1729
|
+
console.log(` ${chalk3.cyan(category.padEnd(15))} ${count}\uAC1C`);
|
|
1489
1730
|
}
|
|
1490
|
-
console.log(
|
|
1731
|
+
console.log(chalk3.bold("\n\uC778\uAE30 \uD0DC\uADF8:"));
|
|
1491
1732
|
const topTags = index.tags.slice(0, 10);
|
|
1492
1733
|
for (const tag of topTags) {
|
|
1493
|
-
console.log(` ${
|
|
1734
|
+
console.log(` ${chalk3.cyan(tag.name.padEnd(15))} ${tag.count}\uAC1C`);
|
|
1494
1735
|
}
|
|
1495
1736
|
console.log();
|
|
1496
1737
|
}
|
|
@@ -1498,61 +1739,61 @@ var LibraryCurator = class {
|
|
|
1498
1739
|
var libraryCurator = new LibraryCurator();
|
|
1499
1740
|
|
|
1500
1741
|
// src/template/index.ts
|
|
1501
|
-
import
|
|
1742
|
+
import chalk8 from "chalk";
|
|
1502
1743
|
import ora5 from "ora";
|
|
1503
1744
|
|
|
1504
1745
|
// src/template/template-apply.ts
|
|
1505
|
-
import
|
|
1506
|
-
import
|
|
1507
|
-
import
|
|
1746
|
+
import fs8 from "fs-extra";
|
|
1747
|
+
import path8 from "path";
|
|
1748
|
+
import chalk5 from "chalk";
|
|
1508
1749
|
import ora3 from "ora";
|
|
1509
1750
|
import prompts from "prompts";
|
|
1510
1751
|
|
|
1511
1752
|
// src/template/post-install.ts
|
|
1512
|
-
import
|
|
1513
|
-
import
|
|
1514
|
-
import
|
|
1753
|
+
import fs6 from "fs-extra";
|
|
1754
|
+
import path6 from "path";
|
|
1755
|
+
import chalk4 from "chalk";
|
|
1515
1756
|
async function runPostInstall(patches, baseDir, dryRun = false) {
|
|
1516
1757
|
for (const patch of patches) {
|
|
1517
|
-
const filePath =
|
|
1758
|
+
const filePath = path6.resolve(baseDir, patch.file);
|
|
1518
1759
|
if (dryRun) {
|
|
1519
|
-
console.log(
|
|
1760
|
+
console.log(chalk4.gray(` [dry-run] patch ${patch.type}: ${patch.file}`));
|
|
1520
1761
|
continue;
|
|
1521
1762
|
}
|
|
1522
|
-
if (!await
|
|
1523
|
-
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}`));
|
|
1524
1765
|
continue;
|
|
1525
1766
|
}
|
|
1526
1767
|
switch (patch.type) {
|
|
1527
1768
|
case "replace": {
|
|
1528
1769
|
if (!patch.search || patch.value === void 0) break;
|
|
1529
|
-
let content = await
|
|
1770
|
+
let content = await fs6.readFile(filePath, "utf-8");
|
|
1530
1771
|
content = content.replace(patch.search, patch.value);
|
|
1531
|
-
await
|
|
1532
|
-
console.log(
|
|
1772
|
+
await fs6.writeFile(filePath, content);
|
|
1773
|
+
console.log(chalk4.gray(` patch replace: ${patch.file}`));
|
|
1533
1774
|
break;
|
|
1534
1775
|
}
|
|
1535
1776
|
case "append": {
|
|
1536
1777
|
if (patch.value === void 0) break;
|
|
1537
|
-
const content = await
|
|
1538
|
-
await
|
|
1539
|
-
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}`));
|
|
1540
1781
|
break;
|
|
1541
1782
|
}
|
|
1542
1783
|
case "prepend": {
|
|
1543
1784
|
if (patch.value === void 0) break;
|
|
1544
|
-
const content = await
|
|
1545
|
-
await
|
|
1546
|
-
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}`));
|
|
1547
1788
|
break;
|
|
1548
1789
|
}
|
|
1549
1790
|
case "json-merge": {
|
|
1550
1791
|
if (!patch.merge) break;
|
|
1551
|
-
const raw = await
|
|
1792
|
+
const raw = await fs6.readFile(filePath, "utf-8");
|
|
1552
1793
|
const json = JSON.parse(raw);
|
|
1553
1794
|
deepMerge(json, patch.merge);
|
|
1554
|
-
await
|
|
1555
|
-
console.log(
|
|
1795
|
+
await fs6.writeJSON(filePath, json, { spaces: 2 });
|
|
1796
|
+
console.log(chalk4.gray(` patch json-merge: ${patch.file}`));
|
|
1556
1797
|
break;
|
|
1557
1798
|
}
|
|
1558
1799
|
}
|
|
@@ -1570,9 +1811,9 @@ function deepMerge(target, source) {
|
|
|
1570
1811
|
}
|
|
1571
1812
|
}
|
|
1572
1813
|
|
|
1573
|
-
// src/config/axis-config.ts
|
|
1574
|
-
import
|
|
1575
|
-
import
|
|
1814
|
+
// ../axis-registry-core/src/config/axis-config.ts
|
|
1815
|
+
import fs7 from "fs-extra";
|
|
1816
|
+
import path7 from "path";
|
|
1576
1817
|
var AXIS_CONFIG_SCHEMA_URL = `${AXIS_SITE_URL}/schema.json`;
|
|
1577
1818
|
var AXIS_CONFIG_FILE = "axis.config.json";
|
|
1578
1819
|
function createInitConfig(answers, registry) {
|
|
@@ -1595,9 +1836,9 @@ function createTemplateConfig(template) {
|
|
|
1595
1836
|
};
|
|
1596
1837
|
}
|
|
1597
1838
|
async function readAxisConfig(baseDir) {
|
|
1598
|
-
const configPath =
|
|
1599
|
-
if (!await
|
|
1600
|
-
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);
|
|
1601
1842
|
}
|
|
1602
1843
|
|
|
1603
1844
|
// src/template/template-apply.ts
|
|
@@ -1611,19 +1852,19 @@ async function applyTemplate(slug, options) {
|
|
|
1611
1852
|
spinner.fail(err.message);
|
|
1612
1853
|
process.exit(1);
|
|
1613
1854
|
}
|
|
1614
|
-
const baseDir =
|
|
1855
|
+
const baseDir = path8.resolve(options.dir || ".");
|
|
1615
1856
|
const conflicts = [];
|
|
1616
1857
|
for (const file of detail.files) {
|
|
1617
|
-
const dest =
|
|
1618
|
-
if (await
|
|
1858
|
+
const dest = path8.join(baseDir, file.path);
|
|
1859
|
+
if (await fs8.pathExists(dest)) {
|
|
1619
1860
|
conflicts.push(file.path);
|
|
1620
1861
|
}
|
|
1621
1862
|
}
|
|
1622
1863
|
if (conflicts.length > 0 && !options.yes && !options.dryRun) {
|
|
1623
|
-
console.log(
|
|
1864
|
+
console.log(chalk5.yellow(`
|
|
1624
1865
|
\uAE30\uC874 \uD30C\uC77C\uACFC \uCDA9\uB3CC\uD558\uB294 ${conflicts.length}\uAC1C \uD30C\uC77C:`));
|
|
1625
1866
|
for (const c of conflicts) {
|
|
1626
|
-
console.log(
|
|
1867
|
+
console.log(chalk5.gray(` - ${c}`));
|
|
1627
1868
|
}
|
|
1628
1869
|
const { proceed } = await prompts({
|
|
1629
1870
|
type: "confirm",
|
|
@@ -1632,59 +1873,59 @@ async function applyTemplate(slug, options) {
|
|
|
1632
1873
|
initial: false
|
|
1633
1874
|
});
|
|
1634
1875
|
if (!proceed) {
|
|
1635
|
-
console.log(
|
|
1876
|
+
console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
1636
1877
|
return;
|
|
1637
1878
|
}
|
|
1638
1879
|
}
|
|
1639
1880
|
if (options.dryRun) {
|
|
1640
|
-
console.log(
|
|
1881
|
+
console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
|
|
1641
1882
|
for (const file of detail.files) {
|
|
1642
|
-
const dest =
|
|
1883
|
+
const dest = path8.join(baseDir, file.path);
|
|
1643
1884
|
const exists = conflicts.includes(file.path);
|
|
1644
|
-
const label = exists ?
|
|
1885
|
+
const label = exists ? chalk5.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk5.green("\uC0DD\uC131");
|
|
1645
1886
|
console.log(` ${label} ${dest}`);
|
|
1646
1887
|
}
|
|
1647
1888
|
if (detail.postInstall?.length) {
|
|
1648
|
-
console.log(
|
|
1889
|
+
console.log(chalk5.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] postInstall \uD328\uCE58:"));
|
|
1649
1890
|
for (const p of detail.postInstall) {
|
|
1650
|
-
console.log(
|
|
1891
|
+
console.log(chalk5.gray(` ${p.type}: ${p.file}`));
|
|
1651
1892
|
}
|
|
1652
1893
|
}
|
|
1653
1894
|
return;
|
|
1654
1895
|
}
|
|
1655
1896
|
const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
|
|
1656
1897
|
for (const file of detail.files) {
|
|
1657
|
-
const dest =
|
|
1658
|
-
await
|
|
1659
|
-
await
|
|
1898
|
+
const dest = path8.join(baseDir, file.path);
|
|
1899
|
+
await fs8.ensureDir(path8.dirname(dest));
|
|
1900
|
+
await fs8.writeFile(dest, file.content);
|
|
1660
1901
|
}
|
|
1661
1902
|
writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
|
|
1662
1903
|
if (detail.postInstall?.length) {
|
|
1663
|
-
console.log(
|
|
1904
|
+
console.log(chalk5.blue("\npostInstall \uD328\uCE58 \uC2E4\uD589 \uC911..."));
|
|
1664
1905
|
await runPostInstall(detail.postInstall, baseDir);
|
|
1665
1906
|
}
|
|
1666
1907
|
if (!options.skipDeps) {
|
|
1667
1908
|
const allDeps = { ...detail.dependencies, ...detail.devDependencies };
|
|
1668
1909
|
const depList = Object.entries(allDeps);
|
|
1669
1910
|
if (depList.length > 0) {
|
|
1670
|
-
console.log(
|
|
1911
|
+
console.log(chalk5.yellow("\n\uD544\uC694\uD55C \uC758\uC874\uC131:"));
|
|
1671
1912
|
const deps = Object.entries(detail.dependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
|
|
1672
1913
|
const devDeps = Object.entries(detail.devDependencies || {}).map(([k, v]) => `${k}@${v}`).join(" ");
|
|
1673
1914
|
if (deps) {
|
|
1674
|
-
console.log(
|
|
1915
|
+
console.log(chalk5.cyan(` pnpm add ${deps}`));
|
|
1675
1916
|
}
|
|
1676
1917
|
if (devDeps) {
|
|
1677
|
-
console.log(
|
|
1918
|
+
console.log(chalk5.cyan(` pnpm add -D ${devDeps}`));
|
|
1678
1919
|
}
|
|
1679
1920
|
}
|
|
1680
1921
|
}
|
|
1681
|
-
console.log(
|
|
1922
|
+
console.log(chalk5.green(`
|
|
1682
1923
|
'${detail.name}' \uD15C\uD50C\uB9BF \uC801\uC6A9 \uC644\uB8CC!`));
|
|
1683
1924
|
}
|
|
1684
1925
|
async function initTemplate(slug, options) {
|
|
1685
1926
|
let selectedSlug = slug;
|
|
1686
1927
|
if (!selectedSlug) {
|
|
1687
|
-
const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-
|
|
1928
|
+
const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-6WSGKPF2.js");
|
|
1688
1929
|
const index = await fetchTemplateIndex2();
|
|
1689
1930
|
const { choice } = await prompts({
|
|
1690
1931
|
type: "select",
|
|
@@ -1697,7 +1938,7 @@ async function initTemplate(slug, options) {
|
|
|
1697
1938
|
}))
|
|
1698
1939
|
});
|
|
1699
1940
|
if (!choice) {
|
|
1700
|
-
console.log(
|
|
1941
|
+
console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
1701
1942
|
return;
|
|
1702
1943
|
}
|
|
1703
1944
|
selectedSlug = choice;
|
|
@@ -1711,14 +1952,14 @@ async function initTemplate(slug, options) {
|
|
|
1711
1952
|
initial: selectedSlug
|
|
1712
1953
|
});
|
|
1713
1954
|
if (!dir) {
|
|
1714
|
-
console.log(
|
|
1955
|
+
console.log(chalk5.gray("\uCDE8\uC18C\uB418\uC5C8\uC2B5\uB2C8\uB2E4."));
|
|
1715
1956
|
return;
|
|
1716
1957
|
}
|
|
1717
1958
|
targetDir = dir;
|
|
1718
1959
|
}
|
|
1719
|
-
const resolved =
|
|
1720
|
-
if (await
|
|
1721
|
-
const entries = await
|
|
1960
|
+
const resolved = path8.resolve(targetDir);
|
|
1961
|
+
if (await fs8.pathExists(resolved)) {
|
|
1962
|
+
const entries = await fs8.readdir(resolved);
|
|
1722
1963
|
if (entries.length > 0) {
|
|
1723
1964
|
const { proceed } = await prompts({
|
|
1724
1965
|
type: "confirm",
|
|
@@ -1729,26 +1970,26 @@ async function initTemplate(slug, options) {
|
|
|
1729
1970
|
if (!proceed) return;
|
|
1730
1971
|
}
|
|
1731
1972
|
} else {
|
|
1732
|
-
await
|
|
1973
|
+
await fs8.ensureDir(resolved);
|
|
1733
1974
|
}
|
|
1734
1975
|
await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
|
|
1735
|
-
const configPath =
|
|
1736
|
-
if (!await
|
|
1976
|
+
const configPath = path8.join(resolved, "axis.config.json");
|
|
1977
|
+
if (!await fs8.pathExists(configPath)) {
|
|
1737
1978
|
const axisConfig = createTemplateConfig(selectedSlug);
|
|
1738
|
-
await
|
|
1739
|
-
console.log(
|
|
1979
|
+
await fs8.writeJSON(configPath, axisConfig, { spaces: 2 });
|
|
1980
|
+
console.log(chalk5.green("axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
|
|
1740
1981
|
}
|
|
1741
|
-
console.log(
|
|
1982
|
+
console.log(chalk5.blue(`
|
|
1742
1983
|
\uB2E4\uC74C \uB2E8\uACC4:`));
|
|
1743
|
-
console.log(
|
|
1744
|
-
console.log(
|
|
1745
|
-
console.log(
|
|
1984
|
+
console.log(chalk5.cyan(` cd ${targetDir}`));
|
|
1985
|
+
console.log(chalk5.cyan(` pnpm install`));
|
|
1986
|
+
console.log(chalk5.cyan(` pnpm dev`));
|
|
1746
1987
|
}
|
|
1747
1988
|
|
|
1748
1989
|
// src/template/template-diff.ts
|
|
1749
|
-
import
|
|
1750
|
-
import
|
|
1751
|
-
import
|
|
1990
|
+
import fs9 from "fs-extra";
|
|
1991
|
+
import path9 from "path";
|
|
1992
|
+
import chalk6 from "chalk";
|
|
1752
1993
|
import ora4 from "ora";
|
|
1753
1994
|
async function diffTemplate(slug, options) {
|
|
1754
1995
|
const spinner = ora4(`'${slug}' \uD15C\uD50C\uB9BF \uAC00\uC838\uC624\uB294 \uC911...`).start();
|
|
@@ -1760,15 +2001,15 @@ async function diffTemplate(slug, options) {
|
|
|
1760
2001
|
spinner.fail(err.message);
|
|
1761
2002
|
process.exit(1);
|
|
1762
2003
|
}
|
|
1763
|
-
const baseDir =
|
|
2004
|
+
const baseDir = path9.resolve(options.dir || ".");
|
|
1764
2005
|
const entries = [];
|
|
1765
2006
|
for (const file of detail.files) {
|
|
1766
|
-
const localPath =
|
|
1767
|
-
if (!await
|
|
2007
|
+
const localPath = path9.join(baseDir, file.path);
|
|
2008
|
+
if (!await fs9.pathExists(localPath)) {
|
|
1768
2009
|
entries.push({ path: file.path, status: "added" });
|
|
1769
2010
|
continue;
|
|
1770
2011
|
}
|
|
1771
|
-
const localContent = await
|
|
2012
|
+
const localContent = await fs9.readFile(localPath, "utf-8");
|
|
1772
2013
|
if (localContent === file.content) {
|
|
1773
2014
|
entries.push({ path: file.path, status: "unchanged" });
|
|
1774
2015
|
} else {
|
|
@@ -1789,14 +2030,14 @@ async function diffTemplate(slug, options) {
|
|
|
1789
2030
|
}
|
|
1790
2031
|
}
|
|
1791
2032
|
}
|
|
1792
|
-
console.log(
|
|
2033
|
+
console.log(chalk6.blue(`
|
|
1793
2034
|
'${detail.name}' \uD15C\uD50C\uB9BF diff \uACB0\uACFC:
|
|
1794
2035
|
`));
|
|
1795
2036
|
const statusIcon = {
|
|
1796
|
-
added:
|
|
1797
|
-
modified:
|
|
1798
|
-
unchanged:
|
|
1799
|
-
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")
|
|
1800
2041
|
};
|
|
1801
2042
|
let added = 0;
|
|
1802
2043
|
let modified = 0;
|
|
@@ -1807,7 +2048,7 @@ async function diffTemplate(slug, options) {
|
|
|
1807
2048
|
console.log(` ${icon.padEnd(28)} ${entry.path}`);
|
|
1808
2049
|
if (entry.status === "modified" && options.verbose) {
|
|
1809
2050
|
console.log(
|
|
1810
|
-
|
|
2051
|
+
chalk6.gray(
|
|
1811
2052
|
` \uB85C\uCEEC ${entry.localLines}\uC904 / \uC6D0\uBCF8 ${entry.remoteLines}\uC904`
|
|
1812
2053
|
)
|
|
1813
2054
|
);
|
|
@@ -1827,9 +2068,9 @@ async function diffTemplate(slug, options) {
|
|
|
1827
2068
|
break;
|
|
1828
2069
|
}
|
|
1829
2070
|
}
|
|
1830
|
-
console.log(
|
|
2071
|
+
console.log(chalk6.blue("\n\uC694\uC57D:"));
|
|
1831
2072
|
console.log(
|
|
1832
|
-
` \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))}` : ""}`
|
|
1833
2074
|
);
|
|
1834
2075
|
}
|
|
1835
2076
|
async function collectLocalFiles(dir, base) {
|
|
@@ -1838,27 +2079,27 @@ async function collectLocalFiles(dir, base) {
|
|
|
1838
2079
|
const results = [];
|
|
1839
2080
|
let entries;
|
|
1840
2081
|
try {
|
|
1841
|
-
entries = await
|
|
2082
|
+
entries = await fs9.readdir(dir, { withFileTypes: true });
|
|
1842
2083
|
} catch {
|
|
1843
2084
|
return results;
|
|
1844
2085
|
}
|
|
1845
2086
|
for (const entry of entries) {
|
|
1846
2087
|
if (ignore.has(entry.name)) continue;
|
|
1847
|
-
const fullPath =
|
|
2088
|
+
const fullPath = path9.join(dir, entry.name);
|
|
1848
2089
|
if (entry.isDirectory()) {
|
|
1849
2090
|
const nested = await collectLocalFiles(fullPath, root);
|
|
1850
2091
|
results.push(...nested);
|
|
1851
2092
|
} else {
|
|
1852
|
-
results.push(
|
|
2093
|
+
results.push(path9.relative(root, fullPath).replace(/\\/g, "/"));
|
|
1853
2094
|
}
|
|
1854
2095
|
}
|
|
1855
2096
|
return results;
|
|
1856
2097
|
}
|
|
1857
2098
|
|
|
1858
2099
|
// src/template/template-check.ts
|
|
1859
|
-
import
|
|
1860
|
-
import
|
|
1861
|
-
import
|
|
2100
|
+
import fs10 from "fs-extra";
|
|
2101
|
+
import path10 from "path";
|
|
2102
|
+
import chalk7 from "chalk";
|
|
1862
2103
|
|
|
1863
2104
|
// src/theme/brand-core.ts
|
|
1864
2105
|
import { existsSync, readFileSync, statSync } from "fs";
|
|
@@ -2104,7 +2345,7 @@ function getBrand(baseDir, name) {
|
|
|
2104
2345
|
};
|
|
2105
2346
|
}
|
|
2106
2347
|
|
|
2107
|
-
// src/template/tailwind-core.ts
|
|
2348
|
+
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
2108
2349
|
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
2109
2350
|
import { join as join2, resolve as resolve2 } from "path";
|
|
2110
2351
|
function hasDependency(pkg, name) {
|
|
@@ -2525,9 +2766,9 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2525
2766
|
return { name: "tailwind.config", severity: "warn", message: "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
|
|
2526
2767
|
}
|
|
2527
2768
|
for (const file of otherFiles) {
|
|
2528
|
-
const
|
|
2529
|
-
if (existsSync2(
|
|
2530
|
-
if (hasTokensPresetReference(readFileSync2(
|
|
2769
|
+
const path18 = join2(baseDir, file);
|
|
2770
|
+
if (existsSync2(path18)) {
|
|
2771
|
+
if (hasTokensPresetReference(readFileSync2(path18, "utf8"))) {
|
|
2531
2772
|
return { name: "tailwind.config", severity: "pass", message: `${file}${PRESET_PASS_SUFFIX}` };
|
|
2532
2773
|
}
|
|
2533
2774
|
return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
|
|
@@ -2538,12 +2779,12 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2538
2779
|
|
|
2539
2780
|
// src/template/template-check.ts
|
|
2540
2781
|
var SEVERITY_ICON = {
|
|
2541
|
-
pass:
|
|
2542
|
-
warn:
|
|
2543
|
-
fail:
|
|
2782
|
+
pass: chalk7.green("PASS"),
|
|
2783
|
+
warn: chalk7.yellow("WARN"),
|
|
2784
|
+
fail: chalk7.red("FAIL")
|
|
2544
2785
|
};
|
|
2545
2786
|
async function collectCheckResults(dir) {
|
|
2546
|
-
const baseDir =
|
|
2787
|
+
const baseDir = path10.resolve(dir || ".");
|
|
2547
2788
|
const results = [];
|
|
2548
2789
|
results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
|
|
2549
2790
|
results.push(checkTailwindSetup(baseDir));
|
|
@@ -2556,7 +2797,7 @@ async function collectCheckResults(dir) {
|
|
|
2556
2797
|
}
|
|
2557
2798
|
async function runCheck(dir) {
|
|
2558
2799
|
const results = await collectCheckResults(dir);
|
|
2559
|
-
console.log(
|
|
2800
|
+
console.log(chalk7.blue("\nAXIS \uD504\uB85C\uC81D\uD2B8 \uAC80\uC99D \uACB0\uACFC:\n"));
|
|
2560
2801
|
let passCount = 0;
|
|
2561
2802
|
let warnCount = 0;
|
|
2562
2803
|
let failCount = 0;
|
|
@@ -2576,19 +2817,19 @@ async function runCheck(dir) {
|
|
|
2576
2817
|
}
|
|
2577
2818
|
console.log();
|
|
2578
2819
|
console.log(
|
|
2579
|
-
` \uACB0\uACFC: ${
|
|
2820
|
+
` \uACB0\uACFC: ${chalk7.green(`${passCount} pass`)} / ${chalk7.yellow(`${warnCount} warn`)} / ${chalk7.red(`${failCount} fail`)}`
|
|
2580
2821
|
);
|
|
2581
2822
|
if (failCount > 0) {
|
|
2582
|
-
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."));
|
|
2583
2824
|
} else if (warnCount > 0) {
|
|
2584
|
-
console.log(
|
|
2825
|
+
console.log(chalk7.yellow("\n\uAD8C\uC7A5 \uD56D\uBAA9\uC744 \uD655\uC778\uD558\uC138\uC694."));
|
|
2585
2826
|
} else {
|
|
2586
|
-
console.log(
|
|
2827
|
+
console.log(chalk7.green("\n\uBAA8\uB4E0 \uAC80\uC99D\uC744 \uD1B5\uACFC\uD588\uC2B5\uB2C8\uB2E4!"));
|
|
2587
2828
|
}
|
|
2588
2829
|
return { pass: passCount, warn: warnCount, fail: failCount };
|
|
2589
2830
|
}
|
|
2590
2831
|
async function checkFileExists(baseDir, fileName, label) {
|
|
2591
|
-
const exists = await
|
|
2832
|
+
const exists = await fs10.pathExists(path10.join(baseDir, fileName));
|
|
2592
2833
|
return {
|
|
2593
2834
|
name: label,
|
|
2594
2835
|
severity: exists ? "pass" : "fail",
|
|
@@ -2604,9 +2845,9 @@ async function checkUtils(baseDir) {
|
|
|
2604
2845
|
"utils.ts"
|
|
2605
2846
|
];
|
|
2606
2847
|
for (const candidate of candidates) {
|
|
2607
|
-
const fullPath =
|
|
2608
|
-
if (await
|
|
2609
|
-
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");
|
|
2610
2851
|
const hasCn = content.includes("function cn");
|
|
2611
2852
|
return {
|
|
2612
2853
|
name: "utils.ts",
|
|
@@ -2622,15 +2863,15 @@ async function checkUtils(baseDir) {
|
|
|
2622
2863
|
};
|
|
2623
2864
|
}
|
|
2624
2865
|
async function checkDependencies(baseDir) {
|
|
2625
|
-
const pkgPath =
|
|
2626
|
-
if (!await
|
|
2866
|
+
const pkgPath = path10.join(baseDir, "package.json");
|
|
2867
|
+
if (!await fs10.pathExists(pkgPath)) {
|
|
2627
2868
|
return {
|
|
2628
2869
|
name: "package.json",
|
|
2629
2870
|
severity: "fail",
|
|
2630
2871
|
message: "package.json \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4"
|
|
2631
2872
|
};
|
|
2632
2873
|
}
|
|
2633
|
-
const pkg = await
|
|
2874
|
+
const pkg = await fs10.readJSON(pkgPath);
|
|
2634
2875
|
const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
2635
2876
|
const required = ["tailwindcss"];
|
|
2636
2877
|
const recommended = ["clsx", "tailwind-merge"];
|
|
@@ -2704,10 +2945,10 @@ function registerTemplateCommand(program2) {
|
|
|
2704
2945
|
templates = templates.filter((t) => t.category === options.category);
|
|
2705
2946
|
}
|
|
2706
2947
|
if (templates.length === 0) {
|
|
2707
|
-
console.log(
|
|
2948
|
+
console.log(chalk8.yellow("\n\uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uD15C\uD50C\uB9BF\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.\n"));
|
|
2708
2949
|
return;
|
|
2709
2950
|
}
|
|
2710
|
-
console.log(
|
|
2951
|
+
console.log(chalk8.blue(`
|
|
2711
2952
|
\u{1F4E6} AXIS \uD15C\uD50C\uB9BF (${templates.length}\uAC1C)
|
|
2712
2953
|
`));
|
|
2713
2954
|
const byCategory = /* @__PURE__ */ new Map();
|
|
@@ -2718,16 +2959,16 @@ function registerTemplateCommand(program2) {
|
|
|
2718
2959
|
byCategory.get(t.category).push(t);
|
|
2719
2960
|
}
|
|
2720
2961
|
for (const [category, items] of byCategory) {
|
|
2721
|
-
console.log(
|
|
2962
|
+
console.log(chalk8.bold(` ${category}`));
|
|
2722
2963
|
for (const t of items) {
|
|
2723
2964
|
console.log(
|
|
2724
|
-
` ${
|
|
2965
|
+
` ${chalk8.cyan(t.slug.padEnd(20))} ${chalk8.gray(t.description.slice(0, 50))}`
|
|
2725
2966
|
);
|
|
2726
2967
|
}
|
|
2727
2968
|
console.log();
|
|
2728
2969
|
}
|
|
2729
|
-
console.log(
|
|
2730
|
-
console.log(
|
|
2970
|
+
console.log(chalk8.gray("\uC0AC\uC6A9\uBC95: axis template info <name>"));
|
|
2971
|
+
console.log(chalk8.gray(" axis template apply <name>\n"));
|
|
2731
2972
|
} catch (err) {
|
|
2732
2973
|
spinner.fail(err.message);
|
|
2733
2974
|
process.exit(1);
|
|
@@ -2738,30 +2979,30 @@ function registerTemplateCommand(program2) {
|
|
|
2738
2979
|
try {
|
|
2739
2980
|
const detail = await fetchTemplateDetail(name);
|
|
2740
2981
|
spinner.stop();
|
|
2741
|
-
console.log(
|
|
2982
|
+
console.log(chalk8.blue(`
|
|
2742
2983
|
\u{1F4CB} ${detail.name}
|
|
2743
2984
|
`));
|
|
2744
|
-
console.log(` ${
|
|
2745
|
-
console.log(` ${
|
|
2746
|
-
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}`);
|
|
2747
2988
|
if (detail.tags.length > 0) {
|
|
2748
|
-
console.log(` ${
|
|
2989
|
+
console.log(` ${chalk8.bold("\uD0DC\uADF8")}: ${detail.tags.join(", ")}`);
|
|
2749
2990
|
}
|
|
2750
2991
|
if (detail.features.length > 0) {
|
|
2751
|
-
console.log(
|
|
2992
|
+
console.log(chalk8.bold("\n \uAE30\uB2A5:"));
|
|
2752
2993
|
for (const f of detail.features) {
|
|
2753
2994
|
console.log(` - ${f}`);
|
|
2754
2995
|
}
|
|
2755
2996
|
}
|
|
2756
|
-
console.log(
|
|
2997
|
+
console.log(chalk8.bold(`
|
|
2757
2998
|
\uD30C\uC77C (${detail.files.length}\uAC1C):`));
|
|
2758
2999
|
for (const f of detail.files) {
|
|
2759
|
-
console.log(` ${
|
|
3000
|
+
console.log(` ${chalk8.cyan(f.path)} ${chalk8.gray(`(${f.type})`)}`);
|
|
2760
3001
|
}
|
|
2761
3002
|
const deps = Object.keys(detail.dependencies || {});
|
|
2762
3003
|
const devDeps = Object.keys(detail.devDependencies || {});
|
|
2763
3004
|
if (deps.length > 0 || devDeps.length > 0) {
|
|
2764
|
-
console.log(
|
|
3005
|
+
console.log(chalk8.bold("\n \uC758\uC874\uC131:"));
|
|
2765
3006
|
if (deps.length > 0) {
|
|
2766
3007
|
console.log(` dependencies: ${deps.join(", ")}`);
|
|
2767
3008
|
}
|
|
@@ -2769,7 +3010,7 @@ function registerTemplateCommand(program2) {
|
|
|
2769
3010
|
console.log(` devDependencies: ${devDeps.join(", ")}`);
|
|
2770
3011
|
}
|
|
2771
3012
|
}
|
|
2772
|
-
console.log(
|
|
3013
|
+
console.log(chalk8.gray(`
|
|
2773
3014
|
\uC0AC\uC6A9\uBC95: axis template apply ${name}
|
|
2774
3015
|
`));
|
|
2775
3016
|
} catch (err) {
|
|
@@ -2795,16 +3036,40 @@ function registerCheckCommand(program2) {
|
|
|
2795
3036
|
}
|
|
2796
3037
|
|
|
2797
3038
|
// src/theme/index.ts
|
|
2798
|
-
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";
|
|
2799
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
|
+
}
|
|
2800
3067
|
|
|
2801
3068
|
// src/theme/theme-add.ts
|
|
2802
|
-
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
|
|
2803
|
-
import path10 from "path";
|
|
2804
3069
|
var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
|
|
2805
3070
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
2806
3071
|
function readText(file) {
|
|
2807
|
-
return
|
|
3072
|
+
return existsSync4(file) ? readFileSync3(file, "utf8") : null;
|
|
2808
3073
|
}
|
|
2809
3074
|
function eolOf(text) {
|
|
2810
3075
|
return text.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -2872,33 +3137,15 @@ function compareVersions(a, b) {
|
|
|
2872
3137
|
function realPathInside(baseDir, file) {
|
|
2873
3138
|
const realBase = realpathSync(baseDir);
|
|
2874
3139
|
const realPath = realpathSync(file);
|
|
2875
|
-
const relPath =
|
|
2876
|
-
const inside = relPath !== "" && !relPath.startsWith("..") && !
|
|
3140
|
+
const relPath = path12.relative(realBase, realPath);
|
|
3141
|
+
const inside = relPath !== "" && !relPath.startsWith("..") && !path12.isAbsolute(relPath);
|
|
2877
3142
|
return { inside, realPath };
|
|
2878
3143
|
}
|
|
2879
3144
|
function isStylesheet(realPath) {
|
|
2880
|
-
return
|
|
2881
|
-
}
|
|
2882
|
-
function detectInstallCommand(baseDir) {
|
|
2883
|
-
if (existsSync3(path10.join(baseDir, "pnpm-lock.yaml"))) return "pnpm install";
|
|
2884
|
-
if (existsSync3(path10.join(baseDir, "yarn.lock"))) return "yarn install";
|
|
2885
|
-
if (existsSync3(path10.join(baseDir, "package-lock.json"))) return "npm install";
|
|
2886
|
-
return "pnpm install";
|
|
2887
|
-
}
|
|
2888
|
-
function hasDependency2(pkg, name) {
|
|
2889
|
-
for (const field of ["dependencies", "devDependencies"]) {
|
|
2890
|
-
const deps = pkg[field];
|
|
2891
|
-
if (typeof deps === "object" && deps !== null && name in deps) {
|
|
2892
|
-
return String(deps[name]);
|
|
2893
|
-
}
|
|
2894
|
-
}
|
|
2895
|
-
return void 0;
|
|
2896
|
-
}
|
|
2897
|
-
function isPlainObject2(value) {
|
|
2898
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3145
|
+
return path12.extname(realPath).toLowerCase() === ".css";
|
|
2899
3146
|
}
|
|
2900
3147
|
function planThemeAdd(baseDirInput, brand) {
|
|
2901
|
-
const baseDir =
|
|
3148
|
+
const baseDir = path12.resolve(baseDirInput);
|
|
2902
3149
|
const plan = {
|
|
2903
3150
|
baseDir,
|
|
2904
3151
|
brand,
|
|
@@ -2910,7 +3157,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2910
3157
|
installCommand: detectInstallCommand(baseDir),
|
|
2911
3158
|
writes: []
|
|
2912
3159
|
};
|
|
2913
|
-
const configFile =
|
|
3160
|
+
const configFile = path12.join(baseDir, AXIS_CONFIG_FILE);
|
|
2914
3161
|
const configText = readText(configFile);
|
|
2915
3162
|
if (configText === null) {
|
|
2916
3163
|
plan.errors.push({ kind: "no-config" });
|
|
@@ -2976,7 +3223,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2976
3223
|
} else {
|
|
2977
3224
|
plan.css = { configuredMissing: location.configuredMissing, action: "manual", otherBrands: [] };
|
|
2978
3225
|
}
|
|
2979
|
-
const pkgFile =
|
|
3226
|
+
const pkgFile = path12.join(baseDir, "package.json");
|
|
2980
3227
|
const pkgText = readText(pkgFile);
|
|
2981
3228
|
const installed = plan.tokens.version;
|
|
2982
3229
|
const upgrade = installed !== void 0 && (compareVersions(installed, MIN_BRAND_TOKENS_VERSION) ?? 0) < 0;
|
|
@@ -3036,8 +3283,8 @@ function applyThemeAdd(plan) {
|
|
|
3036
3283
|
if (current !== w.before) {
|
|
3037
3284
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
3038
3285
|
}
|
|
3039
|
-
const where = realPathInside(plan.baseDir, w.before === null ?
|
|
3040
|
-
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)) {
|
|
3041
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.`);
|
|
3042
3289
|
}
|
|
3043
3290
|
if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
|
|
@@ -3049,7 +3296,7 @@ function applyThemeAdd(plan) {
|
|
|
3049
3296
|
throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3050
3297
|
}
|
|
3051
3298
|
try {
|
|
3052
|
-
accessSync(w.before === null ?
|
|
3299
|
+
accessSync(w.before === null ? path12.dirname(w.file) : w.file, constants.W_OK);
|
|
3053
3300
|
} catch (err) {
|
|
3054
3301
|
throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
|
|
3055
3302
|
}
|
|
@@ -3088,22 +3335,22 @@ function tokensStatusGuide(status, version) {
|
|
|
3088
3335
|
switch (status) {
|
|
3089
3336
|
case "not-installed":
|
|
3090
3337
|
return [
|
|
3091
|
-
|
|
3092
|
-
` \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)}`
|
|
3093
3340
|
];
|
|
3094
3341
|
case "unsupported":
|
|
3095
3342
|
return [
|
|
3096
|
-
|
|
3343
|
+
chalk9.yellow(
|
|
3097
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).`
|
|
3098
3345
|
),
|
|
3099
|
-
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${
|
|
3346
|
+
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
|
|
3100
3347
|
];
|
|
3101
3348
|
case "not-built":
|
|
3102
3349
|
return [
|
|
3103
|
-
|
|
3350
|
+
chalk9.yellow(
|
|
3104
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.`
|
|
3105
3352
|
),
|
|
3106
|
-
` \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)}`
|
|
3107
3354
|
];
|
|
3108
3355
|
}
|
|
3109
3356
|
}
|
|
@@ -3113,22 +3360,22 @@ function renderThemeList(result) {
|
|
|
3113
3360
|
}
|
|
3114
3361
|
if (result.brands.length === 0) {
|
|
3115
3362
|
return {
|
|
3116
|
-
lines: ["",
|
|
3363
|
+
lines: ["", chalk9.yellow(`\uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uBE0C\uB79C\uB4DC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.`), ""],
|
|
3117
3364
|
exitCode: 0
|
|
3118
3365
|
};
|
|
3119
3366
|
}
|
|
3120
3367
|
const width = Math.max(...result.brands.map((b) => b.name.length));
|
|
3121
3368
|
const lines = [
|
|
3122
3369
|
"",
|
|
3123
|
-
|
|
3370
|
+
chalk9.blue(`AXIS \uBE0C\uB79C\uB4DC (${result.brands.length}\uAC1C, ${TOKENS_PACKAGE} ${result.version ?? ""})`),
|
|
3124
3371
|
""
|
|
3125
3372
|
];
|
|
3126
3373
|
for (const b of result.brands) {
|
|
3127
3374
|
lines.push(
|
|
3128
|
-
` ${
|
|
3375
|
+
` ${chalk9.cyan(b.name.padEnd(width))} ${b.description} ${chalk9.gray(`(${b.themes.join(" \xB7 ")})`)}`
|
|
3129
3376
|
);
|
|
3130
3377
|
}
|
|
3131
|
-
lines.push("",
|
|
3378
|
+
lines.push("", chalk9.gray("\uC0AC\uC6A9\uBC95: axis theme info <brand>"), "");
|
|
3132
3379
|
return { lines, exitCode: 0 };
|
|
3133
3380
|
}
|
|
3134
3381
|
function a11yValue(value) {
|
|
@@ -3144,13 +3391,13 @@ function tokenTable(brand) {
|
|
|
3144
3391
|
const header = ["\uD1A0\uD070", "\uB77C\uC774\uD2B8", "\uB2E4\uD06C"];
|
|
3145
3392
|
const w0 = Math.max(header[0].length, ...rows.map((r) => r[0].length));
|
|
3146
3393
|
const w1 = Math.max(header[1].length, ...rows.map((r) => r[1].length));
|
|
3147
|
-
lines.push(
|
|
3394
|
+
lines.push(chalk9.gray(` ${header[0].padEnd(w0)} ${header[1].padEnd(w1)} ${header[2]}`));
|
|
3148
3395
|
for (const [k, l, d] of rows) {
|
|
3149
3396
|
lines.push(` ${k.padEnd(w0)} ${l.padEnd(w1)} ${d}`);
|
|
3150
3397
|
}
|
|
3151
3398
|
}
|
|
3152
3399
|
if (missing.length > 0) {
|
|
3153
|
-
lines.push(
|
|
3400
|
+
lines.push(chalk9.gray(` \uBE0C\uB79C\uB4DC\uAC00 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC74C: ${missing.join(", ")}`));
|
|
3154
3401
|
}
|
|
3155
3402
|
return lines;
|
|
3156
3403
|
}
|
|
@@ -3163,9 +3410,9 @@ function renderThemeInfo(result, name) {
|
|
|
3163
3410
|
return {
|
|
3164
3411
|
lines: [
|
|
3165
3412
|
"",
|
|
3166
|
-
|
|
3413
|
+
chalk9.red(`\uBE0C\uB79C\uB4DC '${name}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${result.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
|
|
3167
3414
|
` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${result.available.length > 0 ? result.available.join(", ") : "(\uC5C6\uC74C)"}`,
|
|
3168
|
-
|
|
3415
|
+
chalk9.gray(" \uBAA9\uB85D: axis theme list"),
|
|
3169
3416
|
""
|
|
3170
3417
|
],
|
|
3171
3418
|
exitCode: 1
|
|
@@ -3173,34 +3420,34 @@ function renderThemeInfo(result, name) {
|
|
|
3173
3420
|
}
|
|
3174
3421
|
const lines = [
|
|
3175
3422
|
"",
|
|
3176
|
-
|
|
3423
|
+
chalk9.blue(`\uBE0C\uB79C\uB4DC ${brand.name}`),
|
|
3177
3424
|
` \uC124\uBA85: ${brand.description}`,
|
|
3178
3425
|
` \uD14C\uB9C8: ${brand.themes.join(" \xB7 ")}`,
|
|
3179
3426
|
"",
|
|
3180
|
-
|
|
3427
|
+
chalk9.bold("Import (globals.css, @charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)"),
|
|
3181
3428
|
` @import "${brand.importPath}";`,
|
|
3182
3429
|
"",
|
|
3183
|
-
|
|
3430
|
+
chalk9.bold("Provider (@axis-ds/theme 1.3.0 \uC774\uC0C1)"),
|
|
3184
3431
|
...brand.providerExample.split("\n").map((l) => l ? ` ${l}` : ""),
|
|
3185
|
-
|
|
3432
|
+
chalk9.gray(
|
|
3186
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.`
|
|
3187
3434
|
),
|
|
3188
3435
|
"",
|
|
3189
|
-
|
|
3436
|
+
chalk9.bold("\uC8FC\uC694 \uD1A0\uD070"),
|
|
3190
3437
|
...tokenTable(brand),
|
|
3191
3438
|
"",
|
|
3192
|
-
|
|
3439
|
+
chalk9.bold("\uBCF4\uC815 \uB0B4\uC5ED"),
|
|
3193
3440
|
` a11y \uC0C1\uD0DC: ${a11yValue(brand.adjustments.a11y.status)}`,
|
|
3194
3441
|
` \uC810\uAC80\uC77C: ${a11yValue(brand.adjustments.a11y.checkedAt)}`,
|
|
3195
3442
|
` \uAC8C\uC774\uD2B8: ${a11yValue(brand.adjustments.a11y.gate)}`,
|
|
3196
3443
|
` \uADFC\uAC70 \uBB38\uC11C: ${brand.adjustments.reference}`,
|
|
3197
|
-
|
|
3444
|
+
chalk9.gray(" \uBCF4\uC815 \uC804 \xB7 \uD6C4 \uAC12\uC740 \uC774 \uBC84\uC804\uC5D0\uC11C \uCD9C\uB825\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."),
|
|
3198
3445
|
""
|
|
3199
3446
|
];
|
|
3200
3447
|
return { lines, exitCode: 0 };
|
|
3201
3448
|
}
|
|
3202
3449
|
function rel(plan, file) {
|
|
3203
|
-
return
|
|
3450
|
+
return path13.relative(plan.baseDir, file) || file;
|
|
3204
3451
|
}
|
|
3205
3452
|
function renderThemeAdd(plan, written) {
|
|
3206
3453
|
const error = plan.errors[0];
|
|
@@ -3209,24 +3456,24 @@ function renderThemeAdd(plan, written) {
|
|
|
3209
3456
|
switch (error.kind) {
|
|
3210
3457
|
case "no-config":
|
|
3211
3458
|
lines2.push(
|
|
3212
|
-
|
|
3213
|
-
` \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.`
|
|
3214
3461
|
);
|
|
3215
3462
|
break;
|
|
3216
3463
|
case "invalid-config":
|
|
3217
|
-
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.`));
|
|
3218
3465
|
break;
|
|
3219
3466
|
case "invalid-package-json":
|
|
3220
|
-
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.`));
|
|
3221
3468
|
break;
|
|
3222
3469
|
case "invalid-name":
|
|
3223
3470
|
lines2.push(
|
|
3224
|
-
|
|
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.`)
|
|
3225
3472
|
);
|
|
3226
3473
|
break;
|
|
3227
3474
|
case "css-outside-project":
|
|
3228
3475
|
lines2.push(
|
|
3229
|
-
|
|
3476
|
+
chalk9.red(
|
|
3230
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.`
|
|
3231
3478
|
),
|
|
3232
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}";`
|
|
@@ -3234,25 +3481,25 @@ function renderThemeAdd(plan, written) {
|
|
|
3234
3481
|
break;
|
|
3235
3482
|
case "css-not-stylesheet":
|
|
3236
3483
|
lines2.push(
|
|
3237
|
-
|
|
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.`),
|
|
3238
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}";`
|
|
3239
3486
|
);
|
|
3240
3487
|
break;
|
|
3241
3488
|
case "unknown-brand":
|
|
3242
3489
|
lines2.push(
|
|
3243
|
-
|
|
3490
|
+
chalk9.red(`\uBE0C\uB79C\uB4DC '${error.brand}' \uAC00 \uC124\uCE58\uB41C ${TOKENS_PACKAGE} ${error.version ?? ""} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4.`),
|
|
3244
3491
|
` \uC124\uCE58\uB41C \uBE0C\uB79C\uB4DC: ${error.available.length > 0 ? error.available.join(", ") : "(\uC5C6\uC74C)"}`,
|
|
3245
|
-
|
|
3492
|
+
chalk9.gray(" \uBAA9\uB85D: axis theme list")
|
|
3246
3493
|
);
|
|
3247
3494
|
break;
|
|
3248
3495
|
}
|
|
3249
3496
|
lines2.push("");
|
|
3250
3497
|
return { lines: lines2, exitCode: 1 };
|
|
3251
3498
|
}
|
|
3252
|
-
const lines = ["",
|
|
3499
|
+
const lines = ["", chalk9.blue(`\uBE0C\uB79C\uB4DC ${plan.brand} \uC801\uC6A9`), ""];
|
|
3253
3500
|
if (plan.unverifiedBrand) {
|
|
3254
3501
|
lines.push(
|
|
3255
|
-
|
|
3502
|
+
chalk9.yellow(
|
|
3256
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.`
|
|
3257
3504
|
)
|
|
3258
3505
|
);
|
|
@@ -3260,24 +3507,24 @@ function renderThemeAdd(plan, written) {
|
|
|
3260
3507
|
const css = plan.css;
|
|
3261
3508
|
if (css?.configuredMissing) {
|
|
3262
3509
|
lines.push(
|
|
3263
|
-
|
|
3510
|
+
chalk9.yellow(
|
|
3264
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.`
|
|
3265
3512
|
)
|
|
3266
3513
|
);
|
|
3267
3514
|
}
|
|
3268
3515
|
if (css?.action === "add" && css.file) {
|
|
3269
|
-
lines.push(` ${
|
|
3516
|
+
lines.push(` ${chalk9.green("\u2713")} ${rel(plan, css.file)}: @import "${plan.importPath}"; \uCD94\uAC00`);
|
|
3270
3517
|
} else if (css?.action === "exists" && css.file) {
|
|
3271
|
-
lines.push(` ${
|
|
3518
|
+
lines.push(` ${chalk9.gray("-")} ${rel(plan, css.file)}: import \uAC00 \uC774\uBBF8 \uC788\uC5B4 \uAC74\uB108\uB700`);
|
|
3272
3519
|
} else {
|
|
3273
3520
|
lines.push(
|
|
3274
|
-
|
|
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."),
|
|
3275
3522
|
` \uC804\uC5ED CSS \uB9E8 \uC55E(@charset \xB7 \uB2E4\uB978 @import \uB2E4\uC74C)\uC5D0 \uC9C1\uC811 \uB123\uC73C\uC138\uC694: @import "${plan.importPath}";`
|
|
3276
3523
|
);
|
|
3277
3524
|
}
|
|
3278
3525
|
if (css && css.otherBrands.length > 0) {
|
|
3279
3526
|
lines.push(
|
|
3280
|
-
|
|
3527
|
+
chalk9.yellow(
|
|
3281
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.`
|
|
3282
3529
|
)
|
|
3283
3530
|
);
|
|
@@ -3285,60 +3532,60 @@ function renderThemeAdd(plan, written) {
|
|
|
3285
3532
|
const dep = plan.dependency;
|
|
3286
3533
|
if (dep?.action === "add") {
|
|
3287
3534
|
lines.push(
|
|
3288
|
-
` ${
|
|
3289
|
-
` \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)}`
|
|
3290
3537
|
);
|
|
3291
3538
|
} else if (dep?.action === "present") {
|
|
3292
|
-
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`);
|
|
3293
3540
|
} else if (dep?.action === "no-package-json") {
|
|
3294
3541
|
lines.push(
|
|
3295
|
-
|
|
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}`)
|
|
3296
3543
|
);
|
|
3297
3544
|
}
|
|
3298
3545
|
if (dep?.upgrade) {
|
|
3299
3546
|
lines.push(
|
|
3300
|
-
|
|
3547
|
+
chalk9.yellow(
|
|
3301
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).`
|
|
3302
3549
|
),
|
|
3303
|
-
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${
|
|
3550
|
+
` \uC5C5\uADF8\uB808\uC774\uB4DC: ${chalk9.cyan(TOKENS_INSTALL_COMMAND)}`
|
|
3304
3551
|
);
|
|
3305
3552
|
}
|
|
3306
3553
|
if (plan.configChanged) {
|
|
3307
|
-
lines.push(` ${
|
|
3554
|
+
lines.push(` ${chalk9.green("\u2713")} axis.config.json: "brand": "${plan.brand}" \uAE30\uB85D`);
|
|
3308
3555
|
} else {
|
|
3309
|
-
lines.push(` ${
|
|
3556
|
+
lines.push(` ${chalk9.gray("-")} axis.config.json: brand \uAC00 \uC774\uBBF8 "${plan.brand}"`);
|
|
3310
3557
|
}
|
|
3311
3558
|
lines.push(
|
|
3312
3559
|
"",
|
|
3313
|
-
|
|
3560
|
+
chalk9.bold(`Provider (${THEME_PACKAGE} 1.3.0 \uC774\uC0C1)`),
|
|
3314
3561
|
...providerExample(plan.brand).split("\n").map((l) => l ? ` ${l}` : ""),
|
|
3315
|
-
|
|
3562
|
+
chalk9.gray(
|
|
3316
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.`
|
|
3317
3564
|
)
|
|
3318
3565
|
);
|
|
3319
3566
|
if (dep?.themeMissing) {
|
|
3320
|
-
lines.push(` ${THEME_PACKAGE} \uC124\uCE58: ${
|
|
3567
|
+
lines.push(` ${THEME_PACKAGE} \uC124\uCE58: ${chalk9.cyan(`pnpm add ${THEME_PACKAGE}@^1.3.0`)}`);
|
|
3321
3568
|
}
|
|
3322
|
-
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."), "");
|
|
3323
3570
|
return { lines, exitCode: 0 };
|
|
3324
3571
|
}
|
|
3325
3572
|
function renderThemeAddFailure(plan, err) {
|
|
3326
3573
|
const lines = [""];
|
|
3327
3574
|
if (err instanceof ThemeApplyError) {
|
|
3328
|
-
lines.push(
|
|
3575
|
+
lines.push(chalk9.red(err.message));
|
|
3329
3576
|
if (err.restored.length > 0) {
|
|
3330
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(", ")}`);
|
|
3331
3578
|
}
|
|
3332
3579
|
if (err.restoreFailed.length > 0) {
|
|
3333
3580
|
lines.push(
|
|
3334
|
-
|
|
3581
|
+
chalk9.red(` \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD574 \uBC14\uB010 \uCC44 \uB0A8\uC740 \uD30C\uC77C: ${err.restoreFailed.map((f) => rel(plan, f)).join(", ")}`)
|
|
3335
3582
|
);
|
|
3336
3583
|
}
|
|
3337
3584
|
if (err.restored.length === 0 && err.restoreFailed.length === 0) {
|
|
3338
3585
|
lines.push(" \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
3339
3586
|
}
|
|
3340
3587
|
} else {
|
|
3341
|
-
lines.push(
|
|
3588
|
+
lines.push(chalk9.red(err instanceof Error ? err.message : String(err)), " \uBC14\uB010 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
3342
3589
|
}
|
|
3343
3590
|
lines.push("");
|
|
3344
3591
|
return { lines, exitCode: 1 };
|
|
@@ -3350,15 +3597,15 @@ function print(output) {
|
|
|
3350
3597
|
function registerThemeCommand(program2) {
|
|
3351
3598
|
const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
|
|
3352
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) => {
|
|
3353
|
-
const baseDir =
|
|
3600
|
+
const baseDir = path13.resolve(options.dir || ".");
|
|
3354
3601
|
print(renderThemeList(listBrands(baseDir)));
|
|
3355
3602
|
});
|
|
3356
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) => {
|
|
3357
|
-
const baseDir =
|
|
3604
|
+
const baseDir = path13.resolve(options.dir || ".");
|
|
3358
3605
|
print(renderThemeInfo(getBrand(baseDir, name), name));
|
|
3359
3606
|
});
|
|
3360
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) => {
|
|
3361
|
-
const baseDir =
|
|
3608
|
+
const baseDir = path13.resolve(options.dir || ".");
|
|
3362
3609
|
const plan = planThemeAdd(baseDir, name);
|
|
3363
3610
|
let written = [];
|
|
3364
3611
|
if (plan.errors.length === 0) {
|
|
@@ -3374,10 +3621,10 @@ function registerThemeCommand(program2) {
|
|
|
3374
3621
|
}
|
|
3375
3622
|
|
|
3376
3623
|
// src/init/index.ts
|
|
3377
|
-
import
|
|
3624
|
+
import chalk11 from "chalk";
|
|
3378
3625
|
import prompts2 from "prompts";
|
|
3379
3626
|
|
|
3380
|
-
// src/registry/schema.ts
|
|
3627
|
+
// ../axis-registry-core/src/registry/schema.ts
|
|
3381
3628
|
import { createHash } from "crypto";
|
|
3382
3629
|
var REGISTRY_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3383
3630
|
var REGISTRY_NAME_MAX_LENGTH = 64;
|
|
@@ -3581,7 +3828,7 @@ function checkItemSha256(item, entry, where = `${item.name}.json`) {
|
|
|
3581
3828
|
}
|
|
3582
3829
|
}
|
|
3583
3830
|
|
|
3584
|
-
// src/registry/remote.ts
|
|
3831
|
+
// ../axis-registry-core/src/registry/remote.ts
|
|
3585
3832
|
var DEFAULT_REGISTRY_URL = REGISTRY_PUBLIC_BASE_URL;
|
|
3586
3833
|
var DEFAULT_REGISTRY_TIMEOUT_MS = 5e3;
|
|
3587
3834
|
var LEGACY_DEFAULT_REGISTRY_URL = "https://axis.minu.best/r";
|
|
@@ -3650,10 +3897,18 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
3650
3897
|
try {
|
|
3651
3898
|
let res;
|
|
3652
3899
|
try {
|
|
3653
|
-
res = await fetchImpl(url, {
|
|
3900
|
+
res = await fetchImpl(url, {
|
|
3901
|
+
signal: controller.signal,
|
|
3902
|
+
headers: { accept: "application/json" },
|
|
3903
|
+
...options.rejectRedirects ? { redirect: "manual" } : {}
|
|
3904
|
+
});
|
|
3654
3905
|
} catch (error) {
|
|
3655
3906
|
throw describe(error);
|
|
3656
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
|
+
}
|
|
3657
3912
|
if (!res.ok) {
|
|
3658
3913
|
await res.text().catch(() => void 0);
|
|
3659
3914
|
throw new RegistryAccessError(`${shown}: HTTP ${res.status}`);
|
|
@@ -3670,15 +3925,15 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
3670
3925
|
}
|
|
3671
3926
|
|
|
3672
3927
|
// src/init/init.ts
|
|
3673
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as
|
|
3674
|
-
import
|
|
3675
|
-
import
|
|
3676
|
-
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";
|
|
3677
3932
|
|
|
3678
|
-
// src/add/safe-write.ts
|
|
3679
|
-
import { constants as fsConstants, existsSync as
|
|
3680
|
-
import
|
|
3681
|
-
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";
|
|
3682
3937
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
3683
3938
|
var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
|
|
3684
3939
|
var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
|
|
@@ -3688,15 +3943,15 @@ function codedError(code, message) {
|
|
|
3688
3943
|
e.code = code;
|
|
3689
3944
|
return e;
|
|
3690
3945
|
}
|
|
3691
|
-
function isSameOrInside(parent, child, impl =
|
|
3946
|
+
function isSameOrInside(parent, child, impl = path14) {
|
|
3692
3947
|
const rel3 = impl.relative(parent, child);
|
|
3693
3948
|
if (rel3 === "") return true;
|
|
3694
3949
|
return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
|
|
3695
3950
|
}
|
|
3696
3951
|
function nearestExisting(p) {
|
|
3697
3952
|
let cur = p;
|
|
3698
|
-
while (!
|
|
3699
|
-
const up =
|
|
3953
|
+
while (!existsSync5(cur)) {
|
|
3954
|
+
const up = path14.dirname(cur);
|
|
3700
3955
|
if (up === cur) return cur;
|
|
3701
3956
|
cur = up;
|
|
3702
3957
|
}
|
|
@@ -3704,10 +3959,10 @@ function nearestExisting(p) {
|
|
|
3704
3959
|
}
|
|
3705
3960
|
function escapeReason(root, target, options = {}) {
|
|
3706
3961
|
const realRoot = realpathSync2(root);
|
|
3707
|
-
if (!isSameOrInside(
|
|
3962
|
+
if (!isSameOrInside(path14.resolve(root), path14.resolve(target)) || path14.resolve(target) === path14.resolve(root)) {
|
|
3708
3963
|
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
3709
3964
|
}
|
|
3710
|
-
const anchor = nearestExisting(
|
|
3965
|
+
const anchor = nearestExisting(path14.dirname(target));
|
|
3711
3966
|
const realAnchor = realpathSync2(anchor);
|
|
3712
3967
|
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
3713
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`;
|
|
@@ -3720,7 +3975,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
3720
3975
|
}
|
|
3721
3976
|
if (st) {
|
|
3722
3977
|
if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
|
|
3723
|
-
const shown =
|
|
3978
|
+
const shown = path14.relative(path14.resolve(root), path14.resolve(target)).split(path14.sep).join("/");
|
|
3724
3979
|
let realTarget;
|
|
3725
3980
|
try {
|
|
3726
3981
|
realTarget = realpathSync2(target);
|
|
@@ -3788,50 +4043,50 @@ async function writeNoFollow(target, content, mode) {
|
|
|
3788
4043
|
let fd;
|
|
3789
4044
|
if (mode === "overwrite") {
|
|
3790
4045
|
try {
|
|
3791
|
-
fd = await
|
|
4046
|
+
fd = await fs11.open(target, OVERWRITE_FLAGS);
|
|
3792
4047
|
} catch (e) {
|
|
3793
4048
|
if (e.code !== "ENOENT") throw e;
|
|
3794
4049
|
actual = "new";
|
|
3795
|
-
fd = await
|
|
4050
|
+
fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
|
|
3796
4051
|
}
|
|
3797
4052
|
} else {
|
|
3798
|
-
fd = await
|
|
4053
|
+
fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
|
|
3799
4054
|
}
|
|
3800
4055
|
try {
|
|
3801
4056
|
if (actual === "overwrite") {
|
|
3802
|
-
const st = await
|
|
4057
|
+
const st = await fs11.fstat(fd);
|
|
3803
4058
|
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3804
4059
|
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
3805
|
-
await
|
|
4060
|
+
await fs11.ftruncate(fd, 0);
|
|
3806
4061
|
}
|
|
3807
|
-
await
|
|
4062
|
+
await fs11.writeFile(fd, content);
|
|
3808
4063
|
} finally {
|
|
3809
|
-
await
|
|
4064
|
+
await fs11.close(fd);
|
|
3810
4065
|
}
|
|
3811
4066
|
return actual;
|
|
3812
4067
|
}
|
|
3813
4068
|
async function overwriteFollowingLinks(target, content) {
|
|
3814
|
-
const fd = await
|
|
4069
|
+
const fd = await fs11.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
|
|
3815
4070
|
try {
|
|
3816
|
-
const st = await
|
|
4071
|
+
const st = await fs11.fstat(fd);
|
|
3817
4072
|
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3818
4073
|
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
3819
|
-
await
|
|
3820
|
-
await
|
|
4074
|
+
await fs11.ftruncate(fd, 0);
|
|
4075
|
+
await fs11.writeFile(fd, content);
|
|
3821
4076
|
} finally {
|
|
3822
|
-
await
|
|
4077
|
+
await fs11.close(fd);
|
|
3823
4078
|
}
|
|
3824
4079
|
}
|
|
3825
4080
|
function checkParentInside(root, target) {
|
|
3826
4081
|
const realRoot = realpathSync2(root);
|
|
3827
|
-
const realParent = realpathSync2(
|
|
4082
|
+
const realParent = realpathSync2(path14.dirname(target));
|
|
3828
4083
|
if (!isSameOrInside(realRoot, realParent)) {
|
|
3829
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`;
|
|
3830
4085
|
}
|
|
3831
4086
|
return escapeReason(root, target);
|
|
3832
4087
|
}
|
|
3833
4088
|
|
|
3834
|
-
// src/
|
|
4089
|
+
// ../axis-registry-core/src/utils-deps.ts
|
|
3835
4090
|
var CLSX_RANGE = "^2.1.1";
|
|
3836
4091
|
var TAILWIND_MERGE_RANGES = {
|
|
3837
4092
|
tailwind4: "^3.4.0",
|
|
@@ -3843,6 +4098,8 @@ function selectUtilsDependencies(tailwind) {
|
|
|
3843
4098
|
"tailwind-merge": tailwind.major !== void 0 && tailwind.major >= 4 ? TAILWIND_MERGE_RANGES.tailwind4 : TAILWIND_MERGE_RANGES.tailwind3
|
|
3844
4099
|
};
|
|
3845
4100
|
}
|
|
4101
|
+
|
|
4102
|
+
// src/init/init.ts
|
|
3846
4103
|
function tailwindWarnings(tailwind, installCommand) {
|
|
3847
4104
|
const out = [];
|
|
3848
4105
|
if (tailwind.source === "none" && tailwind.value !== void 0) {
|
|
@@ -3906,7 +4163,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
|
|
|
3906
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.";
|
|
3907
4164
|
function readPackageJsonSafe(baseDir) {
|
|
3908
4165
|
try {
|
|
3909
|
-
const text = readFileSync4(
|
|
4166
|
+
const text = readFileSync4(path15.join(baseDir, "package.json"), "utf8");
|
|
3910
4167
|
const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
|
|
3911
4168
|
return isPlainObject2(parsed) ? parsed : void 0;
|
|
3912
4169
|
} catch {
|
|
@@ -3971,7 +4228,7 @@ function addCommandFor(installCommand, deps) {
|
|
|
3971
4228
|
return `pnpm add ${specs}`;
|
|
3972
4229
|
}
|
|
3973
4230
|
function planUtilsDependencies(baseDirInput) {
|
|
3974
|
-
const baseDir =
|
|
4231
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
3975
4232
|
const installCommand = detectInstallCommand(baseDir);
|
|
3976
4233
|
const tailwind0 = detectTailwind(baseDir);
|
|
3977
4234
|
const ranges0 = selectUtilsDependencies(tailwind0);
|
|
@@ -3984,8 +4241,8 @@ function planUtilsDependencies(baseDirInput) {
|
|
|
3984
4241
|
installCommand,
|
|
3985
4242
|
addCommand: addCommandFor(installCommand, ranges0)
|
|
3986
4243
|
};
|
|
3987
|
-
const pkgFile =
|
|
3988
|
-
if (!
|
|
4244
|
+
const pkgFile = path15.join(baseDir, "package.json");
|
|
4245
|
+
if (!existsSync6(pkgFile)) return plan;
|
|
3989
4246
|
const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
|
|
3990
4247
|
let where;
|
|
3991
4248
|
try {
|
|
@@ -4038,8 +4295,8 @@ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
|
|
|
4038
4295
|
function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
|
|
4039
4296
|
const w = plan.write;
|
|
4040
4297
|
if (plan.action !== "add" || !w) return false;
|
|
4041
|
-
const baseDir =
|
|
4042
|
-
const current =
|
|
4298
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
4299
|
+
const current = existsSync6(w.file) ? readFileSync4(w.file, "utf8") : null;
|
|
4043
4300
|
if (current !== w.before) {
|
|
4044
4301
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
4045
4302
|
}
|
|
@@ -4068,25 +4325,25 @@ function reportDependencies(plan, log) {
|
|
|
4068
4325
|
const presentText = plan.present.map((p) => `${p.name} (${p.range})`).join(", ");
|
|
4069
4326
|
const basis = ` tailwind-merge \uBC94\uC704 \uAE30\uC900: ${describeTailwindBasis(plan.tailwind)}`;
|
|
4070
4327
|
const logBasis = () => {
|
|
4071
|
-
log(
|
|
4072
|
-
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}`));
|
|
4073
4330
|
};
|
|
4074
4331
|
if (plan.action === "add") {
|
|
4075
4332
|
const addedText = plan.added.map((n) => `${n}@${plan.ranges[n]}`).join(", ");
|
|
4076
|
-
log(
|
|
4077
|
-
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}`));
|
|
4078
4335
|
if (plan.added.includes("tailwind-merge")) logBasis();
|
|
4079
|
-
log(
|
|
4336
|
+
log(chalk10.yellow(` \uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58: ${chalk10.cyan(plan.installCommand)}`));
|
|
4080
4337
|
} else if (plan.action === "present") {
|
|
4081
|
-
log(
|
|
4082
|
-
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)}`));
|
|
4083
4340
|
} else if (plan.action === "no-package-json") {
|
|
4084
|
-
log(
|
|
4085
|
-
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)}`));
|
|
4086
4343
|
logBasis();
|
|
4087
4344
|
} else {
|
|
4088
|
-
log(
|
|
4089
|
-
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)}`));
|
|
4090
4347
|
if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
|
|
4091
4348
|
}
|
|
4092
4349
|
}
|
|
@@ -4109,8 +4366,8 @@ function errCode(e) {
|
|
|
4109
4366
|
return e.code ?? e.message;
|
|
4110
4367
|
}
|
|
4111
4368
|
function planUtilsWrite(baseDirInput, utilsPath) {
|
|
4112
|
-
const baseDir =
|
|
4113
|
-
const shown =
|
|
4369
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
4370
|
+
const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
|
|
4114
4371
|
let st;
|
|
4115
4372
|
try {
|
|
4116
4373
|
st = lstatSync2(utilsPath);
|
|
@@ -4171,7 +4428,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
4171
4428
|
return { action: "overwrite" };
|
|
4172
4429
|
}
|
|
4173
4430
|
async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
4174
|
-
const baseDir =
|
|
4431
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
4175
4432
|
const current = await existingConfig(baseDir);
|
|
4176
4433
|
const existingRegistry = nonEmptyString(current?.registry);
|
|
4177
4434
|
const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
|
|
@@ -4188,13 +4445,13 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4188
4445
|
},
|
|
4189
4446
|
registry
|
|
4190
4447
|
);
|
|
4191
|
-
const configPath =
|
|
4448
|
+
const configPath = path15.join(baseDir, "axis.config.json");
|
|
4192
4449
|
const nextText = `${JSON.stringify(axisConfig, null, 2)}
|
|
4193
4450
|
`;
|
|
4194
4451
|
const rejects = [];
|
|
4195
4452
|
let previousText = null;
|
|
4196
4453
|
try {
|
|
4197
|
-
previousText = await
|
|
4454
|
+
previousText = await fs12.readFile(configPath, "utf8");
|
|
4198
4455
|
} catch (e) {
|
|
4199
4456
|
if (e.code !== "ENOENT") {
|
|
4200
4457
|
rejects.push(`\uAE30\uC874 axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})`);
|
|
@@ -4207,79 +4464,79 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4207
4464
|
} catch {
|
|
4208
4465
|
}
|
|
4209
4466
|
}
|
|
4210
|
-
const utilsPath =
|
|
4467
|
+
const utilsPath = path15.resolve(baseDir, answers.componentsDir, "utils.ts");
|
|
4211
4468
|
const utilsPlan = planUtilsWrite(baseDir, utilsPath);
|
|
4212
4469
|
if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
|
|
4213
4470
|
if (rejects.length > 0) {
|
|
4214
|
-
log(
|
|
4215
|
-
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}`));
|
|
4216
4473
|
process.exitCode = 1;
|
|
4217
4474
|
return;
|
|
4218
4475
|
}
|
|
4219
4476
|
let configState;
|
|
4220
4477
|
if (previousText === null) {
|
|
4221
4478
|
try {
|
|
4222
|
-
await
|
|
4479
|
+
await fs12.writeFile(configPath, nextText, { flag: "wx" });
|
|
4223
4480
|
} catch (err) {
|
|
4224
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;
|
|
4225
|
-
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.`));
|
|
4226
4483
|
process.exitCode = 1;
|
|
4227
4484
|
return;
|
|
4228
4485
|
}
|
|
4229
4486
|
configState = "created";
|
|
4230
|
-
log(
|
|
4487
|
+
log(chalk10.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
|
|
4231
4488
|
} else if (previousText === nextText) {
|
|
4232
4489
|
configState = "kept";
|
|
4233
|
-
log(
|
|
4490
|
+
log(chalk10.green("\u2713 axis.config.json \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
|
|
4234
4491
|
} else {
|
|
4235
4492
|
try {
|
|
4236
4493
|
await overwriteFollowingLinks(configPath, nextText);
|
|
4237
4494
|
} catch (err) {
|
|
4238
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;
|
|
4239
|
-
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.`));
|
|
4240
4497
|
process.exitCode = 1;
|
|
4241
4498
|
return;
|
|
4242
4499
|
}
|
|
4243
4500
|
configState = "updated";
|
|
4244
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";
|
|
4245
4502
|
const agenticNote = existingAgenticDir !== void 0 ? ", agenticDir \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "";
|
|
4246
|
-
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})`));
|
|
4247
4504
|
if (migratedRegistry && existingRegistry !== void 0) {
|
|
4248
4505
|
log(
|
|
4249
|
-
|
|
4506
|
+
chalk10.yellow(
|
|
4250
4507
|
` registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C(${redactRegistryUrl(registry)})\uB85C \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4(\uC885\uC804 axis.minu.best: ${redactRegistryUrl(existingRegistry)}).`
|
|
4251
4508
|
)
|
|
4252
4509
|
);
|
|
4253
4510
|
}
|
|
4254
4511
|
const dropped = current ? Object.keys(current).filter((k) => !(k in axisConfig) && current[k] !== void 0) : [];
|
|
4255
4512
|
if (dropped.length > 0) {
|
|
4256
|
-
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)`));
|
|
4257
4514
|
}
|
|
4258
4515
|
}
|
|
4259
4516
|
let utilsStateNote = "utils.ts \uB294 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9).";
|
|
4260
4517
|
if (utilsPlan.action === "keep") {
|
|
4261
|
-
if (utilsPlan.link === void 0) log(
|
|
4262
|
-
else if (utilsPlan.link.outside === null) log(
|
|
4263
|
-
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})`));
|
|
4264
4521
|
} else {
|
|
4265
4522
|
let actual;
|
|
4266
4523
|
try {
|
|
4267
|
-
await
|
|
4524
|
+
await fs12.ensureDir(path15.dirname(utilsPath));
|
|
4268
4525
|
actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
|
|
4269
4526
|
} catch (err) {
|
|
4270
4527
|
const code = err.code;
|
|
4271
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;
|
|
4272
4529
|
log(
|
|
4273
|
-
|
|
4530
|
+
chalk10.red(
|
|
4274
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.`
|
|
4275
4532
|
)
|
|
4276
4533
|
);
|
|
4277
|
-
log(
|
|
4534
|
+
log(chalk10.yellow(` ${configStateNote(configState)}`));
|
|
4278
4535
|
process.exitCode = 1;
|
|
4279
4536
|
return;
|
|
4280
4537
|
}
|
|
4281
4538
|
log(
|
|
4282
|
-
|
|
4539
|
+
chalk10.green(
|
|
4283
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)"
|
|
4284
4541
|
)
|
|
4285
4542
|
);
|
|
@@ -4288,9 +4545,9 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4288
4545
|
try {
|
|
4289
4546
|
applyUtilsDependencies(baseDir, plan);
|
|
4290
4547
|
} catch (err) {
|
|
4291
|
-
log(
|
|
4292
|
-
log(
|
|
4293
|
-
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)}`));
|
|
4294
4551
|
process.exitCode = 1;
|
|
4295
4552
|
return;
|
|
4296
4553
|
}
|
|
@@ -4302,19 +4559,19 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
|
4302
4559
|
answers.globalCss,
|
|
4303
4560
|
baseDir
|
|
4304
4561
|
);
|
|
4305
|
-
log(
|
|
4562
|
+
log(chalk10.blue(`
|
|
4306
4563
|
${head}`));
|
|
4307
|
-
for (const line of rest) log(line.startsWith(" !") ?
|
|
4564
|
+
for (const line of rest) log(line.startsWith(" !") ? chalk10.yellow(line) : chalk10.cyan(line));
|
|
4308
4565
|
}
|
|
4309
|
-
log(
|
|
4310
|
-
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}
|
|
4311
4568
|
`));
|
|
4312
4569
|
}
|
|
4313
4570
|
|
|
4314
4571
|
// src/init/index.ts
|
|
4315
4572
|
function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
|
|
4316
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) => {
|
|
4317
|
-
console.log(
|
|
4574
|
+
console.log(chalk11.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
|
|
4318
4575
|
const tailwind4 = isTailwind4(planUtilsDependencies(process.cwd()).tailwind);
|
|
4319
4576
|
const config = options.yes ? { ...INIT_DEFAULTS } : await prompts2([
|
|
4320
4577
|
{
|
|
@@ -4341,27 +4598,27 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
|
|
|
4341
4598
|
}
|
|
4342
4599
|
|
|
4343
4600
|
// src/add/index.ts
|
|
4344
|
-
import
|
|
4601
|
+
import chalk12 from "chalk";
|
|
4345
4602
|
import prompts3 from "prompts";
|
|
4346
4603
|
|
|
4347
|
-
// src/add/add.ts
|
|
4348
|
-
import { existsSync as
|
|
4349
|
-
import
|
|
4350
|
-
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";
|
|
4351
4608
|
|
|
4352
|
-
// src/registry/bundled.ts
|
|
4353
|
-
import { existsSync as
|
|
4354
|
-
import
|
|
4609
|
+
// ../axis-registry-core/src/registry/bundled.ts
|
|
4610
|
+
import { existsSync as existsSync7, readFileSync as readFileSync5 } from "fs";
|
|
4611
|
+
import path16 from "path";
|
|
4355
4612
|
import { fileURLToPath } from "url";
|
|
4356
4613
|
function findBundledRegistryDir(moduleUrl = import.meta.url) {
|
|
4357
|
-
const here =
|
|
4358
|
-
for (const dir of [
|
|
4359
|
-
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;
|
|
4360
4617
|
}
|
|
4361
4618
|
return null;
|
|
4362
4619
|
}
|
|
4363
4620
|
function readBundledJson(dir, fileName) {
|
|
4364
|
-
const file =
|
|
4621
|
+
const file = path16.join(dir, fileName);
|
|
4365
4622
|
let text;
|
|
4366
4623
|
try {
|
|
4367
4624
|
text = readFileSync5(file, "utf8");
|
|
@@ -4371,7 +4628,238 @@ function readBundledJson(dir, fileName) {
|
|
|
4371
4628
|
return parseJsonText(text, `\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC ${fileName}`);
|
|
4372
4629
|
}
|
|
4373
4630
|
|
|
4374
|
-
// 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
|
|
4375
4863
|
var RegistryError = class extends Error {
|
|
4376
4864
|
constructor(code, message) {
|
|
4377
4865
|
super(message);
|
|
@@ -4379,15 +4867,41 @@ var RegistryError = class extends Error {
|
|
|
4379
4867
|
this.name = "RegistryError";
|
|
4380
4868
|
}
|
|
4381
4869
|
};
|
|
4382
|
-
|
|
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) {
|
|
4383
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";
|
|
4384
|
-
return `${lead}
|
|
4873
|
+
return `${lead} ${label}(version ${version})\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. (\uC6D0\uC778: ${reason})`;
|
|
4385
4874
|
}
|
|
4386
4875
|
function fallbackKindOf(error) {
|
|
4387
4876
|
return error instanceof RegistryAccessError ? "access" : "invalid";
|
|
4388
4877
|
}
|
|
4389
|
-
function
|
|
4390
|
-
|
|
4878
|
+
function registryContentDiff(remote, bundled) {
|
|
4879
|
+
const r = new Map(remote.items.map((i) => [i.name, i.sha256]));
|
|
4880
|
+
const b = new Map(bundled.items.map((i) => [i.name, i.sha256]));
|
|
4881
|
+
const differ = [];
|
|
4882
|
+
let comparable = true;
|
|
4883
|
+
for (const name of [.../* @__PURE__ */ new Set([...r.keys(), ...b.keys()])].sort()) {
|
|
4884
|
+
if (!r.has(name) || !b.has(name)) {
|
|
4885
|
+
differ.push(name);
|
|
4886
|
+
continue;
|
|
4887
|
+
}
|
|
4888
|
+
const rs = r.get(name);
|
|
4889
|
+
const bs = b.get(name);
|
|
4890
|
+
if (rs === void 0 || bs === void 0) {
|
|
4891
|
+
comparable = false;
|
|
4892
|
+
continue;
|
|
4893
|
+
}
|
|
4894
|
+
if (rs !== bs) differ.push(name);
|
|
4895
|
+
}
|
|
4896
|
+
return { comparable, differ };
|
|
4897
|
+
}
|
|
4898
|
+
function contentMismatchMessage(remoteVersion, bundledVersion, differ, label = DEFAULT_BUNDLED_LABEL) {
|
|
4899
|
+
const shown = differ.slice(0, 5).join(", ");
|
|
4900
|
+
const more = differ.length > 5 ? ` \uC678 ${differ.length - 5}\uAC1C` : "";
|
|
4901
|
+
return `\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${remoteVersion})\uC640 ${label}(version ${bundledVersion})\uC758 \uB0B4\uC6A9\uC774 \uB2E4\uB978 \uD56D\uBAA9\uC774 ${differ.length}\uAC1C \uC788\uC2B5\uB2C8\uB2E4(${shown}${more}). \uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC6B0\uC120 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.`;
|
|
4902
|
+
}
|
|
4903
|
+
function versionMismatchMessage(remoteVersion, bundledVersion, label = DEFAULT_BUNDLED_LABEL) {
|
|
4904
|
+
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.`;
|
|
4391
4905
|
}
|
|
4392
4906
|
function messageOf(error) {
|
|
4393
4907
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -4399,6 +4913,10 @@ var RegistryClient = class {
|
|
|
4399
4913
|
timeoutMs;
|
|
4400
4914
|
fetchImpl;
|
|
4401
4915
|
notify;
|
|
4916
|
+
bundledLabel;
|
|
4917
|
+
rawUrl;
|
|
4918
|
+
urlSource;
|
|
4919
|
+
rejectRedirects;
|
|
4402
4920
|
mode = null;
|
|
4403
4921
|
indexPromise = null;
|
|
4404
4922
|
bundledIndex = null;
|
|
@@ -4421,6 +4939,15 @@ var RegistryClient = class {
|
|
|
4421
4939
|
this.timeoutMs = options.timeoutMs ?? DEFAULT_REGISTRY_TIMEOUT_MS;
|
|
4422
4940
|
this.fetchImpl = options.fetchImpl;
|
|
4423
4941
|
this.notify = options.notify ?? ((message) => console.warn(message));
|
|
4942
|
+
this.bundledLabel = options.bundledLabel ?? DEFAULT_BUNDLED_LABEL;
|
|
4943
|
+
this.rawUrl = options.url;
|
|
4944
|
+
this.urlSource = options.urlSource;
|
|
4945
|
+
this.rejectRedirects = options.rejectRedirects === true;
|
|
4946
|
+
}
|
|
4947
|
+
/** 원격 주소(가림 적용)와 그 출처. 표시용입니다(WI-0055 D13) */
|
|
4948
|
+
get remote() {
|
|
4949
|
+
const url = this.baseUrl ?? this.rawUrl;
|
|
4950
|
+
return { url: url === null ? null : redactRegistryUrl(url), source: this.urlSource };
|
|
4424
4951
|
}
|
|
4425
4952
|
/** 지금 쓰는 출처. index 를 읽기 전에는 null 입니다 */
|
|
4426
4953
|
get origin() {
|
|
@@ -4464,7 +4991,11 @@ var RegistryClient = class {
|
|
|
4464
4991
|
return bases;
|
|
4465
4992
|
}
|
|
4466
4993
|
fetchOptions() {
|
|
4467
|
-
return {
|
|
4994
|
+
return {
|
|
4995
|
+
timeoutMs: this.timeoutMs,
|
|
4996
|
+
...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {},
|
|
4997
|
+
...this.rejectRedirects ? { rejectRedirects: true } : {}
|
|
4998
|
+
};
|
|
4468
4999
|
}
|
|
4469
5000
|
async loadIndex() {
|
|
4470
5001
|
let remoteError;
|
|
@@ -4474,7 +5005,7 @@ var RegistryClient = class {
|
|
|
4474
5005
|
const data = await fetchRegistryJson(`${this.baseUrl}/index.json`, this.fetchOptions());
|
|
4475
5006
|
const index = validateRegistryIndex(data, `${this.baseUrl}/index.json`);
|
|
4476
5007
|
this.mode = "remote";
|
|
4477
|
-
this.warnVersionMismatch(index
|
|
5008
|
+
this.warnVersionMismatch(index);
|
|
4478
5009
|
return index;
|
|
4479
5010
|
} catch (error) {
|
|
4480
5011
|
remoteError = messageOf(error);
|
|
@@ -4488,7 +5019,7 @@ var RegistryClient = class {
|
|
|
4488
5019
|
/** 동봉본 index 를 읽습니다(성공하면 한 번만). 실패하면 이유를 돌려줍니다 */
|
|
4489
5020
|
loadBundledIndex() {
|
|
4490
5021
|
if (this.bundledIndex) return { index: this.bundledIndex };
|
|
4491
|
-
if (!this.bundledDir) return { error:
|
|
5022
|
+
if (!this.bundledDir) return { error: `${this.bundledLabel}\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4` };
|
|
4492
5023
|
try {
|
|
4493
5024
|
this.bundledIndex = validateRegistryIndex(readBundledJson(this.bundledDir, "index.json"), "\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC index.json");
|
|
4494
5025
|
return { index: this.bundledIndex };
|
|
@@ -4496,10 +5027,18 @@ var RegistryClient = class {
|
|
|
4496
5027
|
return { error: messageOf(error) };
|
|
4497
5028
|
}
|
|
4498
5029
|
}
|
|
4499
|
-
warnVersionMismatch(
|
|
5030
|
+
warnVersionMismatch(remote) {
|
|
4500
5031
|
const bundled = this.loadBundledIndex();
|
|
4501
|
-
if ("index" in bundled
|
|
4502
|
-
|
|
5032
|
+
if (!("index" in bundled)) return;
|
|
5033
|
+
const diff = registryContentDiff(remote, bundled.index);
|
|
5034
|
+
if (diff.comparable) {
|
|
5035
|
+
if (diff.differ.length > 0) {
|
|
5036
|
+
this.notify(contentMismatchMessage(remote.version, bundled.index.version, diff.differ, this.bundledLabel));
|
|
5037
|
+
}
|
|
5038
|
+
return;
|
|
5039
|
+
}
|
|
5040
|
+
if (bundled.index.version !== remote.version) {
|
|
5041
|
+
this.notify(versionMismatchMessage(remote.version, bundled.index.version, this.bundledLabel));
|
|
4503
5042
|
}
|
|
4504
5043
|
}
|
|
4505
5044
|
async switchToBundled(reason, kind = "access") {
|
|
@@ -4514,7 +5053,7 @@ var RegistryClient = class {
|
|
|
4514
5053
|
this.indexPromise = Promise.resolve(bundled.index);
|
|
4515
5054
|
if (!this.fallbackAnnounced) {
|
|
4516
5055
|
this.fallbackAnnounced = true;
|
|
4517
|
-
this.notify(bundledFallbackMessage(bundled.index.version, reason, kind));
|
|
5056
|
+
this.notify(bundledFallbackMessage(bundled.index.version, reason, kind, this.bundledLabel));
|
|
4518
5057
|
}
|
|
4519
5058
|
return bundled.index;
|
|
4520
5059
|
}
|
|
@@ -4524,7 +5063,7 @@ var RegistryClient = class {
|
|
|
4524
5063
|
if (!index || !entry || !this.bundledDir) {
|
|
4525
5064
|
throw new RegistryError(
|
|
4526
5065
|
"not-found",
|
|
4527
|
-
`'${name}' \uD56D\uBAA9\uC774
|
|
5066
|
+
`'${name}' \uD56D\uBAA9\uC774 ${this.bundledLabel}(version ${index?.version ?? "\uC54C \uC218 \uC5C6\uC74C"})\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
4528
5067
|
);
|
|
4529
5068
|
}
|
|
4530
5069
|
try {
|
|
@@ -4532,18 +5071,23 @@ var RegistryClient = class {
|
|
|
4532
5071
|
checkItemSha256(item, entry);
|
|
4533
5072
|
return item;
|
|
4534
5073
|
} catch (error) {
|
|
4535
|
-
throw new RegistryError("unavailable",
|
|
5074
|
+
throw new RegistryError("unavailable", `${this.bundledLabel}\uC758 '${name}' \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${messageOf(error)}`);
|
|
4536
5075
|
}
|
|
4537
5076
|
}
|
|
4538
5077
|
};
|
|
4539
5078
|
|
|
4540
|
-
// src/add/add.ts
|
|
5079
|
+
// ../axis-registry-core/src/add/add.ts
|
|
4541
5080
|
var AGENTIC_PREFIX = "agentic-";
|
|
5081
|
+
var CLI_ADD_HINTS = {
|
|
5082
|
+
listCommand: "npx @axis-ds/cli list",
|
|
5083
|
+
overwrite: "--overwrite",
|
|
5084
|
+
agenticFlag: true
|
|
5085
|
+
};
|
|
4542
5086
|
function applyAgenticAlias(name, agentic) {
|
|
4543
5087
|
if (!agentic || name.startsWith(AGENTIC_PREFIX)) return name;
|
|
4544
5088
|
return `${AGENTIC_PREFIX}${name}`;
|
|
4545
5089
|
}
|
|
4546
|
-
function describeMissingName(requested, resolved, index, agentic) {
|
|
5090
|
+
function describeMissingName(requested, resolved, index, agentic, agenticFlag = true) {
|
|
4547
5091
|
const names = new Set(index.items.map((it) => it.name));
|
|
4548
5092
|
if (!isValidRegistryName(resolved)) {
|
|
4549
5093
|
return `'${requested}': \uC774\uB984 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
@@ -4552,6 +5096,9 @@ function describeMissingName(requested, resolved, index, agentic) {
|
|
|
4552
5096
|
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`;
|
|
4553
5097
|
}
|
|
4554
5098
|
if (!agentic && names.has(`${AGENTIC_PREFIX}${requested}`)) {
|
|
5099
|
+
if (!agenticFlag) {
|
|
5100
|
+
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`;
|
|
5101
|
+
}
|
|
4555
5102
|
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`;
|
|
4556
5103
|
}
|
|
4557
5104
|
return `'${requested}': \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`;
|
|
@@ -4566,10 +5113,10 @@ function layoutFromConfig(root, config) {
|
|
|
4566
5113
|
throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
|
|
4567
5114
|
}
|
|
4568
5115
|
const componentsDir = componentsRaw.replace(/\\/g, "/");
|
|
4569
|
-
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") :
|
|
4570
|
-
return { root:
|
|
5116
|
+
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path17.posix.join(path17.posix.dirname(componentsDir), "agentic");
|
|
5117
|
+
return { root: path17.resolve(root), componentsDir, agenticDir };
|
|
4571
5118
|
}
|
|
4572
|
-
function toPosix(p, impl =
|
|
5119
|
+
function toPosix(p, impl = path17) {
|
|
4573
5120
|
return p.split(impl.sep).join("/");
|
|
4574
5121
|
}
|
|
4575
5122
|
function itemKind(item) {
|
|
@@ -4591,12 +5138,12 @@ function placeFile(layout, item, filePath, target) {
|
|
|
4591
5138
|
const problem = registryPathProblem(p);
|
|
4592
5139
|
if (problem) throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(p)}, ${problem})`);
|
|
4593
5140
|
}
|
|
4594
|
-
const base =
|
|
5141
|
+
const base = path17.posix.basename(filePath);
|
|
4595
5142
|
if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
|
|
4596
5143
|
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)`);
|
|
4597
5144
|
}
|
|
4598
5145
|
const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
|
|
4599
|
-
return
|
|
5146
|
+
return path17.resolve(layout.root, dir, base);
|
|
4600
5147
|
}
|
|
4601
5148
|
function stripExt(p) {
|
|
4602
5149
|
return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
|
|
@@ -4607,7 +5154,7 @@ function buildImportTargets(entries) {
|
|
|
4607
5154
|
for (const { item, file, target } of entries) {
|
|
4608
5155
|
const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
|
|
4609
5156
|
exact.set(`@/${rel3}`, target);
|
|
4610
|
-
if (itemKind(item) === "lib") lib.set(
|
|
5157
|
+
if (itemKind(item) === "lib") lib.set(path17.posix.basename(rel3), target);
|
|
4611
5158
|
}
|
|
4612
5159
|
return { exact, lib };
|
|
4613
5160
|
}
|
|
@@ -4683,7 +5230,7 @@ function insideRanges(ranges, at) {
|
|
|
4683
5230
|
}
|
|
4684
5231
|
var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
|
|
4685
5232
|
var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
|
|
4686
|
-
function relativeSpecifier(fromFile, toFile, impl =
|
|
5233
|
+
function relativeSpecifier(fromFile, toFile, impl = path17) {
|
|
4687
5234
|
let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
|
|
4688
5235
|
if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
|
|
4689
5236
|
return rel3;
|
|
@@ -4711,7 +5258,7 @@ function rewriteImports(content, fileTarget, targets) {
|
|
|
4711
5258
|
}
|
|
4712
5259
|
var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
|
|
4713
5260
|
function relativeSpecifierResolves(fromFile, spec) {
|
|
4714
|
-
const base =
|
|
5261
|
+
const base = path17.resolve(path17.dirname(fromFile), spec);
|
|
4715
5262
|
return RESOLVE_EXTS.some((ext) => {
|
|
4716
5263
|
try {
|
|
4717
5264
|
return statSync4(base + ext).isFile();
|
|
@@ -4763,7 +5310,7 @@ function planFiles(layout, items) {
|
|
|
4763
5310
|
}
|
|
4764
5311
|
const prev = byTarget.get(target);
|
|
4765
5312
|
if (prev !== void 0) {
|
|
4766
|
-
errors.push(`${item.name}: ${toPosix(
|
|
5313
|
+
errors.push(`${item.name}: ${toPosix(path17.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
|
|
4767
5314
|
continue;
|
|
4768
5315
|
}
|
|
4769
5316
|
byTarget.set(target, item.name);
|
|
@@ -4789,7 +5336,7 @@ function missingDependencies(root, items) {
|
|
|
4789
5336
|
const installCommand = detectInstallCommand(root);
|
|
4790
5337
|
let pkg;
|
|
4791
5338
|
try {
|
|
4792
|
-
const text = readFileSync6(
|
|
5339
|
+
const text = readFileSync6(path17.join(root, "package.json"), "utf8").replace(/^/, "");
|
|
4793
5340
|
const parsed = JSON.parse(text);
|
|
4794
5341
|
pkg = isPlainObject2(parsed) ? parsed : void 0;
|
|
4795
5342
|
} catch {
|
|
@@ -4821,15 +5368,16 @@ function addCommandForSpecs(installCommand, specs) {
|
|
|
4821
5368
|
return `pnpm add ${args}`;
|
|
4822
5369
|
}
|
|
4823
5370
|
function rel2(root, p) {
|
|
4824
|
-
return toPosix(
|
|
5371
|
+
return toPosix(path17.relative(root, p));
|
|
4825
5372
|
}
|
|
4826
5373
|
async function runAdd(cwd, requested, options, ctx) {
|
|
4827
5374
|
const log = ctx.log ?? console.log;
|
|
4828
5375
|
const error = ctx.error ?? console.error;
|
|
4829
|
-
const
|
|
5376
|
+
const hints = { ...CLI_ADD_HINTS, ...ctx.hints };
|
|
5377
|
+
const root = path17.resolve(cwd);
|
|
4830
5378
|
const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
|
|
4831
5379
|
if (requested.length === 0) {
|
|
4832
|
-
error(
|
|
5380
|
+
error(`\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: ${hints.listCommand}`);
|
|
4833
5381
|
return result;
|
|
4834
5382
|
}
|
|
4835
5383
|
let config;
|
|
@@ -4839,6 +5387,11 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4839
5387
|
error(`axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`);
|
|
4840
5388
|
return result;
|
|
4841
5389
|
}
|
|
5390
|
+
if (!config && ctx.fallbackConfig) {
|
|
5391
|
+
config = ctx.fallbackConfig;
|
|
5392
|
+
result.usedFallbackConfig = true;
|
|
5393
|
+
log(`axis.config.json \uC774 \uC5C6\uC5B4 \uAE30\uBCF8 \uBC30\uCE58(componentsDir ${config.componentsDir ?? "(\uC5C6\uC74C)"})\uB85C \uC124\uCE58\uD569\uB2C8\uB2E4`);
|
|
5394
|
+
}
|
|
4842
5395
|
if (!config) {
|
|
4843
5396
|
error(
|
|
4844
5397
|
`axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
@@ -4866,13 +5419,13 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4866
5419
|
const missing = [];
|
|
4867
5420
|
for (const req of requested) {
|
|
4868
5421
|
const name = applyAgenticAlias(req, options.agentic);
|
|
4869
|
-
if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic));
|
|
5422
|
+
if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic, hints.agenticFlag));
|
|
4870
5423
|
else if (!resolved.includes(name)) resolved.push(name);
|
|
4871
5424
|
}
|
|
4872
5425
|
if (missing.length > 0) {
|
|
4873
5426
|
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}).`);
|
|
4874
5427
|
for (const m of missing) error(` - ${m}`);
|
|
4875
|
-
error(
|
|
5428
|
+
error(` \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: ${hints.listCommand}`);
|
|
4876
5429
|
return result;
|
|
4877
5430
|
}
|
|
4878
5431
|
let items;
|
|
@@ -4884,6 +5437,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4884
5437
|
return result;
|
|
4885
5438
|
}
|
|
4886
5439
|
items = collected.items;
|
|
5440
|
+
result.items = items.map((it) => it.name);
|
|
4887
5441
|
} catch (e) {
|
|
4888
5442
|
const msg = e instanceof RegistryError ? e.message : `\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`;
|
|
4889
5443
|
error(msg);
|
|
@@ -4898,7 +5452,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4898
5452
|
const existing = /* @__PURE__ */ new Map();
|
|
4899
5453
|
const readErrors = [];
|
|
4900
5454
|
for (const file of plan.files) {
|
|
4901
|
-
if (!
|
|
5455
|
+
if (!existsSync8(file.target)) {
|
|
4902
5456
|
existing.set(file, null);
|
|
4903
5457
|
continue;
|
|
4904
5458
|
}
|
|
@@ -4977,7 +5531,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
4977
5531
|
try {
|
|
4978
5532
|
const before = escapeReason(root, d.file.target);
|
|
4979
5533
|
if (before) return stopWriting(p, before);
|
|
4980
|
-
await
|
|
5534
|
+
await fs13.ensureDir(path17.dirname(d.file.target));
|
|
4981
5535
|
const after = checkParentInside(root, d.file.target);
|
|
4982
5536
|
if (after) return stopWriting(p, after);
|
|
4983
5537
|
actual = await writeNoFollow(d.file.target, d.file.content, actual);
|
|
@@ -5033,7 +5587,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
5033
5587
|
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)`);
|
|
5034
5588
|
}
|
|
5035
5589
|
if (result.skipped.length > 0) {
|
|
5036
|
-
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
|
|
5590
|
+
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}):`);
|
|
5037
5591
|
for (const p of result.skipped) log(outsideRel.has(p) ? ` - ${p} (\uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` - ${p}`);
|
|
5038
5592
|
}
|
|
5039
5593
|
if (broken.length > 0) {
|
|
@@ -5043,8 +5597,9 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
5043
5597
|
}
|
|
5044
5598
|
const deps = missingDependencies(root, items);
|
|
5045
5599
|
if (Object.keys(deps.specs).length > 0) {
|
|
5600
|
+
result.dependencyCommand = addCommandForSpecs(deps.installCommand, deps.specs);
|
|
5046
5601
|
log("\npackage.json \uC5D0 \uC5C6\uB294 \uC758\uC874\uC131(\uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4):");
|
|
5047
|
-
log(` ${
|
|
5602
|
+
log(` ${result.dependencyCommand}`);
|
|
5048
5603
|
}
|
|
5049
5604
|
return { ...result, exitCode: 0 };
|
|
5050
5605
|
}
|
|
@@ -5059,17 +5614,50 @@ function groupIndex(index) {
|
|
|
5059
5614
|
}
|
|
5060
5615
|
return { ui, agentic };
|
|
5061
5616
|
}
|
|
5062
|
-
async function createClientFor(cwd, notify, env = process.env) {
|
|
5617
|
+
async function createClientFor(cwd, notify, env = process.env, clientOptions = {}) {
|
|
5618
|
+
const { guardConfigRegistry, ...options } = clientOptions;
|
|
5063
5619
|
let config = null;
|
|
5064
5620
|
try {
|
|
5065
|
-
config = await readAxisConfig(
|
|
5621
|
+
config = await readAxisConfig(path17.resolve(cwd));
|
|
5066
5622
|
} catch {
|
|
5067
5623
|
config = null;
|
|
5068
5624
|
}
|
|
5069
|
-
|
|
5625
|
+
let resolved = resolveRegistryUrl({ config, env });
|
|
5070
5626
|
const say = notify ?? ((message) => console.warn(message));
|
|
5071
5627
|
if (resolved.migratedFrom !== void 0) say(LEGACY_REGISTRY_NOTICE);
|
|
5072
|
-
|
|
5628
|
+
let rejectRedirects = false;
|
|
5629
|
+
if (guardConfigRegistry && resolved.source === "config" && resolved.migratedFrom === void 0 && !isDefaultRegistry(resolved.url)) {
|
|
5630
|
+
const problem = await publicRegistryUrlProblem(resolved.url, guardConfigRegistry.lookup);
|
|
5631
|
+
if (problem !== null) {
|
|
5632
|
+
say(configRegistryRejectedMessage(resolved.url, problem));
|
|
5633
|
+
resolved = { url: DEFAULT_REGISTRY_URL, source: "default" };
|
|
5634
|
+
} else {
|
|
5635
|
+
rejectRedirects = true;
|
|
5636
|
+
if (!options.fetchImpl) {
|
|
5637
|
+
options.fetchImpl = createPinnedFetch({
|
|
5638
|
+
...guardConfigRegistry.lookup ? { lookupAll: guardConfigRegistry.lookup } : {},
|
|
5639
|
+
...guardConfigRegistry.connect
|
|
5640
|
+
});
|
|
5641
|
+
}
|
|
5642
|
+
}
|
|
5643
|
+
}
|
|
5644
|
+
return new RegistryClient({
|
|
5645
|
+
...options,
|
|
5646
|
+
url: resolved.url,
|
|
5647
|
+
urlSource: resolved.source,
|
|
5648
|
+
...rejectRedirects ? { rejectRedirects: true } : {},
|
|
5649
|
+
...notify ? { notify } : {}
|
|
5650
|
+
});
|
|
5651
|
+
}
|
|
5652
|
+
function isDefaultRegistry(url) {
|
|
5653
|
+
try {
|
|
5654
|
+
return normalizeRegistryBaseUrl(url.trim()) === DEFAULT_REGISTRY_URL;
|
|
5655
|
+
} catch {
|
|
5656
|
+
return false;
|
|
5657
|
+
}
|
|
5658
|
+
}
|
|
5659
|
+
function configRegistryRejectedMessage(url, problem) {
|
|
5660
|
+
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`;
|
|
5073
5661
|
}
|
|
5074
5662
|
|
|
5075
5663
|
// src/add/index.ts
|
|
@@ -5080,7 +5668,7 @@ function createConfirm(interactive) {
|
|
|
5080
5668
|
return overwrite === true;
|
|
5081
5669
|
};
|
|
5082
5670
|
}
|
|
5083
|
-
var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(
|
|
5671
|
+
var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk12.yellow(m)));
|
|
5084
5672
|
function registerAddCommand(program2, deps = {}) {
|
|
5085
5673
|
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) => {
|
|
5086
5674
|
const client = await (deps.createClient ?? defaultCreateClient)(process.cwd());
|
|
@@ -5088,7 +5676,7 @@ function registerAddCommand(program2, deps = {}) {
|
|
|
5088
5676
|
const result = await runAdd(process.cwd(), components, options, {
|
|
5089
5677
|
client,
|
|
5090
5678
|
log: (...a) => console.log(...a),
|
|
5091
|
-
error: (...a) => console.error(
|
|
5679
|
+
error: (...a) => console.error(chalk12.red(a.map(String).join(" "))),
|
|
5092
5680
|
...confirm ? { confirm } : {}
|
|
5093
5681
|
});
|
|
5094
5682
|
process.exitCode = result.exitCode;
|
|
@@ -5097,7 +5685,7 @@ function registerAddCommand(program2, deps = {}) {
|
|
|
5097
5685
|
function registerListCommand(program2, deps = {}) {
|
|
5098
5686
|
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) => {
|
|
5099
5687
|
if (options.category !== void 0 && options.category !== "ui" && options.category !== "agentic") {
|
|
5100
|
-
console.error(
|
|
5688
|
+
console.error(chalk12.red(`--category \uB294 ui \uB610\uB294 agentic \uC785\uB2C8\uB2E4(\uBC1B\uC740 \uAC12: ${options.category})`));
|
|
5101
5689
|
process.exitCode = 1;
|
|
5102
5690
|
return;
|
|
5103
5691
|
}
|
|
@@ -5109,26 +5697,26 @@ function registerListCommand(program2, deps = {}) {
|
|
|
5109
5697
|
groups = groupIndex(index);
|
|
5110
5698
|
version = index.version;
|
|
5111
5699
|
} catch (e) {
|
|
5112
|
-
console.error(
|
|
5700
|
+
console.error(chalk12.red(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`));
|
|
5113
5701
|
process.exitCode = 1;
|
|
5114
5702
|
return;
|
|
5115
5703
|
}
|
|
5116
5704
|
const total = groups.ui.length + groups.agentic.length;
|
|
5117
5705
|
const origin = client.origin === "bundled" ? "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC" : "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC";
|
|
5118
|
-
console.log(
|
|
5706
|
+
console.log(chalk12.blue(`
|
|
5119
5707
|
\u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8 ${total}\uAC1C (${origin}, version ${version})
|
|
5120
5708
|
`));
|
|
5121
5709
|
const show = (label, items) => {
|
|
5122
|
-
console.log(
|
|
5710
|
+
console.log(chalk12.bold(`${label} (${items.length})`));
|
|
5123
5711
|
for (const c of items) {
|
|
5124
|
-
console.log(` ${
|
|
5712
|
+
console.log(` ${chalk12.cyan(c.name.padEnd(32))} ${chalk12.gray(c.description ?? c.title ?? "")}`);
|
|
5125
5713
|
}
|
|
5126
5714
|
console.log();
|
|
5127
5715
|
};
|
|
5128
5716
|
if (!options.category || options.category === "ui") show("Core UI", groups.ui);
|
|
5129
5717
|
if (!options.category || options.category === "agentic") show("Agentic UI", groups.agentic);
|
|
5130
|
-
console.log(
|
|
5131
|
-
console.log(
|
|
5718
|
+
console.log(chalk12.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <\uC774\uB984...> (\uC608: add button input card)"));
|
|
5719
|
+
console.log(chalk12.gray("Agentic: npx @axis-ds/cli add run-progress --agentic (= add agentic-run-progress)\n"));
|
|
5132
5720
|
});
|
|
5133
5721
|
}
|
|
5134
5722
|
|
|
@@ -5157,24 +5745,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
|
|
|
5157
5745
|
await client.importFromClipboard();
|
|
5158
5746
|
});
|
|
5159
5747
|
monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
|
|
5160
|
-
console.log(
|
|
5161
|
-
console.log(
|
|
5162
|
-
console.log(
|
|
5163
|
-
console.log(
|
|
5164
|
-
console.log(
|
|
5165
|
-
console.log(
|
|
5166
|
-
console.log(
|
|
5167
|
-
console.log(
|
|
5748
|
+
console.log(chalk13.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
|
|
5749
|
+
console.log(chalk13.bold("1. API \uD0A4 \uBC1C\uAE09:"));
|
|
5750
|
+
console.log(chalk13.cyan(" https://monet.design/mcp\n"));
|
|
5751
|
+
console.log(chalk13.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
|
|
5752
|
+
console.log(chalk13.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
|
|
5753
|
+
console.log(chalk13.cyan(" MONET_API_KEY=your-api-key-here\n"));
|
|
5754
|
+
console.log(chalk13.bold("3. Claude Code MCP \uC124\uC815:"));
|
|
5755
|
+
console.log(chalk13.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
|
|
5168
5756
|
console.log(
|
|
5169
|
-
|
|
5757
|
+
chalk13.cyan(` "monet": {
|
|
5170
5758
|
"url": "https://www.monet.design/api/remote/mcp",
|
|
5171
5759
|
"headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
|
|
5172
5760
|
"disabled": false
|
|
5173
5761
|
}
|
|
5174
5762
|
`)
|
|
5175
5763
|
);
|
|
5176
|
-
console.log(
|
|
5177
|
-
console.log(
|
|
5764
|
+
console.log(chalk13.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
|
|
5765
|
+
console.log(chalk13.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
|
|
5178
5766
|
});
|
|
5179
5767
|
var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
|
|
5180
5768
|
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) => {
|
|
@@ -5211,18 +5799,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
|
|
|
5211
5799
|
total += result.collected;
|
|
5212
5800
|
failed += result.failed;
|
|
5213
5801
|
}
|
|
5214
|
-
console.log(
|
|
5802
|
+
console.log(chalk13.blue(`
|
|
5215
5803
|
\u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
|
|
5216
5804
|
if (failed > 0) {
|
|
5217
|
-
console.log(
|
|
5805
|
+
console.log(chalk13.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
|
|
5218
5806
|
}
|
|
5219
5807
|
});
|
|
5220
5808
|
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) => {
|
|
5221
5809
|
const curator = new LibraryCurator();
|
|
5222
5810
|
const index = await curator.loadIndex();
|
|
5223
5811
|
if (!index) {
|
|
5224
|
-
console.log(
|
|
5225
|
-
console.log(
|
|
5812
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
5813
|
+
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"));
|
|
5226
5814
|
return;
|
|
5227
5815
|
}
|
|
5228
5816
|
let components = index.components;
|
|
@@ -5232,7 +5820,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
5232
5820
|
if (options.source) {
|
|
5233
5821
|
components = components.filter((c) => c.source.type === options.source);
|
|
5234
5822
|
}
|
|
5235
|
-
console.log(
|
|
5823
|
+
console.log(chalk13.blue(`
|
|
5236
5824
|
\u{1F4E6} Library Components (${components.length}\uAC1C)
|
|
5237
5825
|
`));
|
|
5238
5826
|
const byCategory = /* @__PURE__ */ new Map();
|
|
@@ -5244,14 +5832,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
5244
5832
|
byCategory.get(cat).push(comp);
|
|
5245
5833
|
}
|
|
5246
5834
|
for (const [category, items] of byCategory) {
|
|
5247
|
-
console.log(
|
|
5835
|
+
console.log(chalk13.bold(`${category} (${items.length})`));
|
|
5248
5836
|
for (const item of items.slice(0, 10)) {
|
|
5249
5837
|
console.log(
|
|
5250
|
-
` ${
|
|
5838
|
+
` ${chalk13.cyan(item.name.padEnd(25))} ${chalk13.gray(item.source.type.padEnd(8))} ${chalk13.gray(item.description.slice(0, 40))}`
|
|
5251
5839
|
);
|
|
5252
5840
|
}
|
|
5253
5841
|
if (items.length > 10) {
|
|
5254
|
-
console.log(
|
|
5842
|
+
console.log(chalk13.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
|
|
5255
5843
|
}
|
|
5256
5844
|
console.log();
|
|
5257
5845
|
}
|
|
@@ -5263,21 +5851,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
|
|
|
5263
5851
|
source: options.source
|
|
5264
5852
|
});
|
|
5265
5853
|
if (results.length === 0) {
|
|
5266
|
-
console.log(
|
|
5854
|
+
console.log(chalk13.yellow(`
|
|
5267
5855
|
'${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
5268
5856
|
`));
|
|
5269
5857
|
return;
|
|
5270
5858
|
}
|
|
5271
|
-
console.log(
|
|
5859
|
+
console.log(chalk13.blue(`
|
|
5272
5860
|
\u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
|
|
5273
5861
|
`));
|
|
5274
5862
|
for (const comp of results.slice(0, 20)) {
|
|
5275
5863
|
console.log(
|
|
5276
|
-
` ${
|
|
5864
|
+
` ${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))}`
|
|
5277
5865
|
);
|
|
5278
5866
|
}
|
|
5279
5867
|
if (results.length > 20) {
|
|
5280
|
-
console.log(
|
|
5868
|
+
console.log(chalk13.gray(`
|
|
5281
5869
|
... \uC678 ${results.length - 20}\uAC1C`));
|
|
5282
5870
|
}
|
|
5283
5871
|
console.log();
|
|
@@ -5291,12 +5879,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
5291
5879
|
const publisher2 = new Publisher();
|
|
5292
5880
|
const index = await curator.loadIndex();
|
|
5293
5881
|
if (!index) {
|
|
5294
|
-
console.log(
|
|
5295
|
-
console.log(
|
|
5882
|
+
console.log(chalk13.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
5883
|
+
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"));
|
|
5296
5884
|
return;
|
|
5297
5885
|
}
|
|
5298
|
-
console.log(
|
|
5299
|
-
console.log(
|
|
5886
|
+
console.log(chalk13.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
|
|
5887
|
+
console.log(chalk13.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
|
|
5300
5888
|
`));
|
|
5301
5889
|
if (options.clean) {
|
|
5302
5890
|
await publisher2.clean(options.output);
|
|
@@ -5307,21 +5895,22 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
5307
5895
|
generateSearchIndex: true
|
|
5308
5896
|
});
|
|
5309
5897
|
if (result.success) {
|
|
5310
|
-
console.log(
|
|
5898
|
+
console.log(chalk13.green(`
|
|
5311
5899
|
\u2713 \uBC30\uCE58 \uC644\uB8CC`));
|
|
5312
|
-
console.log(
|
|
5313
|
-
console.log(
|
|
5314
|
-
console.log(
|
|
5315
|
-
console.log(
|
|
5900
|
+
console.log(chalk13.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
|
|
5901
|
+
console.log(chalk13.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
|
|
5902
|
+
console.log(chalk13.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
|
|
5903
|
+
console.log(chalk13.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
|
|
5316
5904
|
} else {
|
|
5317
|
-
console.log(
|
|
5905
|
+
console.log(chalk13.red(`
|
|
5318
5906
|
\u2717 \uBC30\uCE58 \uC2E4\uD328`));
|
|
5319
5907
|
for (const error of result.errors) {
|
|
5320
|
-
console.log(
|
|
5908
|
+
console.log(chalk13.red(` - ${error}`));
|
|
5321
5909
|
}
|
|
5322
5910
|
}
|
|
5323
5911
|
console.log();
|
|
5324
5912
|
});
|
|
5913
|
+
registerRefreshAxisCommand(libraryCmd);
|
|
5325
5914
|
registerSyncCommand(program);
|
|
5326
5915
|
registerTemplateCommand(program);
|
|
5327
5916
|
registerCheckCommand(program);
|