@axis-ds/cli 1.4.0 → 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -4
- package/dist/{chunk-3WGMHDZL.js → chunk-NVGENR3K.js} +9 -1
- package/dist/index.js +1544 -254
- package/dist/registry/agentic-a11y-labels.json +16 -0
- package/dist/registry/agentic-agent-avatar.json +19 -0
- package/dist/registry/agentic-approval-card.json +19 -0
- package/dist/registry/agentic-attachment-card.json +19 -0
- package/dist/registry/agentic-code-block.json +18 -0
- package/dist/registry/agentic-context-panel.json +18 -0
- package/dist/registry/agentic-diff-viewer.json +19 -0
- package/dist/registry/agentic-feedback-buttons.json +19 -0
- package/dist/registry/agentic-message-bubble.json +19 -0
- package/dist/registry/agentic-plan-card.json +19 -0
- package/dist/registry/agentic-recovery-banner.json +18 -0
- package/dist/registry/agentic-run-progress.json +19 -0
- package/dist/registry/agentic-source-panel.json +19 -0
- package/dist/registry/agentic-step-timeline.json +19 -0
- package/dist/registry/agentic-streaming-text.json +18 -0
- package/dist/registry/agentic-surface-renderer.json +18 -0
- package/dist/registry/agentic-thinking-indicator.json +18 -0
- package/dist/registry/agentic-token-usage-indicator.json +18 -0
- package/dist/registry/agentic-tool-call-card.json +19 -0
- package/dist/registry/badge.json +20 -0
- package/dist/registry/button.json +21 -0
- package/dist/registry/card.json +18 -0
- package/dist/registry/dialog.json +20 -0
- package/dist/registry/index.json +217 -0
- package/dist/registry/input.json +18 -0
- package/dist/registry/label.json +21 -0
- package/dist/registry/registry.json +218 -0
- package/dist/registry/select.json +20 -0
- package/dist/registry/separator.json +20 -0
- package/dist/registry/tabs.json +20 -0
- package/dist/registry/toast.json +21 -0
- package/dist/registry/utils.json +19 -0
- package/dist/{registry-client-RMES4CL5.js → registry-client-BJ2XYT73.js} +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -9,18 +9,16 @@ import {
|
|
|
9
9
|
registerSyncCommand
|
|
10
10
|
} from "./chunk-QORBOSUA.js";
|
|
11
11
|
import {
|
|
12
|
+
AXIS_QUICK_START_URL,
|
|
13
|
+
AXIS_SITE_URL,
|
|
12
14
|
fetchTemplateDetail,
|
|
13
15
|
fetchTemplateIndex
|
|
14
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-NVGENR3K.js";
|
|
15
17
|
|
|
16
18
|
// src/index.ts
|
|
17
19
|
import { Command } from "commander";
|
|
18
|
-
import
|
|
19
|
-
import ora6 from "ora";
|
|
20
|
-
import fs11 from "fs-extra";
|
|
21
|
-
import path12 from "path";
|
|
20
|
+
import chalk12 from "chalk";
|
|
22
21
|
import { createRequire as createRequire2 } from "module";
|
|
23
|
-
import prompts3 from "prompts";
|
|
24
22
|
|
|
25
23
|
// src/library/base-collector.ts
|
|
26
24
|
import crypto from "crypto";
|
|
@@ -484,11 +482,11 @@ var ShadcnCollector = class extends BaseCollector {
|
|
|
484
482
|
/**
|
|
485
483
|
* 파일 타입 추론
|
|
486
484
|
*/
|
|
487
|
-
getFileType(
|
|
488
|
-
if (
|
|
489
|
-
if (
|
|
490
|
-
if (
|
|
491
|
-
if (
|
|
485
|
+
getFileType(path16) {
|
|
486
|
+
if (path16.includes("hook") || path16.startsWith("use")) return "hook";
|
|
487
|
+
if (path16.includes("util") || path16.includes("lib")) return "util";
|
|
488
|
+
if (path16.endsWith(".css")) return "style";
|
|
489
|
+
if (path16.endsWith(".d.ts") || path16.includes("types")) return "type";
|
|
492
490
|
return "component";
|
|
493
491
|
}
|
|
494
492
|
};
|
|
@@ -1080,7 +1078,7 @@ var AxisCollector = class extends BaseCollector {
|
|
|
1080
1078
|
* 문서 URL 생성
|
|
1081
1079
|
*/
|
|
1082
1080
|
getDocsUrl(slug, category) {
|
|
1083
|
-
const baseUrl =
|
|
1081
|
+
const baseUrl = AXIS_SITE_URL;
|
|
1084
1082
|
const route = category === "agentic" ? "agentic" : "components";
|
|
1085
1083
|
return `${baseUrl}/${route}/${slug}`;
|
|
1086
1084
|
}
|
|
@@ -1505,7 +1503,7 @@ import ora5 from "ora";
|
|
|
1505
1503
|
|
|
1506
1504
|
// src/template/template-apply.ts
|
|
1507
1505
|
import fs7 from "fs-extra";
|
|
1508
|
-
import
|
|
1506
|
+
import path7 from "path";
|
|
1509
1507
|
import chalk4 from "chalk";
|
|
1510
1508
|
import ora3 from "ora";
|
|
1511
1509
|
import prompts from "prompts";
|
|
@@ -1574,12 +1572,14 @@ function deepMerge(target, source) {
|
|
|
1574
1572
|
|
|
1575
1573
|
// src/config/axis-config.ts
|
|
1576
1574
|
import fs6 from "fs-extra";
|
|
1577
|
-
|
|
1575
|
+
import path6 from "path";
|
|
1576
|
+
var AXIS_CONFIG_SCHEMA_URL = `${AXIS_SITE_URL}/schema.json`;
|
|
1578
1577
|
var AXIS_CONFIG_FILE = "axis.config.json";
|
|
1579
1578
|
function createInitConfig(answers, registry) {
|
|
1580
1579
|
return {
|
|
1581
1580
|
$schema: AXIS_CONFIG_SCHEMA_URL,
|
|
1582
1581
|
componentsDir: answers.componentsDir,
|
|
1582
|
+
...answers.agenticDir !== void 0 ? { agenticDir: answers.agenticDir } : {},
|
|
1583
1583
|
...answers.tailwindConfig !== void 0 ? { tailwindConfig: answers.tailwindConfig } : {},
|
|
1584
1584
|
globalCss: answers.globalCss,
|
|
1585
1585
|
registry
|
|
@@ -1594,6 +1594,11 @@ function createTemplateConfig(template) {
|
|
|
1594
1594
|
globalCss: "./globals.css"
|
|
1595
1595
|
};
|
|
1596
1596
|
}
|
|
1597
|
+
async function readAxisConfig(baseDir) {
|
|
1598
|
+
const configPath = path6.join(baseDir, AXIS_CONFIG_FILE);
|
|
1599
|
+
if (!await fs6.pathExists(configPath)) return null;
|
|
1600
|
+
return await fs6.readJSON(configPath);
|
|
1601
|
+
}
|
|
1597
1602
|
|
|
1598
1603
|
// src/template/template-apply.ts
|
|
1599
1604
|
async function applyTemplate(slug, options) {
|
|
@@ -1606,10 +1611,10 @@ async function applyTemplate(slug, options) {
|
|
|
1606
1611
|
spinner.fail(err.message);
|
|
1607
1612
|
process.exit(1);
|
|
1608
1613
|
}
|
|
1609
|
-
const baseDir =
|
|
1614
|
+
const baseDir = path7.resolve(options.dir || ".");
|
|
1610
1615
|
const conflicts = [];
|
|
1611
1616
|
for (const file of detail.files) {
|
|
1612
|
-
const dest =
|
|
1617
|
+
const dest = path7.join(baseDir, file.path);
|
|
1613
1618
|
if (await fs7.pathExists(dest)) {
|
|
1614
1619
|
conflicts.push(file.path);
|
|
1615
1620
|
}
|
|
@@ -1634,7 +1639,7 @@ async function applyTemplate(slug, options) {
|
|
|
1634
1639
|
if (options.dryRun) {
|
|
1635
1640
|
console.log(chalk4.blue("\n[\uBBF8\uB9AC\uBCF4\uAE30] \uC0DD\uC131\uB420 \uD30C\uC77C:"));
|
|
1636
1641
|
for (const file of detail.files) {
|
|
1637
|
-
const dest =
|
|
1642
|
+
const dest = path7.join(baseDir, file.path);
|
|
1638
1643
|
const exists = conflicts.includes(file.path);
|
|
1639
1644
|
const label = exists ? chalk4.yellow("\uB36E\uC5B4\uC4F0\uAE30") : chalk4.green("\uC0DD\uC131");
|
|
1640
1645
|
console.log(` ${label} ${dest}`);
|
|
@@ -1649,8 +1654,8 @@ async function applyTemplate(slug, options) {
|
|
|
1649
1654
|
}
|
|
1650
1655
|
const writeSpinner = ora3("\uD30C\uC77C \uC0DD\uC131 \uC911...").start();
|
|
1651
1656
|
for (const file of detail.files) {
|
|
1652
|
-
const dest =
|
|
1653
|
-
await fs7.ensureDir(
|
|
1657
|
+
const dest = path7.join(baseDir, file.path);
|
|
1658
|
+
await fs7.ensureDir(path7.dirname(dest));
|
|
1654
1659
|
await fs7.writeFile(dest, file.content);
|
|
1655
1660
|
}
|
|
1656
1661
|
writeSpinner.succeed(`${detail.files.length}\uAC1C \uD30C\uC77C \uC0DD\uC131 \uC644\uB8CC`);
|
|
@@ -1679,7 +1684,7 @@ async function applyTemplate(slug, options) {
|
|
|
1679
1684
|
async function initTemplate(slug, options) {
|
|
1680
1685
|
let selectedSlug = slug;
|
|
1681
1686
|
if (!selectedSlug) {
|
|
1682
|
-
const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-
|
|
1687
|
+
const { fetchTemplateIndex: fetchTemplateIndex2 } = await import("./registry-client-BJ2XYT73.js");
|
|
1683
1688
|
const index = await fetchTemplateIndex2();
|
|
1684
1689
|
const { choice } = await prompts({
|
|
1685
1690
|
type: "select",
|
|
@@ -1711,7 +1716,7 @@ async function initTemplate(slug, options) {
|
|
|
1711
1716
|
}
|
|
1712
1717
|
targetDir = dir;
|
|
1713
1718
|
}
|
|
1714
|
-
const resolved =
|
|
1719
|
+
const resolved = path7.resolve(targetDir);
|
|
1715
1720
|
if (await fs7.pathExists(resolved)) {
|
|
1716
1721
|
const entries = await fs7.readdir(resolved);
|
|
1717
1722
|
if (entries.length > 0) {
|
|
@@ -1727,7 +1732,7 @@ async function initTemplate(slug, options) {
|
|
|
1727
1732
|
await fs7.ensureDir(resolved);
|
|
1728
1733
|
}
|
|
1729
1734
|
await applyTemplate(selectedSlug, { dir: targetDir, yes: true });
|
|
1730
|
-
const configPath =
|
|
1735
|
+
const configPath = path7.join(resolved, "axis.config.json");
|
|
1731
1736
|
if (!await fs7.pathExists(configPath)) {
|
|
1732
1737
|
const axisConfig = createTemplateConfig(selectedSlug);
|
|
1733
1738
|
await fs7.writeJSON(configPath, axisConfig, { spaces: 2 });
|
|
@@ -1742,7 +1747,7 @@ async function initTemplate(slug, options) {
|
|
|
1742
1747
|
|
|
1743
1748
|
// src/template/template-diff.ts
|
|
1744
1749
|
import fs8 from "fs-extra";
|
|
1745
|
-
import
|
|
1750
|
+
import path8 from "path";
|
|
1746
1751
|
import chalk5 from "chalk";
|
|
1747
1752
|
import ora4 from "ora";
|
|
1748
1753
|
async function diffTemplate(slug, options) {
|
|
@@ -1755,10 +1760,10 @@ async function diffTemplate(slug, options) {
|
|
|
1755
1760
|
spinner.fail(err.message);
|
|
1756
1761
|
process.exit(1);
|
|
1757
1762
|
}
|
|
1758
|
-
const baseDir =
|
|
1763
|
+
const baseDir = path8.resolve(options.dir || ".");
|
|
1759
1764
|
const entries = [];
|
|
1760
1765
|
for (const file of detail.files) {
|
|
1761
|
-
const localPath =
|
|
1766
|
+
const localPath = path8.join(baseDir, file.path);
|
|
1762
1767
|
if (!await fs8.pathExists(localPath)) {
|
|
1763
1768
|
entries.push({ path: file.path, status: "added" });
|
|
1764
1769
|
continue;
|
|
@@ -1839,12 +1844,12 @@ async function collectLocalFiles(dir, base) {
|
|
|
1839
1844
|
}
|
|
1840
1845
|
for (const entry of entries) {
|
|
1841
1846
|
if (ignore.has(entry.name)) continue;
|
|
1842
|
-
const fullPath =
|
|
1847
|
+
const fullPath = path8.join(dir, entry.name);
|
|
1843
1848
|
if (entry.isDirectory()) {
|
|
1844
1849
|
const nested = await collectLocalFiles(fullPath, root);
|
|
1845
1850
|
results.push(...nested);
|
|
1846
1851
|
} else {
|
|
1847
|
-
results.push(
|
|
1852
|
+
results.push(path8.relative(root, fullPath).replace(/\\/g, "/"));
|
|
1848
1853
|
}
|
|
1849
1854
|
}
|
|
1850
1855
|
return results;
|
|
@@ -1852,7 +1857,7 @@ async function collectLocalFiles(dir, base) {
|
|
|
1852
1857
|
|
|
1853
1858
|
// src/template/template-check.ts
|
|
1854
1859
|
import fs9 from "fs-extra";
|
|
1855
|
-
import
|
|
1860
|
+
import path9 from "path";
|
|
1856
1861
|
import chalk6 from "chalk";
|
|
1857
1862
|
|
|
1858
1863
|
// src/theme/brand-core.ts
|
|
@@ -2520,9 +2525,9 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2520
2525
|
return { name: "tailwind.config", severity: "warn", message: "tailwind.config.ts\uC5D0 AXIS \uD1A0\uD070 \uC124\uC815\uC774 \uC5C6\uC2B5\uB2C8\uB2E4" };
|
|
2521
2526
|
}
|
|
2522
2527
|
for (const file of otherFiles) {
|
|
2523
|
-
const
|
|
2524
|
-
if (existsSync2(
|
|
2525
|
-
if (hasTokensPresetReference(readFileSync2(
|
|
2528
|
+
const path16 = join2(baseDir, file);
|
|
2529
|
+
if (existsSync2(path16)) {
|
|
2530
|
+
if (hasTokensPresetReference(readFileSync2(path16, "utf8"))) {
|
|
2526
2531
|
return { name: "tailwind.config", severity: "pass", message: `${file}${PRESET_PASS_SUFFIX}` };
|
|
2527
2532
|
}
|
|
2528
2533
|
return { name: "tailwind.config", severity: "warn", message: `${file} \uC874\uC7AC (TypeScript \uAD8C\uC7A5)` };
|
|
@@ -2538,7 +2543,7 @@ var SEVERITY_ICON = {
|
|
|
2538
2543
|
fail: chalk6.red("FAIL")
|
|
2539
2544
|
};
|
|
2540
2545
|
async function collectCheckResults(dir) {
|
|
2541
|
-
const baseDir =
|
|
2546
|
+
const baseDir = path9.resolve(dir || ".");
|
|
2542
2547
|
const results = [];
|
|
2543
2548
|
results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
|
|
2544
2549
|
results.push(checkTailwindSetup(baseDir));
|
|
@@ -2583,7 +2588,7 @@ async function runCheck(dir) {
|
|
|
2583
2588
|
return { pass: passCount, warn: warnCount, fail: failCount };
|
|
2584
2589
|
}
|
|
2585
2590
|
async function checkFileExists(baseDir, fileName, label) {
|
|
2586
|
-
const exists = await fs9.pathExists(
|
|
2591
|
+
const exists = await fs9.pathExists(path9.join(baseDir, fileName));
|
|
2587
2592
|
return {
|
|
2588
2593
|
name: label,
|
|
2589
2594
|
severity: exists ? "pass" : "fail",
|
|
@@ -2599,7 +2604,7 @@ async function checkUtils(baseDir) {
|
|
|
2599
2604
|
"utils.ts"
|
|
2600
2605
|
];
|
|
2601
2606
|
for (const candidate of candidates) {
|
|
2602
|
-
const fullPath =
|
|
2607
|
+
const fullPath = path9.join(baseDir, candidate);
|
|
2603
2608
|
if (await fs9.pathExists(fullPath)) {
|
|
2604
2609
|
const content = await fs9.readFile(fullPath, "utf-8");
|
|
2605
2610
|
const hasCn = content.includes("function cn");
|
|
@@ -2617,7 +2622,7 @@ async function checkUtils(baseDir) {
|
|
|
2617
2622
|
};
|
|
2618
2623
|
}
|
|
2619
2624
|
async function checkDependencies(baseDir) {
|
|
2620
|
-
const pkgPath =
|
|
2625
|
+
const pkgPath = path9.join(baseDir, "package.json");
|
|
2621
2626
|
if (!await fs9.pathExists(pkgPath)) {
|
|
2622
2627
|
return {
|
|
2623
2628
|
name: "package.json",
|
|
@@ -2791,11 +2796,11 @@ function registerCheckCommand(program2) {
|
|
|
2791
2796
|
|
|
2792
2797
|
// src/theme/index.ts
|
|
2793
2798
|
import chalk8 from "chalk";
|
|
2794
|
-
import
|
|
2799
|
+
import path11 from "path";
|
|
2795
2800
|
|
|
2796
2801
|
// src/theme/theme-add.ts
|
|
2797
2802
|
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync3, realpathSync, unlinkSync, writeFileSync } from "fs";
|
|
2798
|
-
import
|
|
2803
|
+
import path10 from "path";
|
|
2799
2804
|
var TOKENS_DEPENDENCY_RANGE = `^${MIN_BRAND_TOKENS_VERSION}`;
|
|
2800
2805
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
2801
2806
|
function readText(file) {
|
|
@@ -2867,17 +2872,17 @@ function compareVersions(a, b) {
|
|
|
2867
2872
|
function realPathInside(baseDir, file) {
|
|
2868
2873
|
const realBase = realpathSync(baseDir);
|
|
2869
2874
|
const realPath = realpathSync(file);
|
|
2870
|
-
const relPath =
|
|
2871
|
-
const inside = relPath !== "" && !relPath.startsWith("..") && !
|
|
2875
|
+
const relPath = path10.relative(realBase, realPath);
|
|
2876
|
+
const inside = relPath !== "" && !relPath.startsWith("..") && !path10.isAbsolute(relPath);
|
|
2872
2877
|
return { inside, realPath };
|
|
2873
2878
|
}
|
|
2874
2879
|
function isStylesheet(realPath) {
|
|
2875
|
-
return
|
|
2880
|
+
return path10.extname(realPath).toLowerCase() === ".css";
|
|
2876
2881
|
}
|
|
2877
2882
|
function detectInstallCommand(baseDir) {
|
|
2878
|
-
if (existsSync3(
|
|
2879
|
-
if (existsSync3(
|
|
2880
|
-
if (existsSync3(
|
|
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";
|
|
2881
2886
|
return "pnpm install";
|
|
2882
2887
|
}
|
|
2883
2888
|
function hasDependency2(pkg, name) {
|
|
@@ -2893,7 +2898,7 @@ function isPlainObject2(value) {
|
|
|
2893
2898
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2894
2899
|
}
|
|
2895
2900
|
function planThemeAdd(baseDirInput, brand) {
|
|
2896
|
-
const baseDir =
|
|
2901
|
+
const baseDir = path10.resolve(baseDirInput);
|
|
2897
2902
|
const plan = {
|
|
2898
2903
|
baseDir,
|
|
2899
2904
|
brand,
|
|
@@ -2905,7 +2910,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2905
2910
|
installCommand: detectInstallCommand(baseDir),
|
|
2906
2911
|
writes: []
|
|
2907
2912
|
};
|
|
2908
|
-
const configFile =
|
|
2913
|
+
const configFile = path10.join(baseDir, AXIS_CONFIG_FILE);
|
|
2909
2914
|
const configText = readText(configFile);
|
|
2910
2915
|
if (configText === null) {
|
|
2911
2916
|
plan.errors.push({ kind: "no-config" });
|
|
@@ -2971,7 +2976,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
2971
2976
|
} else {
|
|
2972
2977
|
plan.css = { configuredMissing: location.configuredMissing, action: "manual", otherBrands: [] };
|
|
2973
2978
|
}
|
|
2974
|
-
const pkgFile =
|
|
2979
|
+
const pkgFile = path10.join(baseDir, "package.json");
|
|
2975
2980
|
const pkgText = readText(pkgFile);
|
|
2976
2981
|
const installed = plan.tokens.version;
|
|
2977
2982
|
const upgrade = installed !== void 0 && (compareVersions(installed, MIN_BRAND_TOKENS_VERSION) ?? 0) < 0;
|
|
@@ -3031,8 +3036,8 @@ function applyThemeAdd(plan) {
|
|
|
3031
3036
|
if (current !== w.before) {
|
|
3032
3037
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
3033
3038
|
}
|
|
3034
|
-
const where = realPathInside(plan.baseDir, w.before === null ?
|
|
3035
|
-
if (!where.inside && !(w.before === null &&
|
|
3039
|
+
const where = realPathInside(plan.baseDir, w.before === null ? path10.dirname(w.file) : w.file);
|
|
3040
|
+
if (!where.inside && !(w.before === null && path10.dirname(w.file) === plan.baseDir)) {
|
|
3036
3041
|
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.`);
|
|
3037
3042
|
}
|
|
3038
3043
|
if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
|
|
@@ -3044,7 +3049,7 @@ function applyThemeAdd(plan) {
|
|
|
3044
3049
|
throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3045
3050
|
}
|
|
3046
3051
|
try {
|
|
3047
|
-
accessSync(w.before === null ?
|
|
3052
|
+
accessSync(w.before === null ? path10.dirname(w.file) : w.file, constants.W_OK);
|
|
3048
3053
|
} catch (err) {
|
|
3049
3054
|
throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
|
|
3050
3055
|
}
|
|
@@ -3195,7 +3200,7 @@ function renderThemeInfo(result, name) {
|
|
|
3195
3200
|
return { lines, exitCode: 0 };
|
|
3196
3201
|
}
|
|
3197
3202
|
function rel(plan, file) {
|
|
3198
|
-
return
|
|
3203
|
+
return path11.relative(plan.baseDir, file) || file;
|
|
3199
3204
|
}
|
|
3200
3205
|
function renderThemeAdd(plan, written) {
|
|
3201
3206
|
const error = plan.errors[0];
|
|
@@ -3345,15 +3350,15 @@ function print(output) {
|
|
|
3345
3350
|
function registerThemeCommand(program2) {
|
|
3346
3351
|
const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
|
|
3347
3352
|
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) => {
|
|
3348
|
-
const baseDir =
|
|
3353
|
+
const baseDir = path11.resolve(options.dir || ".");
|
|
3349
3354
|
print(renderThemeList(listBrands(baseDir)));
|
|
3350
3355
|
});
|
|
3351
3356
|
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) => {
|
|
3352
|
-
const baseDir =
|
|
3357
|
+
const baseDir = path11.resolve(options.dir || ".");
|
|
3353
3358
|
print(renderThemeInfo(getBrand(baseDir, name), name));
|
|
3354
3359
|
});
|
|
3355
3360
|
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) => {
|
|
3356
|
-
const baseDir =
|
|
3361
|
+
const baseDir = path11.resolve(options.dir || ".");
|
|
3357
3362
|
const plan = planThemeAdd(baseDir, name);
|
|
3358
3363
|
let written = [];
|
|
3359
3364
|
if (plan.errors.length === 0) {
|
|
@@ -3372,11 +3377,461 @@ function registerThemeCommand(program2) {
|
|
|
3372
3377
|
import chalk10 from "chalk";
|
|
3373
3378
|
import prompts2 from "prompts";
|
|
3374
3379
|
|
|
3380
|
+
// src/registry/schema.ts
|
|
3381
|
+
import { createHash } from "crypto";
|
|
3382
|
+
var REGISTRY_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
3383
|
+
var REGISTRY_NAME_MAX_LENGTH = 64;
|
|
3384
|
+
function isValidRegistryName(name) {
|
|
3385
|
+
return typeof name === "string" && name.length > 0 && name.length <= REGISTRY_NAME_MAX_LENGTH && REGISTRY_NAME_PATTERN.test(name);
|
|
3386
|
+
}
|
|
3387
|
+
var REGISTRY_PUBLIC_BASE_URL = `${AXIS_SITE_URL}/r`;
|
|
3388
|
+
function redactRegistryUrl(raw) {
|
|
3389
|
+
return maskQueryAndHash(redactUserinfo(raw));
|
|
3390
|
+
}
|
|
3391
|
+
function maskQueryAndHash(value) {
|
|
3392
|
+
const hashAt = value.indexOf("#");
|
|
3393
|
+
let head = hashAt >= 0 ? value.slice(0, hashAt) : value;
|
|
3394
|
+
const queryAt = head.indexOf("?");
|
|
3395
|
+
if (queryAt >= 0) head = `${head.slice(0, queryAt)}?***`;
|
|
3396
|
+
return hashAt >= 0 ? `${head}#***` : head;
|
|
3397
|
+
}
|
|
3398
|
+
function redactUserinfo(raw) {
|
|
3399
|
+
let parsed = null;
|
|
3400
|
+
try {
|
|
3401
|
+
parsed = new URL(raw);
|
|
3402
|
+
} catch {
|
|
3403
|
+
parsed = null;
|
|
3404
|
+
}
|
|
3405
|
+
if (parsed && (parsed.username || parsed.password)) {
|
|
3406
|
+
parsed.username = "";
|
|
3407
|
+
parsed.password = "";
|
|
3408
|
+
const href = parsed.href;
|
|
3409
|
+
const scheme = `${parsed.protocol}//`;
|
|
3410
|
+
return href.startsWith(scheme) ? `${scheme}***@${href.slice(scheme.length)}` : `***@${href}`;
|
|
3411
|
+
}
|
|
3412
|
+
const authPrefix = /^\s*[A-Za-z][A-Za-z0-9+.-]*:[/\\]*/.exec(raw)?.[0] ?? "";
|
|
3413
|
+
const authority = raw.slice(authPrefix.length).split(/[/\\]/)[0];
|
|
3414
|
+
const authorityAt = authority.lastIndexOf("@");
|
|
3415
|
+
if (authPrefix && authorityAt >= 0) return `${authPrefix}***${raw.slice(authPrefix.length + authorityAt)}`;
|
|
3416
|
+
if (parsed && (parsed.protocol === "http:" || parsed.protocol === "https:")) return raw;
|
|
3417
|
+
const at = raw.lastIndexOf("@");
|
|
3418
|
+
if (at < 0) return raw;
|
|
3419
|
+
const prefix = /^\s*[A-Za-z][A-Za-z0-9+.-]*:[/\\]*/.exec(raw)?.[0] ?? "";
|
|
3420
|
+
if (prefix.length > at) return raw;
|
|
3421
|
+
return `${prefix}***${raw.slice(at)}`;
|
|
3422
|
+
}
|
|
3423
|
+
var DEFAULT_DEPENDENCY_BASES = [REGISTRY_PUBLIC_BASE_URL];
|
|
3424
|
+
function trimBase(base) {
|
|
3425
|
+
return base.replace(/\/+$/, "");
|
|
3426
|
+
}
|
|
3427
|
+
function registryDependencyName(dep, allowedBases = DEFAULT_DEPENDENCY_BASES) {
|
|
3428
|
+
if (REGISTRY_NAME_PATTERN.test(dep) && dep.length <= REGISTRY_NAME_MAX_LENGTH) return dep;
|
|
3429
|
+
if (/\s/.test(dep) || dep.includes("?") || dep.includes("#")) return null;
|
|
3430
|
+
let url;
|
|
3431
|
+
try {
|
|
3432
|
+
url = new URL(dep);
|
|
3433
|
+
} catch {
|
|
3434
|
+
return null;
|
|
3435
|
+
}
|
|
3436
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
3437
|
+
if (url.username || url.password || url.search || url.hash) return null;
|
|
3438
|
+
for (const raw of allowedBases) {
|
|
3439
|
+
const prefix = `${trimBase(raw)}/`;
|
|
3440
|
+
if (!dep.startsWith(prefix) || !dep.endsWith(".json")) continue;
|
|
3441
|
+
const name = dep.slice(prefix.length, -".json".length);
|
|
3442
|
+
if (isValidRegistryName(name)) return name;
|
|
3443
|
+
}
|
|
3444
|
+
return null;
|
|
3445
|
+
}
|
|
3446
|
+
function registryDependencyArray(obj, where, allowedBases) {
|
|
3447
|
+
const names = [];
|
|
3448
|
+
for (const dep of stringArray(obj, "registryDependencies", where)) {
|
|
3449
|
+
const name = registryDependencyName(dep, allowedBases);
|
|
3450
|
+
if (name === null) {
|
|
3451
|
+
throw new Error(
|
|
3452
|
+
`${where}: registryDependencies \uC758 ${JSON.stringify(redactRegistryUrl(dep).slice(0, 120))} \uB294 \uD56D\uBAA9 \uC774\uB984\uC774\uB098 <\uB808\uC9C0\uC2A4\uD2B8\uB9AC base>/<\uC774\uB984>.json \uD615\uD0DC\uAC00 \uC544\uB2D9\uB2C8\uB2E4(\uBC1B\uB294 base: ${allowedBases.map(trimBase).join(", ")})`
|
|
3453
|
+
);
|
|
3454
|
+
}
|
|
3455
|
+
if (!names.includes(name)) names.push(name);
|
|
3456
|
+
}
|
|
3457
|
+
return names;
|
|
3458
|
+
}
|
|
3459
|
+
function parseJsonText(text, where) {
|
|
3460
|
+
try {
|
|
3461
|
+
return JSON.parse(text);
|
|
3462
|
+
} catch {
|
|
3463
|
+
const head = text.slice(0, 40).replace(/\s+/g, " ").trim();
|
|
3464
|
+
throw new Error(`${where}: JSON \uC774 \uC544\uB2D9\uB2C8\uB2E4(\uC55E\uBD80\uBD84: ${JSON.stringify(head)})`);
|
|
3465
|
+
}
|
|
3466
|
+
}
|
|
3467
|
+
function isRecord(v) {
|
|
3468
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3469
|
+
}
|
|
3470
|
+
function optionalString(obj, key, where) {
|
|
3471
|
+
const v = obj[key];
|
|
3472
|
+
if (v === void 0) return void 0;
|
|
3473
|
+
if (typeof v !== "string") throw new Error(`${where}: ${key} \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3474
|
+
return v;
|
|
3475
|
+
}
|
|
3476
|
+
function stringArray(obj, key, where) {
|
|
3477
|
+
const v = obj[key];
|
|
3478
|
+
if (v === void 0) return [];
|
|
3479
|
+
if (!Array.isArray(v) || v.some((s) => typeof s !== "string" || s.length === 0)) {
|
|
3480
|
+
throw new Error(`${where}: ${key} \uB294 \uBE44\uC5B4 \uC788\uC9C0 \uC54A\uC740 \uBB38\uC790\uC5F4 \uBC30\uC5F4\uC774\uC5B4\uC57C \uD569\uB2C8\uB2E4`);
|
|
3481
|
+
}
|
|
3482
|
+
return v;
|
|
3483
|
+
}
|
|
3484
|
+
var DEPENDENCY_SPEC_PATTERN = /^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*(?:@[0-9A-Za-z.^~<>=*+| -]+)?$/;
|
|
3485
|
+
function dependencyArray(obj, key, where) {
|
|
3486
|
+
const list = stringArray(obj, key, where);
|
|
3487
|
+
const bad = list.find((s) => s.length > 214 || !DEPENDENCY_SPEC_PATTERN.test(s));
|
|
3488
|
+
if (bad !== void 0) {
|
|
3489
|
+
throw new Error(`${where}: ${key} \uC5D0 \uD328\uD0A4\uC9C0 \uC774\uB984 \uADDC\uCE59\uC5D0 \uB9DE\uC9C0 \uC54A\uB294 \uAC12\uC774 \uC788\uC2B5\uB2C8\uB2E4(${JSON.stringify(bad.slice(0, 60))})`);
|
|
3490
|
+
}
|
|
3491
|
+
return list;
|
|
3492
|
+
}
|
|
3493
|
+
function requireType(obj, where) {
|
|
3494
|
+
const type = obj.type;
|
|
3495
|
+
if (typeof type !== "string" || !type.startsWith("registry:")) {
|
|
3496
|
+
throw new Error(`${where}: type \uC774 registry:* \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3497
|
+
}
|
|
3498
|
+
return type;
|
|
3499
|
+
}
|
|
3500
|
+
function validateRegistryIndex(data, where = "index.json") {
|
|
3501
|
+
if (!isRecord(data)) throw new Error(`${where}: \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3502
|
+
const version = data.version;
|
|
3503
|
+
if (typeof version !== "string" || version.length === 0) {
|
|
3504
|
+
throw new Error(`${where}: version \uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
3505
|
+
}
|
|
3506
|
+
if (!Array.isArray(data.items)) throw new Error(`${where}: items \uAC00 \uBC30\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3507
|
+
const seen = /* @__PURE__ */ new Set();
|
|
3508
|
+
const items = data.items.map((raw, i) => {
|
|
3509
|
+
const at = `${where} items[${i}]`;
|
|
3510
|
+
if (!isRecord(raw)) throw new Error(`${at}: \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3511
|
+
if (!isValidRegistryName(raw.name)) throw new Error(`${at}: name \uC774 slug \uADDC\uCE59\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
|
|
3512
|
+
if (seen.has(raw.name)) throw new Error(`${at}: name '${raw.name}' \uAC00 \uC911\uBCF5\uC785\uB2C8\uB2E4`);
|
|
3513
|
+
seen.add(raw.name);
|
|
3514
|
+
const sha256 = optionalString(raw, "sha256", at);
|
|
3515
|
+
if (sha256 !== void 0 && !/^[0-9a-f]{64}$/.test(sha256)) {
|
|
3516
|
+
throw new Error(`${at}: sha256 \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3517
|
+
}
|
|
3518
|
+
return {
|
|
3519
|
+
name: raw.name,
|
|
3520
|
+
type: requireType(raw, at),
|
|
3521
|
+
title: optionalString(raw, "title", at),
|
|
3522
|
+
description: optionalString(raw, "description", at),
|
|
3523
|
+
...sha256 !== void 0 ? { sha256 } : {}
|
|
3524
|
+
};
|
|
3525
|
+
});
|
|
3526
|
+
return {
|
|
3527
|
+
name: optionalString(data, "name", where),
|
|
3528
|
+
homepage: optionalString(data, "homepage", where),
|
|
3529
|
+
version,
|
|
3530
|
+
items
|
|
3531
|
+
};
|
|
3532
|
+
}
|
|
3533
|
+
function validateRegistryItem(data, expectedName, where = `${expectedName}.json`, dependencyBases = DEFAULT_DEPENDENCY_BASES) {
|
|
3534
|
+
if (!isRecord(data)) throw new Error(`${where}: \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3535
|
+
if (data.name !== expectedName) {
|
|
3536
|
+
throw new Error(`${where}: name \uC774 '${expectedName}' \uAC00 \uC544\uB2D9\uB2C8\uB2E4(${JSON.stringify(data.name)})`);
|
|
3537
|
+
}
|
|
3538
|
+
const type = requireType(data, where);
|
|
3539
|
+
if (!Array.isArray(data.files) || data.files.length === 0) {
|
|
3540
|
+
throw new Error(`${where}: files \uAC00 \uBE44\uC5B4 \uC788\uC2B5\uB2C8\uB2E4`);
|
|
3541
|
+
}
|
|
3542
|
+
const files = data.files.map((raw, i) => {
|
|
3543
|
+
const at = `${where} files[${i}]`;
|
|
3544
|
+
if (!isRecord(raw)) throw new Error(`${at}: \uAC1D\uCCB4\uAC00 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3545
|
+
if (typeof raw.path !== "string" || raw.path.length === 0 || raw.path.includes("\0")) {
|
|
3546
|
+
throw new Error(`${at}: path \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
3547
|
+
}
|
|
3548
|
+
if (typeof raw.content !== "string") throw new Error(`${at}: content \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3549
|
+
const fileType = optionalString(raw, "type", at);
|
|
3550
|
+
const target = optionalString(raw, "target", at);
|
|
3551
|
+
return {
|
|
3552
|
+
path: raw.path,
|
|
3553
|
+
content: raw.content,
|
|
3554
|
+
...fileType !== void 0 ? { type: fileType } : {},
|
|
3555
|
+
...target !== void 0 ? { target } : {}
|
|
3556
|
+
};
|
|
3557
|
+
});
|
|
3558
|
+
return {
|
|
3559
|
+
name: expectedName,
|
|
3560
|
+
type,
|
|
3561
|
+
title: optionalString(data, "title", where),
|
|
3562
|
+
description: optionalString(data, "description", where),
|
|
3563
|
+
dependencies: dependencyArray(data, "dependencies", where),
|
|
3564
|
+
devDependencies: dependencyArray(data, "devDependencies", where),
|
|
3565
|
+
// URL 형태는 이름으로 바꿔 둡니다. 호출한 쪽(add 의 collectItems)은 이름만 봅니다
|
|
3566
|
+
registryDependencies: registryDependencyArray(data, where, dependencyBases),
|
|
3567
|
+
files
|
|
3568
|
+
};
|
|
3569
|
+
}
|
|
3570
|
+
function sha256Hex(text) {
|
|
3571
|
+
return createHash("sha256").update(text, "utf8").digest("hex");
|
|
3572
|
+
}
|
|
3573
|
+
function checkItemSha256(item, entry, where = `${item.name}.json`) {
|
|
3574
|
+
if (entry.sha256 === void 0) return;
|
|
3575
|
+
if (item.files.length !== 1) {
|
|
3576
|
+
throw new Error(`${where}: index.json \uC5D0 sha256 \uC774 \uC788\uB294\uB370 files \uAC00 ${item.files.length}\uAC1C\uB77C sha256 \uC744 \uB300\uC870\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
3577
|
+
}
|
|
3578
|
+
const actual = sha256Hex(item.files[0].content);
|
|
3579
|
+
if (actual !== entry.sha256) {
|
|
3580
|
+
throw new Error(`${where}: content sha256 \uC774 index.json \uACFC \uB2E4\uB985\uB2C8\uB2E4`);
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
|
|
3584
|
+
// src/registry/remote.ts
|
|
3585
|
+
var DEFAULT_REGISTRY_URL = REGISTRY_PUBLIC_BASE_URL;
|
|
3586
|
+
var DEFAULT_REGISTRY_TIMEOUT_MS = 5e3;
|
|
3587
|
+
var LEGACY_DEFAULT_REGISTRY_URL = "https://axis.minu.best/r";
|
|
3588
|
+
var LEGACY_REGISTRY_NOTICE = `axis.config.json \uC758 registry \uAC00 \uC885\uC804 \uAE30\uBCF8 \uC8FC\uC18C(${LEGACY_DEFAULT_REGISTRY_URL})\uB77C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C(${REGISTRY_PUBLIC_BASE_URL})\uB85C \uC870\uD68C\uD574\uC694. axis.config.json \uC758 registry \uB97C \uACE0\uCE58\uBA74 \uC774 \uC548\uB0B4\uAC00 \uC0AC\uB77C\uC838\uC694`;
|
|
3589
|
+
function isLegacyDefaultRegistryUrl(value) {
|
|
3590
|
+
let normalized;
|
|
3591
|
+
try {
|
|
3592
|
+
normalized = normalizeRegistryBaseUrl(value.trim());
|
|
3593
|
+
} catch {
|
|
3594
|
+
return false;
|
|
3595
|
+
}
|
|
3596
|
+
return normalized === LEGACY_DEFAULT_REGISTRY_URL;
|
|
3597
|
+
}
|
|
3598
|
+
function resolveRegistryUrl(options) {
|
|
3599
|
+
const env = options.env ?? process.env;
|
|
3600
|
+
const fromEnv = env.AXIS_REGISTRY_URL?.trim();
|
|
3601
|
+
if (fromEnv) return { url: fromEnv, source: "env" };
|
|
3602
|
+
const fromConfig = typeof options.config?.registry === "string" ? options.config.registry.trim() : "";
|
|
3603
|
+
if (fromConfig) {
|
|
3604
|
+
if (isLegacyDefaultRegistryUrl(fromConfig)) {
|
|
3605
|
+
return { url: DEFAULT_REGISTRY_URL, source: "config", migratedFrom: fromConfig };
|
|
3606
|
+
}
|
|
3607
|
+
return { url: fromConfig, source: "config" };
|
|
3608
|
+
}
|
|
3609
|
+
return { url: DEFAULT_REGISTRY_URL, source: "default" };
|
|
3610
|
+
}
|
|
3611
|
+
function normalizeRegistryBaseUrl(raw) {
|
|
3612
|
+
const shown = redactRegistryUrl(raw);
|
|
3613
|
+
if (/\s/.test(raw)) throw new Error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC5D0 \uACF5\uBC31\uC744 \uB458 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${JSON.stringify(shown)}`);
|
|
3614
|
+
if (raw.includes("?") || raw.includes("#")) throw new Error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC5D0 \uCFFC\uB9AC \xB7 \uD574\uC2DC\uB97C \uB458 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${shown}`);
|
|
3615
|
+
let parsed;
|
|
3616
|
+
try {
|
|
3617
|
+
parsed = new URL(raw);
|
|
3618
|
+
} catch {
|
|
3619
|
+
throw new Error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4: ${shown}`);
|
|
3620
|
+
}
|
|
3621
|
+
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
|
|
3622
|
+
throw new Error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC740 http \xB7 https \uB9CC \uC9C0\uC6D0\uD569\uB2C8\uB2E4: ${shown}`);
|
|
3623
|
+
}
|
|
3624
|
+
if (parsed.username || parsed.password) {
|
|
3625
|
+
throw new Error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC5D0 \uC0AC\uC6A9\uC790 \uC815\uBCF4(userinfo)\uB97C \uB458 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${shown}`);
|
|
3626
|
+
}
|
|
3627
|
+
if (parsed.search || parsed.hash) throw new Error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC5D0 \uCFFC\uB9AC \xB7 \uD574\uC2DC\uB97C \uB458 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4: ${shown}`);
|
|
3628
|
+
return `${parsed.protocol}//${parsed.host}${parsed.pathname.replace(/\/+$/, "")}`;
|
|
3629
|
+
}
|
|
3630
|
+
var RegistryAccessError = class extends Error {
|
|
3631
|
+
constructor(message) {
|
|
3632
|
+
super(message);
|
|
3633
|
+
this.name = "RegistryAccessError";
|
|
3634
|
+
}
|
|
3635
|
+
};
|
|
3636
|
+
async function fetchRegistryJson(url, options = {}) {
|
|
3637
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_REGISTRY_TIMEOUT_MS;
|
|
3638
|
+
const fetchImpl = options.fetchImpl ?? globalThis.fetch;
|
|
3639
|
+
if (!fetchImpl) throw new RegistryAccessError("\uC774 Node \uB7F0\uD0C0\uC784\uC5D0\uB294 fetch \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(Node 18 \uC774\uC0C1 \uD544\uC694)");
|
|
3640
|
+
const shown = redactRegistryUrl(url);
|
|
3641
|
+
const controller = new AbortController();
|
|
3642
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
3643
|
+
const describe = (error) => {
|
|
3644
|
+
if (controller.signal.aborted) return new RegistryAccessError(`${shown}: ${timeoutMs}ms \uC548\uC5D0 \uC751\uB2F5\uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
3645
|
+
const cause = error?.cause;
|
|
3646
|
+
const detail = cause?.code ?? cause?.message ?? (error instanceof Error ? error.message : String(error));
|
|
3647
|
+
return new RegistryAccessError(`${shown}: \uC694\uCCAD \uC2E4\uD328(${detail})`);
|
|
3648
|
+
};
|
|
3649
|
+
let text;
|
|
3650
|
+
try {
|
|
3651
|
+
let res;
|
|
3652
|
+
try {
|
|
3653
|
+
res = await fetchImpl(url, { signal: controller.signal, headers: { accept: "application/json" } });
|
|
3654
|
+
} catch (error) {
|
|
3655
|
+
throw describe(error);
|
|
3656
|
+
}
|
|
3657
|
+
if (!res.ok) {
|
|
3658
|
+
await res.text().catch(() => void 0);
|
|
3659
|
+
throw new RegistryAccessError(`${shown}: HTTP ${res.status}`);
|
|
3660
|
+
}
|
|
3661
|
+
try {
|
|
3662
|
+
text = await res.text();
|
|
3663
|
+
} catch (error) {
|
|
3664
|
+
throw describe(error);
|
|
3665
|
+
}
|
|
3666
|
+
} finally {
|
|
3667
|
+
clearTimeout(timer);
|
|
3668
|
+
}
|
|
3669
|
+
return parseJsonText(text, shown);
|
|
3670
|
+
}
|
|
3671
|
+
|
|
3375
3672
|
// src/init/init.ts
|
|
3376
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as
|
|
3377
|
-
import
|
|
3673
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync5, lstatSync as lstatSync2, readFileSync as readFileSync4, realpathSync as realpathSync3, statSync as statSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
3674
|
+
import path13 from "path";
|
|
3378
3675
|
import chalk9 from "chalk";
|
|
3676
|
+
import fs11 from "fs-extra";
|
|
3677
|
+
|
|
3678
|
+
// src/add/safe-write.ts
|
|
3679
|
+
import { constants as fsConstants, existsSync as existsSync4, lstatSync, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
|
|
3680
|
+
import path12 from "path";
|
|
3379
3681
|
import fs10 from "fs-extra";
|
|
3682
|
+
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
3683
|
+
var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
|
|
3684
|
+
var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
|
|
3685
|
+
var NOT_REGULAR_ERROR_CODE = "EAXISNOTREG";
|
|
3686
|
+
function codedError(code, message) {
|
|
3687
|
+
const e = new Error(message);
|
|
3688
|
+
e.code = code;
|
|
3689
|
+
return e;
|
|
3690
|
+
}
|
|
3691
|
+
function isSameOrInside(parent, child, impl = path12) {
|
|
3692
|
+
const rel3 = impl.relative(parent, child);
|
|
3693
|
+
if (rel3 === "") return true;
|
|
3694
|
+
return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
|
|
3695
|
+
}
|
|
3696
|
+
function nearestExisting(p) {
|
|
3697
|
+
let cur = p;
|
|
3698
|
+
while (!existsSync4(cur)) {
|
|
3699
|
+
const up = path12.dirname(cur);
|
|
3700
|
+
if (up === cur) return cur;
|
|
3701
|
+
cur = up;
|
|
3702
|
+
}
|
|
3703
|
+
return cur;
|
|
3704
|
+
}
|
|
3705
|
+
function escapeReason(root, target, options = {}) {
|
|
3706
|
+
const realRoot = realpathSync2(root);
|
|
3707
|
+
if (!isSameOrInside(path12.resolve(root), path12.resolve(target)) || path12.resolve(target) === path12.resolve(root)) {
|
|
3708
|
+
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
3709
|
+
}
|
|
3710
|
+
const anchor = nearestExisting(path12.dirname(target));
|
|
3711
|
+
const realAnchor = realpathSync2(anchor);
|
|
3712
|
+
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
3713
|
+
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`;
|
|
3714
|
+
}
|
|
3715
|
+
let st = null;
|
|
3716
|
+
try {
|
|
3717
|
+
st = lstatSync(target);
|
|
3718
|
+
} catch {
|
|
3719
|
+
st = null;
|
|
3720
|
+
}
|
|
3721
|
+
if (st) {
|
|
3722
|
+
if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
|
|
3723
|
+
const shown = path12.relative(path12.resolve(root), path12.resolve(target)).split(path12.sep).join("/");
|
|
3724
|
+
let realTarget;
|
|
3725
|
+
try {
|
|
3726
|
+
realTarget = realpathSync2(target);
|
|
3727
|
+
} catch {
|
|
3728
|
+
return `\uAE30\uC874 \uD30C\uC77C ${shown} \uC774 \uAE68\uC9C4 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C \uB530\uB77C\uAC08 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uACE0\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694)`;
|
|
3729
|
+
}
|
|
3730
|
+
if (!isSameOrInside(realRoot, realTarget) && !(options.allowOutsideLink && st.isSymbolicLink())) {
|
|
3731
|
+
return `\uAE30\uC874 \uD30C\uC77C\uC758 \uC2E4\uC81C \uC704\uCE58(${realTarget})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
|
|
3732
|
+
}
|
|
3733
|
+
let followed;
|
|
3734
|
+
try {
|
|
3735
|
+
followed = statSync2(realTarget);
|
|
3736
|
+
} catch {
|
|
3737
|
+
return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
|
|
3738
|
+
}
|
|
3739
|
+
if (followed.isDirectory()) {
|
|
3740
|
+
return `\uAC19\uC740 \uC774\uB984\uC758 \uB9C1\uD06C\uAC00 \uB514\uB809\uD130\uB9AC(${realTarget})\uB97C \uAC00\uB9AC\uD0B5\uB2C8\uB2E4(${target})`;
|
|
3741
|
+
}
|
|
3742
|
+
if (!followed.isFile()) {
|
|
3743
|
+
const where = st.isSymbolicLink() ? `\uB9C1\uD06C \uB300\uC0C1(${realTarget})\uC774` : "\uAE30\uC874 \uD30C\uC77C\uC774";
|
|
3744
|
+
return `${where} \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB77C \uBE44\uAD50 \xB7 \uB36E\uC5B4\uC4F0\uAE30\uB97C \uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${shown})`;
|
|
3745
|
+
}
|
|
3746
|
+
}
|
|
3747
|
+
return null;
|
|
3748
|
+
}
|
|
3749
|
+
function isSymlink(p) {
|
|
3750
|
+
try {
|
|
3751
|
+
return lstatSync(p).isSymbolicLink();
|
|
3752
|
+
} catch {
|
|
3753
|
+
return false;
|
|
3754
|
+
}
|
|
3755
|
+
}
|
|
3756
|
+
function outsideLinkTarget(root, target) {
|
|
3757
|
+
if (!isSymlink(target)) return null;
|
|
3758
|
+
try {
|
|
3759
|
+
const realTarget = realpathSync2(target);
|
|
3760
|
+
return isSameOrInside(realpathSync2(root), realTarget) ? null : realTarget;
|
|
3761
|
+
} catch {
|
|
3762
|
+
return null;
|
|
3763
|
+
}
|
|
3764
|
+
}
|
|
3765
|
+
function hardLinkCount(target) {
|
|
3766
|
+
try {
|
|
3767
|
+
const st = lstatSync(target);
|
|
3768
|
+
return st.isFile() && st.nlink >= 2 ? st.nlink : null;
|
|
3769
|
+
} catch {
|
|
3770
|
+
return null;
|
|
3771
|
+
}
|
|
3772
|
+
}
|
|
3773
|
+
function hardLinkMessage(shownPath, nlink) {
|
|
3774
|
+
return `\uAE30\uC874 \uD30C\uC77C ${shownPath} \uC774 \uB2E4\uB978 \uACBD\uB85C\uC640 \uD558\uB4DC\uB9C1\uD06C\uB85C \uC774\uC5B4\uC9C4 \uD30C\uC77C\uC774\uB77C(\uB9C1\uD06C \uC218 ${nlink}) \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uBA74 \uC774\uC5B4\uC9C4 \uB2E4\uB978 \uACBD\uB85C\uC758 \uB0B4\uC6A9\uB3C4 \uBC14\uB01D\uB2C8\uB2E4. \uD558\uB4DC\uB9C1\uD06C\uB97C \uB04A\uC740(\uD30C\uC77C\uC744 \uBCF5\uC0AC\uD574 \uBC14\uAFBC) \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694`;
|
|
3775
|
+
}
|
|
3776
|
+
function writtenOutside(root, target) {
|
|
3777
|
+
const realRoot = realpathSync2(root);
|
|
3778
|
+
let realTarget;
|
|
3779
|
+
try {
|
|
3780
|
+
realTarget = realpathSync2(target);
|
|
3781
|
+
} catch {
|
|
3782
|
+
return target;
|
|
3783
|
+
}
|
|
3784
|
+
return isSameOrInside(realRoot, realTarget) ? null : realTarget;
|
|
3785
|
+
}
|
|
3786
|
+
async function writeNoFollow(target, content, mode) {
|
|
3787
|
+
let actual = mode;
|
|
3788
|
+
let fd;
|
|
3789
|
+
if (mode === "overwrite") {
|
|
3790
|
+
try {
|
|
3791
|
+
fd = await fs10.open(target, OVERWRITE_FLAGS);
|
|
3792
|
+
} catch (e) {
|
|
3793
|
+
if (e.code !== "ENOENT") throw e;
|
|
3794
|
+
actual = "new";
|
|
3795
|
+
fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
|
|
3796
|
+
}
|
|
3797
|
+
} else {
|
|
3798
|
+
fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
|
|
3799
|
+
}
|
|
3800
|
+
try {
|
|
3801
|
+
if (actual === "overwrite") {
|
|
3802
|
+
const st = await fs10.fstat(fd);
|
|
3803
|
+
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3804
|
+
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
3805
|
+
await fs10.ftruncate(fd, 0);
|
|
3806
|
+
}
|
|
3807
|
+
await fs10.writeFile(fd, content);
|
|
3808
|
+
} finally {
|
|
3809
|
+
await fs10.close(fd);
|
|
3810
|
+
}
|
|
3811
|
+
return actual;
|
|
3812
|
+
}
|
|
3813
|
+
async function overwriteFollowingLinks(target, content) {
|
|
3814
|
+
const fd = await fs10.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
|
|
3815
|
+
try {
|
|
3816
|
+
const st = await fs10.fstat(fd);
|
|
3817
|
+
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
3818
|
+
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
3819
|
+
await fs10.ftruncate(fd, 0);
|
|
3820
|
+
await fs10.writeFile(fd, content);
|
|
3821
|
+
} finally {
|
|
3822
|
+
await fs10.close(fd);
|
|
3823
|
+
}
|
|
3824
|
+
}
|
|
3825
|
+
function checkParentInside(root, target) {
|
|
3826
|
+
const realRoot = realpathSync2(root);
|
|
3827
|
+
const realParent = realpathSync2(path12.dirname(target));
|
|
3828
|
+
if (!isSameOrInside(realRoot, realParent)) {
|
|
3829
|
+
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
|
+
}
|
|
3831
|
+
return escapeReason(root, target);
|
|
3832
|
+
}
|
|
3833
|
+
|
|
3834
|
+
// src/init/init.ts
|
|
3380
3835
|
var CLSX_RANGE = "^2.1.1";
|
|
3381
3836
|
var TAILWIND_MERGE_RANGES = {
|
|
3382
3837
|
tailwind4: "^3.4.0",
|
|
@@ -3411,8 +3866,29 @@ function describeTailwindBasis(tailwind) {
|
|
|
3411
3866
|
return "tailwindcss \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uAE30\uBCF8\uAC12(Tailwind 3)";
|
|
3412
3867
|
}
|
|
3413
3868
|
var UTILS_TS_CONTENT = `import { type ClassValue, clsx } from "clsx";
|
|
3414
|
-
import {
|
|
3869
|
+
import { extendTailwindMerge } from "tailwind-merge";
|
|
3870
|
+
|
|
3871
|
+
/**
|
|
3872
|
+
* \`shadow-[shadow:<CSS \uBCC0\uC218 \uCC38\uC870>]\` \uCC98\uB7FC \`shadow:\` \uD0C0\uC785 \uD78C\uD2B8\uAC00 \uBD99\uC740 \uC784\uC758\uAC12 \uADF8\uB9BC\uC790 \uD074\uB798\uC2A4\uC778\uC9C0 \uD310\uC815
|
|
3873
|
+
*
|
|
3874
|
+
* tailwind-merge \uAE30\uBCF8 \uC124\uC815\uC740 \uC774 \uD074\uB798\uC2A4\uB97C \uADF8\uB9BC\uC790 \uC0C9(shadow-color) \uADF8\uB8F9\uC73C\uB85C \uBD84\uB958\uD574\uC11C
|
|
3875
|
+
* \`cn(\uAE30\uBCF8, "shadow-none")\` \uC774 \uAE30\uBCF8 \uADF8\uB9BC\uC790\uB97C \uC9C0\uC6B0\uC9C0 \uBABB\uD558\uACE0, \`shadow-black/50\` \uC740 \uADF8\uB9BC\uC790\uB97C \uD1B5\uC9F8\uB85C \uC9C0\uC6B4\uB2E4.
|
|
3876
|
+
* \uADF8\uB9BC\uC790(shadow) \uADF8\uB8F9\uC5D0 \uB4F1\uB85D\uD574 \uC885\uC804 \`shadow-sm\` \xB7 \`shadow-lg\` \uC640 \uAC19\uC740 \uBCD1\uD569 \uACB0\uACFC\uB97C \uB0B8\uB2E4(WI-0025 U4).
|
|
3877
|
+
*/
|
|
3878
|
+
const isArbitraryShadowWithHint = (value: string) => /^\\[shadow:.+\\]$/.test(value);
|
|
3415
3879
|
|
|
3880
|
+
const twMerge = extendTailwindMerge({
|
|
3881
|
+
extend: {
|
|
3882
|
+
classGroups: {
|
|
3883
|
+
shadow: [{ shadow: [isArbitraryShadowWithHint] }],
|
|
3884
|
+
},
|
|
3885
|
+
},
|
|
3886
|
+
});
|
|
3887
|
+
|
|
3888
|
+
/**
|
|
3889
|
+
* Tailwind CSS \uD074\uB798\uC2A4\uB97C \uBCD1\uD569\uD558\uB294 \uC720\uD2F8\uB9AC\uD2F0 \uD568\uC218
|
|
3890
|
+
* clsx\uB85C \uC870\uAC74\uBD80 \uD074\uB798\uC2A4\uB97C \uCC98\uB9AC\uD558\uACE0 tailwind-merge\uB85C \uCDA9\uB3CC\uC744 \uD574\uACB0
|
|
3891
|
+
*/
|
|
3416
3892
|
export function cn(...inputs: ClassValue[]) {
|
|
3417
3893
|
return twMerge(clsx(inputs));
|
|
3418
3894
|
}
|
|
@@ -3430,7 +3906,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
|
|
|
3430
3906
|
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.";
|
|
3431
3907
|
function readPackageJsonSafe(baseDir) {
|
|
3432
3908
|
try {
|
|
3433
|
-
const text = readFileSync4(
|
|
3909
|
+
const text = readFileSync4(path13.join(baseDir, "package.json"), "utf8");
|
|
3434
3910
|
const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
|
|
3435
3911
|
return isPlainObject2(parsed) ? parsed : void 0;
|
|
3436
3912
|
} catch {
|
|
@@ -3495,7 +3971,7 @@ function addCommandFor(installCommand, deps) {
|
|
|
3495
3971
|
return `pnpm add ${specs}`;
|
|
3496
3972
|
}
|
|
3497
3973
|
function planUtilsDependencies(baseDirInput) {
|
|
3498
|
-
const baseDir =
|
|
3974
|
+
const baseDir = path13.resolve(baseDirInput);
|
|
3499
3975
|
const installCommand = detectInstallCommand(baseDir);
|
|
3500
3976
|
const tailwind0 = detectTailwind(baseDir);
|
|
3501
3977
|
const ranges0 = selectUtilsDependencies(tailwind0);
|
|
@@ -3508,8 +3984,8 @@ function planUtilsDependencies(baseDirInput) {
|
|
|
3508
3984
|
installCommand,
|
|
3509
3985
|
addCommand: addCommandFor(installCommand, ranges0)
|
|
3510
3986
|
};
|
|
3511
|
-
const pkgFile =
|
|
3512
|
-
if (!
|
|
3987
|
+
const pkgFile = path13.join(baseDir, "package.json");
|
|
3988
|
+
if (!existsSync5(pkgFile)) return plan;
|
|
3513
3989
|
const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
|
|
3514
3990
|
let where;
|
|
3515
3991
|
try {
|
|
@@ -3562,8 +4038,8 @@ var defaultWriteFile = (file, data) => writeFileSync2(file, data);
|
|
|
3562
4038
|
function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
|
|
3563
4039
|
const w = plan.write;
|
|
3564
4040
|
if (plan.action !== "add" || !w) return false;
|
|
3565
|
-
const baseDir =
|
|
3566
|
-
const current =
|
|
4041
|
+
const baseDir = path13.resolve(baseDirInput);
|
|
4042
|
+
const current = existsSync5(w.file) ? readFileSync4(w.file, "utf8") : null;
|
|
3567
4043
|
if (current !== w.before) {
|
|
3568
4044
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
3569
4045
|
}
|
|
@@ -3614,29 +4090,206 @@ function reportDependencies(plan, log) {
|
|
|
3614
4090
|
if (plan.addCommand.includes('"tailwind-merge@')) logBasis();
|
|
3615
4091
|
}
|
|
3616
4092
|
}
|
|
4093
|
+
async function existingConfig(baseDir) {
|
|
4094
|
+
try {
|
|
4095
|
+
return await readAxisConfig(baseDir);
|
|
4096
|
+
} catch {
|
|
4097
|
+
return null;
|
|
4098
|
+
}
|
|
4099
|
+
}
|
|
4100
|
+
function configStateNote(state) {
|
|
4101
|
+
if (state === "created") return "axis.config.json \uC740 \uC774\uBBF8 \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
4102
|
+
if (state === "updated") return "axis.config.json \uC740 \uC774\uBBF8 \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4.";
|
|
4103
|
+
return "axis.config.json \uC740 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9).";
|
|
4104
|
+
}
|
|
4105
|
+
function nonEmptyString(value) {
|
|
4106
|
+
return typeof value === "string" && value.trim() !== "" ? value : void 0;
|
|
4107
|
+
}
|
|
4108
|
+
function errCode(e) {
|
|
4109
|
+
return e.code ?? e.message;
|
|
4110
|
+
}
|
|
4111
|
+
function planUtilsWrite(baseDirInput, utilsPath) {
|
|
4112
|
+
const baseDir = path13.resolve(baseDirInput);
|
|
4113
|
+
const shown = path13.relative(baseDir, utilsPath).split(path13.sep).join("/") || utilsPath;
|
|
4114
|
+
let st;
|
|
4115
|
+
try {
|
|
4116
|
+
st = lstatSync2(utilsPath);
|
|
4117
|
+
} catch (e) {
|
|
4118
|
+
if (e.code === "ENOENT") return { action: "create" };
|
|
4119
|
+
return { action: "reject", reason: `${shown} \uC758 \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
4120
|
+
}
|
|
4121
|
+
if (st.isSymbolicLink()) {
|
|
4122
|
+
let real;
|
|
4123
|
+
try {
|
|
4124
|
+
real = realpathSync3(utilsPath);
|
|
4125
|
+
} catch {
|
|
4126
|
+
return { action: "reject", reason: `${shown} \uC774 \uAE68\uC9C4 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uACE0\uCE5C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694` };
|
|
4127
|
+
}
|
|
4128
|
+
let outside = null;
|
|
4129
|
+
try {
|
|
4130
|
+
outside = isSameOrInside(realpathSync3(baseDir), real) ? null : real;
|
|
4131
|
+
} catch {
|
|
4132
|
+
outside = null;
|
|
4133
|
+
}
|
|
4134
|
+
let target;
|
|
4135
|
+
try {
|
|
4136
|
+
target = statSync3(real);
|
|
4137
|
+
} catch (e) {
|
|
4138
|
+
return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC758 \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
4139
|
+
}
|
|
4140
|
+
if (target.isDirectory()) return { action: "reject", reason: `${shown} \uB9C1\uD06C\uAC00 \uB514\uB809\uD130\uB9AC(${real})\uB97C \uAC00\uB9AC\uD0B5\uB2C8\uB2E4` };
|
|
4141
|
+
if (!target.isFile()) return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4` };
|
|
4142
|
+
let content2;
|
|
4143
|
+
try {
|
|
4144
|
+
content2 = readFileSync4(utilsPath, "utf8");
|
|
4145
|
+
} catch (e) {
|
|
4146
|
+
return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
4147
|
+
}
|
|
4148
|
+
if (content2 === UTILS_TS_CONTENT) return { action: "keep", link: { outside } };
|
|
4149
|
+
const what = outside !== null ? `\uD504\uB85C\uC81D\uD2B8 \uBC16(${outside})\uC744 \uAC00\uB9AC\uD0A4\uB294 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C` : "\uD504\uB85C\uC81D\uD2B8 \uC548\uC744 \uAC00\uB9AC\uD0A4\uB294 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C";
|
|
4150
|
+
return {
|
|
4151
|
+
action: "reject",
|
|
4152
|
+
reason: `\uAE30\uC874 ${shown} \uC774 ${what} \uB36E\uC5B4\uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(\uB0B4\uC6A9\uC774 init \uC758 utils \uC640 \uB2E4\uB984). \uB9C1\uD06C\uB294 \uB530\uB77C\uAC00 \uC4F0\uC9C0 \uC54A\uC73C\uB2C8 \uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uC2E4\uC81C \uD30C\uC77C\uB85C \uBC14\uAFBC \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694`
|
|
4153
|
+
};
|
|
4154
|
+
}
|
|
4155
|
+
if (st.isDirectory()) return { action: "reject", reason: `${shown} \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC5B4 \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` };
|
|
4156
|
+
if (!st.isFile()) return { action: "reject", reason: `${shown} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` };
|
|
4157
|
+
let content;
|
|
4158
|
+
try {
|
|
4159
|
+
content = readFileSync4(utilsPath, "utf8");
|
|
4160
|
+
} catch (e) {
|
|
4161
|
+
return { action: "reject", reason: `\uAE30\uC874 ${shown} \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
4162
|
+
}
|
|
4163
|
+
if (content === UTILS_TS_CONTENT) return { action: "keep" };
|
|
4164
|
+
const nlink = hardLinkCount(utilsPath);
|
|
4165
|
+
if (nlink !== null) return { action: "reject", reason: hardLinkMessage(shown, nlink) };
|
|
4166
|
+
try {
|
|
4167
|
+
accessSync2(utilsPath, constants2.W_OK);
|
|
4168
|
+
} catch (e) {
|
|
4169
|
+
return { action: "reject", reason: `\uAE30\uC874 ${shown} \uC5D0 \uC4F8 \uAD8C\uD55C\uC774 \uC5C6\uC5B4 \uB36E\uC5B4\uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
4170
|
+
}
|
|
4171
|
+
return { action: "overwrite" };
|
|
4172
|
+
}
|
|
3617
4173
|
async function runInit(baseDirInput, answers, registryUrl, log = console.log) {
|
|
3618
|
-
const baseDir =
|
|
4174
|
+
const baseDir = path13.resolve(baseDirInput);
|
|
4175
|
+
const current = await existingConfig(baseDir);
|
|
4176
|
+
const existingRegistry = nonEmptyString(current?.registry);
|
|
4177
|
+
const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
|
|
4178
|
+
const registry = existingRegistry !== void 0 && !migratedRegistry ? existingRegistry : registryUrl;
|
|
4179
|
+
const existingAgenticDir = nonEmptyString(current?.agenticDir);
|
|
3619
4180
|
const plan = planUtilsDependencies(baseDir);
|
|
3620
4181
|
const tailwind4 = isTailwind4(plan.tailwind);
|
|
3621
4182
|
const axisConfig = createInitConfig(
|
|
3622
4183
|
{
|
|
3623
4184
|
componentsDir: answers.componentsDir,
|
|
4185
|
+
agenticDir: existingAgenticDir,
|
|
3624
4186
|
tailwindConfig: tailwind4 ? void 0 : answers.tailwindConfig,
|
|
3625
4187
|
globalCss: answers.globalCss
|
|
3626
4188
|
},
|
|
3627
|
-
|
|
4189
|
+
registry
|
|
3628
4190
|
);
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
|
|
3632
|
-
|
|
3633
|
-
|
|
3634
|
-
|
|
4191
|
+
const configPath = path13.join(baseDir, "axis.config.json");
|
|
4192
|
+
const nextText = `${JSON.stringify(axisConfig, null, 2)}
|
|
4193
|
+
`;
|
|
4194
|
+
const rejects = [];
|
|
4195
|
+
let previousText = null;
|
|
4196
|
+
try {
|
|
4197
|
+
previousText = await fs11.readFile(configPath, "utf8");
|
|
4198
|
+
} catch (e) {
|
|
4199
|
+
if (e.code !== "ENOENT") {
|
|
4200
|
+
rejects.push(`\uAE30\uC874 axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})`);
|
|
4201
|
+
}
|
|
4202
|
+
}
|
|
4203
|
+
if (previousText !== null && previousText !== nextText) {
|
|
4204
|
+
try {
|
|
4205
|
+
const st = statSync3(configPath);
|
|
4206
|
+
if (st.isFile() && st.nlink >= 2) rejects.push(hardLinkMessage("axis.config.json", st.nlink));
|
|
4207
|
+
} catch {
|
|
4208
|
+
}
|
|
4209
|
+
}
|
|
4210
|
+
const utilsPath = path13.resolve(baseDir, answers.componentsDir, "utils.ts");
|
|
4211
|
+
const utilsPlan = planUtilsWrite(baseDir, utilsPath);
|
|
4212
|
+
if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
|
|
4213
|
+
if (rejects.length > 0) {
|
|
4214
|
+
log(chalk9.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)."));
|
|
4215
|
+
for (const r of rejects) log(chalk9.red(` - ${r}`));
|
|
4216
|
+
process.exitCode = 1;
|
|
4217
|
+
return;
|
|
4218
|
+
}
|
|
4219
|
+
let configState;
|
|
4220
|
+
if (previousText === null) {
|
|
4221
|
+
try {
|
|
4222
|
+
await fs11.writeFile(configPath, nextText, { flag: "wx" });
|
|
4223
|
+
} catch (err) {
|
|
4224
|
+
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(chalk9.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
|
+
process.exitCode = 1;
|
|
4227
|
+
return;
|
|
4228
|
+
}
|
|
4229
|
+
configState = "created";
|
|
4230
|
+
log(chalk9.green("\u2713 axis.config.json \uC0DD\uC131 \uC644\uB8CC"));
|
|
4231
|
+
} else if (previousText === nextText) {
|
|
4232
|
+
configState = "kept";
|
|
4233
|
+
log(chalk9.green("\u2713 axis.config.json \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
|
|
4234
|
+
} else {
|
|
4235
|
+
try {
|
|
4236
|
+
await overwriteFollowingLinks(configPath, nextText);
|
|
4237
|
+
} catch (err) {
|
|
4238
|
+
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(chalk9.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
|
+
process.exitCode = 1;
|
|
4241
|
+
return;
|
|
4242
|
+
}
|
|
4243
|
+
configState = "updated";
|
|
4244
|
+
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
|
+
const agenticNote = existingAgenticDir !== void 0 ? ", agenticDir \uB294 \uAE30\uC874 \uAC12 \uC720\uC9C0" : "";
|
|
4246
|
+
log(chalk9.green(`\u2713 axis.config.json \uAC31\uC2E0(\uAE30\uC874 \uD30C\uC77C\uC744 init \uAC12\uC73C\uB85C \uB2E4\uC2DC \uC500, ${registryNote}${agenticNote})`));
|
|
4247
|
+
if (migratedRegistry && existingRegistry !== void 0) {
|
|
4248
|
+
log(
|
|
4249
|
+
chalk9.yellow(
|
|
4250
|
+
` registry \uB97C \uC0C8 \uAE30\uBCF8 \uC8FC\uC18C(${redactRegistryUrl(registry)})\uB85C \uAC31\uC2E0\uD588\uC2B5\uB2C8\uB2E4(\uC885\uC804 axis.minu.best: ${redactRegistryUrl(existingRegistry)}).`
|
|
4251
|
+
)
|
|
4252
|
+
);
|
|
4253
|
+
}
|
|
4254
|
+
const dropped = current ? Object.keys(current).filter((k) => !(k in axisConfig) && current[k] !== void 0) : [];
|
|
4255
|
+
if (dropped.length > 0) {
|
|
4256
|
+
log(chalk9.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
|
+
}
|
|
4258
|
+
}
|
|
4259
|
+
let utilsStateNote = "utils.ts \uB294 \uBC14\uAFB8\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9).";
|
|
4260
|
+
if (utilsPlan.action === "keep") {
|
|
4261
|
+
if (utilsPlan.link === void 0) log(chalk9.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9)"));
|
|
4262
|
+
else if (utilsPlan.link.outside === null) log(chalk9.green("\u2713 utils.ts \uC720\uC9C0(\uC774\uBBF8 \uAC19\uC740 \uB0B4\uC6A9, \uB9C1\uD06C)"));
|
|
4263
|
+
else log(chalk9.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
|
+
} else {
|
|
4265
|
+
let actual;
|
|
4266
|
+
try {
|
|
4267
|
+
await fs11.ensureDir(path13.dirname(utilsPath));
|
|
4268
|
+
actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
|
|
4269
|
+
} catch (err) {
|
|
4270
|
+
const code = err.code;
|
|
4271
|
+
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
|
+
log(
|
|
4273
|
+
chalk9.red(
|
|
4274
|
+
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
|
+
)
|
|
4276
|
+
);
|
|
4277
|
+
log(chalk9.yellow(` ${configStateNote(configState)}`));
|
|
4278
|
+
process.exitCode = 1;
|
|
4279
|
+
return;
|
|
4280
|
+
}
|
|
4281
|
+
log(
|
|
4282
|
+
chalk9.green(
|
|
4283
|
+
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
|
+
)
|
|
4285
|
+
);
|
|
4286
|
+
utilsStateNote = actual === "new" ? "utils.ts \uB294 \uC774\uBBF8 \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4." : "utils.ts \uB294 \uC774\uBBF8 \uB36E\uC5B4\uC37C\uC2B5\uB2C8\uB2E4.";
|
|
4287
|
+
}
|
|
3635
4288
|
try {
|
|
3636
4289
|
applyUtilsDependencies(baseDir, plan);
|
|
3637
4290
|
} catch (err) {
|
|
3638
4291
|
log(chalk9.red(`\u2717 package.json \uC744 \uC4F0\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${err.message}`));
|
|
3639
|
-
log(chalk9.yellow(
|
|
4292
|
+
log(chalk9.yellow(` ${configStateNote(configState)} ${utilsStateNote}`));
|
|
3640
4293
|
log(chalk9.yellow(` utils.ts \uC758\uC874\uC131 \uC124\uCE58: ${chalk9.cyan(plan.addCommand)}`));
|
|
3641
4294
|
process.exitCode = 1;
|
|
3642
4295
|
return;
|
|
@@ -3659,7 +4312,7 @@ ${head}`));
|
|
|
3659
4312
|
}
|
|
3660
4313
|
|
|
3661
4314
|
// src/init/index.ts
|
|
3662
|
-
function registerInitCommand(program2, registryUrl) {
|
|
4315
|
+
function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL) {
|
|
3663
4316
|
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) => {
|
|
3664
4317
|
console.log(chalk10.blue("\n\u{1F3A8} AXIS Design System \uCD08\uAE30\uD654\n"));
|
|
3665
4318
|
const tailwind4 = isTailwind4(planUtilsDependencies(process.cwd()).tailwind);
|
|
@@ -3687,108 +4340,805 @@ function registerInitCommand(program2, registryUrl) {
|
|
|
3687
4340
|
});
|
|
3688
4341
|
}
|
|
3689
4342
|
|
|
3690
|
-
// src/index.ts
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
4343
|
+
// src/add/index.ts
|
|
4344
|
+
import chalk11 from "chalk";
|
|
4345
|
+
import prompts3 from "prompts";
|
|
4346
|
+
|
|
4347
|
+
// src/add/add.ts
|
|
4348
|
+
import { existsSync as existsSync7, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
|
|
4349
|
+
import path15 from "path";
|
|
4350
|
+
import fs12 from "fs-extra";
|
|
4351
|
+
|
|
4352
|
+
// src/registry/bundled.ts
|
|
4353
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
4354
|
+
import path14 from "path";
|
|
4355
|
+
import { fileURLToPath } from "url";
|
|
4356
|
+
function findBundledRegistryDir(moduleUrl = import.meta.url) {
|
|
4357
|
+
const here = path14.dirname(fileURLToPath(moduleUrl));
|
|
4358
|
+
for (const dir of [path14.join(here, "registry"), path14.join(here, "..", "registry")]) {
|
|
4359
|
+
if (existsSync6(path14.join(dir, "index.json"))) return dir;
|
|
4360
|
+
}
|
|
4361
|
+
return null;
|
|
4362
|
+
}
|
|
4363
|
+
function readBundledJson(dir, fileName) {
|
|
4364
|
+
const file = path14.join(dir, fileName);
|
|
4365
|
+
let text;
|
|
3698
4366
|
try {
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
4367
|
+
text = readFileSync5(file, "utf8");
|
|
4368
|
+
} catch {
|
|
4369
|
+
throw new Error(`\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 ${fileName} \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(${dir})`);
|
|
4370
|
+
}
|
|
4371
|
+
return parseJsonText(text, `\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC ${fileName}`);
|
|
4372
|
+
}
|
|
4373
|
+
|
|
4374
|
+
// src/registry/index.ts
|
|
4375
|
+
var RegistryError = class extends Error {
|
|
4376
|
+
constructor(code, message) {
|
|
4377
|
+
super(message);
|
|
4378
|
+
this.code = code;
|
|
4379
|
+
this.name = "RegistryError";
|
|
4380
|
+
}
|
|
4381
|
+
};
|
|
4382
|
+
function bundledFallbackMessage(version, reason, kind = "access") {
|
|
4383
|
+
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} CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${version})\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4. (\uC6D0\uC778: ${reason})`;
|
|
4385
|
+
}
|
|
4386
|
+
function fallbackKindOf(error) {
|
|
4387
|
+
return error instanceof RegistryAccessError ? "access" : "invalid";
|
|
4388
|
+
}
|
|
4389
|
+
function versionMismatchMessage(remoteVersion, bundledVersion) {
|
|
4390
|
+
return `\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${remoteVersion})\uC640 CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC(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
|
+
}
|
|
4392
|
+
function messageOf(error) {
|
|
4393
|
+
return error instanceof Error ? error.message : String(error);
|
|
4394
|
+
}
|
|
4395
|
+
var RegistryClient = class {
|
|
4396
|
+
baseUrl;
|
|
4397
|
+
baseUrlError;
|
|
4398
|
+
bundledDir;
|
|
4399
|
+
timeoutMs;
|
|
4400
|
+
fetchImpl;
|
|
4401
|
+
notify;
|
|
4402
|
+
mode = null;
|
|
4403
|
+
indexPromise = null;
|
|
4404
|
+
bundledIndex = null;
|
|
4405
|
+
fallbackAnnounced = false;
|
|
4406
|
+
constructor(options) {
|
|
4407
|
+
let baseUrl = null;
|
|
4408
|
+
let baseUrlError = null;
|
|
4409
|
+
if (options.url !== null) {
|
|
4410
|
+
try {
|
|
4411
|
+
baseUrl = normalizeRegistryBaseUrl(options.url);
|
|
4412
|
+
} catch (error) {
|
|
4413
|
+
baseUrlError = messageOf(error);
|
|
4414
|
+
}
|
|
4415
|
+
} else {
|
|
4416
|
+
baseUrlError = "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4";
|
|
4417
|
+
}
|
|
4418
|
+
this.baseUrl = baseUrl;
|
|
4419
|
+
this.baseUrlError = baseUrlError;
|
|
4420
|
+
this.bundledDir = options.bundledDir === void 0 ? findBundledRegistryDir() : options.bundledDir;
|
|
4421
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_REGISTRY_TIMEOUT_MS;
|
|
4422
|
+
this.fetchImpl = options.fetchImpl;
|
|
4423
|
+
this.notify = options.notify ?? ((message) => console.warn(message));
|
|
4424
|
+
}
|
|
4425
|
+
/** 지금 쓰는 출처. index 를 읽기 전에는 null 입니다 */
|
|
4426
|
+
get origin() {
|
|
4427
|
+
return this.mode;
|
|
4428
|
+
}
|
|
4429
|
+
/** 레지스트리 목록(index.json) */
|
|
4430
|
+
getIndex() {
|
|
4431
|
+
if (!this.indexPromise) this.indexPromise = this.loadIndex();
|
|
4432
|
+
return this.indexPromise;
|
|
4433
|
+
}
|
|
4434
|
+
/** 항목 하나. 이름 검사 → index 확인 → 항목 조회 순서입니다 */
|
|
4435
|
+
async getItem(name) {
|
|
4436
|
+
if (!isValidRegistryName(name)) {
|
|
4437
|
+
throw new RegistryError(
|
|
4438
|
+
"invalid-name",
|
|
4439
|
+
`'${name}' \uB294 \uB808\uC9C0\uC2A4\uD2B8\uB9AC \uD56D\uBAA9 \uC774\uB984 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`
|
|
3703
4440
|
);
|
|
3704
|
-
process.exit(1);
|
|
3705
4441
|
}
|
|
3706
|
-
const
|
|
3707
|
-
const
|
|
3708
|
-
|
|
3709
|
-
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
|
|
3713
|
-
|
|
4442
|
+
const index = await this.getIndex();
|
|
4443
|
+
const entry = index.items.find((it) => it.name === name);
|
|
4444
|
+
if (!entry) {
|
|
4445
|
+
throw new RegistryError("not-found", `'${name}' \uD56D\uBAA9\uC774 \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${index.version})\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
4446
|
+
}
|
|
4447
|
+
if (this.mode === "remote" && this.baseUrl) {
|
|
4448
|
+
try {
|
|
4449
|
+
const data = await fetchRegistryJson(`${this.baseUrl}/${name}.json`, this.fetchOptions());
|
|
4450
|
+
const item = validateRegistryItem(data, name, `${name}.json`, this.remoteDependencyBases());
|
|
4451
|
+
checkItemSha256(item, entry);
|
|
4452
|
+
return item;
|
|
4453
|
+
} catch (error) {
|
|
4454
|
+
await this.switchToBundled(messageOf(error), fallbackKindOf(error));
|
|
4455
|
+
return this.readBundledItem(name);
|
|
4456
|
+
}
|
|
4457
|
+
}
|
|
4458
|
+
return this.readBundledItem(name);
|
|
4459
|
+
}
|
|
4460
|
+
/** 원격 응답의 의존 URL 로 받아 주는 base: 지금 조회 중인 원격 base 와 공개 기본 base(D11) */
|
|
4461
|
+
remoteDependencyBases() {
|
|
4462
|
+
const bases = [REGISTRY_PUBLIC_BASE_URL];
|
|
4463
|
+
if (this.baseUrl && this.baseUrl !== REGISTRY_PUBLIC_BASE_URL) bases.unshift(this.baseUrl);
|
|
4464
|
+
return bases;
|
|
4465
|
+
}
|
|
4466
|
+
fetchOptions() {
|
|
4467
|
+
return { timeoutMs: this.timeoutMs, ...this.fetchImpl ? { fetchImpl: this.fetchImpl } : {} };
|
|
4468
|
+
}
|
|
4469
|
+
async loadIndex() {
|
|
4470
|
+
let remoteError;
|
|
4471
|
+
let kind = "access";
|
|
4472
|
+
if (this.baseUrl) {
|
|
4473
|
+
try {
|
|
4474
|
+
const data = await fetchRegistryJson(`${this.baseUrl}/index.json`, this.fetchOptions());
|
|
4475
|
+
const index = validateRegistryIndex(data, `${this.baseUrl}/index.json`);
|
|
4476
|
+
this.mode = "remote";
|
|
4477
|
+
this.warnVersionMismatch(index.version);
|
|
4478
|
+
return index;
|
|
4479
|
+
} catch (error) {
|
|
4480
|
+
remoteError = messageOf(error);
|
|
4481
|
+
kind = fallbackKindOf(error);
|
|
4482
|
+
}
|
|
4483
|
+
} else {
|
|
4484
|
+
remoteError = this.baseUrlError ?? "\uC6D0\uACA9 \uB808\uC9C0\uC2A4\uD2B8\uB9AC URL \uC774 \uC5C6\uC2B5\uB2C8\uB2E4";
|
|
4485
|
+
}
|
|
4486
|
+
return this.switchToBundled(remoteError, kind);
|
|
4487
|
+
}
|
|
4488
|
+
/** 동봉본 index 를 읽습니다(성공하면 한 번만). 실패하면 이유를 돌려줍니다 */
|
|
4489
|
+
loadBundledIndex() {
|
|
4490
|
+
if (this.bundledIndex) return { index: this.bundledIndex };
|
|
4491
|
+
if (!this.bundledDir) return { error: "CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4" };
|
|
4492
|
+
try {
|
|
4493
|
+
this.bundledIndex = validateRegistryIndex(readBundledJson(this.bundledDir, "index.json"), "\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC index.json");
|
|
4494
|
+
return { index: this.bundledIndex };
|
|
4495
|
+
} catch (error) {
|
|
4496
|
+
return { error: messageOf(error) };
|
|
4497
|
+
}
|
|
4498
|
+
}
|
|
4499
|
+
warnVersionMismatch(remoteVersion) {
|
|
4500
|
+
const bundled = this.loadBundledIndex();
|
|
4501
|
+
if ("index" in bundled && bundled.index.version !== remoteVersion) {
|
|
4502
|
+
this.notify(versionMismatchMessage(remoteVersion, bundled.index.version));
|
|
4503
|
+
}
|
|
4504
|
+
}
|
|
4505
|
+
async switchToBundled(reason, kind = "access") {
|
|
4506
|
+
const bundled = this.loadBundledIndex();
|
|
4507
|
+
if ("error" in bundled) {
|
|
4508
|
+
throw new RegistryError(
|
|
4509
|
+
"unavailable",
|
|
4510
|
+
`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4. \uC6D0\uACA9: ${reason} / \uB3D9\uBD09\uBCF8: ${bundled.error}`
|
|
3714
4511
|
);
|
|
3715
|
-
process.exit(1);
|
|
3716
4512
|
}
|
|
3717
|
-
|
|
3718
|
-
|
|
3719
|
-
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
|
|
3723
|
-
|
|
3724
|
-
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
4513
|
+
this.mode = "bundled";
|
|
4514
|
+
this.indexPromise = Promise.resolve(bundled.index);
|
|
4515
|
+
if (!this.fallbackAnnounced) {
|
|
4516
|
+
this.fallbackAnnounced = true;
|
|
4517
|
+
this.notify(bundledFallbackMessage(bundled.index.version, reason, kind));
|
|
4518
|
+
}
|
|
4519
|
+
return bundled.index;
|
|
4520
|
+
}
|
|
4521
|
+
readBundledItem(name) {
|
|
4522
|
+
const index = this.bundledIndex;
|
|
4523
|
+
const entry = index?.items.find((it) => it.name === name);
|
|
4524
|
+
if (!index || !entry || !this.bundledDir) {
|
|
4525
|
+
throw new RegistryError(
|
|
4526
|
+
"not-found",
|
|
4527
|
+
`'${name}' \uD56D\uBAA9\uC774 CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC(version ${index?.version ?? "\uC54C \uC218 \uC5C6\uC74C"})\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
4528
|
+
);
|
|
4529
|
+
}
|
|
4530
|
+
try {
|
|
4531
|
+
const item = validateRegistryItem(readBundledJson(this.bundledDir, `${name}.json`), name, `${name}.json`, DEFAULT_DEPENDENCY_BASES);
|
|
4532
|
+
checkItemSha256(item, entry);
|
|
4533
|
+
return item;
|
|
4534
|
+
} catch (error) {
|
|
4535
|
+
throw new RegistryError("unavailable", `CLI \uC5D0 \uD3EC\uD568\uB41C \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC758 '${name}' \uD56D\uBAA9\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${messageOf(error)}`);
|
|
4536
|
+
}
|
|
4537
|
+
}
|
|
4538
|
+
};
|
|
4539
|
+
|
|
4540
|
+
// src/add/add.ts
|
|
4541
|
+
var AGENTIC_PREFIX = "agentic-";
|
|
4542
|
+
function applyAgenticAlias(name, agentic) {
|
|
4543
|
+
if (!agentic || name.startsWith(AGENTIC_PREFIX)) return name;
|
|
4544
|
+
return `${AGENTIC_PREFIX}${name}`;
|
|
4545
|
+
}
|
|
4546
|
+
function describeMissingName(requested, resolved, index, agentic) {
|
|
4547
|
+
const names = new Set(index.items.map((it) => it.name));
|
|
4548
|
+
if (!isValidRegistryName(resolved)) {
|
|
4549
|
+
return `'${requested}': \uC774\uB984 \uADDC\uCE59(\uC18C\uBB38\uC790 \xB7 \uC22B\uC790 \xB7 \uD558\uC774\uD508)\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
4550
|
+
}
|
|
4551
|
+
if (agentic && resolved !== requested && names.has(requested)) {
|
|
4552
|
+
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
|
+
}
|
|
4554
|
+
if (!agentic && names.has(`${AGENTIC_PREFIX}${requested}`)) {
|
|
4555
|
+
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
|
+
}
|
|
4557
|
+
return `'${requested}': \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4`;
|
|
4558
|
+
}
|
|
4559
|
+
function layoutFromConfig(root, config) {
|
|
4560
|
+
const componentsRaw = config.componentsDir;
|
|
4561
|
+
if (typeof componentsRaw !== "string" || componentsRaw.trim() === "") {
|
|
4562
|
+
throw new Error("axis.config.json \uC5D0 componentsDir \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. 'npx @axis-ds/cli init' \uC744 \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uC801\uC73C\uC138\uC694");
|
|
4563
|
+
}
|
|
4564
|
+
const agenticRaw = config.agenticDir;
|
|
4565
|
+
if (agenticRaw !== void 0 && (typeof agenticRaw !== "string" || agenticRaw.trim() === "")) {
|
|
4566
|
+
throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
|
|
4567
|
+
}
|
|
4568
|
+
const componentsDir = componentsRaw.replace(/\\/g, "/");
|
|
4569
|
+
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path15.posix.join(path15.posix.dirname(componentsDir), "agentic");
|
|
4570
|
+
return { root: path15.resolve(root), componentsDir, agenticDir };
|
|
4571
|
+
}
|
|
4572
|
+
function toPosix(p, impl = path15) {
|
|
4573
|
+
return p.split(impl.sep).join("/");
|
|
4574
|
+
}
|
|
4575
|
+
function itemKind(item) {
|
|
4576
|
+
if (item.type === "registry:lib") return "lib";
|
|
4577
|
+
return item.name.startsWith(AGENTIC_PREFIX) ? "agentic" : "ui";
|
|
4578
|
+
}
|
|
4579
|
+
var INSTALL_FILE_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_-]*(?:\.[A-Za-z0-9_-]+)*\.tsx?$/;
|
|
4580
|
+
function registryPathProblem(p) {
|
|
4581
|
+
if (p.length === 0) return "\uBE44\uC5B4 \uC788\uC74C";
|
|
4582
|
+
if (p.includes("\0")) return "NUL \uBB38\uC790";
|
|
4583
|
+
if (p.includes("\\")) return "\uC5ED\uC2AC\uB798\uC2DC";
|
|
4584
|
+
if (p.startsWith("/") || /^[A-Za-z]:/.test(p)) return "\uC808\uB300 \uACBD\uB85C";
|
|
4585
|
+
const segments = p.split("/");
|
|
4586
|
+
if (segments.some((seg) => seg === "" || seg === "." || seg === "..")) return "`..` \xB7 `.` \xB7 \uBE48 \uC138\uADF8\uBA3C\uD2B8";
|
|
4587
|
+
return null;
|
|
4588
|
+
}
|
|
4589
|
+
function placeFile(layout, item, filePath, target) {
|
|
4590
|
+
for (const p of target === void 0 ? [filePath] : [filePath, target]) {
|
|
4591
|
+
const problem = registryPathProblem(p);
|
|
4592
|
+
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
|
+
}
|
|
4594
|
+
const base = path15.posix.basename(filePath);
|
|
4595
|
+
if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
|
|
4596
|
+
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
|
+
}
|
|
4598
|
+
const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
|
|
4599
|
+
return path15.resolve(layout.root, dir, base);
|
|
4600
|
+
}
|
|
4601
|
+
function stripExt(p) {
|
|
4602
|
+
return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
|
|
4603
|
+
}
|
|
4604
|
+
function buildImportTargets(entries) {
|
|
4605
|
+
const exact = /* @__PURE__ */ new Map();
|
|
4606
|
+
const lib = /* @__PURE__ */ new Map();
|
|
4607
|
+
for (const { item, file, target } of entries) {
|
|
4608
|
+
const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
|
|
4609
|
+
exact.set(`@/${rel3}`, target);
|
|
4610
|
+
if (itemKind(item) === "lib") lib.set(path15.posix.basename(rel3), target);
|
|
4611
|
+
}
|
|
4612
|
+
return { exact, lib };
|
|
4613
|
+
}
|
|
4614
|
+
function nonCodeRanges(src) {
|
|
4615
|
+
const comments = [];
|
|
4616
|
+
const strings = [];
|
|
4617
|
+
function scanTemplate(start) {
|
|
4618
|
+
let i = start + 1;
|
|
4619
|
+
let seg = start;
|
|
4620
|
+
while (i < src.length) {
|
|
4621
|
+
const c = src[i];
|
|
4622
|
+
if (c === "\\") {
|
|
4623
|
+
i += 2;
|
|
4624
|
+
} else if (c === "`") {
|
|
4625
|
+
strings.push([seg, i + 1]);
|
|
4626
|
+
return i + 1;
|
|
4627
|
+
} else if (c === "$" && src[i + 1] === "{") {
|
|
4628
|
+
strings.push([seg, i]);
|
|
4629
|
+
i = scanCode(i + 2, true);
|
|
4630
|
+
seg = i;
|
|
4631
|
+
i++;
|
|
4632
|
+
} else {
|
|
4633
|
+
i++;
|
|
4634
|
+
}
|
|
4635
|
+
}
|
|
4636
|
+
strings.push([seg, src.length]);
|
|
4637
|
+
return src.length;
|
|
4638
|
+
}
|
|
4639
|
+
function scanCode(start, untilBrace) {
|
|
4640
|
+
let i = start;
|
|
4641
|
+
let depth = 0;
|
|
4642
|
+
while (i < src.length) {
|
|
4643
|
+
const c = src[i];
|
|
4644
|
+
if (c === "/" && src[i + 1] === "/") {
|
|
4645
|
+
const end = src.indexOf("\n", i);
|
|
4646
|
+
const stop = end === -1 ? src.length : end;
|
|
4647
|
+
comments.push([i, stop]);
|
|
4648
|
+
i = stop;
|
|
4649
|
+
} else if (c === "/" && src[i + 1] === "*") {
|
|
4650
|
+
const end = src.indexOf("*/", i + 2);
|
|
4651
|
+
const stop = end === -1 ? src.length : end + 2;
|
|
4652
|
+
comments.push([i, stop]);
|
|
4653
|
+
i = stop;
|
|
4654
|
+
} else if (c === '"' || c === "'") {
|
|
4655
|
+
const s = i;
|
|
4656
|
+
i++;
|
|
4657
|
+
while (i < src.length && src[i] !== c && src[i] !== "\n") {
|
|
4658
|
+
if (src[i] === "\\") i++;
|
|
4659
|
+
i++;
|
|
3729
4660
|
}
|
|
4661
|
+
i = Math.min(i + 1, src.length);
|
|
4662
|
+
strings.push([s, i]);
|
|
4663
|
+
} else if (c === "`") {
|
|
4664
|
+
i = scanTemplate(i);
|
|
4665
|
+
} else if (c === "{") {
|
|
4666
|
+
depth++;
|
|
4667
|
+
i++;
|
|
4668
|
+
} else if (c === "}") {
|
|
4669
|
+
if (untilBrace && depth === 0) return i;
|
|
4670
|
+
depth = Math.max(0, depth - 1);
|
|
4671
|
+
i++;
|
|
4672
|
+
} else {
|
|
4673
|
+
i++;
|
|
3730
4674
|
}
|
|
3731
|
-
await fs11.ensureDir(path12.dirname(filePath));
|
|
3732
|
-
await fs11.writeFile(filePath, file.content);
|
|
3733
4675
|
}
|
|
3734
|
-
|
|
3735
|
-
|
|
3736
|
-
|
|
3737
|
-
|
|
4676
|
+
return src.length;
|
|
4677
|
+
}
|
|
4678
|
+
scanCode(0, false);
|
|
4679
|
+
return { comments, strings };
|
|
4680
|
+
}
|
|
4681
|
+
function insideRanges(ranges, at) {
|
|
4682
|
+
return ranges.some(([a, b]) => at >= a && at < b);
|
|
4683
|
+
}
|
|
4684
|
+
var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
|
|
4685
|
+
var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
|
|
4686
|
+
function relativeSpecifier(fromFile, toFile, impl = path15) {
|
|
4687
|
+
let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
|
|
4688
|
+
if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
|
|
4689
|
+
return rel3;
|
|
4690
|
+
}
|
|
4691
|
+
function rewriteImports(content, fileTarget, targets) {
|
|
4692
|
+
const rewritten = [];
|
|
4693
|
+
const unresolved = [];
|
|
4694
|
+
const { comments, strings } = nonCodeRanges(content);
|
|
4695
|
+
const out = content.replace(SPECIFIER_PATTERN, (whole, lead, quote, spec, offset) => {
|
|
4696
|
+
if (insideRanges(comments, offset) || insideRanges(strings, offset)) return whole;
|
|
4697
|
+
let target = targets.exact.get(spec);
|
|
4698
|
+
if (target === void 0) {
|
|
4699
|
+
const m = STANDARD_LIB_PATTERN.exec(spec);
|
|
4700
|
+
if (m) target = targets.lib.get(m[1]);
|
|
4701
|
+
}
|
|
4702
|
+
if (target === void 0) {
|
|
4703
|
+
if (spec.startsWith("@/registry/")) unresolved.push(spec);
|
|
4704
|
+
return whole;
|
|
4705
|
+
}
|
|
4706
|
+
const to = relativeSpecifier(fileTarget, target);
|
|
4707
|
+
rewritten.push({ from: spec, to, target });
|
|
4708
|
+
return `${lead}${quote}${to}${quote}`;
|
|
4709
|
+
});
|
|
4710
|
+
return { content: out, rewritten, unresolved };
|
|
4711
|
+
}
|
|
4712
|
+
var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
|
|
4713
|
+
function relativeSpecifierResolves(fromFile, spec) {
|
|
4714
|
+
const base = path15.resolve(path15.dirname(fromFile), spec);
|
|
4715
|
+
return RESOLVE_EXTS.some((ext) => {
|
|
4716
|
+
try {
|
|
4717
|
+
return statSync4(base + ext).isFile();
|
|
4718
|
+
} catch {
|
|
4719
|
+
return false;
|
|
3738
4720
|
}
|
|
3739
|
-
}
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
4721
|
+
});
|
|
4722
|
+
}
|
|
4723
|
+
async function collectItems(client, roots) {
|
|
4724
|
+
const first = await collectOnce(client, roots);
|
|
4725
|
+
if (first.origin === "remote" && client.origin === "bundled") return collectOnce(client, roots);
|
|
4726
|
+
return first;
|
|
4727
|
+
}
|
|
4728
|
+
async function collectOnce(client, roots) {
|
|
4729
|
+
const index = await client.getIndex();
|
|
4730
|
+
const origin = client.origin;
|
|
4731
|
+
const known = new Set(index.items.map((it) => it.name));
|
|
4732
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4733
|
+
const items = [];
|
|
4734
|
+
const missingDeps = [];
|
|
4735
|
+
async function visit(name) {
|
|
4736
|
+
if (visited.has(name)) return;
|
|
4737
|
+
visited.add(name);
|
|
4738
|
+
const item = await client.getItem(name);
|
|
4739
|
+
for (const dep of item.registryDependencies) {
|
|
4740
|
+
if (!known.has(dep)) {
|
|
4741
|
+
missingDeps.push({ name: dep, from: name });
|
|
4742
|
+
continue;
|
|
4743
|
+
}
|
|
4744
|
+
await visit(dep);
|
|
4745
|
+
}
|
|
4746
|
+
items.push(item);
|
|
4747
|
+
}
|
|
4748
|
+
for (const root of roots) await visit(root);
|
|
4749
|
+
return { items, missingDeps, origin };
|
|
4750
|
+
}
|
|
4751
|
+
function planFiles(layout, items) {
|
|
4752
|
+
const errors = [];
|
|
4753
|
+
const placed = [];
|
|
4754
|
+
const byTarget = /* @__PURE__ */ new Map();
|
|
4755
|
+
for (const item of items) {
|
|
4756
|
+
for (const file of item.files) {
|
|
4757
|
+
let target;
|
|
4758
|
+
try {
|
|
4759
|
+
target = placeFile(layout, item, file.path, file.target);
|
|
4760
|
+
} catch (error) {
|
|
4761
|
+
errors.push(error.message);
|
|
4762
|
+
continue;
|
|
4763
|
+
}
|
|
4764
|
+
const prev = byTarget.get(target);
|
|
4765
|
+
if (prev !== void 0) {
|
|
4766
|
+
errors.push(`${item.name}: ${toPosix(path15.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
|
|
4767
|
+
continue;
|
|
4768
|
+
}
|
|
4769
|
+
byTarget.set(target, item.name);
|
|
4770
|
+
placed.push({ item, file, target });
|
|
4771
|
+
}
|
|
4772
|
+
}
|
|
4773
|
+
const targets = buildImportTargets(placed);
|
|
4774
|
+
const files = [];
|
|
4775
|
+
for (const { item, file, target } of placed) {
|
|
4776
|
+
const r = rewriteImports(file.content, target, targets);
|
|
4777
|
+
for (const spec of r.unresolved) {
|
|
4778
|
+
errors.push(`${item.name}: import '${spec}' \uB97C \uC124\uCE58 \uC704\uCE58\uB85C \uBC14\uAFC0 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(registryDependencies \uC5D0 \uD574\uB2F9 \uD56D\uBAA9\uC774 \uC5C6\uC74C)`);
|
|
4779
|
+
}
|
|
4780
|
+
files.push({ item, sourcePath: file.path, target, content: r.content, rewritten: r.rewritten });
|
|
4781
|
+
}
|
|
4782
|
+
for (const f of files) {
|
|
4783
|
+
const reason = escapeReason(layout.root, f.target, { allowOutsideLink: true });
|
|
4784
|
+
if (reason) errors.push(`${f.item.name}: ${reason}. \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
|
|
4785
|
+
}
|
|
4786
|
+
return { files, errors };
|
|
4787
|
+
}
|
|
4788
|
+
function missingDependencies(root, items) {
|
|
4789
|
+
const installCommand = detectInstallCommand(root);
|
|
4790
|
+
let pkg;
|
|
4791
|
+
try {
|
|
4792
|
+
const text = readFileSync6(path15.join(root, "package.json"), "utf8").replace(/^/, "");
|
|
4793
|
+
const parsed = JSON.parse(text);
|
|
4794
|
+
pkg = isPlainObject2(parsed) ? parsed : void 0;
|
|
4795
|
+
} catch {
|
|
4796
|
+
pkg = void 0;
|
|
4797
|
+
}
|
|
4798
|
+
const ranges = selectUtilsDependencies(detectTailwind(root, pkg));
|
|
4799
|
+
const specs = {};
|
|
4800
|
+
for (const item of items) {
|
|
4801
|
+
for (const dep of item.dependencies) {
|
|
4802
|
+
const name = dependencyName(dep);
|
|
4803
|
+
if (pkg !== void 0 && hasDependency2(pkg, name) !== void 0) continue;
|
|
4804
|
+
if (name in specs) continue;
|
|
4805
|
+
const explicit = dep.length > name.length ? dep.slice(name.length + 1) : void 0;
|
|
4806
|
+
specs[name] = explicit ?? ranges[name];
|
|
4807
|
+
}
|
|
4808
|
+
}
|
|
4809
|
+
const sorted = {};
|
|
4810
|
+
for (const name of Object.keys(specs).sort()) sorted[name] = specs[name];
|
|
4811
|
+
return { specs: sorted, installCommand };
|
|
4812
|
+
}
|
|
4813
|
+
function dependencyName(spec) {
|
|
4814
|
+
const at = spec.indexOf("@", spec.startsWith("@") ? 1 : 0);
|
|
4815
|
+
return at > 0 ? spec.slice(0, at) : spec;
|
|
4816
|
+
}
|
|
4817
|
+
function addCommandForSpecs(installCommand, specs) {
|
|
4818
|
+
const args = Object.entries(specs).map(([name, range]) => range ? `"${name}@${range}"` : name).join(" ");
|
|
4819
|
+
if (installCommand.startsWith("yarn")) return `yarn add ${args}`;
|
|
4820
|
+
if (installCommand.startsWith("npm")) return `npm install ${args}`;
|
|
4821
|
+
return `pnpm add ${args}`;
|
|
4822
|
+
}
|
|
4823
|
+
function rel2(root, p) {
|
|
4824
|
+
return toPosix(path15.relative(root, p));
|
|
4825
|
+
}
|
|
4826
|
+
async function runAdd(cwd, requested, options, ctx) {
|
|
4827
|
+
const log = ctx.log ?? console.log;
|
|
4828
|
+
const error = ctx.error ?? console.error;
|
|
4829
|
+
const root = path15.resolve(cwd);
|
|
4830
|
+
const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
|
|
4831
|
+
if (requested.length === 0) {
|
|
4832
|
+
error("\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: npx @axis-ds/cli list");
|
|
4833
|
+
return result;
|
|
4834
|
+
}
|
|
4835
|
+
let config;
|
|
4836
|
+
try {
|
|
4837
|
+
config = await readAxisConfig(root);
|
|
4838
|
+
} catch (e) {
|
|
4839
|
+
error(`axis.config.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`);
|
|
4840
|
+
return result;
|
|
4841
|
+
}
|
|
4842
|
+
if (!config) {
|
|
4843
|
+
error(
|
|
4844
|
+
`axis.config.json\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
4845
|
+
\uD574\uACB0: \uD504\uB85C\uC81D\uD2B8 \uB8E8\uD2B8\uC5D0\uC11C 'npx @axis-ds/cli init'\uC744 \uC2E4\uD589\uD558\uC138\uC694.
|
|
4846
|
+
\uCC38\uACE0: ${AXIS_QUICK_START_URL}`
|
|
3744
4847
|
);
|
|
3745
|
-
|
|
4848
|
+
return result;
|
|
3746
4849
|
}
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
|
|
3773
|
-
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
|
|
4850
|
+
let layout;
|
|
4851
|
+
try {
|
|
4852
|
+
layout = layoutFromConfig(root, config);
|
|
4853
|
+
} catch (e) {
|
|
4854
|
+
error(e.message);
|
|
4855
|
+
return result;
|
|
4856
|
+
}
|
|
4857
|
+
let index;
|
|
4858
|
+
try {
|
|
4859
|
+
index = await ctx.client.getIndex();
|
|
4860
|
+
} catch (e) {
|
|
4861
|
+
error(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`);
|
|
4862
|
+
return result;
|
|
4863
|
+
}
|
|
4864
|
+
const names = new Set(index.items.map((it) => it.name));
|
|
4865
|
+
const resolved = [];
|
|
4866
|
+
const missing = [];
|
|
4867
|
+
for (const req of requested) {
|
|
4868
|
+
const name = applyAgenticAlias(req, options.agentic);
|
|
4869
|
+
if (!isValidRegistryName(name) || !names.has(name)) missing.push(describeMissingName(req, name, index, options.agentic));
|
|
4870
|
+
else if (!resolved.includes(name)) resolved.push(name);
|
|
4871
|
+
}
|
|
4872
|
+
if (missing.length > 0) {
|
|
4873
|
+
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
|
+
for (const m of missing) error(` - ${m}`);
|
|
4875
|
+
error(" \uC0AC\uC6A9 \uAC00\uB2A5\uD55C \uBAA9\uB85D: npx @axis-ds/cli list");
|
|
4876
|
+
return result;
|
|
4877
|
+
}
|
|
4878
|
+
let items;
|
|
4879
|
+
try {
|
|
4880
|
+
const collected = await collectItems(ctx.client, resolved);
|
|
4881
|
+
if (collected.missingDeps.length > 0) {
|
|
4882
|
+
error("\uB808\uC9C0\uC2A4\uD2B8\uB9AC \uD56D\uBAA9\uC758 \uC758\uC874 \uD56D\uBAA9\uC774 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 \uC5C6\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC124\uCE58\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
|
|
4883
|
+
for (const d of collected.missingDeps) error(` - ${d.from} \u2192 ${d.name}`);
|
|
4884
|
+
return result;
|
|
4885
|
+
}
|
|
4886
|
+
items = collected.items;
|
|
4887
|
+
} catch (e) {
|
|
4888
|
+
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
|
+
error(msg);
|
|
4890
|
+
return result;
|
|
4891
|
+
}
|
|
4892
|
+
const plan = planFiles(layout, items);
|
|
4893
|
+
if (plan.errors.length > 0) {
|
|
4894
|
+
error("\uC124\uCE58\uD560 \uC218 \uC5C6\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
|
|
4895
|
+
for (const e of plan.errors) error(` - ${e}`);
|
|
4896
|
+
return result;
|
|
4897
|
+
}
|
|
4898
|
+
const existing = /* @__PURE__ */ new Map();
|
|
4899
|
+
const readErrors = [];
|
|
4900
|
+
for (const file of plan.files) {
|
|
4901
|
+
if (!existsSync7(file.target)) {
|
|
4902
|
+
existing.set(file, null);
|
|
4903
|
+
continue;
|
|
4904
|
+
}
|
|
4905
|
+
try {
|
|
4906
|
+
existing.set(file, readFileSync6(file.target, "utf8"));
|
|
4907
|
+
} catch (e) {
|
|
4908
|
+
readErrors.push(
|
|
4909
|
+
`${file.item.name}: \uAE30\uC874 \uD30C\uC77C ${rel2(root, file.target)} \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${e.code ?? e.message})`
|
|
4910
|
+
);
|
|
4911
|
+
}
|
|
4912
|
+
}
|
|
4913
|
+
if (readErrors.length > 0) {
|
|
4914
|
+
error("\uC124\uCE58\uD560 \uC218 \uC5C6\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
|
|
4915
|
+
for (const e of readErrors) error(` - ${e}`);
|
|
4916
|
+
return result;
|
|
4917
|
+
}
|
|
4918
|
+
const decisions = [];
|
|
4919
|
+
for (const file of plan.files) {
|
|
4920
|
+
const current = existing.get(file) ?? null;
|
|
4921
|
+
if (current === null) {
|
|
4922
|
+
decisions.push({ file, action: "write" });
|
|
4923
|
+
continue;
|
|
4924
|
+
}
|
|
4925
|
+
if (current === file.content) {
|
|
4926
|
+
decisions.push({ file, action: "unchanged" });
|
|
4927
|
+
continue;
|
|
4928
|
+
}
|
|
4929
|
+
if (options.overwrite) {
|
|
4930
|
+
decisions.push({ file, action: "overwrite" });
|
|
4931
|
+
} else if (options.yes || !ctx.confirm) {
|
|
4932
|
+
decisions.push({ file, action: "skip" });
|
|
4933
|
+
} else {
|
|
4934
|
+
const ok = await ctx.confirm(`${rel2(root, file.target)} \uC758 \uB0B4\uC6A9\uC774 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC640 \uB2E4\uB985\uB2C8\uB2E4. \uB36E\uC5B4\uC4F0\uC2DC\uACA0\uC2B5\uB2C8\uAE4C?`);
|
|
4935
|
+
decisions.push({ file, action: ok ? "overwrite" : "skip" });
|
|
4936
|
+
}
|
|
4937
|
+
}
|
|
4938
|
+
const outsideLinks = /* @__PURE__ */ new Map();
|
|
4939
|
+
for (const d of decisions) {
|
|
4940
|
+
const outside = outsideLinkTarget(root, d.file.target);
|
|
4941
|
+
if (outside !== null) outsideLinks.set(d.file, outside);
|
|
4942
|
+
}
|
|
4943
|
+
const linkErrors = decisions.filter((d) => (d.action === "write" || d.action === "overwrite") && isSymlink(d.file.target)).map((d) => {
|
|
4944
|
+
const outside = outsideLinks.get(d.file);
|
|
4945
|
+
const what = outside !== void 0 ? `\uD504\uB85C\uC81D\uD2B8 \uBC16(${outside})\uC744 \uAC00\uB9AC\uD0A4\uB294 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C` : "\uD504\uB85C\uC81D\uD2B8 \uC548\uC744 \uAC00\uB9AC\uD0A4\uB294 \uC2EC\uBCFC\uB9AD \uB9C1\uD06C\uB77C";
|
|
4946
|
+
return `${d.file.item.name}: \uAE30\uC874 \uD30C\uC77C ${rel2(root, d.file.target)} \uC774 ${what} \uB36E\uC5B4\uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uB9C1\uD06C\uB294 \uB530\uB77C\uAC00 \uC4F0\uC9C0 \uC54A\uC73C\uB2C8 \uB9C1\uD06C\uB97C \uC9C0\uC6B0\uAC70\uB098 \uC2E4\uC81C \uD30C\uC77C\uB85C \uBC14\uAFBC \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694`;
|
|
4947
|
+
});
|
|
4948
|
+
for (const d of decisions) {
|
|
4949
|
+
if (d.action !== "overwrite") continue;
|
|
4950
|
+
const nlink = hardLinkCount(d.file.target);
|
|
4951
|
+
if (nlink !== null) linkErrors.push(`${d.file.item.name}: ${hardLinkMessage(rel2(root, d.file.target), nlink)}`);
|
|
4952
|
+
}
|
|
4953
|
+
if (linkErrors.length > 0) {
|
|
4954
|
+
error("\uC124\uCE58\uD560 \uC218 \uC5C6\uC5B4 \uC544\uBB34\uAC83\uB3C4 \uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
|
|
4955
|
+
for (const e of linkErrors) error(` - ${e}`);
|
|
4956
|
+
return result;
|
|
4957
|
+
}
|
|
4958
|
+
const stopWriting = (p, reason, tail = "\uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.") => {
|
|
4959
|
+
error(`${p}: ${reason}. ${tail}`);
|
|
4960
|
+
if (result.written.length > 0) {
|
|
4961
|
+
error(`\uC774\uBBF8 \uC4F4 \uD30C\uC77C(${result.written.length}):`);
|
|
4962
|
+
for (const w of result.written) error(` ${result.overwritten.includes(w) ? "~" : "+"} ${w}`);
|
|
4963
|
+
}
|
|
4964
|
+
return { ...result, exitCode: 1 };
|
|
3782
4965
|
};
|
|
3783
|
-
|
|
3784
|
-
|
|
4966
|
+
for (const d of decisions) {
|
|
4967
|
+
const p = rel2(root, d.file.target);
|
|
4968
|
+
if (d.action === "unchanged") {
|
|
4969
|
+
result.unchanged.push(p);
|
|
4970
|
+
continue;
|
|
4971
|
+
}
|
|
4972
|
+
if (d.action === "skip") {
|
|
4973
|
+
result.skipped.push(p);
|
|
4974
|
+
continue;
|
|
4975
|
+
}
|
|
4976
|
+
let actual = d.action === "write" ? "new" : "overwrite";
|
|
4977
|
+
try {
|
|
4978
|
+
const before = escapeReason(root, d.file.target);
|
|
4979
|
+
if (before) return stopWriting(p, before);
|
|
4980
|
+
await fs12.ensureDir(path15.dirname(d.file.target));
|
|
4981
|
+
const after = checkParentInside(root, d.file.target);
|
|
4982
|
+
if (after) return stopWriting(p, after);
|
|
4983
|
+
actual = await writeNoFollow(d.file.target, d.file.content, actual);
|
|
4984
|
+
} catch (e) {
|
|
4985
|
+
const code = e.code;
|
|
4986
|
+
if (code === "ELOOP" || code === "EEXIST" && isSymlink(d.file.target)) {
|
|
4987
|
+
return stopWriting(p, "\uAC80\uC0AC \uB4A4 \uC4F0\uAE30 \uC9C1\uC804\uC5D0 \uB9C1\uD06C\uB85C \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569)");
|
|
4988
|
+
}
|
|
4989
|
+
if (code === HARDLINK_ERROR_CODE) {
|
|
4990
|
+
return stopWriting(
|
|
4991
|
+
p,
|
|
4992
|
+
"\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)",
|
|
4993
|
+
"\uADF8 \uD30C\uC77C\uC740 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4(D19). \uD558\uB4DC\uB9C1\uD06C\uB97C \uB04A\uC740 \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694."
|
|
4994
|
+
);
|
|
4995
|
+
}
|
|
4996
|
+
if (code === "EEXIST") {
|
|
4997
|
+
return stopWriting(
|
|
4998
|
+
p,
|
|
4999
|
+
"\uC0C8 \uD30C\uC77C\uB85C \uD310\uC815\uD55C \uB4A4(\uD655\uC778 \uB300\uAE30 \uC911 \uB4F1) \uAC19\uC740 \uC774\uB984\uC758 \uD30C\uC77C\uC774 \uC0DD\uACBC\uC2B5\uB2C8\uB2E4(\uB3D9\uC2DC \uACBD\uD569)",
|
|
5000
|
+
"\uADF8 \uD30C\uC77C\uC740 \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uB0B4\uC6A9\uC744 \uD655\uC778\uD55C \uB4A4 \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694."
|
|
5001
|
+
);
|
|
5002
|
+
}
|
|
5003
|
+
return stopWriting(p, `\uC4F0\uAE30 \uC2E4\uD328(${e.message})`);
|
|
5004
|
+
}
|
|
5005
|
+
const outside = writtenOutside(root, d.file.target);
|
|
5006
|
+
if (outside !== null) {
|
|
5007
|
+
return stopWriting(
|
|
5008
|
+
p,
|
|
5009
|
+
`\uC4F4 \uB4A4 \uD655\uC778\uD55C \uC2E4\uC81C \uC704\uCE58(${outside})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(\uAC80\uC0AC\uC640 \uC4F0\uAE30 \uC0AC\uC774\uC5D0 \uC0C1\uC704 \uB514\uB809\uD130\uB9AC\uAC00 \uBC14\uB010 \uB3D9\uC2DC \uACBD\uD569)`,
|
|
5010
|
+
`\uADF8 \uD30C\uC77C\uC740 \uC9C0\uC6B0\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${outside} \uB97C \uC9C1\uC811 \uD655\uC778\uD558\uC138\uC694.`
|
|
5011
|
+
);
|
|
5012
|
+
}
|
|
5013
|
+
result.written.push(p);
|
|
5014
|
+
if (actual === "overwrite") result.overwritten.push(p);
|
|
5015
|
+
}
|
|
5016
|
+
const broken = [];
|
|
5017
|
+
for (const d of decisions) {
|
|
5018
|
+
if (d.action === "skip") continue;
|
|
5019
|
+
for (const r of d.file.rewritten) {
|
|
5020
|
+
if (!relativeSpecifierResolves(d.file.target, r.to)) {
|
|
5021
|
+
broken.push(`${rel2(root, d.file.target)}: '${r.to}'(\uC6D0\uB798 '${r.from}')\uAC00 \uAC00\uB9AC\uD0A4\uB294 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4`);
|
|
5022
|
+
}
|
|
5023
|
+
}
|
|
3785
5024
|
}
|
|
3786
|
-
|
|
3787
|
-
|
|
5025
|
+
const itemNames = items.map((it) => it.name);
|
|
5026
|
+
log(`\uC124\uCE58 \uD56D\uBAA9(${items.length}): ${itemNames.join(", ")}`);
|
|
5027
|
+
for (const p of result.written) {
|
|
5028
|
+
if (result.overwritten.includes(p)) log(` ~ ${p} (\uB36E\uC5B4\uC500)`);
|
|
5029
|
+
else log(` + ${p}`);
|
|
3788
5030
|
}
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
});
|
|
5031
|
+
const outsideRel = new Set([...outsideLinks.keys()].map((f) => rel2(root, f.target)));
|
|
5032
|
+
for (const p of result.unchanged) {
|
|
5033
|
+
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
|
+
}
|
|
5035
|
+
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 --overwrite):`);
|
|
5037
|
+
for (const p of result.skipped) log(outsideRel.has(p) ? ` - ${p} (\uB9C1\uD06C \uB300\uC0C1\uC774 \uD504\uB85C\uC81D\uD2B8 \uBC16)` : ` - ${p}`);
|
|
5038
|
+
}
|
|
5039
|
+
if (broken.length > 0) {
|
|
5040
|
+
error("\uC124\uCE58\uD55C \uD30C\uC77C\uC758 import \uAC00 \uD480\uB9AC\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4:");
|
|
5041
|
+
for (const b of broken) error(` - ${b}`);
|
|
5042
|
+
return { ...result, exitCode: 1 };
|
|
5043
|
+
}
|
|
5044
|
+
const deps = missingDependencies(root, items);
|
|
5045
|
+
if (Object.keys(deps.specs).length > 0) {
|
|
5046
|
+
log("\npackage.json \uC5D0 \uC5C6\uB294 \uC758\uC874\uC131(\uC124\uCE58\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4):");
|
|
5047
|
+
log(` ${addCommandForSpecs(deps.installCommand, deps.specs)}`);
|
|
5048
|
+
}
|
|
5049
|
+
return { ...result, exitCode: 0 };
|
|
5050
|
+
}
|
|
5051
|
+
function groupIndex(index) {
|
|
5052
|
+
const ui = [];
|
|
5053
|
+
const agentic = [];
|
|
5054
|
+
for (const it of index.items) {
|
|
5055
|
+
const kind = itemKind(it);
|
|
5056
|
+
if (kind === "lib") continue;
|
|
5057
|
+
const entry = { name: it.name, title: it.title, description: it.description };
|
|
5058
|
+
(kind === "agentic" ? agentic : ui).push(entry);
|
|
5059
|
+
}
|
|
5060
|
+
return { ui, agentic };
|
|
5061
|
+
}
|
|
5062
|
+
async function createClientFor(cwd, notify, env = process.env) {
|
|
5063
|
+
let config = null;
|
|
5064
|
+
try {
|
|
5065
|
+
config = await readAxisConfig(path15.resolve(cwd));
|
|
5066
|
+
} catch {
|
|
5067
|
+
config = null;
|
|
5068
|
+
}
|
|
5069
|
+
const resolved = resolveRegistryUrl({ config, env });
|
|
5070
|
+
const say = notify ?? ((message) => console.warn(message));
|
|
5071
|
+
if (resolved.migratedFrom !== void 0) say(LEGACY_REGISTRY_NOTICE);
|
|
5072
|
+
return new RegistryClient({ url: resolved.url, ...notify ? { notify } : {} });
|
|
5073
|
+
}
|
|
5074
|
+
|
|
5075
|
+
// src/add/index.ts
|
|
5076
|
+
function createConfirm(interactive) {
|
|
5077
|
+
if (!interactive) return void 0;
|
|
5078
|
+
return async (message) => {
|
|
5079
|
+
const { overwrite } = await prompts3({ type: "confirm", name: "overwrite", message, initial: false });
|
|
5080
|
+
return overwrite === true;
|
|
5081
|
+
};
|
|
5082
|
+
}
|
|
5083
|
+
var defaultCreateClient = (cwd) => createClientFor(cwd, (m) => console.warn(chalk11.yellow(m)));
|
|
5084
|
+
function registerAddCommand(program2, deps = {}) {
|
|
5085
|
+
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
|
+
const client = await (deps.createClient ?? defaultCreateClient)(process.cwd());
|
|
5087
|
+
const confirm = createConfirm((deps.isInteractive ?? (() => process.stdin.isTTY === true))());
|
|
5088
|
+
const result = await runAdd(process.cwd(), components, options, {
|
|
5089
|
+
client,
|
|
5090
|
+
log: (...a) => console.log(...a),
|
|
5091
|
+
error: (...a) => console.error(chalk11.red(a.map(String).join(" "))),
|
|
5092
|
+
...confirm ? { confirm } : {}
|
|
5093
|
+
});
|
|
5094
|
+
process.exitCode = result.exitCode;
|
|
5095
|
+
});
|
|
5096
|
+
}
|
|
5097
|
+
function registerListCommand(program2, deps = {}) {
|
|
5098
|
+
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
|
+
if (options.category !== void 0 && options.category !== "ui" && options.category !== "agentic") {
|
|
5100
|
+
console.error(chalk11.red(`--category \uB294 ui \uB610\uB294 agentic \uC785\uB2C8\uB2E4(\uBC1B\uC740 \uAC12: ${options.category})`));
|
|
5101
|
+
process.exitCode = 1;
|
|
5102
|
+
return;
|
|
5103
|
+
}
|
|
5104
|
+
const client = await (deps.createClient ?? defaultCreateClient)(process.cwd());
|
|
5105
|
+
let groups;
|
|
5106
|
+
let version;
|
|
5107
|
+
try {
|
|
5108
|
+
const index = await client.getIndex();
|
|
5109
|
+
groups = groupIndex(index);
|
|
5110
|
+
version = index.version;
|
|
5111
|
+
} catch (e) {
|
|
5112
|
+
console.error(chalk11.red(`\uB808\uC9C0\uC2A4\uD2B8\uB9AC\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${e.message}`));
|
|
5113
|
+
process.exitCode = 1;
|
|
5114
|
+
return;
|
|
5115
|
+
}
|
|
5116
|
+
const total = groups.ui.length + groups.agentic.length;
|
|
5117
|
+
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(chalk11.blue(`
|
|
5119
|
+
\u{1F4E6} AXIS Design System \uCEF4\uD3EC\uB10C\uD2B8 ${total}\uAC1C (${origin}, version ${version})
|
|
5120
|
+
`));
|
|
5121
|
+
const show = (label, items) => {
|
|
5122
|
+
console.log(chalk11.bold(`${label} (${items.length})`));
|
|
5123
|
+
for (const c of items) {
|
|
5124
|
+
console.log(` ${chalk11.cyan(c.name.padEnd(32))} ${chalk11.gray(c.description ?? c.title ?? "")}`);
|
|
5125
|
+
}
|
|
5126
|
+
console.log();
|
|
5127
|
+
};
|
|
5128
|
+
if (!options.category || options.category === "ui") show("Core UI", groups.ui);
|
|
5129
|
+
if (!options.category || options.category === "agentic") show("Agentic UI", groups.agentic);
|
|
5130
|
+
console.log(chalk11.gray("\uC0AC\uC6A9\uBC95: npx @axis-ds/cli add <\uC774\uB984...> (\uC608: add button input card)"));
|
|
5131
|
+
console.log(chalk11.gray("Agentic: npx @axis-ds/cli add run-progress --agentic (= add agentic-run-progress)\n"));
|
|
5132
|
+
});
|
|
5133
|
+
}
|
|
5134
|
+
|
|
5135
|
+
// src/index.ts
|
|
5136
|
+
var { version: CLI_VERSION } = createRequire2(import.meta.url)("../package.json");
|
|
5137
|
+
var program = new Command();
|
|
5138
|
+
program.name("axis").description("AXIS Design System CLI - shadcn \uD638\uD658 \uCEF4\uD3EC\uB10C\uD2B8 \uC124\uCE58 \uB3C4\uAD6C").version(CLI_VERSION);
|
|
5139
|
+
registerInitCommand(program);
|
|
5140
|
+
registerAddCommand(program);
|
|
5141
|
+
registerListCommand(program);
|
|
3792
5142
|
var monetCmd = program.command("monet").description("Monet Design \uCEF4\uD3EC\uB10C\uD2B8 \uAD00\uB9AC (https://monet.design)");
|
|
3793
5143
|
monetCmd.command("list").alias("ls").description("Monet \uCE74\uD14C\uACE0\uB9AC \uBAA9\uB85D").action(async () => {
|
|
3794
5144
|
const client = new MonetClient();
|
|
@@ -3807,24 +5157,24 @@ monetCmd.command("import").alias("i").description("\uD074\uB9BD\uBCF4\uB4DC\uC5D
|
|
|
3807
5157
|
await client.importFromClipboard();
|
|
3808
5158
|
});
|
|
3809
5159
|
monetCmd.command("setup").description("Monet MCP \uC11C\uBC84 \uC124\uC815 \uC548\uB0B4").action(() => {
|
|
3810
|
-
console.log(
|
|
3811
|
-
console.log(
|
|
3812
|
-
console.log(
|
|
3813
|
-
console.log(
|
|
3814
|
-
console.log(
|
|
3815
|
-
console.log(
|
|
3816
|
-
console.log(
|
|
3817
|
-
console.log(
|
|
5160
|
+
console.log(chalk12.blue("\n\u{1F527} Monet MCP \uC11C\uBC84 \uC124\uC815\n"));
|
|
5161
|
+
console.log(chalk12.bold("1. API \uD0A4 \uBC1C\uAE09:"));
|
|
5162
|
+
console.log(chalk12.cyan(" https://monet.design/mcp\n"));
|
|
5163
|
+
console.log(chalk12.bold("2. \uD658\uACBD \uBCC0\uC218 \uC124\uC815:"));
|
|
5164
|
+
console.log(chalk12.gray(" .env \uD30C\uC77C\uC5D0 \uCD94\uAC00:"));
|
|
5165
|
+
console.log(chalk12.cyan(" MONET_API_KEY=your-api-key-here\n"));
|
|
5166
|
+
console.log(chalk12.bold("3. Claude Code MCP \uC124\uC815:"));
|
|
5167
|
+
console.log(chalk12.gray(" .claude/mcp.json\uC5D0\uC11C monet \uC11C\uBC84 \uD65C\uC131\uD654:\n"));
|
|
3818
5168
|
console.log(
|
|
3819
|
-
|
|
5169
|
+
chalk12.cyan(` "monet": {
|
|
3820
5170
|
"url": "https://www.monet.design/api/remote/mcp",
|
|
3821
5171
|
"headers": { "Authorization": "Bearer \${MONET_API_KEY}" },
|
|
3822
5172
|
"disabled": false
|
|
3823
5173
|
}
|
|
3824
5174
|
`)
|
|
3825
5175
|
);
|
|
3826
|
-
console.log(
|
|
3827
|
-
console.log(
|
|
5176
|
+
console.log(chalk12.bold("4. Claude Code \uC7AC\uC2DC\uC791 \uD6C4 \uC0AC\uC6A9:"));
|
|
5177
|
+
console.log(chalk12.gray(' "monet\uC5D0\uC11C hero \uCEF4\uD3EC\uB10C\uD2B8 \uCC3E\uC544\uC918"\n'));
|
|
3828
5178
|
});
|
|
3829
5179
|
var v0Cmd = program.command("v0").description("V0 (v0.app) \uCF54\uB4DC \uBCC0\uD658 \uBC0F \uD1B5\uD569");
|
|
3830
5180
|
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) => {
|
|
@@ -3861,18 +5211,18 @@ libraryCmd.command("collect").alias("c").description("\uC678\uBD80 \uC18C\uC2A4\
|
|
|
3861
5211
|
total += result.collected;
|
|
3862
5212
|
failed += result.failed;
|
|
3863
5213
|
}
|
|
3864
|
-
console.log(
|
|
5214
|
+
console.log(chalk12.blue(`
|
|
3865
5215
|
\u{1F4CA} \uC218\uC9D1 \uC644\uB8CC: ${total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8`));
|
|
3866
5216
|
if (failed > 0) {
|
|
3867
|
-
console.log(
|
|
5217
|
+
console.log(chalk12.yellow(` \uC2E4\uD328: ${failed}\uAC1C`));
|
|
3868
5218
|
}
|
|
3869
5219
|
});
|
|
3870
5220
|
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) => {
|
|
3871
5221
|
const curator = new LibraryCurator();
|
|
3872
5222
|
const index = await curator.loadIndex();
|
|
3873
5223
|
if (!index) {
|
|
3874
|
-
console.log(
|
|
3875
|
-
console.log(
|
|
5224
|
+
console.log(chalk12.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
5225
|
+
console.log(chalk12.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
3876
5226
|
return;
|
|
3877
5227
|
}
|
|
3878
5228
|
let components = index.components;
|
|
@@ -3882,7 +5232,7 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
3882
5232
|
if (options.source) {
|
|
3883
5233
|
components = components.filter((c) => c.source.type === options.source);
|
|
3884
5234
|
}
|
|
3885
|
-
console.log(
|
|
5235
|
+
console.log(chalk12.blue(`
|
|
3886
5236
|
\u{1F4E6} Library Components (${components.length}\uAC1C)
|
|
3887
5237
|
`));
|
|
3888
5238
|
const byCategory = /* @__PURE__ */ new Map();
|
|
@@ -3894,14 +5244,14 @@ libraryCmd.command("list").alias("ls").description("\uB77C\uC774\uBE0C\uB7EC\uB9
|
|
|
3894
5244
|
byCategory.get(cat).push(comp);
|
|
3895
5245
|
}
|
|
3896
5246
|
for (const [category, items] of byCategory) {
|
|
3897
|
-
console.log(
|
|
5247
|
+
console.log(chalk12.bold(`${category} (${items.length})`));
|
|
3898
5248
|
for (const item of items.slice(0, 10)) {
|
|
3899
5249
|
console.log(
|
|
3900
|
-
` ${
|
|
5250
|
+
` ${chalk12.cyan(item.name.padEnd(25))} ${chalk12.gray(item.source.type.padEnd(8))} ${chalk12.gray(item.description.slice(0, 40))}`
|
|
3901
5251
|
);
|
|
3902
5252
|
}
|
|
3903
5253
|
if (items.length > 10) {
|
|
3904
|
-
console.log(
|
|
5254
|
+
console.log(chalk12.gray(` ... \uC678 ${items.length - 10}\uAC1C`));
|
|
3905
5255
|
}
|
|
3906
5256
|
console.log();
|
|
3907
5257
|
}
|
|
@@ -3913,21 +5263,21 @@ libraryCmd.command("search <query>").alias("s").description("\uCEF4\uD3EC\uB10C\
|
|
|
3913
5263
|
source: options.source
|
|
3914
5264
|
});
|
|
3915
5265
|
if (results.length === 0) {
|
|
3916
|
-
console.log(
|
|
5266
|
+
console.log(chalk12.yellow(`
|
|
3917
5267
|
'${query}'\uC5D0 \uB300\uD55C \uAC80\uC0C9 \uACB0\uACFC\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4.
|
|
3918
5268
|
`));
|
|
3919
5269
|
return;
|
|
3920
5270
|
}
|
|
3921
|
-
console.log(
|
|
5271
|
+
console.log(chalk12.blue(`
|
|
3922
5272
|
\u{1F50D} '${query}' \uAC80\uC0C9 \uACB0\uACFC (${results.length}\uAC1C)
|
|
3923
5273
|
`));
|
|
3924
5274
|
for (const comp of results.slice(0, 20)) {
|
|
3925
5275
|
console.log(
|
|
3926
|
-
` ${
|
|
5276
|
+
` ${chalk12.cyan(comp.name.padEnd(25))} ${chalk12.gray(comp.source.type.padEnd(8))} ${chalk12.gray(comp.category.padEnd(12))} ${chalk12.gray(comp.description.slice(0, 30))}`
|
|
3927
5277
|
);
|
|
3928
5278
|
}
|
|
3929
5279
|
if (results.length > 20) {
|
|
3930
|
-
console.log(
|
|
5280
|
+
console.log(chalk12.gray(`
|
|
3931
5281
|
... \uC678 ${results.length - 20}\uAC1C`));
|
|
3932
5282
|
}
|
|
3933
5283
|
console.log();
|
|
@@ -3941,12 +5291,12 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
3941
5291
|
const publisher2 = new Publisher();
|
|
3942
5292
|
const index = await curator.loadIndex();
|
|
3943
5293
|
if (!index) {
|
|
3944
|
-
console.log(
|
|
3945
|
-
console.log(
|
|
5294
|
+
console.log(chalk12.yellow("\n\u26A0\uFE0F \uB77C\uC774\uBE0C\uB7EC\uB9AC \uC778\uB371\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4."));
|
|
5295
|
+
console.log(chalk12.gray(" \uD574\uACB0: npx @axis-ds/cli library collect \uBA85\uB839\uC5B4\uB85C \uC218\uC9D1\uC744 \uBA3C\uC800 \uC2E4\uD589\uD558\uC138\uC694.\n"));
|
|
3946
5296
|
return;
|
|
3947
5297
|
}
|
|
3948
|
-
console.log(
|
|
3949
|
-
console.log(
|
|
5298
|
+
console.log(chalk12.blue("\n\u{1F4E4} Library \uBC30\uCE58\n"));
|
|
5299
|
+
console.log(chalk12.gray(`\uCD1D ${index.stats.total}\uAC1C \uCEF4\uD3EC\uB10C\uD2B8
|
|
3950
5300
|
`));
|
|
3951
5301
|
if (options.clean) {
|
|
3952
5302
|
await publisher2.clean(options.output);
|
|
@@ -3957,17 +5307,17 @@ libraryCmd.command("publish").description("\uC0AC\uC774\uD2B8\uC5D0 \uB77C\uC774
|
|
|
3957
5307
|
generateSearchIndex: true
|
|
3958
5308
|
});
|
|
3959
5309
|
if (result.success) {
|
|
3960
|
-
console.log(
|
|
5310
|
+
console.log(chalk12.green(`
|
|
3961
5311
|
\u2713 \uBC30\uCE58 \uC644\uB8CC`));
|
|
3962
|
-
console.log(
|
|
3963
|
-
console.log(
|
|
3964
|
-
console.log(
|
|
3965
|
-
console.log(
|
|
5312
|
+
console.log(chalk12.gray(` - \uCD9C\uB825 \uB514\uB809\uD1A0\uB9AC: ${result.outputDir}`));
|
|
5313
|
+
console.log(chalk12.gray(` - \uC0DD\uC131\uB41C \uD30C\uC77C: ${result.files.length}\uAC1C`));
|
|
5314
|
+
console.log(chalk12.gray(` - \uCE74\uD14C\uACE0\uB9AC: ${result.stats.categoriesPublished}\uAC1C`));
|
|
5315
|
+
console.log(chalk12.gray(` - \uAC80\uC0C9 \uC778\uB371\uC2A4: ${result.stats.searchIndexSize}\uAC1C \uD56D\uBAA9`));
|
|
3966
5316
|
} else {
|
|
3967
|
-
console.log(
|
|
5317
|
+
console.log(chalk12.red(`
|
|
3968
5318
|
\u2717 \uBC30\uCE58 \uC2E4\uD328`));
|
|
3969
5319
|
for (const error of result.errors) {
|
|
3970
|
-
console.log(
|
|
5320
|
+
console.log(chalk12.red(` - ${error}`));
|
|
3971
5321
|
}
|
|
3972
5322
|
}
|
|
3973
5323
|
console.log();
|
|
@@ -3976,64 +5326,4 @@ registerSyncCommand(program);
|
|
|
3976
5326
|
registerTemplateCommand(program);
|
|
3977
5327
|
registerCheckCommand(program);
|
|
3978
5328
|
registerThemeCommand(program);
|
|
3979
|
-
async function getComponentInfo(name, category) {
|
|
3980
|
-
const localComponents = {
|
|
3981
|
-
button: {
|
|
3982
|
-
name: "button",
|
|
3983
|
-
type: "ui",
|
|
3984
|
-
description: "Primary button component",
|
|
3985
|
-
dependencies: ["@radix-ui/react-slot", "class-variance-authority", "clsx", "tailwind-merge"],
|
|
3986
|
-
files: [
|
|
3987
|
-
{
|
|
3988
|
-
path: "button.tsx",
|
|
3989
|
-
content: `import * as React from "react"
|
|
3990
|
-
import { Slot } from "@radix-ui/react-slot"
|
|
3991
|
-
import { cva, type VariantProps } from "class-variance-authority"
|
|
3992
|
-
import { cn } from "./utils"
|
|
3993
|
-
|
|
3994
|
-
const buttonVariants = cva(
|
|
3995
|
-
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
|
|
3996
|
-
{
|
|
3997
|
-
variants: {
|
|
3998
|
-
variant: {
|
|
3999
|
-
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
4000
|
-
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
4001
|
-
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
4002
|
-
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
4003
|
-
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
4004
|
-
link: "text-primary underline-offset-4 hover:underline",
|
|
4005
|
-
},
|
|
4006
|
-
size: {
|
|
4007
|
-
sm: "h-8 px-3 text-xs",
|
|
4008
|
-
default: "h-10 px-4 py-2",
|
|
4009
|
-
lg: "h-12 px-6 text-base",
|
|
4010
|
-
icon: "h-10 w-10",
|
|
4011
|
-
},
|
|
4012
|
-
},
|
|
4013
|
-
defaultVariants: { variant: "default", size: "default" },
|
|
4014
|
-
}
|
|
4015
|
-
)
|
|
4016
|
-
|
|
4017
|
-
export interface ButtonProps
|
|
4018
|
-
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
|
4019
|
-
VariantProps<typeof buttonVariants> {
|
|
4020
|
-
asChild?: boolean
|
|
4021
|
-
}
|
|
4022
|
-
|
|
4023
|
-
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
|
4024
|
-
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
4025
|
-
const Comp = asChild ? Slot : "button"
|
|
4026
|
-
return <Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
|
|
4027
|
-
}
|
|
4028
|
-
)
|
|
4029
|
-
Button.displayName = "Button"
|
|
4030
|
-
|
|
4031
|
-
export { Button, buttonVariants }
|
|
4032
|
-
`
|
|
4033
|
-
}
|
|
4034
|
-
]
|
|
4035
|
-
}
|
|
4036
|
-
};
|
|
4037
|
-
return localComponents[name] || null;
|
|
4038
|
-
}
|
|
4039
5329
|
program.parse();
|