@axis-ds/cli 1.7.10 → 1.8.0
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 +10 -2
- package/dist/index.js +845 -243
- package/dist/registry/agentic-tool-call-card.json +1 -1
- package/dist/registry/index.json +4 -4
- package/dist/registry/registry.json +4 -4
- package/dist/registry/select.json +1 -1
- package/dist/registry/toast.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -526,11 +526,11 @@ var ShadcnCollector = class extends BaseCollector {
|
|
|
526
526
|
/**
|
|
527
527
|
* 파일 타입 추론
|
|
528
528
|
*/
|
|
529
|
-
getFileType(
|
|
530
|
-
if (
|
|
531
|
-
if (
|
|
532
|
-
if (
|
|
533
|
-
if (
|
|
529
|
+
getFileType(path18) {
|
|
530
|
+
if (path18.includes("hook") || path18.startsWith("use")) return "hook";
|
|
531
|
+
if (path18.includes("util") || path18.includes("lib")) return "util";
|
|
532
|
+
if (path18.endsWith(".css")) return "style";
|
|
533
|
+
if (path18.endsWith(".d.ts") || path18.includes("types")) return "type";
|
|
534
534
|
return "component";
|
|
535
535
|
}
|
|
536
536
|
};
|
|
@@ -2982,9 +2982,9 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2982
2982
|
};
|
|
2983
2983
|
}
|
|
2984
2984
|
for (const file of TAILWIND_CONFIG_FILES) {
|
|
2985
|
-
const
|
|
2986
|
-
if (!existsSync2(
|
|
2987
|
-
const content = readFileSync2(
|
|
2985
|
+
const path18 = join(baseDir, file);
|
|
2986
|
+
if (!existsSync2(path18)) continue;
|
|
2987
|
+
const content = readFileSync2(path18, "utf8");
|
|
2988
2988
|
if (hasTokensPresetReference(content)) {
|
|
2989
2989
|
const code = stripJsComments(content);
|
|
2990
2990
|
const bareCjs = isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code);
|
|
@@ -3906,8 +3906,8 @@ async function collectLocalFiles(dir, base) {
|
|
|
3906
3906
|
}
|
|
3907
3907
|
|
|
3908
3908
|
// src/template/template-check.ts
|
|
3909
|
-
import
|
|
3910
|
-
import
|
|
3909
|
+
import fs11 from "fs-extra";
|
|
3910
|
+
import path12 from "path";
|
|
3911
3911
|
import chalk7 from "chalk";
|
|
3912
3912
|
|
|
3913
3913
|
// src/theme/brand-core.ts
|
|
@@ -4502,6 +4502,763 @@ function checkDependencies(baseDirInput) {
|
|
|
4502
4502
|
};
|
|
4503
4503
|
}
|
|
4504
4504
|
|
|
4505
|
+
// ../axis-registry-core/src/template/template-checks.ts
|
|
4506
|
+
import { lstatSync as lstatSync4, readdirSync as readdirSync3, readFileSync as readFileSync5, realpathSync as realpathSync4, statSync as statSync4 } from "fs";
|
|
4507
|
+
import path11 from "path";
|
|
4508
|
+
|
|
4509
|
+
// ../axis-registry-core/src/add/safe-write.ts
|
|
4510
|
+
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync3, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
4511
|
+
import path10 from "path";
|
|
4512
|
+
import fs10 from "fs-extra";
|
|
4513
|
+
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
4514
|
+
var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
|
|
4515
|
+
var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
|
|
4516
|
+
var NOT_REGULAR_ERROR_CODE = "EAXISNOTREG";
|
|
4517
|
+
function codedError(code, message) {
|
|
4518
|
+
const e = new Error(message);
|
|
4519
|
+
e.code = code;
|
|
4520
|
+
return e;
|
|
4521
|
+
}
|
|
4522
|
+
function isSameOrInside(parent, child, impl = path10) {
|
|
4523
|
+
const rel3 = impl.relative(parent, child);
|
|
4524
|
+
if (rel3 === "") return true;
|
|
4525
|
+
return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
|
|
4526
|
+
}
|
|
4527
|
+
function nearestExisting(p) {
|
|
4528
|
+
let cur = p;
|
|
4529
|
+
while (!existsSync4(cur)) {
|
|
4530
|
+
const up = path10.dirname(cur);
|
|
4531
|
+
if (up === cur) return cur;
|
|
4532
|
+
cur = up;
|
|
4533
|
+
}
|
|
4534
|
+
return cur;
|
|
4535
|
+
}
|
|
4536
|
+
function escapeReason(root, target, options = {}) {
|
|
4537
|
+
const realRoot = realpathSync3(root);
|
|
4538
|
+
if (!isSameOrInside(path10.resolve(root), path10.resolve(target)) || path10.resolve(target) === path10.resolve(root)) {
|
|
4539
|
+
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
4540
|
+
}
|
|
4541
|
+
const anchor = nearestExisting(path10.dirname(target));
|
|
4542
|
+
const realAnchor = realpathSync3(anchor);
|
|
4543
|
+
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
4544
|
+
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`;
|
|
4545
|
+
}
|
|
4546
|
+
let st = null;
|
|
4547
|
+
try {
|
|
4548
|
+
st = lstatSync3(target);
|
|
4549
|
+
} catch {
|
|
4550
|
+
st = null;
|
|
4551
|
+
}
|
|
4552
|
+
if (st) {
|
|
4553
|
+
if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
|
|
4554
|
+
const shown = path10.relative(path10.resolve(root), path10.resolve(target)).split(path10.sep).join("/");
|
|
4555
|
+
let realTarget;
|
|
4556
|
+
try {
|
|
4557
|
+
realTarget = realpathSync3(target);
|
|
4558
|
+
} catch {
|
|
4559
|
+
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)`;
|
|
4560
|
+
}
|
|
4561
|
+
if (!isSameOrInside(realRoot, realTarget) && !(options.allowOutsideLink && st.isSymbolicLink())) {
|
|
4562
|
+
return `\uAE30\uC874 \uD30C\uC77C\uC758 \uC2E4\uC81C \uC704\uCE58(${realTarget})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
|
|
4563
|
+
}
|
|
4564
|
+
let followed;
|
|
4565
|
+
try {
|
|
4566
|
+
followed = statSync3(realTarget);
|
|
4567
|
+
} catch {
|
|
4568
|
+
return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
|
|
4569
|
+
}
|
|
4570
|
+
if (followed.isDirectory()) {
|
|
4571
|
+
return `\uAC19\uC740 \uC774\uB984\uC758 \uB9C1\uD06C\uAC00 \uB514\uB809\uD130\uB9AC(${realTarget})\uB97C \uAC00\uB9AC\uD0B5\uB2C8\uB2E4(${target})`;
|
|
4572
|
+
}
|
|
4573
|
+
if (!followed.isFile()) {
|
|
4574
|
+
const where = st.isSymbolicLink() ? `\uB9C1\uD06C \uB300\uC0C1(${realTarget})\uC774` : "\uAE30\uC874 \uD30C\uC77C\uC774";
|
|
4575
|
+
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})`;
|
|
4576
|
+
}
|
|
4577
|
+
}
|
|
4578
|
+
return null;
|
|
4579
|
+
}
|
|
4580
|
+
function isSymlink(p) {
|
|
4581
|
+
try {
|
|
4582
|
+
return lstatSync3(p).isSymbolicLink();
|
|
4583
|
+
} catch {
|
|
4584
|
+
return false;
|
|
4585
|
+
}
|
|
4586
|
+
}
|
|
4587
|
+
function outsideLinkTarget(root, target) {
|
|
4588
|
+
if (!isSymlink(target)) return null;
|
|
4589
|
+
try {
|
|
4590
|
+
const realTarget = realpathSync3(target);
|
|
4591
|
+
return isSameOrInside(realpathSync3(root), realTarget) ? null : realTarget;
|
|
4592
|
+
} catch {
|
|
4593
|
+
return null;
|
|
4594
|
+
}
|
|
4595
|
+
}
|
|
4596
|
+
function hardLinkCount(target) {
|
|
4597
|
+
try {
|
|
4598
|
+
const st = lstatSync3(target);
|
|
4599
|
+
return st.isFile() && st.nlink >= 2 ? st.nlink : null;
|
|
4600
|
+
} catch {
|
|
4601
|
+
return null;
|
|
4602
|
+
}
|
|
4603
|
+
}
|
|
4604
|
+
function hardLinkMessage(shownPath, nlink) {
|
|
4605
|
+
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`;
|
|
4606
|
+
}
|
|
4607
|
+
function writtenOutside(root, target) {
|
|
4608
|
+
const realRoot = realpathSync3(root);
|
|
4609
|
+
let realTarget;
|
|
4610
|
+
try {
|
|
4611
|
+
realTarget = realpathSync3(target);
|
|
4612
|
+
} catch {
|
|
4613
|
+
return target;
|
|
4614
|
+
}
|
|
4615
|
+
return isSameOrInside(realRoot, realTarget) ? null : realTarget;
|
|
4616
|
+
}
|
|
4617
|
+
async function writeNoFollow(target, content, mode) {
|
|
4618
|
+
let actual = mode;
|
|
4619
|
+
let fd;
|
|
4620
|
+
if (mode === "overwrite") {
|
|
4621
|
+
try {
|
|
4622
|
+
fd = await fs10.open(target, OVERWRITE_FLAGS);
|
|
4623
|
+
} catch (e) {
|
|
4624
|
+
if (e.code !== "ENOENT") throw e;
|
|
4625
|
+
actual = "new";
|
|
4626
|
+
fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
|
|
4627
|
+
}
|
|
4628
|
+
} else {
|
|
4629
|
+
fd = await fs10.open(target, NEW_FILE_FLAGS, 438);
|
|
4630
|
+
}
|
|
4631
|
+
try {
|
|
4632
|
+
if (actual === "overwrite") {
|
|
4633
|
+
const st = await fs10.fstat(fd);
|
|
4634
|
+
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
4635
|
+
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
4636
|
+
await fs10.ftruncate(fd, 0);
|
|
4637
|
+
}
|
|
4638
|
+
await fs10.writeFile(fd, content);
|
|
4639
|
+
} finally {
|
|
4640
|
+
await fs10.close(fd);
|
|
4641
|
+
}
|
|
4642
|
+
return actual;
|
|
4643
|
+
}
|
|
4644
|
+
async function overwriteFollowingLinks(target, content) {
|
|
4645
|
+
const fd = await fs10.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
|
|
4646
|
+
try {
|
|
4647
|
+
const st = await fs10.fstat(fd);
|
|
4648
|
+
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
4649
|
+
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
4650
|
+
await fs10.ftruncate(fd, 0);
|
|
4651
|
+
await fs10.writeFile(fd, content);
|
|
4652
|
+
} finally {
|
|
4653
|
+
await fs10.close(fd);
|
|
4654
|
+
}
|
|
4655
|
+
}
|
|
4656
|
+
function checkParentInside(root, target) {
|
|
4657
|
+
const realRoot = realpathSync3(root);
|
|
4658
|
+
const realParent = realpathSync3(path10.dirname(target));
|
|
4659
|
+
if (!isSameOrInside(realRoot, realParent)) {
|
|
4660
|
+
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`;
|
|
4661
|
+
}
|
|
4662
|
+
return escapeReason(root, target);
|
|
4663
|
+
}
|
|
4664
|
+
|
|
4665
|
+
// ../axis-registry-core/src/template/template-checks.ts
|
|
4666
|
+
var TEMPLATE_CHECK_DEFINITIONS = /* @__PURE__ */ new Map([
|
|
4667
|
+
["ontology-rules", { id: "ontology-rules", script: "check:ontology" }]
|
|
4668
|
+
]);
|
|
4669
|
+
var TEMPLATE_CHECKS = /* @__PURE__ */ new Map([["ontology-console", ["ontology-rules"]]]);
|
|
4670
|
+
var TEMPLATE_SLUG = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
4671
|
+
var ONTOLOGY_RULE_IDS = ["em-dash", "exclamation", "one-side-line", "card-shadow", "palette"];
|
|
4672
|
+
var ONTOLOGY_TARGETS = ["app", "components", "lib"];
|
|
4673
|
+
var ONTOLOGY_MAX_FILE_BYTES = 256 * 1024;
|
|
4674
|
+
var ONTOLOGY_DIR_DEPTH_LIMIT = 32;
|
|
4675
|
+
var ONTOLOGY_MAX_UNIT_CHARS = 8e3;
|
|
4676
|
+
var ONTOLOGY_SCAN_STEPS_PER_CHAR = 16;
|
|
4677
|
+
var ONTOLOGY_SCAN_STEPS_BASE = 1e5;
|
|
4678
|
+
var ONTOLOGY_MAX_FILES = 4e3;
|
|
4679
|
+
var ONTOLOGY_MAX_TOTAL_BYTES = 16 * 1024 * 1024;
|
|
4680
|
+
var ONTOLOGY_MAX_ENTRIES = 5e4;
|
|
4681
|
+
var ONTOLOGY_DEFAULT_BUDGET = Object.freeze({
|
|
4682
|
+
maxFiles: ONTOLOGY_MAX_FILES,
|
|
4683
|
+
maxBytes: ONTOLOGY_MAX_TOTAL_BYTES,
|
|
4684
|
+
maxEntries: ONTOLOGY_MAX_ENTRIES
|
|
4685
|
+
});
|
|
4686
|
+
var MESSAGE_PATH_MAX = 120;
|
|
4687
|
+
function templateChecksFor(baseDirInput) {
|
|
4688
|
+
let config;
|
|
4689
|
+
try {
|
|
4690
|
+
config = JSON.parse(readFileSync5(path11.join(path11.resolve(baseDirInput), "axis.config.json"), "utf8"));
|
|
4691
|
+
} catch {
|
|
4692
|
+
return null;
|
|
4693
|
+
}
|
|
4694
|
+
if (typeof config !== "object" || config === null || Array.isArray(config)) return null;
|
|
4695
|
+
if (!Object.prototype.hasOwnProperty.call(config, "template")) return null;
|
|
4696
|
+
const template = config.template;
|
|
4697
|
+
if (typeof template !== "string" || !TEMPLATE_SLUG.test(template)) return null;
|
|
4698
|
+
const ids = TEMPLATE_CHECKS.get(template);
|
|
4699
|
+
if (!ids || ids.length === 0) return null;
|
|
4700
|
+
return { template, ids };
|
|
4701
|
+
}
|
|
4702
|
+
function collectTemplateCheckResults(baseDirInput) {
|
|
4703
|
+
const baseDir = path11.resolve(baseDirInput);
|
|
4704
|
+
const picked = templateChecksFor(baseDir);
|
|
4705
|
+
if (!picked) return [];
|
|
4706
|
+
const out = [];
|
|
4707
|
+
for (const id of picked.ids) {
|
|
4708
|
+
const def = TEMPLATE_CHECK_DEFINITIONS.get(id);
|
|
4709
|
+
if (def?.id === "ontology-rules") out.push(ontologyRulesResult(baseDir, picked.template, def));
|
|
4710
|
+
}
|
|
4711
|
+
return out;
|
|
4712
|
+
}
|
|
4713
|
+
function hasPackageScript(baseDir, script) {
|
|
4714
|
+
try {
|
|
4715
|
+
const pkg = JSON.parse(readFileSync5(path11.join(baseDir, "package.json"), "utf8"));
|
|
4716
|
+
if (typeof pkg !== "object" || pkg === null || Array.isArray(pkg)) return false;
|
|
4717
|
+
const scripts = pkg.scripts;
|
|
4718
|
+
if (typeof scripts !== "object" || scripts === null || Array.isArray(scripts)) return false;
|
|
4719
|
+
return Object.prototype.hasOwnProperty.call(scripts, script) && typeof scripts[script] === "string";
|
|
4720
|
+
} catch {
|
|
4721
|
+
return false;
|
|
4722
|
+
}
|
|
4723
|
+
}
|
|
4724
|
+
var MESSAGE_PATH_KEEP = /^[\p{L}\p{N}\p{P}\p{S} ]$/u;
|
|
4725
|
+
function messageSafePath(p) {
|
|
4726
|
+
let out = "";
|
|
4727
|
+
for (const ch of p) {
|
|
4728
|
+
const cp = ch.codePointAt(0);
|
|
4729
|
+
const piece = MESSAGE_PATH_KEEP.test(ch) && ch !== '"' && ch !== "`" && ch !== "\\" ? ch : cp > 65535 ? `\\u{${cp.toString(16)}}` : `\\u${cp.toString(16).padStart(4, "0")}`;
|
|
4730
|
+
if (out.length + piece.length > MESSAGE_PATH_MAX) return `${out}...`;
|
|
4731
|
+
out += piece;
|
|
4732
|
+
}
|
|
4733
|
+
return out;
|
|
4734
|
+
}
|
|
4735
|
+
function ontologyRulesResult(baseDir, template, def) {
|
|
4736
|
+
const name = `template.${def.id}`;
|
|
4737
|
+
const head = `\uD15C\uD50C\uB9BF ${template} \uADDC\uCE59 \uAC80\uC0AC(axis \uB0B4\uC7A5 \uADDC\uCE59, \uC124\uCE58\uD55C axis \uBC84\uC804 \uAE30\uC900 \xB7 \uD504\uB85C\uC81D\uD2B8 \uC2A4\uD06C\uB9BD\uD2B8\uB294 \uC2E4\uD589\uD558\uC9C0 \uC54A\uC74C)`;
|
|
4738
|
+
let inspection;
|
|
4739
|
+
try {
|
|
4740
|
+
inspection = inspectOntologyRules(baseDir);
|
|
4741
|
+
} catch (e) {
|
|
4742
|
+
const code = typeof e?.code === "string" && /^[A-Z0-9_]{1,32}$/.test(e.code) ? e.code : "\uC624\uB958";
|
|
4743
|
+
return { name, severity: "warn", message: `${head}: \uCE21\uC815 \uC2E4\uD328, \uD30C\uC77C\uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${code})` };
|
|
4744
|
+
}
|
|
4745
|
+
const parts = ontologySkippedParts(inspection);
|
|
4746
|
+
const skipped = parts.length > 0 ? `, \uAC74\uB108\uB700: ${parts.join(" \xB7 ")}` : "";
|
|
4747
|
+
if (inspection.checked === 0) {
|
|
4748
|
+
return {
|
|
4749
|
+
name,
|
|
4750
|
+
severity: "warn",
|
|
4751
|
+
message: `${head}: \uCE21\uC815 \uC2E4\uD328, \uAC80\uC0AC\uD560 \uD30C\uC77C\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(\uB300\uC0C1: ${ONTOLOGY_TARGETS.join(" \xB7 ")})${skipped}`
|
|
4752
|
+
};
|
|
4753
|
+
}
|
|
4754
|
+
const { violations } = inspection;
|
|
4755
|
+
if (violations.length === 0) {
|
|
4756
|
+
if (isOntologyIncomplete(inspection)) {
|
|
4757
|
+
return { name, severity: "warn", message: `${head}: \uC77C\uBD80 \uCE21\uC815 \uC2E4\uD328, \uD30C\uC77C ${inspection.checked}\uAC1C \uC704\uBC18 0\uAC74${skipped}` };
|
|
4758
|
+
}
|
|
4759
|
+
return { name, severity: "pass", message: `${head}: \uD30C\uC77C ${inspection.checked}\uAC1C, \uC704\uBC18 0\uAC74${skipped}` };
|
|
4760
|
+
}
|
|
4761
|
+
const counts = ONTOLOGY_RULE_IDS.map((rule) => [rule, violations.filter((v) => v.rule === rule).length]).filter(([, n]) => n > 0).map(([rule, n]) => `${rule} ${n}`).join(" \xB7 ");
|
|
4762
|
+
const first = violations[0];
|
|
4763
|
+
const hint = hasPackageScript(baseDir, def.script) ? ` \u2192 \uC804\uCCB4 \uBCF4\uAE30: npm run ${def.script}` : "";
|
|
4764
|
+
return {
|
|
4765
|
+
name,
|
|
4766
|
+
severity: "warn",
|
|
4767
|
+
message: `${head}: \uD30C\uC77C ${inspection.checked}\uAC1C, \uC704\uBC18 ${violations.length}\uAC74(${counts}), \uCCAB \uC704\uCE58 "${messageSafePath(first.file)}":${first.line} ${first.rule}${skipped}${hint}`
|
|
4768
|
+
};
|
|
4769
|
+
}
|
|
4770
|
+
function ontologySkippedParts(found) {
|
|
4771
|
+
const parts = [];
|
|
4772
|
+
if (found.skippedLarge > 0) parts.push(`\uD06C\uAE30 \uC0C1\uD55C(256KB) \uCD08\uACFC ${found.skippedLarge}\uAC1C`);
|
|
4773
|
+
if (found.skippedLinks > 0) parts.push(`\uD504\uB85C\uC81D\uD2B8 \uBC16 \xB7 \uAE68\uC9C4 \uB9C1\uD06C ${found.skippedLinks}\uAC1C`);
|
|
4774
|
+
if (found.skippedDeep > 0) parts.push(`\uAE4A\uC774 ${ONTOLOGY_DIR_DEPTH_LIMIT} \uB2E8\uACC4 \uBC16 \uB514\uB809\uD130\uB9AC ${found.skippedDeep}\uAC1C`);
|
|
4775
|
+
if (found.partialFiles > 0) parts.push(`\uD074\uB798\uC2A4 \uBB36\uC74C \uC791\uC5C5\uB7C9 \uC0C1\uD55C \uCD08\uACFC(\uC77C\uBD80\uB9CC \uD310\uC815) ${found.partialFiles}\uAC1C`);
|
|
4776
|
+
if (found.budgetStop) parts.push(ontologyBudgetStopText(found.budgetStop));
|
|
4777
|
+
return parts;
|
|
4778
|
+
}
|
|
4779
|
+
function formatBytes(n) {
|
|
4780
|
+
if (n % (1024 * 1024) === 0) return `${n / (1024 * 1024)}MB`;
|
|
4781
|
+
if (n % 1024 === 0) return `${n / 1024}KB`;
|
|
4782
|
+
return `${n}B`;
|
|
4783
|
+
}
|
|
4784
|
+
function ontologyBudgetStopText(stop) {
|
|
4785
|
+
if (stop.reason === "files") return `\uD504\uB85C\uC81D\uD2B8 \uC608\uC0B0 \uCD08\uACFC\uB85C \uCE21\uC815 \uC911\uB2E8(\uD30C\uC77C ${stop.limit}\uAC1C \uC0C1\uD55C)`;
|
|
4786
|
+
if (stop.reason === "entries") return `\uD504\uB85C\uC81D\uD2B8 \uC608\uC0B0 \uCD08\uACFC\uB85C \uCE21\uC815 \uC911\uB2E8(\uB514\uB809\uD130\uB9AC \uD56D\uBAA9 ${stop.limit}\uAC1C \uC0C1\uD55C)`;
|
|
4787
|
+
return `\uD504\uB85C\uC81D\uD2B8 \uC608\uC0B0 \uCD08\uACFC\uB85C \uCE21\uC815 \uC911\uB2E8(\uC77D\uAE30 ${formatBytes(stop.limit)} \uC0C1\uD55C)`;
|
|
4788
|
+
}
|
|
4789
|
+
function isOntologyIncomplete(found) {
|
|
4790
|
+
return found.skippedLarge > 0 || found.skippedDeep > 0 || found.partialFiles > 0 || found.budgetStop !== null;
|
|
4791
|
+
}
|
|
4792
|
+
var EXTS = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".css"]);
|
|
4793
|
+
var EM_DASH = String.fromCharCode(8212);
|
|
4794
|
+
var FULLWIDTH_BANG = String.fromCharCode(65281);
|
|
4795
|
+
var NEUTRAL_BORDER = /* @__PURE__ */ new Set(["border-border", "border-input", "border-transparent", "border-inherit", "border-current"]);
|
|
4796
|
+
var SIDE_WIDTH = /(?:^|\s|:)border-[lrse](?:-(?:0|2|4|8|\[[^\]]+\]))?(?=\s|$)/;
|
|
4797
|
+
var BORDER_COLOR = /(?:^|\s|:)(border-(?:[lrse]-)?(?!(?:0|2|4|8|x|y|t|b|l|r|s|e|solid|dashed|dotted|double|none|hidden|collapse|separate|spacing)(?:\s|$))[a-z][\w-]*(?:\/\d+)?|border-(?:[lrse]-)?\[(?:#|rgb|hsl)[^\]]*\])(?=\s|$)/g;
|
|
4798
|
+
var BORDER_NOT_COLOR = /^border-(?:(?:[lrsetbxy])(?:-(?:0|2|4|8|\[[^\]]+\]))?|0|2|4|8|\[\d[^\]]*\]|solid|dashed|dotted|double|none|hidden|collapse|separate)$/;
|
|
4799
|
+
var SHADOW = /(?:^|\s|:)shadow(?:-(?!none(?:\s|$))[\w[\]().,%-]+)?(?=\s|$)/;
|
|
4800
|
+
var PALETTE_NAMES = "slate|gray|zinc|neutral|stone|red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose";
|
|
4801
|
+
var PALETTE_CLASS = new RegExp(
|
|
4802
|
+
`(?:^|[\\s:"'\`])((?:bg|text|border|ring|fill|stroke|from|via|to|outline|divide|decoration|shadow|accent|caret|placeholder)-(?:(?:${PALETTE_NAMES})-\\d{2,3}|white|black)(?:\\/\\d+)?)(?=[\\s"'\`]|$)`,
|
|
4803
|
+
"g"
|
|
4804
|
+
);
|
|
4805
|
+
var HEX = /#[0-9a-fA-F]{3,8}\b/g;
|
|
4806
|
+
var NAMED_COLORS = new Set(
|
|
4807
|
+
"aliceblue antiquewhite aqua aquamarine azure beige bisque black blanchedalmond blue blueviolet brown burlywood cadetblue chartreuse chocolate coral cornflowerblue cornsilk crimson cyan darkblue darkcyan darkgoldenrod darkgray darkgreen darkgrey darkkhaki darkmagenta darkolivegreen darkorange darkorchid darkred darksalmon darkseagreen darkslateblue darkslategray darkslategrey darkturquoise darkviolet deeppink deepskyblue dimgray dimgrey dodgerblue firebrick floralwhite forestgreen fuchsia gainsboro ghostwhite gold goldenrod gray green greenyellow grey honeydew hotpink indianred indigo ivory khaki lavender lavenderblush lawngreen lemonchiffon lightblue lightcoral lightcyan lightgoldenrodyellow lightgray lightgreen lightgrey lightpink lightsalmon lightseagreen lightskyblue lightslategray lightslategrey lightsteelblue lightyellow lime limegreen linen magenta maroon mediumaquamarine mediumblue mediumorchid mediumpurple mediumseagreen mediumslateblue mediumspringgreen mediumturquoise mediumvioletred midnightblue mintcream mistyrose moccasin navajowhite navy oldlace olive olivedrab orange orangered orchid palegoldenrod palegreen paleturquoise palevioletred papayawhip peachpuff peru pink plum powderblue purple rebeccapurple red rosybrown royalblue saddlebrown salmon sandybrown seagreen seashell sienna silver skyblue slateblue slategray slategrey snow springgreen steelblue tan teal thistle tomato turquoise violet wheat white whitesmoke yellow yellowgreen".split(" ")
|
|
4808
|
+
);
|
|
4809
|
+
var CSS_COLOR_PROP = /(?:^|[;{\s])((?:background|border|outline|text-decoration|column-rule)(?:-(?:top|right|bottom|left|inline-start|inline-end))?(?:-color)?|color|fill|stroke|caret-color|accent-color|box-shadow)\s*:\s*([^;}]+)/g;
|
|
4810
|
+
var STYLE_COLOR_KEY = /\b((?:background|border|outline|textDecoration|columnRule)(?:Top|Right|Bottom|Left|InlineStart|InlineEnd)?(?:Color)?|color|fill|stroke|caretColor|accentColor|boxShadow)\s*:\s*(["'`])([^"'`]*)\2/g;
|
|
4811
|
+
var COLOR_FN = /\b(?:rgba?|hsla?)\(\s*\d/g;
|
|
4812
|
+
var HANGUL = /[가-힣]/;
|
|
4813
|
+
function stripComments2(src) {
|
|
4814
|
+
const blank = (m) => m.replace(/[^\n]/g, " ");
|
|
4815
|
+
let out = "";
|
|
4816
|
+
let last = 0;
|
|
4817
|
+
for (let i = src.indexOf("/*"); i !== -1; i = src.indexOf("/*", last)) {
|
|
4818
|
+
const end = src.indexOf("*/", i + 2);
|
|
4819
|
+
if (end === -1) break;
|
|
4820
|
+
out += src.slice(last, i) + blank(src.slice(i, end + 2));
|
|
4821
|
+
last = end + 2;
|
|
4822
|
+
}
|
|
4823
|
+
out += src.slice(last);
|
|
4824
|
+
return out.replace(/(^|[^:'"`\\])(\/\/[^\n]*)/g, (_, pre, c) => pre + blank(c));
|
|
4825
|
+
}
|
|
4826
|
+
function lineIndex(src) {
|
|
4827
|
+
const breaks = [];
|
|
4828
|
+
for (let i = src.indexOf("\n"); i !== -1; i = src.indexOf("\n", i + 1)) breaks.push(i);
|
|
4829
|
+
return (index) => {
|
|
4830
|
+
let lo = 0;
|
|
4831
|
+
let hi = breaks.length;
|
|
4832
|
+
while (lo < hi) {
|
|
4833
|
+
const mid = lo + hi >> 1;
|
|
4834
|
+
if (breaks[mid] < index) lo = mid + 1;
|
|
4835
|
+
else hi = mid;
|
|
4836
|
+
}
|
|
4837
|
+
return lo + 1;
|
|
4838
|
+
};
|
|
4839
|
+
}
|
|
4840
|
+
var isLineTerminator = (c) => c === "\n" || c === "\r" || c === "\u2028" || c === "\u2029";
|
|
4841
|
+
function literalEnds(code, q) {
|
|
4842
|
+
const n = code.length;
|
|
4843
|
+
const end = new Int32Array(n + 2).fill(-1);
|
|
4844
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
4845
|
+
const c = code[i];
|
|
4846
|
+
if (c === q) end[i] = i;
|
|
4847
|
+
else if (c === "\n") end[i] = -1;
|
|
4848
|
+
else if (c === "\\") end[i] = i + 1 < n && !isLineTerminator(code[i + 1]) ? end[i + 2] : -1;
|
|
4849
|
+
else end[i] = end[i + 1];
|
|
4850
|
+
}
|
|
4851
|
+
return end;
|
|
4852
|
+
}
|
|
4853
|
+
function stringLiterals2(code) {
|
|
4854
|
+
const ends = { '"': literalEnds(code, '"'), "'": literalEnds(code, "'"), "`": literalEnds(code, "`") };
|
|
4855
|
+
const out = [];
|
|
4856
|
+
for (let i = 0; i < code.length; i++) {
|
|
4857
|
+
const c = code[i];
|
|
4858
|
+
if (c !== '"' && c !== "'" && c !== "`") continue;
|
|
4859
|
+
const e = ends[c][i + 1];
|
|
4860
|
+
if (e === -1) continue;
|
|
4861
|
+
out.push({ text: code.slice(i + 1, e), index: i });
|
|
4862
|
+
i = e;
|
|
4863
|
+
}
|
|
4864
|
+
return out;
|
|
4865
|
+
}
|
|
4866
|
+
function textChunks(code, isJsx) {
|
|
4867
|
+
const out = stringLiterals2(code).map((x) => ({ text: x.text, index: x.index, kind: "string" }));
|
|
4868
|
+
let m;
|
|
4869
|
+
if (isJsx) {
|
|
4870
|
+
const jsx = /[>}]([^<>{}]+)(?=[<{])/g;
|
|
4871
|
+
while (m = jsx.exec(code)) {
|
|
4872
|
+
if (/[=;]/.test(m[1])) continue;
|
|
4873
|
+
const text = m[1].replace(/(["'`])(?:(?!\1)[^\n])*\1/g, " ");
|
|
4874
|
+
out.push({ text, index: m.index + 1, kind: "jsx" });
|
|
4875
|
+
}
|
|
4876
|
+
}
|
|
4877
|
+
return out;
|
|
4878
|
+
}
|
|
4879
|
+
var SCAN_BUDGET_EXCEEDED = /* @__PURE__ */ Symbol("scan-budget-exceeded");
|
|
4880
|
+
function spend(budget, steps) {
|
|
4881
|
+
budget.left -= steps;
|
|
4882
|
+
if (budget.left < 0) throw SCAN_BUDGET_EXCEEDED;
|
|
4883
|
+
}
|
|
4884
|
+
function skipEnds(code, q) {
|
|
4885
|
+
const n = code.length;
|
|
4886
|
+
const end = new Int32Array(n + 2).fill(n);
|
|
4887
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
4888
|
+
const c = code[i];
|
|
4889
|
+
end[i] = c === q ? i : c === "\\" ? end[Math.min(i + 2, n)] : end[i + 1];
|
|
4890
|
+
}
|
|
4891
|
+
return end;
|
|
4892
|
+
}
|
|
4893
|
+
function closeMatcher(code, budget) {
|
|
4894
|
+
const memo = /* @__PURE__ */ new Map();
|
|
4895
|
+
const pair = { "(": ")", "{": "}" };
|
|
4896
|
+
const skips = { '"': skipEnds(code, '"'), "'": skipEnds(code, "'"), "`": skipEnds(code, "`") };
|
|
4897
|
+
return (open) => {
|
|
4898
|
+
const known = memo.get(open);
|
|
4899
|
+
if (known !== void 0) return known;
|
|
4900
|
+
const limit = open + ONTOLOGY_MAX_UNIT_CHARS;
|
|
4901
|
+
const stack = [pair[code[open]]];
|
|
4902
|
+
const opens = [open];
|
|
4903
|
+
let steps = 0;
|
|
4904
|
+
for (let i = open + 1; i < code.length; i++) {
|
|
4905
|
+
if (++steps === 1024) {
|
|
4906
|
+
spend(budget, steps);
|
|
4907
|
+
steps = 0;
|
|
4908
|
+
}
|
|
4909
|
+
if (i >= limit) {
|
|
4910
|
+
spend(budget, steps);
|
|
4911
|
+
memo.set(open, -1);
|
|
4912
|
+
return -1;
|
|
4913
|
+
}
|
|
4914
|
+
const c = code[i];
|
|
4915
|
+
if (c === '"' || c === "'" || c === "`") {
|
|
4916
|
+
i = skips[c][i + 1];
|
|
4917
|
+
continue;
|
|
4918
|
+
}
|
|
4919
|
+
if (c === "(" || c === "{") {
|
|
4920
|
+
const inner = memo.get(i);
|
|
4921
|
+
if (inner !== void 0) {
|
|
4922
|
+
if (inner === -1) {
|
|
4923
|
+
spend(budget, steps);
|
|
4924
|
+
for (const p of opens) memo.set(p, -1);
|
|
4925
|
+
return -1;
|
|
4926
|
+
}
|
|
4927
|
+
i = inner;
|
|
4928
|
+
continue;
|
|
4929
|
+
}
|
|
4930
|
+
stack.push(pair[c]);
|
|
4931
|
+
opens.push(i);
|
|
4932
|
+
} else if (c === stack[stack.length - 1]) {
|
|
4933
|
+
stack.pop();
|
|
4934
|
+
memo.set(opens.pop(), i);
|
|
4935
|
+
if (stack.length === 0) {
|
|
4936
|
+
spend(budget, steps);
|
|
4937
|
+
return i;
|
|
4938
|
+
}
|
|
4939
|
+
}
|
|
4940
|
+
}
|
|
4941
|
+
spend(budget, steps);
|
|
4942
|
+
for (const p of opens) memo.set(p, -1);
|
|
4943
|
+
return -1;
|
|
4944
|
+
};
|
|
4945
|
+
}
|
|
4946
|
+
function joinStrings(expr, budget) {
|
|
4947
|
+
spend(budget, expr.length);
|
|
4948
|
+
return stringLiterals2(expr).map((x) => x.text).join(" ");
|
|
4949
|
+
}
|
|
4950
|
+
function isCardTagAt(code, at, end) {
|
|
4951
|
+
if (at < 0 || at + 5 > end || !code.startsWith("<Card", at)) return false;
|
|
4952
|
+
const next = at + 5;
|
|
4953
|
+
return next >= end || !/\w/.test(code[next]);
|
|
4954
|
+
}
|
|
4955
|
+
function lastLtFinder(code) {
|
|
4956
|
+
let pos = 0;
|
|
4957
|
+
let last = -1;
|
|
4958
|
+
return (index) => {
|
|
4959
|
+
for (; pos <= index && pos < code.length; pos++) if (code[pos] === "<") last = pos;
|
|
4960
|
+
return last;
|
|
4961
|
+
};
|
|
4962
|
+
}
|
|
4963
|
+
function cardClassStrings(code) {
|
|
4964
|
+
const out = [];
|
|
4965
|
+
let from = 0;
|
|
4966
|
+
let noQuoteAfter = Infinity;
|
|
4967
|
+
for (let at = code.indexOf("<Card", from); at !== -1; at = code.indexOf("<Card", from)) {
|
|
4968
|
+
from = at + 1;
|
|
4969
|
+
if (!isCardTagAt(code, at, code.length)) continue;
|
|
4970
|
+
for (let k = at + 5; k < code.length; k++) {
|
|
4971
|
+
if (k + 11 <= code.length && code.startsWith('className="', k) && k + 11 < noQuoteAfter) {
|
|
4972
|
+
const q = code.indexOf('"', k + 11);
|
|
4973
|
+
if (q !== -1) {
|
|
4974
|
+
out.push({ text: code.slice(k + 11, q), index: at, card: true });
|
|
4975
|
+
from = q + 1;
|
|
4976
|
+
break;
|
|
4977
|
+
}
|
|
4978
|
+
noQuoteAfter = k + 11;
|
|
4979
|
+
}
|
|
4980
|
+
const c = code[k];
|
|
4981
|
+
if (c === "<") break;
|
|
4982
|
+
if (c === ">" && !(k - 1 >= at + 5 && code[k - 1] === "=")) break;
|
|
4983
|
+
}
|
|
4984
|
+
}
|
|
4985
|
+
return out;
|
|
4986
|
+
}
|
|
4987
|
+
function classUnits(code, budget) {
|
|
4988
|
+
const out = [];
|
|
4989
|
+
const matchClose = closeMatcher(code, budget);
|
|
4990
|
+
const lastLt = lastLtFinder(code);
|
|
4991
|
+
let m;
|
|
4992
|
+
const attr = /className=\{/g;
|
|
4993
|
+
while (m = attr.exec(code)) {
|
|
4994
|
+
const open = m.index + m[0].length - 1;
|
|
4995
|
+
const close = matchClose(open);
|
|
4996
|
+
if (close === -1 || close - open + 1 > ONTOLOGY_MAX_UNIT_CHARS) continue;
|
|
4997
|
+
out.push({ text: joinStrings(code.slice(open, close + 1), budget), index: m.index, card: isCardTagAt(code, lastLt(m.index), m.index) });
|
|
4998
|
+
}
|
|
4999
|
+
const call = /\b(?:cn|clsx|cva|twMerge)\(/g;
|
|
5000
|
+
while (m = call.exec(code)) {
|
|
5001
|
+
const open = m.index + m[0].length - 1;
|
|
5002
|
+
const close = matchClose(open);
|
|
5003
|
+
if (close === -1 || close - open + 1 > ONTOLOGY_MAX_UNIT_CHARS) continue;
|
|
5004
|
+
out.push({ text: joinStrings(code.slice(open, close + 1), budget), index: m.index, card: false });
|
|
5005
|
+
}
|
|
5006
|
+
out.push(...cardClassStrings(code));
|
|
5007
|
+
return out;
|
|
5008
|
+
}
|
|
5009
|
+
function cssRules(code) {
|
|
5010
|
+
const out = [];
|
|
5011
|
+
const nextBrace = (from) => {
|
|
5012
|
+
for (let k = from; k < code.length; k++) if (code[k] === "{" || code[k] === "}") return k;
|
|
5013
|
+
return -1;
|
|
5014
|
+
};
|
|
5015
|
+
let i = 0;
|
|
5016
|
+
while (i < code.length) {
|
|
5017
|
+
if (code[i] === "{" || code[i] === "}") {
|
|
5018
|
+
i++;
|
|
5019
|
+
continue;
|
|
5020
|
+
}
|
|
5021
|
+
const open = nextBrace(i);
|
|
5022
|
+
if (open === -1) break;
|
|
5023
|
+
if (code[open] !== "{") {
|
|
5024
|
+
i = open + 1;
|
|
5025
|
+
continue;
|
|
5026
|
+
}
|
|
5027
|
+
const close = nextBrace(open + 1);
|
|
5028
|
+
if (close === -1) break;
|
|
5029
|
+
if (code[close] !== "}") {
|
|
5030
|
+
i = open + 1;
|
|
5031
|
+
continue;
|
|
5032
|
+
}
|
|
5033
|
+
out.push({ selector: code.slice(i, open), body: code.slice(open + 1, close), open });
|
|
5034
|
+
i = close + 1;
|
|
5035
|
+
}
|
|
5036
|
+
return out;
|
|
5037
|
+
}
|
|
5038
|
+
function oneSideColors(t) {
|
|
5039
|
+
if (!SIDE_WIDTH.test(t)) return [];
|
|
5040
|
+
return [...t.matchAll(BORDER_COLOR)].map((x) => x[1]).filter((c) => !NEUTRAL_BORDER.has(c.replace(/^border-[lrse]-/, "border-")) && !BORDER_NOT_COLOR.test(c));
|
|
5041
|
+
}
|
|
5042
|
+
function isCardLike(t, card) {
|
|
5043
|
+
return card || /(?:^|\s)bg-card(?=\s|$)/.test(t) || /(?:^|\s)rounded(?:-[\w[\]]+)?(?=\s|$)/.test(t) && /(?:^|\s)border(?:-(?:0|2|4|8))?(?=\s|$)/.test(t);
|
|
5044
|
+
}
|
|
5045
|
+
function sideValueColored(value) {
|
|
5046
|
+
const v = value.trim();
|
|
5047
|
+
const neutral = /^(?:0|none|hidden)$/.test(v) || /var\(--border\)|hsl\(var\(--border\)\)|transparent|currentColor/.test(v);
|
|
5048
|
+
const colored = /#|rgb|hsl|var\(--/.test(v) || v.split(/[\s,()]+/).some((w) => NAMED_COLORS.has(w.toLowerCase()));
|
|
5049
|
+
return colored && !neutral;
|
|
5050
|
+
}
|
|
5051
|
+
function byLineThenRule(a, b) {
|
|
5052
|
+
return a.line - b.line || ONTOLOGY_RULE_IDS.indexOf(a.rule) - ONTOLOGY_RULE_IDS.indexOf(b.rule);
|
|
5053
|
+
}
|
|
5054
|
+
function inspectOntologySourceDetailed(raw, ext) {
|
|
5055
|
+
const out = [];
|
|
5056
|
+
let partial = false;
|
|
5057
|
+
const seen = /* @__PURE__ */ new Set();
|
|
5058
|
+
const code = stripComments2(raw);
|
|
5059
|
+
const lineOf = lineIndex(raw);
|
|
5060
|
+
const report = (index, rule) => {
|
|
5061
|
+
const line = lineOf(index);
|
|
5062
|
+
const key = `${line}:${rule}`;
|
|
5063
|
+
if (seen.has(key)) return;
|
|
5064
|
+
seen.add(key);
|
|
5065
|
+
out.push({ line, rule });
|
|
5066
|
+
};
|
|
5067
|
+
for (let i = raw.indexOf(EM_DASH); i !== -1; i = raw.indexOf(EM_DASH, i + 1)) report(i, "em-dash");
|
|
5068
|
+
if (ext === ".css") {
|
|
5069
|
+
const side = /border-(?:left|right|inline-start|inline-end)(?:-color)?\s*:\s*([^;}]+)/g;
|
|
5070
|
+
let m2;
|
|
5071
|
+
while (m2 = side.exec(code)) {
|
|
5072
|
+
if (sideValueColored(m2[1])) report(m2.index, "one-side-line");
|
|
5073
|
+
}
|
|
5074
|
+
for (const r of cssRules(code)) {
|
|
5075
|
+
if (/card/i.test(r.selector) && /box-shadow\s*:(?!\s*(?:none\b|0 0 #0000))/.test(r.body)) report(r.open, "card-shadow");
|
|
5076
|
+
}
|
|
5077
|
+
} else {
|
|
5078
|
+
const isJsx = ext === ".tsx" || ext === ".jsx";
|
|
5079
|
+
for (const chunk of textChunks(code, isJsx)) {
|
|
5080
|
+
const t = chunk.text;
|
|
5081
|
+
if (HANGUL.test(t) && (t.includes("!") || t.includes(FULLWIDTH_BANG))) report(chunk.index, "exclamation");
|
|
5082
|
+
if (chunk.kind !== "string") continue;
|
|
5083
|
+
if (t.length > ONTOLOGY_MAX_UNIT_CHARS) continue;
|
|
5084
|
+
if (oneSideColors(t).length > 0) report(chunk.index, "one-side-line");
|
|
5085
|
+
if (isCardLike(t, false) && SHADOW.test(t)) report(chunk.index, "card-shadow");
|
|
5086
|
+
}
|
|
5087
|
+
let units = [];
|
|
5088
|
+
try {
|
|
5089
|
+
units = classUnits(code, { left: code.length * ONTOLOGY_SCAN_STEPS_PER_CHAR + ONTOLOGY_SCAN_STEPS_BASE });
|
|
5090
|
+
} catch (e) {
|
|
5091
|
+
if (e !== SCAN_BUDGET_EXCEEDED) throw e;
|
|
5092
|
+
partial = true;
|
|
5093
|
+
}
|
|
5094
|
+
for (const unit of units) {
|
|
5095
|
+
const t = unit.text;
|
|
5096
|
+
if (oneSideColors(t).length > 0) report(unit.index, "one-side-line");
|
|
5097
|
+
if (isCardLike(t, unit.card) && SHADOW.test(t)) report(unit.index, "card-shadow");
|
|
5098
|
+
}
|
|
5099
|
+
const lastLt = lastLtFinder(code);
|
|
5100
|
+
let m2;
|
|
5101
|
+
STYLE_COLOR_KEY.lastIndex = 0;
|
|
5102
|
+
while (m2 = STYLE_COLOR_KEY.exec(code)) {
|
|
5103
|
+
const key = m2[1];
|
|
5104
|
+
const value = m2[3];
|
|
5105
|
+
if (/^border(?:Left|Right|InlineStart|InlineEnd)(?:Color)?$/.test(key) && sideValueColored(value)) {
|
|
5106
|
+
report(m2.index, "one-side-line");
|
|
5107
|
+
}
|
|
5108
|
+
if (key === "boxShadow" && !/^(?:none|0 0 #0000)$/.test(value.trim())) {
|
|
5109
|
+
if (isCardTagAt(code, lastLt(m2.index), code.length)) report(m2.index, "card-shadow");
|
|
5110
|
+
}
|
|
5111
|
+
if (value.split(/[\s,()]+/).some((w) => NAMED_COLORS.has(w.toLowerCase()))) report(m2.index, "palette");
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
5114
|
+
if (ext === ".css") {
|
|
5115
|
+
let m2;
|
|
5116
|
+
CSS_COLOR_PROP.lastIndex = 0;
|
|
5117
|
+
while (m2 = CSS_COLOR_PROP.exec(code)) {
|
|
5118
|
+
if (m2[2].split(/[\s,()]+/).some((w) => NAMED_COLORS.has(w.toLowerCase()))) report(m2.index, "palette");
|
|
5119
|
+
}
|
|
5120
|
+
}
|
|
5121
|
+
let m;
|
|
5122
|
+
HEX.lastIndex = 0;
|
|
5123
|
+
while (m = HEX.exec(code)) {
|
|
5124
|
+
if (code[m.index - 1] === "&") continue;
|
|
5125
|
+
if (/[\w/]/.test(code[m.index - 1] ?? "")) continue;
|
|
5126
|
+
if (/(?:href|to|id)=\{?\s*["'`]$/.test(code.slice(Math.max(0, m.index - 12), m.index))) continue;
|
|
5127
|
+
report(m.index, "palette");
|
|
5128
|
+
}
|
|
5129
|
+
COLOR_FN.lastIndex = 0;
|
|
5130
|
+
while (m = COLOR_FN.exec(code)) report(m.index, "palette");
|
|
5131
|
+
PALETTE_CLASS.lastIndex = 0;
|
|
5132
|
+
while (m = PALETTE_CLASS.exec(code)) report(m.index, "palette");
|
|
5133
|
+
return { violations: out.sort(byLineThenRule), partial };
|
|
5134
|
+
}
|
|
5135
|
+
function collectOntologyFiles(baseDir, targets, maxFiles, maxEntries) {
|
|
5136
|
+
const rootReal = realpathSync4(baseDir);
|
|
5137
|
+
const found = {
|
|
5138
|
+
files: [],
|
|
5139
|
+
skippedLarge: 0,
|
|
5140
|
+
skippedLinks: 0,
|
|
5141
|
+
skippedDeep: 0,
|
|
5142
|
+
partialFiles: 0,
|
|
5143
|
+
budgetStop: null
|
|
5144
|
+
};
|
|
5145
|
+
const visitedDirs = /* @__PURE__ */ new Set();
|
|
5146
|
+
const seenFiles = /* @__PURE__ */ new Set();
|
|
5147
|
+
let entries = 0;
|
|
5148
|
+
const toRel = (p) => path11.relative(baseDir, p).split(path11.sep).join("/");
|
|
5149
|
+
const resolveEntry = (p, st) => {
|
|
5150
|
+
if (!st.isSymbolicLink()) return { st, real: void 0 };
|
|
5151
|
+
let real;
|
|
5152
|
+
let target;
|
|
5153
|
+
try {
|
|
5154
|
+
real = realpathSync4(p);
|
|
5155
|
+
target = statSync4(real);
|
|
5156
|
+
} catch {
|
|
5157
|
+
found.skippedLinks++;
|
|
5158
|
+
return void 0;
|
|
5159
|
+
}
|
|
5160
|
+
if (!isSameOrInside(rootReal, real)) {
|
|
5161
|
+
found.skippedLinks++;
|
|
5162
|
+
return void 0;
|
|
5163
|
+
}
|
|
5164
|
+
return { st: target, real };
|
|
5165
|
+
};
|
|
5166
|
+
const addFile = (p, real, st, ext) => {
|
|
5167
|
+
if (seenFiles.has(real)) return;
|
|
5168
|
+
seenFiles.add(real);
|
|
5169
|
+
if (st.size > ONTOLOGY_MAX_FILE_BYTES) {
|
|
5170
|
+
found.skippedLarge++;
|
|
5171
|
+
return;
|
|
5172
|
+
}
|
|
5173
|
+
if (found.files.length >= maxFiles) {
|
|
5174
|
+
found.budgetStop = { reason: "files", limit: maxFiles };
|
|
5175
|
+
return;
|
|
5176
|
+
}
|
|
5177
|
+
found.files.push({ rel: toRel(p), real, ext, size: st.size });
|
|
5178
|
+
};
|
|
5179
|
+
const walk = (dir, dirReal, depth) => {
|
|
5180
|
+
const names = readdirSync3(dir).sort();
|
|
5181
|
+
for (const name of names) {
|
|
5182
|
+
if (found.budgetStop) return;
|
|
5183
|
+
if (entries >= maxEntries) {
|
|
5184
|
+
found.budgetStop = { reason: "entries", limit: maxEntries };
|
|
5185
|
+
return;
|
|
5186
|
+
}
|
|
5187
|
+
entries++;
|
|
5188
|
+
if (name === "node_modules" || name.startsWith(".")) continue;
|
|
5189
|
+
const p = path11.join(dir, name);
|
|
5190
|
+
const entry = resolveEntry(p, lstatSync4(p));
|
|
5191
|
+
if (!entry) continue;
|
|
5192
|
+
const real = entry.real ?? path11.join(dirReal, name);
|
|
5193
|
+
if (entry.st.isDirectory()) {
|
|
5194
|
+
if (visitedDirs.has(real)) continue;
|
|
5195
|
+
if (depth >= ONTOLOGY_DIR_DEPTH_LIMIT) {
|
|
5196
|
+
found.skippedDeep++;
|
|
5197
|
+
continue;
|
|
5198
|
+
}
|
|
5199
|
+
visitedDirs.add(real);
|
|
5200
|
+
walk(p, real, depth + 1);
|
|
5201
|
+
} else if (entry.st.isFile() && EXTS.has(path11.extname(name))) {
|
|
5202
|
+
addFile(p, real, entry.st, path11.extname(name));
|
|
5203
|
+
}
|
|
5204
|
+
}
|
|
5205
|
+
};
|
|
5206
|
+
for (const t of targets) {
|
|
5207
|
+
if (found.budgetStop) break;
|
|
5208
|
+
const p = path11.join(baseDir, t);
|
|
5209
|
+
let st;
|
|
5210
|
+
try {
|
|
5211
|
+
st = lstatSync4(p);
|
|
5212
|
+
} catch (e) {
|
|
5213
|
+
if (e?.code === "ENOENT") continue;
|
|
5214
|
+
throw e;
|
|
5215
|
+
}
|
|
5216
|
+
const entry = resolveEntry(p, st);
|
|
5217
|
+
if (!entry) continue;
|
|
5218
|
+
const real = entry.real ?? realpathSync4(p);
|
|
5219
|
+
if (!isSameOrInside(rootReal, real)) {
|
|
5220
|
+
found.skippedLinks++;
|
|
5221
|
+
continue;
|
|
5222
|
+
}
|
|
5223
|
+
if (entry.st.isDirectory()) {
|
|
5224
|
+
if (visitedDirs.has(real)) continue;
|
|
5225
|
+
visitedDirs.add(real);
|
|
5226
|
+
walk(p, real, 1);
|
|
5227
|
+
} else if (entry.st.isFile() && EXTS.has(path11.extname(p))) {
|
|
5228
|
+
addFile(p, real, entry.st, path11.extname(p));
|
|
5229
|
+
}
|
|
5230
|
+
}
|
|
5231
|
+
return found;
|
|
5232
|
+
}
|
|
5233
|
+
function inspectOntologyRules(baseDirInput, targets = ONTOLOGY_TARGETS, budget = ONTOLOGY_DEFAULT_BUDGET) {
|
|
5234
|
+
const baseDir = path11.resolve(baseDirInput);
|
|
5235
|
+
const found = collectOntologyFiles(baseDir, targets, budget.maxFiles, budget.maxEntries);
|
|
5236
|
+
const violations = [];
|
|
5237
|
+
let checked = 0;
|
|
5238
|
+
let bytes = 0;
|
|
5239
|
+
for (const f of found.files) {
|
|
5240
|
+
if (bytes + f.size > budget.maxBytes) {
|
|
5241
|
+
found.budgetStop = { reason: "bytes", limit: budget.maxBytes };
|
|
5242
|
+
break;
|
|
5243
|
+
}
|
|
5244
|
+
bytes += f.size;
|
|
5245
|
+
const raw = readFileSync5(f.real, "utf8");
|
|
5246
|
+
checked++;
|
|
5247
|
+
const result = inspectOntologySourceDetailed(raw, f.ext);
|
|
5248
|
+
if (result.partial) found.partialFiles++;
|
|
5249
|
+
for (const v of result.violations) violations.push({ file: f.rel, line: v.line, rule: v.rule });
|
|
5250
|
+
}
|
|
5251
|
+
return {
|
|
5252
|
+
checked,
|
|
5253
|
+
violations,
|
|
5254
|
+
skippedLarge: found.skippedLarge,
|
|
5255
|
+
skippedLinks: found.skippedLinks,
|
|
5256
|
+
skippedDeep: found.skippedDeep,
|
|
5257
|
+
partialFiles: found.partialFiles,
|
|
5258
|
+
budgetStop: found.budgetStop
|
|
5259
|
+
};
|
|
5260
|
+
}
|
|
5261
|
+
|
|
4505
5262
|
// src/template/template-check.ts
|
|
4506
5263
|
var SEVERITY_ICON = {
|
|
4507
5264
|
pass: chalk7.green("PASS"),
|
|
@@ -4509,7 +5266,7 @@ var SEVERITY_ICON = {
|
|
|
4509
5266
|
fail: chalk7.red("FAIL")
|
|
4510
5267
|
};
|
|
4511
5268
|
async function collectCheckResults(dir) {
|
|
4512
|
-
const baseDir =
|
|
5269
|
+
const baseDir = path12.resolve(dir || ".");
|
|
4513
5270
|
const results = [];
|
|
4514
5271
|
results.push(await checkFileExists(baseDir, "axis.config.json", "axis.config.json"));
|
|
4515
5272
|
results.push(checkTailwindSetup(baseDir));
|
|
@@ -4524,6 +5281,7 @@ async function collectCheckResults(dir) {
|
|
|
4524
5281
|
if (content) results.push(content);
|
|
4525
5282
|
const animation = checkAnimationPlugin(baseDir);
|
|
4526
5283
|
if (animation) results.push(animation);
|
|
5284
|
+
results.push(...collectTemplateCheckResults(baseDir));
|
|
4527
5285
|
return results;
|
|
4528
5286
|
}
|
|
4529
5287
|
async function runCheck(dir) {
|
|
@@ -4560,7 +5318,7 @@ async function runCheck(dir) {
|
|
|
4560
5318
|
return { pass: passCount, warn: warnCount, fail: failCount };
|
|
4561
5319
|
}
|
|
4562
5320
|
async function checkFileExists(baseDir, fileName, label) {
|
|
4563
|
-
const exists = await
|
|
5321
|
+
const exists = await fs11.pathExists(path12.join(baseDir, fileName));
|
|
4564
5322
|
return {
|
|
4565
5323
|
name: label,
|
|
4566
5324
|
severity: exists ? "pass" : "fail",
|
|
@@ -4576,9 +5334,9 @@ async function checkUtils(baseDir) {
|
|
|
4576
5334
|
"utils.ts"
|
|
4577
5335
|
];
|
|
4578
5336
|
for (const candidate of candidates) {
|
|
4579
|
-
const fullPath =
|
|
4580
|
-
if (await
|
|
4581
|
-
const content = await
|
|
5337
|
+
const fullPath = path12.join(baseDir, candidate);
|
|
5338
|
+
if (await fs11.pathExists(fullPath)) {
|
|
5339
|
+
const content = await fs11.readFile(fullPath, "utf-8");
|
|
4582
5340
|
const hasCn = content.includes("function cn");
|
|
4583
5341
|
return {
|
|
4584
5342
|
name: "utils.ts",
|
|
@@ -4766,16 +5524,16 @@ function registerCheckCommand(program2) {
|
|
|
4766
5524
|
|
|
4767
5525
|
// src/theme/index.ts
|
|
4768
5526
|
import chalk9 from "chalk";
|
|
4769
|
-
import
|
|
5527
|
+
import path14 from "path";
|
|
4770
5528
|
|
|
4771
5529
|
// src/theme/theme-add.ts
|
|
4772
|
-
import { accessSync, constants, existsSync as
|
|
4773
|
-
import
|
|
5530
|
+
import { accessSync, constants, existsSync as existsSync5, readFileSync as readFileSync6, realpathSync as realpathSync5, unlinkSync as unlinkSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
5531
|
+
import path13 from "path";
|
|
4774
5532
|
var TOKENS_DEPENDENCY_RANGE = `^${TOKENS_DEPENDENCY_MIN_VERSION}`;
|
|
4775
5533
|
var TAILWIND3_BASE_IMPORTS = [`${TOKENS_PACKAGE}/css`, `${TOKENS_PACKAGE}/css/shadcn`];
|
|
4776
5534
|
var THEME_MIN_VERSION = "1.3.0";
|
|
4777
5535
|
function readText(file) {
|
|
4778
|
-
return
|
|
5536
|
+
return existsSync5(file) ? readFileSync6(file, "utf8") : null;
|
|
4779
5537
|
}
|
|
4780
5538
|
function eolOf(text) {
|
|
4781
5539
|
return text.includes("\r\n") ? "\r\n" : "\n";
|
|
@@ -4866,17 +5624,17 @@ function compareVersions(a, b) {
|
|
|
4866
5624
|
return 0;
|
|
4867
5625
|
}
|
|
4868
5626
|
function realPathInside(baseDir, file) {
|
|
4869
|
-
const realBase =
|
|
4870
|
-
const realPath =
|
|
4871
|
-
const relPath =
|
|
4872
|
-
const inside = relPath !== "" && !relPath.startsWith("..") && !
|
|
5627
|
+
const realBase = realpathSync5(baseDir);
|
|
5628
|
+
const realPath = realpathSync5(file);
|
|
5629
|
+
const relPath = path13.relative(realBase, realPath);
|
|
5630
|
+
const inside = relPath !== "" && !relPath.startsWith("..") && !path13.isAbsolute(relPath);
|
|
4873
5631
|
return { inside, realPath };
|
|
4874
5632
|
}
|
|
4875
5633
|
function isStylesheet(realPath) {
|
|
4876
|
-
return
|
|
5634
|
+
return path13.extname(realPath).toLowerCase() === ".css";
|
|
4877
5635
|
}
|
|
4878
5636
|
function planThemeAdd(baseDirInput, brand) {
|
|
4879
|
-
const baseDir =
|
|
5637
|
+
const baseDir = path13.resolve(baseDirInput);
|
|
4880
5638
|
const plan = {
|
|
4881
5639
|
baseDir,
|
|
4882
5640
|
brand,
|
|
@@ -4889,7 +5647,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4889
5647
|
tokensGuide: dependencyInstallGuide(baseDir, TOKENS_PACKAGE, TOKENS_DEPENDENCY_RANGE),
|
|
4890
5648
|
writes: []
|
|
4891
5649
|
};
|
|
4892
|
-
const configFile =
|
|
5650
|
+
const configFile = path13.join(baseDir, AXIS_CONFIG_FILE);
|
|
4893
5651
|
const configText = readText(configFile);
|
|
4894
5652
|
if (configText === null) {
|
|
4895
5653
|
plan.errors.push({ kind: "no-config" });
|
|
@@ -4910,7 +5668,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4910
5668
|
}
|
|
4911
5669
|
plan.tokens = resolveTokens(baseDir);
|
|
4912
5670
|
if (plan.tokens.status === "ok" && plan.tokens.indexPath) {
|
|
4913
|
-
const data = JSON.parse(
|
|
5671
|
+
const data = JSON.parse(readFileSync6(plan.tokens.indexPath, "utf8"));
|
|
4914
5672
|
const entries = Array.isArray(data.brands) ? data.brands : [];
|
|
4915
5673
|
const entry = entries.find((e) => e.name === brand);
|
|
4916
5674
|
if (!entry) {
|
|
@@ -4926,7 +5684,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4926
5684
|
} else {
|
|
4927
5685
|
plan.unverifiedBrand = true;
|
|
4928
5686
|
}
|
|
4929
|
-
const pkgFile =
|
|
5687
|
+
const pkgFile = path13.join(baseDir, "package.json");
|
|
4930
5688
|
const pkgText = readText(pkgFile);
|
|
4931
5689
|
let pkg;
|
|
4932
5690
|
if (pkgText !== null) {
|
|
@@ -4969,7 +5727,7 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4969
5727
|
plan.writes = [];
|
|
4970
5728
|
return plan;
|
|
4971
5729
|
}
|
|
4972
|
-
const before =
|
|
5730
|
+
const before = readFileSync6(location.path, "utf8");
|
|
4973
5731
|
const imported = findBrandImports(before);
|
|
4974
5732
|
const otherBrands = [...new Set(imported.filter((n) => n !== brand))];
|
|
4975
5733
|
const brandAdded = !imported.includes(brand);
|
|
@@ -5005,11 +5763,11 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
5005
5763
|
};
|
|
5006
5764
|
}
|
|
5007
5765
|
if (!tailwind4) {
|
|
5008
|
-
const configFile2 = TAILWIND_CONFIG_FILES.find((f) =>
|
|
5766
|
+
const configFile2 = TAILWIND_CONFIG_FILES.find((f) => existsSync5(path13.join(baseDir, f)));
|
|
5009
5767
|
const content = inspectTailwindContent(baseDir);
|
|
5010
5768
|
plan.tailwindConfig = {
|
|
5011
5769
|
configFile: configFile2,
|
|
5012
|
-
presetMissing: configFile2 === void 0 || !hasTokensPresetReference(
|
|
5770
|
+
presetMissing: configFile2 === void 0 || !hasTokensPresetReference(readFileSync6(path13.join(baseDir, configFile2), "utf8")),
|
|
5013
5771
|
contentMissing: content?.targets.filter((t) => !t.covered) ?? [],
|
|
5014
5772
|
contentUnknown: content !== null && (content.unreadable || content.dynamic)
|
|
5015
5773
|
};
|
|
@@ -5073,8 +5831,8 @@ function applyThemeAdd(plan) {
|
|
|
5073
5831
|
if (current !== w.before) {
|
|
5074
5832
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
5075
5833
|
}
|
|
5076
|
-
const where = realPathInside(plan.baseDir, w.before === null ?
|
|
5077
|
-
if (!where.inside && !(w.before === null &&
|
|
5834
|
+
const where = realPathInside(plan.baseDir, w.before === null ? path13.dirname(w.file) : w.file);
|
|
5835
|
+
if (!where.inside && !(w.before === null && path13.dirname(w.file) === plan.baseDir)) {
|
|
5078
5836
|
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.`);
|
|
5079
5837
|
}
|
|
5080
5838
|
if (!w.file.endsWith(".json") && !isStylesheet(where.realPath)) {
|
|
@@ -5086,7 +5844,7 @@ function applyThemeAdd(plan) {
|
|
|
5086
5844
|
throw new Error(`${w.file}: \uBE0C\uB79C\uB4DC import \uAC00 \uC815\uD655\uD788 1\uC904\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
5087
5845
|
}
|
|
5088
5846
|
try {
|
|
5089
|
-
accessSync(w.before === null ?
|
|
5847
|
+
accessSync(w.before === null ? path13.dirname(w.file) : w.file, constants.W_OK);
|
|
5090
5848
|
} catch (err) {
|
|
5091
5849
|
throw new Error(`${w.file} \uC5D0 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errorMessage(err)}).`);
|
|
5092
5850
|
}
|
|
@@ -5277,7 +6035,7 @@ function renderThemeInfo(result, name, installCommand) {
|
|
|
5277
6035
|
return { lines, exitCode: 0 };
|
|
5278
6036
|
}
|
|
5279
6037
|
function rel(plan, file) {
|
|
5280
|
-
return
|
|
6038
|
+
return path14.relative(plan.baseDir, file) || file;
|
|
5281
6039
|
}
|
|
5282
6040
|
function renderThemeAdd(plan, written) {
|
|
5283
6041
|
const error = plan.errors[0];
|
|
@@ -5491,15 +6249,15 @@ function print(output) {
|
|
|
5491
6249
|
function registerThemeCommand(program2) {
|
|
5492
6250
|
const themeCmd = program2.command("theme").description("\uBE0C\uB79C\uB4DC \uD14C\uB9C8 (@axis-ds/tokens \uBE0C\uB79C\uB4DC)");
|
|
5493
6251
|
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) => {
|
|
5494
|
-
const baseDir =
|
|
6252
|
+
const baseDir = path14.resolve(options.dir || ".");
|
|
5495
6253
|
print(renderThemeList(listBrands(baseDir), tokensInstallGuide(baseDir)));
|
|
5496
6254
|
});
|
|
5497
6255
|
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) => {
|
|
5498
|
-
const baseDir =
|
|
6256
|
+
const baseDir = path14.resolve(options.dir || ".");
|
|
5499
6257
|
print(renderThemeInfo(getBrand(baseDir, name), name, tokensInstallGuide(baseDir)));
|
|
5500
6258
|
});
|
|
5501
6259
|
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) => {
|
|
5502
|
-
const baseDir =
|
|
6260
|
+
const baseDir = path14.resolve(options.dir || ".");
|
|
5503
6261
|
const plan = planThemeAdd(baseDir, name);
|
|
5504
6262
|
let written = [];
|
|
5505
6263
|
if (plan.errors.length === 0) {
|
|
@@ -5818,167 +6576,11 @@ async function fetchRegistryJson(url, options = {}) {
|
|
|
5818
6576
|
}
|
|
5819
6577
|
|
|
5820
6578
|
// src/init/init.ts
|
|
5821
|
-
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as
|
|
5822
|
-
import
|
|
6579
|
+
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync6, lstatSync as lstatSync5, readFileSync as readFileSync7, realpathSync as realpathSync6, statSync as statSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
6580
|
+
import path15 from "path";
|
|
5823
6581
|
import chalk10 from "chalk";
|
|
5824
6582
|
import fs12 from "fs-extra";
|
|
5825
6583
|
|
|
5826
|
-
// ../axis-registry-core/src/add/safe-write.ts
|
|
5827
|
-
import { constants as fsConstants, existsSync as existsSync5, lstatSync as lstatSync3, realpathSync as realpathSync4, statSync as statSync3 } from "fs";
|
|
5828
|
-
import path13 from "path";
|
|
5829
|
-
import fs11 from "fs-extra";
|
|
5830
|
-
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
5831
|
-
var OVERWRITE_FLAGS = fsConstants.O_WRONLY | (fsConstants.O_NOFOLLOW ?? 0);
|
|
5832
|
-
var HARDLINK_ERROR_CODE = "EAXISHARDLINK";
|
|
5833
|
-
var NOT_REGULAR_ERROR_CODE = "EAXISNOTREG";
|
|
5834
|
-
function codedError(code, message) {
|
|
5835
|
-
const e = new Error(message);
|
|
5836
|
-
e.code = code;
|
|
5837
|
-
return e;
|
|
5838
|
-
}
|
|
5839
|
-
function isSameOrInside(parent, child, impl = path13) {
|
|
5840
|
-
const rel3 = impl.relative(parent, child);
|
|
5841
|
-
if (rel3 === "") return true;
|
|
5842
|
-
return !(rel3 === ".." || rel3.startsWith(`..${impl.sep}`) || impl.isAbsolute(rel3));
|
|
5843
|
-
}
|
|
5844
|
-
function nearestExisting(p) {
|
|
5845
|
-
let cur = p;
|
|
5846
|
-
while (!existsSync5(cur)) {
|
|
5847
|
-
const up = path13.dirname(cur);
|
|
5848
|
-
if (up === cur) return cur;
|
|
5849
|
-
cur = up;
|
|
5850
|
-
}
|
|
5851
|
-
return cur;
|
|
5852
|
-
}
|
|
5853
|
-
function escapeReason(root, target, options = {}) {
|
|
5854
|
-
const realRoot = realpathSync4(root);
|
|
5855
|
-
if (!isSameOrInside(path13.resolve(root), path13.resolve(target)) || path13.resolve(target) === path13.resolve(root)) {
|
|
5856
|
-
return `\uACBD\uB85C\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4(${target})`;
|
|
5857
|
-
}
|
|
5858
|
-
const anchor = nearestExisting(path13.dirname(target));
|
|
5859
|
-
const realAnchor = realpathSync4(anchor);
|
|
5860
|
-
if (!isSameOrInside(realRoot, realAnchor)) {
|
|
5861
|
-
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`;
|
|
5862
|
-
}
|
|
5863
|
-
let st = null;
|
|
5864
|
-
try {
|
|
5865
|
-
st = lstatSync3(target);
|
|
5866
|
-
} catch {
|
|
5867
|
-
st = null;
|
|
5868
|
-
}
|
|
5869
|
-
if (st) {
|
|
5870
|
-
if (st.isDirectory()) return `\uAC19\uC740 \uC774\uB984\uC758 \uB514\uB809\uD130\uB9AC\uAC00 \uC788\uC2B5\uB2C8\uB2E4(${target})`;
|
|
5871
|
-
const shown = path13.relative(path13.resolve(root), path13.resolve(target)).split(path13.sep).join("/");
|
|
5872
|
-
let realTarget;
|
|
5873
|
-
try {
|
|
5874
|
-
realTarget = realpathSync4(target);
|
|
5875
|
-
} catch {
|
|
5876
|
-
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)`;
|
|
5877
|
-
}
|
|
5878
|
-
if (!isSameOrInside(realRoot, realTarget) && !(options.allowOutsideLink && st.isSymbolicLink())) {
|
|
5879
|
-
return `\uAE30\uC874 \uD30C\uC77C\uC758 \uC2E4\uC81C \uC704\uCE58(${realTarget})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`;
|
|
5880
|
-
}
|
|
5881
|
-
let followed;
|
|
5882
|
-
try {
|
|
5883
|
-
followed = statSync3(realTarget);
|
|
5884
|
-
} catch {
|
|
5885
|
-
return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
|
|
5886
|
-
}
|
|
5887
|
-
if (followed.isDirectory()) {
|
|
5888
|
-
return `\uAC19\uC740 \uC774\uB984\uC758 \uB9C1\uD06C\uAC00 \uB514\uB809\uD130\uB9AC(${realTarget})\uB97C \uAC00\uB9AC\uD0B5\uB2C8\uB2E4(${target})`;
|
|
5889
|
-
}
|
|
5890
|
-
if (!followed.isFile()) {
|
|
5891
|
-
const where = st.isSymbolicLink() ? `\uB9C1\uD06C \uB300\uC0C1(${realTarget})\uC774` : "\uAE30\uC874 \uD30C\uC77C\uC774";
|
|
5892
|
-
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})`;
|
|
5893
|
-
}
|
|
5894
|
-
}
|
|
5895
|
-
return null;
|
|
5896
|
-
}
|
|
5897
|
-
function isSymlink(p) {
|
|
5898
|
-
try {
|
|
5899
|
-
return lstatSync3(p).isSymbolicLink();
|
|
5900
|
-
} catch {
|
|
5901
|
-
return false;
|
|
5902
|
-
}
|
|
5903
|
-
}
|
|
5904
|
-
function outsideLinkTarget(root, target) {
|
|
5905
|
-
if (!isSymlink(target)) return null;
|
|
5906
|
-
try {
|
|
5907
|
-
const realTarget = realpathSync4(target);
|
|
5908
|
-
return isSameOrInside(realpathSync4(root), realTarget) ? null : realTarget;
|
|
5909
|
-
} catch {
|
|
5910
|
-
return null;
|
|
5911
|
-
}
|
|
5912
|
-
}
|
|
5913
|
-
function hardLinkCount(target) {
|
|
5914
|
-
try {
|
|
5915
|
-
const st = lstatSync3(target);
|
|
5916
|
-
return st.isFile() && st.nlink >= 2 ? st.nlink : null;
|
|
5917
|
-
} catch {
|
|
5918
|
-
return null;
|
|
5919
|
-
}
|
|
5920
|
-
}
|
|
5921
|
-
function hardLinkMessage(shownPath, nlink) {
|
|
5922
|
-
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`;
|
|
5923
|
-
}
|
|
5924
|
-
function writtenOutside(root, target) {
|
|
5925
|
-
const realRoot = realpathSync4(root);
|
|
5926
|
-
let realTarget;
|
|
5927
|
-
try {
|
|
5928
|
-
realTarget = realpathSync4(target);
|
|
5929
|
-
} catch {
|
|
5930
|
-
return target;
|
|
5931
|
-
}
|
|
5932
|
-
return isSameOrInside(realRoot, realTarget) ? null : realTarget;
|
|
5933
|
-
}
|
|
5934
|
-
async function writeNoFollow(target, content, mode) {
|
|
5935
|
-
let actual = mode;
|
|
5936
|
-
let fd;
|
|
5937
|
-
if (mode === "overwrite") {
|
|
5938
|
-
try {
|
|
5939
|
-
fd = await fs11.open(target, OVERWRITE_FLAGS);
|
|
5940
|
-
} catch (e) {
|
|
5941
|
-
if (e.code !== "ENOENT") throw e;
|
|
5942
|
-
actual = "new";
|
|
5943
|
-
fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
|
|
5944
|
-
}
|
|
5945
|
-
} else {
|
|
5946
|
-
fd = await fs11.open(target, NEW_FILE_FLAGS, 438);
|
|
5947
|
-
}
|
|
5948
|
-
try {
|
|
5949
|
-
if (actual === "overwrite") {
|
|
5950
|
-
const st = await fs11.fstat(fd);
|
|
5951
|
-
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
5952
|
-
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
5953
|
-
await fs11.ftruncate(fd, 0);
|
|
5954
|
-
}
|
|
5955
|
-
await fs11.writeFile(fd, content);
|
|
5956
|
-
} finally {
|
|
5957
|
-
await fs11.close(fd);
|
|
5958
|
-
}
|
|
5959
|
-
return actual;
|
|
5960
|
-
}
|
|
5961
|
-
async function overwriteFollowingLinks(target, content) {
|
|
5962
|
-
const fd = await fs11.open(target, fsConstants.O_WRONLY | fsConstants.O_CREAT, 438);
|
|
5963
|
-
try {
|
|
5964
|
-
const st = await fs11.fstat(fd);
|
|
5965
|
-
if (!st.isFile()) throw codedError(NOT_REGULAR_ERROR_CODE, `${target} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
5966
|
-
if (st.nlink >= 2) throw codedError(HARDLINK_ERROR_CODE, hardLinkMessage(target, st.nlink));
|
|
5967
|
-
await fs11.ftruncate(fd, 0);
|
|
5968
|
-
await fs11.writeFile(fd, content);
|
|
5969
|
-
} finally {
|
|
5970
|
-
await fs11.close(fd);
|
|
5971
|
-
}
|
|
5972
|
-
}
|
|
5973
|
-
function checkParentInside(root, target) {
|
|
5974
|
-
const realRoot = realpathSync4(root);
|
|
5975
|
-
const realParent = realpathSync4(path13.dirname(target));
|
|
5976
|
-
if (!isSameOrInside(realRoot, realParent)) {
|
|
5977
|
-
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`;
|
|
5978
|
-
}
|
|
5979
|
-
return escapeReason(root, target);
|
|
5980
|
-
}
|
|
5981
|
-
|
|
5982
6584
|
// ../axis-registry-core/src/utils-deps.ts
|
|
5983
6585
|
var CLSX_RANGE = "^2.1.1";
|
|
5984
6586
|
var TAILWIND_MERGE_RANGES = {
|
|
@@ -6044,7 +6646,7 @@ export function cn(...inputs: ClassValue[]) {
|
|
|
6044
6646
|
}
|
|
6045
6647
|
`;
|
|
6046
6648
|
async function resolveInitAnswers(baseDirInput, tailwind4) {
|
|
6047
|
-
const baseDir =
|
|
6649
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
6048
6650
|
const tw4 = tailwind4 ?? isTailwind4(planUtilsDependencies(baseDir).tailwind);
|
|
6049
6651
|
const current = await existingConfig(baseDir);
|
|
6050
6652
|
const found = detectProjectPaths(baseDir);
|
|
@@ -6139,7 +6741,7 @@ var TAILWIND4_TOKENS_VERSION = TAILWIND4_MIN_AXIS_VERSION;
|
|
|
6139
6741
|
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.";
|
|
6140
6742
|
function readPackageJsonSafe(baseDir) {
|
|
6141
6743
|
try {
|
|
6142
|
-
const text =
|
|
6744
|
+
const text = readFileSync7(path15.join(baseDir, "package.json"), "utf8");
|
|
6143
6745
|
const parsed = JSON.parse(text.startsWith(BOM) ? text.slice(1) : text);
|
|
6144
6746
|
return isPlainObject(parsed) ? parsed : void 0;
|
|
6145
6747
|
} catch {
|
|
@@ -6205,7 +6807,7 @@ function tailwind4GuideLines(pkg, installCommand, globalCss, baseDir) {
|
|
|
6205
6807
|
}
|
|
6206
6808
|
var BOM = "\uFEFF";
|
|
6207
6809
|
function planUtilsDependencies(baseDirInput) {
|
|
6208
|
-
const baseDir =
|
|
6810
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
6209
6811
|
const installCommand = detectInstallCommand(baseDir);
|
|
6210
6812
|
const tailwind0 = detectTailwind(baseDir);
|
|
6211
6813
|
const ranges0 = selectUtilsDependencies(tailwind0);
|
|
@@ -6219,7 +6821,7 @@ function planUtilsDependencies(baseDirInput) {
|
|
|
6219
6821
|
installCommand,
|
|
6220
6822
|
addCommand: addCommandFor(installCommand, ranges0)
|
|
6221
6823
|
};
|
|
6222
|
-
const pkgFile =
|
|
6824
|
+
const pkgFile = path15.join(baseDir, "package.json");
|
|
6223
6825
|
if (!existsSync6(pkgFile)) return plan;
|
|
6224
6826
|
const unwritable = (reason) => ({ ...plan, action: "unwritable", reason });
|
|
6225
6827
|
let where;
|
|
@@ -6231,7 +6833,7 @@ function planUtilsDependencies(baseDirInput) {
|
|
|
6231
6833
|
if (!where.inside) return unwritable(`\uC2E4\uC81C \uC704\uCE58(${where.realPath})\uAC00 \uD504\uB85C\uC81D\uD2B8 \uB514\uB809\uD130\uB9AC \uBC16\uC785\uB2C8\uB2E4`);
|
|
6232
6834
|
let text;
|
|
6233
6835
|
try {
|
|
6234
|
-
text =
|
|
6836
|
+
text = readFileSync7(pkgFile, "utf8");
|
|
6235
6837
|
} catch (err) {
|
|
6236
6838
|
return unwritable(err.message);
|
|
6237
6839
|
}
|
|
@@ -6276,8 +6878,8 @@ var defaultWriteFile = (file, data) => writeFileSync3(file, data);
|
|
|
6276
6878
|
function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile) {
|
|
6277
6879
|
const w = plan.write;
|
|
6278
6880
|
if (plan.action !== "add" || !w) return false;
|
|
6279
|
-
const baseDir =
|
|
6280
|
-
const current = existsSync6(w.file) ?
|
|
6881
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
6882
|
+
const current = existsSync6(w.file) ? readFileSync7(w.file, "utf8") : null;
|
|
6281
6883
|
if (current !== w.before) {
|
|
6282
6884
|
throw new Error(`${w.file} \uC774 \uACC4\uD68D \uB4A4\uC5D0 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC2E4\uD589\uD558\uC138\uC694.`);
|
|
6283
6885
|
}
|
|
@@ -6293,7 +6895,7 @@ function applyUtilsDependencies(baseDirInput, plan, writeFile = defaultWriteFile
|
|
|
6293
6895
|
let restored;
|
|
6294
6896
|
try {
|
|
6295
6897
|
writeFile(w.file, w.before);
|
|
6296
|
-
if (
|
|
6898
|
+
if (readFileSync7(w.file, "utf8") !== w.before) throw new Error("\uB418\uB3CC\uB9B0 \uB0B4\uC6A9\uC774 \uC6D0\uB798 \uB0B4\uC6A9\uACFC \uB2E4\uB985\uB2C8\uB2E4");
|
|
6297
6899
|
restored = "\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB838\uC2B5\uB2C8\uB2E4";
|
|
6298
6900
|
} catch (restoreErr) {
|
|
6299
6901
|
restored = `\uC6D0\uB798 \uB0B4\uC6A9\uC73C\uB85C \uB418\uB3CC\uB9AC\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${restoreErr.message}). \uD30C\uC77C\uC774 \uC798\uB838\uAC70\uB098 \uBE44\uC5C8\uC744 \uC218 \uC788\uC73C\uB2C8 \uBC84\uC804 \uAD00\uB9AC \uB3C4\uAD6C \uB4F1\uC73C\uB85C \uBCF5\uAD6C\uD558\uC138\uC694`;
|
|
@@ -6377,11 +6979,11 @@ function errCode(e) {
|
|
|
6377
6979
|
return e.code ?? e.message;
|
|
6378
6980
|
}
|
|
6379
6981
|
function planUtilsWrite(baseDirInput, utilsPath) {
|
|
6380
|
-
const baseDir =
|
|
6381
|
-
const shown =
|
|
6982
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
6983
|
+
const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
|
|
6382
6984
|
let st;
|
|
6383
6985
|
try {
|
|
6384
|
-
st =
|
|
6986
|
+
st = lstatSync5(utilsPath);
|
|
6385
6987
|
} catch (e) {
|
|
6386
6988
|
if (e.code === "ENOENT") return { action: "create" };
|
|
6387
6989
|
return { action: "reject", reason: `${shown} \uC758 \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
@@ -6389,19 +6991,19 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
6389
6991
|
if (st.isSymbolicLink()) {
|
|
6390
6992
|
let real;
|
|
6391
6993
|
try {
|
|
6392
|
-
real =
|
|
6994
|
+
real = realpathSync6(utilsPath);
|
|
6393
6995
|
} catch {
|
|
6394
6996
|
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` };
|
|
6395
6997
|
}
|
|
6396
6998
|
let outside = null;
|
|
6397
6999
|
try {
|
|
6398
|
-
outside = isSameOrInside(
|
|
7000
|
+
outside = isSameOrInside(realpathSync6(baseDir), real) ? null : real;
|
|
6399
7001
|
} catch {
|
|
6400
7002
|
outside = null;
|
|
6401
7003
|
}
|
|
6402
7004
|
let target;
|
|
6403
7005
|
try {
|
|
6404
|
-
target =
|
|
7006
|
+
target = statSync5(real);
|
|
6405
7007
|
} catch (e) {
|
|
6406
7008
|
return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC758 \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
6407
7009
|
}
|
|
@@ -6409,7 +7011,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
6409
7011
|
if (!target.isFile()) return { action: "reject", reason: `${shown} \uB9C1\uD06C \uB300\uC0C1(${real})\uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2D9\uB2C8\uB2E4` };
|
|
6410
7012
|
let content2;
|
|
6411
7013
|
try {
|
|
6412
|
-
content2 =
|
|
7014
|
+
content2 = readFileSync7(utilsPath, "utf8");
|
|
6413
7015
|
} catch (e) {
|
|
6414
7016
|
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)})` };
|
|
6415
7017
|
}
|
|
@@ -6424,7 +7026,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
6424
7026
|
if (!st.isFile()) return { action: "reject", reason: `${shown} \uC774 \uC77C\uBC18 \uD30C\uC77C\uC774 \uC544\uB2C8\uB77C \uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` };
|
|
6425
7027
|
let content;
|
|
6426
7028
|
try {
|
|
6427
|
-
content =
|
|
7029
|
+
content = readFileSync7(utilsPath, "utf8");
|
|
6428
7030
|
} catch (e) {
|
|
6429
7031
|
return { action: "reject", reason: `\uAE30\uC874 ${shown} \uC744 \uC77D\uC9C0 \uBABB\uD574 \uBE44\uAD50\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${errCode(e)})` };
|
|
6430
7032
|
}
|
|
@@ -6439,7 +7041,7 @@ function planUtilsWrite(baseDirInput, utilsPath) {
|
|
|
6439
7041
|
return { action: "overwrite" };
|
|
6440
7042
|
}
|
|
6441
7043
|
async function runInit(baseDirInput, answers, registryUrl, log = console.log, options = {}) {
|
|
6442
|
-
const baseDir =
|
|
7044
|
+
const baseDir = path15.resolve(baseDirInput);
|
|
6443
7045
|
const current = await existingConfig(baseDir);
|
|
6444
7046
|
const existingRegistry = nonEmptyString(current?.registry);
|
|
6445
7047
|
const migratedRegistry = existingRegistry !== void 0 && isLegacyDefaultRegistryUrl(existingRegistry);
|
|
@@ -6456,7 +7058,7 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
|
|
|
6456
7058
|
},
|
|
6457
7059
|
registry
|
|
6458
7060
|
);
|
|
6459
|
-
const configPath =
|
|
7061
|
+
const configPath = path15.join(baseDir, "axis.config.json");
|
|
6460
7062
|
const rejects = [];
|
|
6461
7063
|
let previousText = null;
|
|
6462
7064
|
try {
|
|
@@ -6477,16 +7079,16 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
|
|
|
6477
7079
|
}
|
|
6478
7080
|
if (previousText !== null && previousText !== nextText) {
|
|
6479
7081
|
try {
|
|
6480
|
-
const st =
|
|
7082
|
+
const st = statSync5(configPath);
|
|
6481
7083
|
if (st.isFile() && st.nlink >= 2) rejects.push(hardLinkMessage("axis.config.json", st.nlink));
|
|
6482
7084
|
} catch {
|
|
6483
7085
|
}
|
|
6484
7086
|
}
|
|
6485
|
-
const utilsPath =
|
|
7087
|
+
const utilsPath = path15.resolve(baseDir, answers.componentsDir, "utils.ts");
|
|
6486
7088
|
const utilsPlan = planUtilsWrite(baseDir, utilsPath);
|
|
6487
7089
|
if (utilsPlan.action === "reject") rejects.push(utilsPlan.reason);
|
|
6488
7090
|
if (utilsPlan.action === "overwrite" && options.allowOverwrite === false) {
|
|
6489
|
-
const shown =
|
|
7091
|
+
const shown = path15.relative(baseDir, utilsPath).split(path15.sep).join("/") || utilsPath;
|
|
6490
7092
|
rejects.push(
|
|
6491
7093
|
`\uBE44\uB300\uD654\uD615 \uC2E4\uD589\uC774\uB77C \uB0B4\uC6A9\uC774 \uB2E4\uB978 \uAE30\uC874 ${shown} \uB97C \uB36E\uC5B4\uC4F0\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uB36E\uC5B4\uC368\uB3C4 \uB418\uBA74 axis init -y \uB85C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uB300\uD654\uD615 \uD130\uBBF8\uB110\uC5D0\uC11C \uC2E4\uD589\uD558\uC138\uC694`
|
|
6492
7094
|
);
|
|
@@ -6545,7 +7147,7 @@ async function runInit(baseDirInput, answers, registryUrl, log = console.log, op
|
|
|
6545
7147
|
} else {
|
|
6546
7148
|
let actual;
|
|
6547
7149
|
try {
|
|
6548
|
-
await fs12.ensureDir(
|
|
7150
|
+
await fs12.ensureDir(path15.dirname(utilsPath));
|
|
6549
7151
|
actual = await writeNoFollow(utilsPath, UTILS_TS_CONTENT, utilsPlan.action === "create" ? "new" : "overwrite");
|
|
6550
7152
|
} catch (err) {
|
|
6551
7153
|
const code = err.code;
|
|
@@ -6638,26 +7240,26 @@ function registerInitCommand(program2, registryUrl = DEFAULT_REGISTRY_URL, deps
|
|
|
6638
7240
|
import chalk12 from "chalk";
|
|
6639
7241
|
|
|
6640
7242
|
// ../axis-registry-core/src/add/add.ts
|
|
6641
|
-
import { existsSync as existsSync8, readFileSync as
|
|
6642
|
-
import
|
|
7243
|
+
import { existsSync as existsSync8, readFileSync as readFileSync9, statSync as statSync6 } from "fs";
|
|
7244
|
+
import path17 from "path";
|
|
6643
7245
|
import fs13 from "fs-extra";
|
|
6644
7246
|
|
|
6645
7247
|
// ../axis-registry-core/src/registry/bundled.ts
|
|
6646
|
-
import { existsSync as existsSync7, readFileSync as
|
|
6647
|
-
import
|
|
7248
|
+
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
|
|
7249
|
+
import path16 from "path";
|
|
6648
7250
|
import { fileURLToPath } from "url";
|
|
6649
7251
|
function findBundledRegistryDir(moduleUrl = import.meta.url) {
|
|
6650
|
-
const here =
|
|
6651
|
-
for (const dir of [
|
|
6652
|
-
if (existsSync7(
|
|
7252
|
+
const here = path16.dirname(fileURLToPath(moduleUrl));
|
|
7253
|
+
for (const dir of [path16.join(here, "registry"), path16.join(here, "..", "registry")]) {
|
|
7254
|
+
if (existsSync7(path16.join(dir, "index.json"))) return dir;
|
|
6653
7255
|
}
|
|
6654
7256
|
return null;
|
|
6655
7257
|
}
|
|
6656
7258
|
function readBundledJson(dir, fileName) {
|
|
6657
|
-
const file =
|
|
7259
|
+
const file = path16.join(dir, fileName);
|
|
6658
7260
|
let text;
|
|
6659
7261
|
try {
|
|
6660
|
-
text =
|
|
7262
|
+
text = readFileSync8(file, "utf8");
|
|
6661
7263
|
} catch {
|
|
6662
7264
|
throw new Error(`\uB3D9\uBD09 \uB808\uC9C0\uC2A4\uD2B8\uB9AC\uC5D0 ${fileName} \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(${dir})`);
|
|
6663
7265
|
}
|
|
@@ -7149,10 +7751,10 @@ function layoutFromConfig(root, config) {
|
|
|
7149
7751
|
throw new Error("axis.config.json \uC758 agenticDir \uAC00 \uBB38\uC790\uC5F4\uC774 \uC544\uB2D9\uB2C8\uB2E4");
|
|
7150
7752
|
}
|
|
7151
7753
|
const componentsDir = componentsRaw.replace(/\\/g, "/");
|
|
7152
|
-
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") :
|
|
7153
|
-
return { root:
|
|
7754
|
+
const agenticDir = typeof agenticRaw === "string" ? agenticRaw.replace(/\\/g, "/") : path17.posix.join(path17.posix.dirname(componentsDir), "agentic");
|
|
7755
|
+
return { root: path17.resolve(root), componentsDir, agenticDir };
|
|
7154
7756
|
}
|
|
7155
|
-
function toPosix(p, impl =
|
|
7757
|
+
function toPosix(p, impl = path17) {
|
|
7156
7758
|
return p.split(impl.sep).join("/");
|
|
7157
7759
|
}
|
|
7158
7760
|
function itemKind(item) {
|
|
@@ -7174,12 +7776,12 @@ function placeFile(layout, item, filePath, target) {
|
|
|
7174
7776
|
const problem = registryPathProblem(p);
|
|
7175
7777
|
if (problem) throw new Error(`${item.name}: \uD30C\uC77C \uACBD\uB85C\uAC00 \uC62C\uBC14\uB974\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${JSON.stringify(p)}, ${problem})`);
|
|
7176
7778
|
}
|
|
7177
|
-
const base =
|
|
7779
|
+
const base = path17.posix.basename(filePath);
|
|
7178
7780
|
if (!INSTALL_FILE_NAME_PATTERN.test(base)) {
|
|
7179
7781
|
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)`);
|
|
7180
7782
|
}
|
|
7181
7783
|
const dir = itemKind(item) === "agentic" ? layout.agenticDir : layout.componentsDir;
|
|
7182
|
-
return
|
|
7784
|
+
return path17.resolve(layout.root, dir, base);
|
|
7183
7785
|
}
|
|
7184
7786
|
function stripExt(p) {
|
|
7185
7787
|
return p.replace(/\.(?:tsx?|jsx?|mjs|cjs)$/, "");
|
|
@@ -7190,7 +7792,7 @@ function buildImportTargets(entries) {
|
|
|
7190
7792
|
for (const { item, file, target } of entries) {
|
|
7191
7793
|
const rel3 = stripExt(file.path.replace(/\\/g, "/").replace(/^\.?\//, ""));
|
|
7192
7794
|
exact.set(`@/${rel3}`, target);
|
|
7193
|
-
if (itemKind(item) === "lib") lib.set(
|
|
7795
|
+
if (itemKind(item) === "lib") lib.set(path17.posix.basename(rel3), target);
|
|
7194
7796
|
}
|
|
7195
7797
|
return { exact, lib };
|
|
7196
7798
|
}
|
|
@@ -7266,7 +7868,7 @@ function insideRanges(ranges, at) {
|
|
|
7266
7868
|
}
|
|
7267
7869
|
var SPECIFIER_PATTERN = /(\bfrom\s*|\bimport\s*\(\s*|\bimport\s+|\brequire\s*\(\s*)(["'])(@\/[^"'\n]+)\2/g;
|
|
7268
7870
|
var STANDARD_LIB_PATTERN = /^@\/registry\/[^/]+\/lib\/(.+)$/;
|
|
7269
|
-
function relativeSpecifier(fromFile, toFile, impl =
|
|
7871
|
+
function relativeSpecifier(fromFile, toFile, impl = path17) {
|
|
7270
7872
|
let rel3 = toPosix(impl.relative(impl.dirname(fromFile), stripExt(toFile)), impl);
|
|
7271
7873
|
if (!rel3.startsWith(".")) rel3 = `./${rel3}`;
|
|
7272
7874
|
return rel3;
|
|
@@ -7294,10 +7896,10 @@ function rewriteImports(content, fileTarget, targets) {
|
|
|
7294
7896
|
}
|
|
7295
7897
|
var RESOLVE_EXTS = ["", ".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", "/index.ts", "/index.tsx", "/index.js"];
|
|
7296
7898
|
function relativeSpecifierResolves(fromFile, spec) {
|
|
7297
|
-
const base =
|
|
7899
|
+
const base = path17.resolve(path17.dirname(fromFile), spec);
|
|
7298
7900
|
return RESOLVE_EXTS.some((ext) => {
|
|
7299
7901
|
try {
|
|
7300
|
-
return
|
|
7902
|
+
return statSync6(base + ext).isFile();
|
|
7301
7903
|
} catch {
|
|
7302
7904
|
return false;
|
|
7303
7905
|
}
|
|
@@ -7346,7 +7948,7 @@ function planFiles(layout, items) {
|
|
|
7346
7948
|
}
|
|
7347
7949
|
const prev = byTarget.get(target);
|
|
7348
7950
|
if (prev !== void 0) {
|
|
7349
|
-
errors.push(`${item.name}: ${toPosix(
|
|
7951
|
+
errors.push(`${item.name}: ${toPosix(path17.relative(layout.root, target))} \uB97C ${prev} \uC640 \uD568\uAED8 \uC501\uB2C8\uB2E4(\uAC19\uC740 \uC704\uCE58)`);
|
|
7350
7952
|
continue;
|
|
7351
7953
|
}
|
|
7352
7954
|
byTarget.set(target, item.name);
|
|
@@ -7372,7 +7974,7 @@ function missingDependencies(root, items) {
|
|
|
7372
7974
|
const installCommand = detectInstallCommand(root);
|
|
7373
7975
|
let pkg;
|
|
7374
7976
|
try {
|
|
7375
|
-
const text =
|
|
7977
|
+
const text = readFileSync9(path17.join(root, "package.json"), "utf8").replace(/^\uFEFF/, "");
|
|
7376
7978
|
const parsed = JSON.parse(text);
|
|
7377
7979
|
pkg = isPlainObject(parsed) ? parsed : void 0;
|
|
7378
7980
|
} catch {
|
|
@@ -7403,13 +8005,13 @@ function addCommandForSpecs(installCommand, specs) {
|
|
|
7403
8005
|
return `${addCommandPrefix(installCommand)} ${args}`;
|
|
7404
8006
|
}
|
|
7405
8007
|
function rel2(root, p) {
|
|
7406
|
-
return toPosix(
|
|
8008
|
+
return toPosix(path17.relative(root, p));
|
|
7407
8009
|
}
|
|
7408
8010
|
async function runAdd(cwd, requested, options, ctx) {
|
|
7409
8011
|
const log = ctx.log ?? console.log;
|
|
7410
8012
|
const error = ctx.error ?? console.error;
|
|
7411
8013
|
const hints = { ...CLI_ADD_HINTS, ...ctx.hints };
|
|
7412
|
-
const root =
|
|
8014
|
+
const root = path17.resolve(cwd);
|
|
7413
8015
|
const result = { exitCode: 1, written: [], overwritten: [], unchanged: [], skipped: [] };
|
|
7414
8016
|
if (requested.length === 0) {
|
|
7415
8017
|
error(`\uCD94\uAC00\uD560 \uCEF4\uD3EC\uB10C\uD2B8 \uC774\uB984\uC744 \uD558\uB098 \uC774\uC0C1 \uC801\uC73C\uC138\uC694. \uBAA9\uB85D: ${hints.listCommand}`);
|
|
@@ -7492,7 +8094,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
7492
8094
|
continue;
|
|
7493
8095
|
}
|
|
7494
8096
|
try {
|
|
7495
|
-
existing.set(file,
|
|
8097
|
+
existing.set(file, readFileSync9(file.target, "utf8"));
|
|
7496
8098
|
} catch (e) {
|
|
7497
8099
|
readErrors.push(
|
|
7498
8100
|
`${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})`
|
|
@@ -7566,7 +8168,7 @@ async function runAdd(cwd, requested, options, ctx) {
|
|
|
7566
8168
|
try {
|
|
7567
8169
|
const before = escapeReason(root, d.file.target);
|
|
7568
8170
|
if (before) return stopWriting(p, before);
|
|
7569
|
-
await fs13.ensureDir(
|
|
8171
|
+
await fs13.ensureDir(path17.dirname(d.file.target));
|
|
7570
8172
|
const after = checkParentInside(root, d.file.target);
|
|
7571
8173
|
if (after) return stopWriting(p, after);
|
|
7572
8174
|
actual = await writeNoFollow(d.file.target, d.file.content, actual);
|
|
@@ -7653,7 +8255,7 @@ async function createClientFor(cwd, notify, env = process.env, clientOptions = {
|
|
|
7653
8255
|
const { guardConfigRegistry, ...options } = clientOptions;
|
|
7654
8256
|
let config = null;
|
|
7655
8257
|
try {
|
|
7656
|
-
config = await readAxisConfig(
|
|
8258
|
+
config = await readAxisConfig(path17.resolve(cwd));
|
|
7657
8259
|
} catch {
|
|
7658
8260
|
config = null;
|
|
7659
8261
|
}
|