@axis-ds/mcp 1.4.5 → 1.4.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +632 -116
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ function getTokenStats() {
|
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
// ../axis-registry-core/src/add/add.ts
|
|
80
|
-
import { existsSync as existsSync5, readFileSync as readFileSync5, statSync as
|
|
80
|
+
import { existsSync as existsSync5, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
|
|
81
81
|
import path5 from "path";
|
|
82
82
|
import fs3 from "fs-extra";
|
|
83
83
|
|
|
@@ -871,7 +871,7 @@ var RegistryClient = class {
|
|
|
871
871
|
};
|
|
872
872
|
|
|
873
873
|
// ../axis-registry-core/src/project.ts
|
|
874
|
-
import { existsSync as existsSync2, readFileSync as readFileSync3, realpathSync, statSync } from "fs";
|
|
874
|
+
import { existsSync as existsSync2, readdirSync, readFileSync as readFileSync3, realpathSync, statSync } from "fs";
|
|
875
875
|
import path3 from "path";
|
|
876
876
|
function resolveBaseDir(baseDirInput) {
|
|
877
877
|
const resolved = path3.resolve(baseDirInput);
|
|
@@ -1062,6 +1062,32 @@ function isFile(file) {
|
|
|
1062
1062
|
return false;
|
|
1063
1063
|
}
|
|
1064
1064
|
}
|
|
1065
|
+
function selectGlobalCss(baseDir, configured, candidates, options = {}) {
|
|
1066
|
+
const result = {};
|
|
1067
|
+
if (typeof configured === "string" && configured.trim() !== "") {
|
|
1068
|
+
const file = path3.resolve(baseDir, configured);
|
|
1069
|
+
if (!isFile(file)) result.configuredMissing = configured;
|
|
1070
|
+
else if (options.requireStylesheet && path3.extname(file).toLowerCase() !== ".css") result.configuredRejected = configured;
|
|
1071
|
+
else return { path: file, rel: path3.relative(baseDir, file).split(path3.sep).join("/") };
|
|
1072
|
+
}
|
|
1073
|
+
for (const candidate of candidates) {
|
|
1074
|
+
const file = path3.join(baseDir, candidate);
|
|
1075
|
+
if (isFile(file)) {
|
|
1076
|
+
result.path = file;
|
|
1077
|
+
result.rel = candidate;
|
|
1078
|
+
break;
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
return result;
|
|
1082
|
+
}
|
|
1083
|
+
function globalCssSelectionNote(selection) {
|
|
1084
|
+
if (selection.configuredMissing !== void 0) return ` (globalCss ${selection.configuredMissing} \uC5C6\uC74C)`;
|
|
1085
|
+
if (selection.configuredRejected !== void 0) return ` (globalCss ${selection.configuredRejected}: .css \uD30C\uC77C\uC774 \uC544\uB2D8)`;
|
|
1086
|
+
return "";
|
|
1087
|
+
}
|
|
1088
|
+
function cssImportViaNote(files) {
|
|
1089
|
+
return files !== void 0 && files.length > 0 ? ` (${files.join(" \xB7 ")} \uC758 import)` : "";
|
|
1090
|
+
}
|
|
1065
1091
|
var ROOT_LAYOUT_FILES = [
|
|
1066
1092
|
"app/layout.tsx",
|
|
1067
1093
|
"app/layout.jsx",
|
|
@@ -1105,15 +1131,174 @@ function findInstalledPackage(baseDirInput, name) {
|
|
|
1105
1131
|
}
|
|
1106
1132
|
}
|
|
1107
1133
|
function isPnpProject(baseDirInput) {
|
|
1134
|
+
return pnpProjectRoot(baseDirInput) !== void 0;
|
|
1135
|
+
}
|
|
1136
|
+
function pnpProjectRoot(baseDirInput) {
|
|
1108
1137
|
let dir = resolveBaseDir(baseDirInput);
|
|
1109
1138
|
for (; ; ) {
|
|
1110
|
-
if (isFile(path3.join(dir, ".pnp.cjs")) || isFile(path3.join(dir, ".pnp.js"))) return
|
|
1111
|
-
if (existsSync2(path3.join(dir, ".git"))) return
|
|
1139
|
+
if (isFile(path3.join(dir, ".pnp.cjs")) || isFile(path3.join(dir, ".pnp.js"))) return dir;
|
|
1140
|
+
if (existsSync2(path3.join(dir, ".git"))) return void 0;
|
|
1112
1141
|
const parent = path3.dirname(dir);
|
|
1113
|
-
if (parent === dir) return
|
|
1142
|
+
if (parent === dir) return void 0;
|
|
1114
1143
|
dir = parent;
|
|
1115
1144
|
}
|
|
1116
1145
|
}
|
|
1146
|
+
var TAILWIND4_MIN_AXIS_VERSION = "1.4.0";
|
|
1147
|
+
var COMPONENT_TAILWIND_CSS_MIN_VERSION = TAILWIND4_MIN_AXIS_VERSION;
|
|
1148
|
+
function componentCssResolution(baseDir, pkg, name) {
|
|
1149
|
+
if (pkg === void 0) return { kind: "undeclared" };
|
|
1150
|
+
const own = hasDependency(pkg, name);
|
|
1151
|
+
if (own !== void 0) return { kind: "app", range: own };
|
|
1152
|
+
const pnpRoot = pnpRootOnlyDependency(baseDir, pkg, name);
|
|
1153
|
+
if (pnpRoot !== void 0) return { kind: "pnp-root-only", range: pnpRoot.range };
|
|
1154
|
+
const declared = declaredDependency(baseDir, pkg, name);
|
|
1155
|
+
if (declared?.source !== "root") return { kind: "undeclared" };
|
|
1156
|
+
if (!rootDeclarationsAllowed(baseDir, pkg)) return { kind: "app-lockfile", range: declared.range };
|
|
1157
|
+
const installed = findInstalledPackage(baseDir, name);
|
|
1158
|
+
if (installed === void 0) return { kind: "root-not-installed", range: declared.range };
|
|
1159
|
+
if (isFile(path3.join(installed.dir, "tailwind.css"))) {
|
|
1160
|
+
return installed.version !== void 0 ? { kind: "root-ok", range: declared.range, installedVersion: installed.version } : { kind: "root-ok", range: declared.range };
|
|
1161
|
+
}
|
|
1162
|
+
const installedVersion = installed.version ?? "?";
|
|
1163
|
+
const current = installedVersion !== "?" && (compareExactVersions(installedVersion, COMPONENT_TAILWIND_CSS_MIN_VERSION) ?? -1) >= 0;
|
|
1164
|
+
return current ? { kind: "root-missing-file", range: declared.range, installedVersion } : { kind: "root-old", range: declared.range, installedVersion };
|
|
1165
|
+
}
|
|
1166
|
+
function componentCssResolvable(resolution) {
|
|
1167
|
+
return resolution.kind === "app" || resolution.kind === "root-ok";
|
|
1168
|
+
}
|
|
1169
|
+
function tokensCssResolution(baseDir, pkg, name = "@axis-ds/tokens") {
|
|
1170
|
+
const own = pkg !== void 0 ? hasDependency(pkg, name) : void 0;
|
|
1171
|
+
if (own !== void 0) return { kind: "app", range: own };
|
|
1172
|
+
const pnpRoot = pnpRootOnlyDependency(baseDir, pkg, name);
|
|
1173
|
+
if (pnpRoot !== void 0) return { kind: "pnp-root-only", range: pnpRoot.range };
|
|
1174
|
+
if (!isPnpProject(baseDir) && findInstalledPackage(baseDir, name) !== void 0) return { kind: "installed" };
|
|
1175
|
+
const declared = rootDeclarationsAllowed(baseDir, pkg) ? declaredDependency(baseDir, pkg, name) : void 0;
|
|
1176
|
+
return declared?.source === "root" ? { kind: "not-installed", source: "root", range: declared.range } : { kind: "not-installed", source: "none" };
|
|
1177
|
+
}
|
|
1178
|
+
function outsideCssPackageResolution(baseDir, cssDir, name, file) {
|
|
1179
|
+
if (isPnpProject(baseDir)) return "unknown";
|
|
1180
|
+
const usable = (p) => p !== void 0 && (file === void 0 || isFile(path3.join(p.dir, file)));
|
|
1181
|
+
if (!usable(findInstalledPackage(baseDir, name))) return "unknown";
|
|
1182
|
+
return usable(findInstalledPackage(cssDir, name)) ? "resolved" : "unresolved";
|
|
1183
|
+
}
|
|
1184
|
+
function findPnpUnpluggedPackages(baseDirInput, name, range) {
|
|
1185
|
+
const root = pnpProjectRoot(baseDirInput);
|
|
1186
|
+
if (root === void 0) return [];
|
|
1187
|
+
const unplugged = path3.join(root, ".yarn", "unplugged");
|
|
1188
|
+
let entries;
|
|
1189
|
+
try {
|
|
1190
|
+
entries = readdirSync(unplugged).sort();
|
|
1191
|
+
} catch {
|
|
1192
|
+
return [];
|
|
1193
|
+
}
|
|
1194
|
+
const found = [];
|
|
1195
|
+
for (const entry of entries) {
|
|
1196
|
+
const pkgDir = path3.join(unplugged, entry, "node_modules", ...name.split("/"));
|
|
1197
|
+
let version;
|
|
1198
|
+
try {
|
|
1199
|
+
const parsed = JSON.parse(readFileSync3(path3.join(pkgDir, "package.json"), "utf8"));
|
|
1200
|
+
version = isPlainObject(parsed) && parsed.name === name ? exactVersionOf(parsed.version) : void 0;
|
|
1201
|
+
} catch {
|
|
1202
|
+
version = void 0;
|
|
1203
|
+
}
|
|
1204
|
+
if (version !== void 0 && versionSatisfiesRange(version, range) === true) found.push(pkgDir);
|
|
1205
|
+
}
|
|
1206
|
+
return found;
|
|
1207
|
+
}
|
|
1208
|
+
function parsePartialVersion(token) {
|
|
1209
|
+
const m = /^v?(\d+|[xX*])(?:\.(\d+|[xX*]))?(?:\.(\d+|[xX*]))?(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(token.trim());
|
|
1210
|
+
if (!m) return void 0;
|
|
1211
|
+
const num = (s) => s === void 0 || /^[xX*]$/.test(s) ? void 0 : Number(s);
|
|
1212
|
+
const major = num(m[1]);
|
|
1213
|
+
const minor = major === void 0 ? void 0 : num(m[2]);
|
|
1214
|
+
const patch = minor === void 0 ? void 0 : num(m[3]);
|
|
1215
|
+
return { major, minor, patch, pre: patch === void 0 ? void 0 : m[4] };
|
|
1216
|
+
}
|
|
1217
|
+
function coreOf(v) {
|
|
1218
|
+
return v.replace(/^v/, "").replace(/[-+].*$/, "");
|
|
1219
|
+
}
|
|
1220
|
+
function intervalsOfToken(token) {
|
|
1221
|
+
const t = token.trim();
|
|
1222
|
+
if (t === "" || t === "*" || /^[xX]$/.test(t)) return [{ preCores: [] }];
|
|
1223
|
+
const op = /^(\^|~>?|>=|<=|>|<|=)?\s*(.+)$/.exec(t);
|
|
1224
|
+
if (!op) return void 0;
|
|
1225
|
+
const p = parsePartialVersion(op[2]);
|
|
1226
|
+
if (!p) return void 0;
|
|
1227
|
+
const full = (maj, min, pat, pre) => `${maj}.${min}.${pat}${pre ? `-${pre}` : ""}`;
|
|
1228
|
+
const preCores = p.pre !== void 0 ? [full(p.major ?? 0, p.minor ?? 0, p.patch ?? 0)] : [];
|
|
1229
|
+
const lower = full(p.major ?? 0, p.minor ?? 0, p.patch ?? 0, p.pre);
|
|
1230
|
+
const kind = op[1] ?? "";
|
|
1231
|
+
if (p.major === void 0) return kind === "" || kind === "=" || kind === ">=" ? [{ preCores }] : void 0;
|
|
1232
|
+
const next = p.minor === void 0 ? full(p.major + 1, 0, 0) : p.patch === void 0 ? full(p.major, p.minor + 1, 0) : void 0;
|
|
1233
|
+
switch (kind) {
|
|
1234
|
+
case "":
|
|
1235
|
+
case "=":
|
|
1236
|
+
return [next === void 0 ? { min: { v: lower, inclusive: true }, max: { v: lower, inclusive: true }, preCores } : { min: { v: lower, inclusive: true }, max: { v: next, inclusive: false, coreOnly: true }, preCores }];
|
|
1237
|
+
case ">=":
|
|
1238
|
+
return [{ min: { v: lower, inclusive: true }, preCores }];
|
|
1239
|
+
case ">":
|
|
1240
|
+
return [next === void 0 ? { min: { v: lower, inclusive: false }, preCores } : { min: { v: next, inclusive: true }, preCores }];
|
|
1241
|
+
case "<":
|
|
1242
|
+
return [{ max: { v: lower, inclusive: false, coreOnly: p.pre === void 0 }, preCores }];
|
|
1243
|
+
case "<=":
|
|
1244
|
+
return [next === void 0 ? { max: { v: lower, inclusive: true }, preCores } : { max: { v: next, inclusive: false, coreOnly: true }, preCores }];
|
|
1245
|
+
case "~":
|
|
1246
|
+
case "~>": {
|
|
1247
|
+
const upper = p.minor === void 0 ? full(p.major + 1, 0, 0) : full(p.major, p.minor + 1, 0);
|
|
1248
|
+
return [{ min: { v: lower, inclusive: true }, max: { v: upper, inclusive: false, coreOnly: true }, preCores }];
|
|
1249
|
+
}
|
|
1250
|
+
case "^": {
|
|
1251
|
+
const upper = p.major > 0 || p.minor === void 0 ? full(p.major + 1, 0, 0) : p.minor > 0 || p.patch === void 0 ? full(0, p.minor + 1, 0) : full(0, 0, p.patch + 1);
|
|
1252
|
+
return [{ min: { v: lower, inclusive: true }, max: { v: upper, inclusive: false, coreOnly: true }, preCores }];
|
|
1253
|
+
}
|
|
1254
|
+
}
|
|
1255
|
+
return void 0;
|
|
1256
|
+
}
|
|
1257
|
+
function satisfiesInterval(version, iv) {
|
|
1258
|
+
if (iv.min !== void 0) {
|
|
1259
|
+
const c = compareExactVersions(version, iv.min.v);
|
|
1260
|
+
if (c === void 0) return void 0;
|
|
1261
|
+
if (c < 0 || c === 0 && !iv.min.inclusive) return false;
|
|
1262
|
+
}
|
|
1263
|
+
if (iv.max !== void 0) {
|
|
1264
|
+
const c = iv.max.coreOnly ? compareExactVersions(coreOf(version), coreOf(iv.max.v)) : compareExactVersions(version, iv.max.v);
|
|
1265
|
+
if (c === void 0) return void 0;
|
|
1266
|
+
if (c > 0 || c === 0 && !iv.max.inclusive) return false;
|
|
1267
|
+
}
|
|
1268
|
+
return true;
|
|
1269
|
+
}
|
|
1270
|
+
function versionSatisfiesRange(version, range) {
|
|
1271
|
+
if (exactVersionOf(version) === void 0) return void 0;
|
|
1272
|
+
const alternatives = range.trim().split("||");
|
|
1273
|
+
let unknown = false;
|
|
1274
|
+
for (const alt of alternatives) {
|
|
1275
|
+
const a = alt.trim();
|
|
1276
|
+
let intervals;
|
|
1277
|
+
const hyphen = /^(\S+)\s+-\s+(\S+)$/.exec(a);
|
|
1278
|
+
if (hyphen) {
|
|
1279
|
+
const lo = intervalsOfToken(`>=${hyphen[1]}`);
|
|
1280
|
+
const hi = intervalsOfToken(`<=${hyphen[2]}`);
|
|
1281
|
+
intervals = lo && hi ? [...lo, ...hi] : void 0;
|
|
1282
|
+
} else {
|
|
1283
|
+
const tokens = a === "" ? [""] : a.replace(/(>=|<=|>|<|=|\^|~>?)\s+/g, "$1").split(/\s+/);
|
|
1284
|
+
const parts = tokens.map(intervalsOfToken);
|
|
1285
|
+
intervals = parts.every((x) => x !== void 0) ? parts.flat() : void 0;
|
|
1286
|
+
}
|
|
1287
|
+
if (intervals === void 0) {
|
|
1288
|
+
unknown = true;
|
|
1289
|
+
continue;
|
|
1290
|
+
}
|
|
1291
|
+
const pre = /-/.test(version.replace(/\+.*$/, ""));
|
|
1292
|
+
if (pre && !intervals.some((iv) => iv.preCores.includes(coreOf(version)))) continue;
|
|
1293
|
+
const results = intervals.map((iv) => satisfiesInterval(version, iv));
|
|
1294
|
+
if (results.some((x) => x === void 0)) {
|
|
1295
|
+
unknown = true;
|
|
1296
|
+
continue;
|
|
1297
|
+
}
|
|
1298
|
+
if (results.every((x) => x === true)) return true;
|
|
1299
|
+
}
|
|
1300
|
+
return unknown ? void 0 : false;
|
|
1301
|
+
}
|
|
1117
1302
|
function compareExactVersions(a, b) {
|
|
1118
1303
|
const parse = (v) => {
|
|
1119
1304
|
const m = /^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z.-]+)?/.exec(v.trim());
|
|
@@ -1127,7 +1312,7 @@ function compareExactVersions(a, b) {
|
|
|
1127
1312
|
}
|
|
1128
1313
|
|
|
1129
1314
|
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
1130
|
-
import { existsSync as existsSync3, lstatSync, readdirSync, readFileSync as readFileSync4, realpathSync as realpathSync2 } from "fs";
|
|
1315
|
+
import { existsSync as existsSync3, lstatSync, readdirSync as readdirSync2, readFileSync as readFileSync4, realpathSync as realpathSync2, statSync as statSync2 } from "fs";
|
|
1131
1316
|
import { basename, dirname as dirname2, extname, isAbsolute, join as join2, relative, resolve, sep } from "path";
|
|
1132
1317
|
function declaredRange(baseDir, pkg, name) {
|
|
1133
1318
|
return declaredDependency(baseDir, pkg, name)?.range;
|
|
@@ -1255,6 +1440,157 @@ var TOKENS_CSS_IMPORT = /@import\s+(?:url\(\s*)?["'](@axis-ds\/tokens\/css(?:\/s
|
|
|
1255
1440
|
function findTokensCssImport(css) {
|
|
1256
1441
|
return TOKENS_CSS_IMPORT.exec(stripCssComments(css))?.[1];
|
|
1257
1442
|
}
|
|
1443
|
+
var CSS_IMPORT_DEPTH_LIMIT = 32;
|
|
1444
|
+
var CSS_IMPORT_CYCLE_DEPTH_LIMIT = 100;
|
|
1445
|
+
var RELATIVE_CSS_IMPORT = /@import\s*(?:"(\.{1,2}\/[^"\n]*)"|'(\.{1,2}\/[^'\n]*)')(?=([^;{}]*))/g;
|
|
1446
|
+
function isConditionalCssImport(tail) {
|
|
1447
|
+
return tail !== void 0 && tail.trim() !== "";
|
|
1448
|
+
}
|
|
1449
|
+
function resolveRelativeCssImport(fromDir, spec) {
|
|
1450
|
+
if (spec.endsWith("/")) return void 0;
|
|
1451
|
+
const target = resolve(fromDir, spec);
|
|
1452
|
+
if (regularFile(target)) return target;
|
|
1453
|
+
if (regularFile(`${target}.css`)) return `${target}.css`;
|
|
1454
|
+
return void 0;
|
|
1455
|
+
}
|
|
1456
|
+
var CSS_IMPORT_SPEC = /@import\s+(?:url\(\s*)?(["'])([^"'\n]+)\1/g;
|
|
1457
|
+
function isPackageCssSpec(spec) {
|
|
1458
|
+
return !spec.startsWith("./") && !spec.startsWith("../") && !spec.startsWith("/") && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(spec);
|
|
1459
|
+
}
|
|
1460
|
+
function cssImportCycleIssue(files) {
|
|
1461
|
+
if (files.length === 1) return `${files[0]} \uC774 \uC790\uAE30 \uC790\uC2E0\uC744 @import \uD574 \uBE4C\uB4DC\uAC00 \uC21C\uD658\uC73C\uB85C \uC2E4\uD328\uD569\uB2C8\uB2E4 \u2192 \uC21C\uD658\uD558\uB294 @import \uB97C \uC5C6\uC560\uC138\uC694`;
|
|
1462
|
+
return `${files.join(" \xB7 ")} \uC774 \uC11C\uB85C @import \uD574 \uBE4C\uB4DC\uAC00 \uC21C\uD658\uC73C\uB85C \uC2E4\uD328\uD569\uB2C8\uB2E4 \u2192 \uC21C\uD658\uD558\uB294 @import \uB97C \uC5C6\uC560\uC138\uC694`;
|
|
1463
|
+
}
|
|
1464
|
+
function findImportCycle(start, edges) {
|
|
1465
|
+
const state = /* @__PURE__ */ new Map();
|
|
1466
|
+
const trail = [start];
|
|
1467
|
+
const stack = [{ node: start, next: 0 }];
|
|
1468
|
+
state.set(start, "open");
|
|
1469
|
+
while (stack.length > 0) {
|
|
1470
|
+
const top = stack[stack.length - 1];
|
|
1471
|
+
const out = edges.get(top.node) ?? [];
|
|
1472
|
+
if (top.next >= out.length) {
|
|
1473
|
+
state.set(top.node, "done");
|
|
1474
|
+
stack.pop();
|
|
1475
|
+
trail.pop();
|
|
1476
|
+
continue;
|
|
1477
|
+
}
|
|
1478
|
+
const to = out[top.next++];
|
|
1479
|
+
const s = state.get(to);
|
|
1480
|
+
if (s === "open") return trail.slice(trail.indexOf(to));
|
|
1481
|
+
if (s === "done") continue;
|
|
1482
|
+
state.set(to, "open");
|
|
1483
|
+
trail.push(to);
|
|
1484
|
+
stack.push({ node: to, next: 0 });
|
|
1485
|
+
}
|
|
1486
|
+
return void 0;
|
|
1487
|
+
}
|
|
1488
|
+
function regularFile(file) {
|
|
1489
|
+
try {
|
|
1490
|
+
return statSync2(file).isFile();
|
|
1491
|
+
} catch {
|
|
1492
|
+
return false;
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
function expandGlobalCss(baseDirInput, entryPath, entryRel, entryCssDir) {
|
|
1496
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1497
|
+
const entry = readFileSync4(entryPath, "utf8");
|
|
1498
|
+
let entryReal = entryPath;
|
|
1499
|
+
try {
|
|
1500
|
+
entryReal = realpathSync2(entryPath);
|
|
1501
|
+
} catch {
|
|
1502
|
+
}
|
|
1503
|
+
const raws = /* @__PURE__ */ new Map([[entryReal, entry]]);
|
|
1504
|
+
const files = [];
|
|
1505
|
+
const packageLines = [];
|
|
1506
|
+
const evidenceWalk = walkRelativeCssImports(baseDir, entryReal, raws, CSS_IMPORT_DEPTH_LIMIT, false);
|
|
1507
|
+
const relOfReal = /* @__PURE__ */ new Map([[entryReal, entryRel]]);
|
|
1508
|
+
for (const node of evidenceWalk.order) {
|
|
1509
|
+
const isEntry = node.real === entryReal;
|
|
1510
|
+
const rel2 = isEntry ? entryRel : node.rel;
|
|
1511
|
+
const css = stripCssComments(raws.get(node.real) ?? "");
|
|
1512
|
+
const file = { rel: rel2, path: node.real, css, depth: node.depth };
|
|
1513
|
+
const cssDir = isEntry ? entryCssDir : dirname2(node.real);
|
|
1514
|
+
if (cssDir !== void 0) file.cssDir = cssDir;
|
|
1515
|
+
files.push(file);
|
|
1516
|
+
relOfReal.set(node.real, rel2);
|
|
1517
|
+
for (const m of css.matchAll(CSS_IMPORT_SPEC)) {
|
|
1518
|
+
if (!isPackageCssSpec(m[2])) continue;
|
|
1519
|
+
const line = { spec: m[2], file: rel2 };
|
|
1520
|
+
if (cssDir !== void 0) line.cssDir = cssDir;
|
|
1521
|
+
packageLines.push(line);
|
|
1522
|
+
}
|
|
1523
|
+
}
|
|
1524
|
+
const cycleWalk = walkRelativeCssImports(baseDir, entryReal, raws, CSS_IMPORT_CYCLE_DEPTH_LIMIT, true);
|
|
1525
|
+
const cycle = findImportCycle(entryReal, cycleWalk.edges);
|
|
1526
|
+
if (cycle !== void 0) {
|
|
1527
|
+
for (const node of cycleWalk.order) if (!relOfReal.has(node.real)) relOfReal.set(node.real, node.rel);
|
|
1528
|
+
const head = files[0];
|
|
1529
|
+
return {
|
|
1530
|
+
entry,
|
|
1531
|
+
evidence: entry,
|
|
1532
|
+
files: [head],
|
|
1533
|
+
packageLines: packageLines.filter((l) => l.file === head.rel),
|
|
1534
|
+
cycle: cycle.map((p) => relOfReal.get(p) ?? p)
|
|
1535
|
+
};
|
|
1536
|
+
}
|
|
1537
|
+
const evidence = files.length === 1 ? entry : files.map((f) => f.css).join("\n");
|
|
1538
|
+
return { entry, evidence, files, packageLines };
|
|
1539
|
+
}
|
|
1540
|
+
function walkRelativeCssImports(baseDir, entryReal, raws, limit, includeConditional) {
|
|
1541
|
+
const order = [];
|
|
1542
|
+
const edges = /* @__PURE__ */ new Map();
|
|
1543
|
+
const visited = /* @__PURE__ */ new Set([entryReal]);
|
|
1544
|
+
const queue = [{ real: entryReal, rel: "", depth: 0 }];
|
|
1545
|
+
while (queue.length > 0) {
|
|
1546
|
+
const cur = queue.shift();
|
|
1547
|
+
order.push(cur);
|
|
1548
|
+
const css = stripCssComments(raws.get(cur.real) ?? "");
|
|
1549
|
+
const out = [];
|
|
1550
|
+
edges.set(cur.real, out);
|
|
1551
|
+
for (const m of css.matchAll(RELATIVE_CSS_IMPORT)) {
|
|
1552
|
+
if (!includeConditional && isConditionalCssImport(m[3])) continue;
|
|
1553
|
+
const target = resolveRelativeCssImport(dirname2(cur.real), m[1] ?? m[2]);
|
|
1554
|
+
if (target === void 0) continue;
|
|
1555
|
+
let real;
|
|
1556
|
+
try {
|
|
1557
|
+
real = realpathSync2(target);
|
|
1558
|
+
} catch {
|
|
1559
|
+
continue;
|
|
1560
|
+
}
|
|
1561
|
+
if (visited.has(real)) {
|
|
1562
|
+
out.push(real);
|
|
1563
|
+
continue;
|
|
1564
|
+
}
|
|
1565
|
+
if (cur.depth >= limit) continue;
|
|
1566
|
+
const rel2 = relative(baseDir, real);
|
|
1567
|
+
if (rel2 === "" || rel2 === ".." || rel2.startsWith(`..${sep}`) || isAbsolute(rel2)) continue;
|
|
1568
|
+
if (!raws.has(real)) {
|
|
1569
|
+
try {
|
|
1570
|
+
raws.set(real, readFileSync4(real, "utf8"));
|
|
1571
|
+
} catch {
|
|
1572
|
+
continue;
|
|
1573
|
+
}
|
|
1574
|
+
}
|
|
1575
|
+
visited.add(real);
|
|
1576
|
+
out.push(real);
|
|
1577
|
+
queue.push({ real, rel: rel2.split(sep).join("/"), depth: cur.depth + 1 });
|
|
1578
|
+
}
|
|
1579
|
+
}
|
|
1580
|
+
return { order, edges };
|
|
1581
|
+
}
|
|
1582
|
+
function evidenceOrigin(expanded, test) {
|
|
1583
|
+
return expanded.files.find((f) => test(f.css));
|
|
1584
|
+
}
|
|
1585
|
+
function packageLineCssDir(expanded, spec) {
|
|
1586
|
+
const line = expanded.packageLines.find((l) => l.spec === spec);
|
|
1587
|
+
return line !== void 0 ? line.cssDir : expanded.files[0]?.cssDir;
|
|
1588
|
+
}
|
|
1589
|
+
function viaFiles(origins) {
|
|
1590
|
+
const out = [];
|
|
1591
|
+
for (const o of origins) if (o !== void 0 && o.depth > 0 && !out.includes(o.rel)) out.push(o.rel);
|
|
1592
|
+
return out;
|
|
1593
|
+
}
|
|
1258
1594
|
var TOKENS_CSS_JS_IMPORT = /(?:\bimport\s+|\bfrom\s+|\brequire\s*\(\s*)(["'])(@axis-ds\/tokens\/css(?:\/shadcn|\/tailwind4)?)\1/;
|
|
1259
1595
|
var AXIS_VARIABLE_DEFINITION = /(?<![\w-])--axis-[\w-]+\s*:/;
|
|
1260
1596
|
function findLayoutTokensCssImport(baseDirInput) {
|
|
@@ -1273,45 +1609,92 @@ function findLayoutTokensCssImport(baseDirInput) {
|
|
|
1273
1609
|
}
|
|
1274
1610
|
return void 0;
|
|
1275
1611
|
}
|
|
1612
|
+
var TOKENS_PACKAGE_NAME = "@axis-ds/tokens";
|
|
1613
|
+
function outsideCssDir(selection) {
|
|
1614
|
+
if (selection.path === void 0 || selection.rel === void 0) return void 0;
|
|
1615
|
+
const outside = selection.rel === ".." || selection.rel.startsWith("../") || isAbsolute(selection.rel);
|
|
1616
|
+
return outside ? dirname2(selection.path) : void 0;
|
|
1617
|
+
}
|
|
1618
|
+
function outsideCssUnresolvedIssue(spec, name) {
|
|
1619
|
+
return `${spec} import \uAC00 \uC788\uC9C0\uB9CC \uC774 \uD30C\uC77C \uC704\uCE58\uC5D0\uC11C ${name} \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC124\uCE58\uBCF8\uC774 \uC571 \uCABD node_modules \uC5D0\uB9CC \uC788\uC74C) \u2192 \uC774 \uD30C\uC77C\uC758 \uC0C1\uC704 node_modules(\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uB4F1)\uC5D0 \uC124\uCE58\uD558\uAC70\uB098 globalCss \uB97C \uC571 \uC548 \uD30C\uC77C\uB85C \uBC14\uAFB8\uC138\uC694`;
|
|
1620
|
+
}
|
|
1621
|
+
function tokensInstallPhrase(baseDir) {
|
|
1622
|
+
const g = dependencyInstallGuide(baseDir, TOKENS_PACKAGE_NAME, `^${TAILWIND4_MIN_AXIS_VERSION}`);
|
|
1623
|
+
if (g.kind === "install-at-root") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${g.installCommand}`;
|
|
1624
|
+
return g.kind === "install" ? g.installCommand : g.addCommand;
|
|
1625
|
+
}
|
|
1626
|
+
function tokensCssUnresolvedIssue(baseDir, pkg, spec, cssDir) {
|
|
1627
|
+
const r = tokensCssResolution(baseDir, pkg, TOKENS_PACKAGE_NAME);
|
|
1628
|
+
const head = `${spec} import \uAC00 \uC788\uC9C0\uB9CC`;
|
|
1629
|
+
if (r.kind === "pnp-root-only") return `${head} ${TOKENS_PACKAGE_NAME} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`;
|
|
1630
|
+
if (r.kind === "not-installed") {
|
|
1631
|
+
return `${head} ${TOKENS_PACKAGE_NAME} \uAC00 \uC124\uCE58\uB418\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC124\uCE58(${tokensInstallPhrase(baseDir)})`;
|
|
1632
|
+
}
|
|
1633
|
+
if (cssDir !== void 0 && outsideCssPackageResolution(baseDir, cssDir, TOKENS_PACKAGE_NAME) === "unresolved") {
|
|
1634
|
+
return outsideCssUnresolvedIssue(spec, TOKENS_PACKAGE_NAME);
|
|
1635
|
+
}
|
|
1636
|
+
return void 0;
|
|
1637
|
+
}
|
|
1276
1638
|
function checkGlobalsCss(baseDirInput) {
|
|
1277
1639
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
const
|
|
1282
|
-
const
|
|
1283
|
-
const
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
if (
|
|
1640
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
1641
|
+
const note = globalCssSelectionNote(selection);
|
|
1642
|
+
if (selection.path !== void 0 && selection.rel !== void 0) {
|
|
1643
|
+
const candidate = selection.rel;
|
|
1644
|
+
const expanded = expandGlobalCss(baseDir, selection.path, candidate, outsideCssDir(selection));
|
|
1645
|
+
const judged = judgeGlobalsCss(baseDir, selection, candidate, expanded);
|
|
1646
|
+
if (expanded.cycle !== void 0) {
|
|
1647
|
+
return { name: "globals.css", severity: "warn", message: `${judged.message} / ${cssImportCycleIssue(expanded.cycle)}${note}` };
|
|
1648
|
+
}
|
|
1649
|
+
return { name: "globals.css", severity: judged.severity, message: `${judged.message}${note}` };
|
|
1650
|
+
}
|
|
1651
|
+
return { name: "globals.css", severity: "fail", message: `globals.css \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4${note}` };
|
|
1652
|
+
}
|
|
1653
|
+
function judgeGlobalsCss(baseDir, selection, candidate, expanded) {
|
|
1654
|
+
const content = expanded.entry;
|
|
1655
|
+
const css = stripCssComments(content);
|
|
1656
|
+
const imported = findTokensCssImport(expanded.evidence);
|
|
1657
|
+
const pkg = readPackageJson(baseDir);
|
|
1658
|
+
let pass;
|
|
1659
|
+
let unresolved;
|
|
1660
|
+
let via = "";
|
|
1661
|
+
if (imported !== void 0) {
|
|
1662
|
+
const origin = evidenceOrigin(expanded, (f) => findTokensCssImport(f) === imported);
|
|
1663
|
+
via = cssImportViaNote(viaFiles([origin]));
|
|
1664
|
+
const issue = tokensCssUnresolvedIssue(baseDir, pkg, imported, origin !== void 0 ? origin.cssDir : outsideCssDir(selection));
|
|
1665
|
+
if (issue !== void 0) unresolved = `${candidate}\uC5D0 ${issue}`;
|
|
1666
|
+
else pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${imported} import)`;
|
|
1667
|
+
} else if (AXIS_VARIABLE_DEFINITION.test(stripCssComments(expanded.evidence))) {
|
|
1668
|
+
via = cssImportViaNote(viaFiles([evidenceOrigin(expanded, (f) => AXIS_VARIABLE_DEFINITION.test(f))]));
|
|
1669
|
+
pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218(--axis-*)\uAC00 \uC815\uC758\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4`;
|
|
1670
|
+
} else {
|
|
1671
|
+
const layout = findLayoutTokensCssImport(baseDir);
|
|
1672
|
+
if (layout) {
|
|
1673
|
+
const issue = tokensCssUnresolvedIssue(baseDir, pkg, layout.spec);
|
|
1674
|
+
if (issue !== void 0) unresolved = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC5C6\uACE0 ${layout.file}\uC758 ${issue}`;
|
|
1675
|
+
else pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${layout.file}\uC758 ${layout.spec} import)`;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
const head = pass ?? unresolved;
|
|
1679
|
+
if (head !== void 0) {
|
|
1680
|
+
const tailwind = detectTailwind(baseDir, pkg);
|
|
1681
|
+
const tailwind4 = tailwind.major !== void 0 && tailwind.major >= 4;
|
|
1682
|
+
if (!tailwind4 && findCreateNextAppDefaults(content).some((d) => d.includes("font-family: Arial"))) {
|
|
1304
1683
|
return {
|
|
1305
|
-
name: "globals.css",
|
|
1306
1684
|
severity: "warn",
|
|
1307
|
-
message: `${
|
|
1685
|
+
message: `${head}. \uB2E4\uB9CC create-next-app \uAE30\uBCF8 body font-family: Arial \uC774 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4 \u2192 \uC9C0\uC6B0\uC138\uC694(AXIS \uAE00\uAF34 \uB300\uC2E0 Arial \uC774 \uC801\uC6A9\uB428)${via}`
|
|
1308
1686
|
};
|
|
1309
1687
|
}
|
|
1310
|
-
return {
|
|
1688
|
+
return { severity: pass !== void 0 ? "pass" : "warn", message: `${head}${via}` };
|
|
1689
|
+
}
|
|
1690
|
+
if (css.includes("--background") && css.includes("--primary")) {
|
|
1691
|
+
return {
|
|
1692
|
+
severity: "warn",
|
|
1693
|
+
message: `${candidate}\uC5D0 \uC790\uCCB4 CSS \uBCC0\uC218(--background \xB7 --primary)\uB9CC \uC788\uACE0 AXIS \uD1A0\uD070\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 @axis-ds/tokens CSS \uB97C import \uD558\uC138\uC694`
|
|
1694
|
+
};
|
|
1311
1695
|
}
|
|
1312
|
-
return {
|
|
1696
|
+
return { severity: "warn", message: `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4` };
|
|
1313
1697
|
}
|
|
1314
|
-
var TAILWIND4_MIN_AXIS_VERSION = "1.4.0";
|
|
1315
1698
|
var TAILWIND4_AXIS_PACKAGES = ["@axis-ds/tokens", "@axis-ds/ui-react", "@axis-ds/agentic-ui"];
|
|
1316
1699
|
function lowerOf(token) {
|
|
1317
1700
|
const v = versionParts(token);
|
|
@@ -1544,66 +1927,134 @@ function readPackageJson(baseDir) {
|
|
|
1544
1927
|
return void 0;
|
|
1545
1928
|
}
|
|
1546
1929
|
}
|
|
1547
|
-
function tailwind4Issues(
|
|
1930
|
+
function tailwind4Issues(input, pkg, versions, baseDir) {
|
|
1931
|
+
const { entry, evidence } = input;
|
|
1932
|
+
const cssDirOf = input.cssDirOf ?? (() => void 0);
|
|
1548
1933
|
const issues = [];
|
|
1549
|
-
const
|
|
1934
|
+
const tailwindDir = cssDirOf("tailwindcss");
|
|
1935
|
+
if (tailwindDir !== void 0 && outsideCssPackageResolution(baseDir, tailwindDir, "tailwindcss") === "unresolved") {
|
|
1936
|
+
issues.push(outsideCssUnresolvedIssue("tailwindcss", "tailwindcss"));
|
|
1937
|
+
}
|
|
1938
|
+
const hasEntry = hasTokensTailwind4Import(evidence);
|
|
1550
1939
|
if (!hasEntry) issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${TOKENS_TAILWIND4_IMPORT_LINE}`);
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
|
|
1940
|
+
const resolutions = new Map(TAILWIND4_COMPONENT_PACKAGES.map((name) => [name, componentCssResolution(baseDir, pkg, name)]));
|
|
1941
|
+
const missing = [];
|
|
1942
|
+
const unresolvedMissing = [];
|
|
1943
|
+
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1944
|
+
const r = resolutions.get(name);
|
|
1945
|
+
if (r.kind === "undeclared" || r.kind === "app-lockfile") continue;
|
|
1946
|
+
if (hasComponentTailwindImport(evidence, name) || hasComponentSource(evidence, name)) continue;
|
|
1947
|
+
if (componentCssResolvable(r)) missing.push(name);
|
|
1948
|
+
else unresolvedMissing.push(componentCssMissingIssue(baseDir, name, r));
|
|
1949
|
+
}
|
|
1554
1950
|
if (missing.length > 0) {
|
|
1555
1951
|
issues.push(`\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C(tailwind.css)\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${missing.map(componentTailwindImportLine).join(" ")}`);
|
|
1556
1952
|
}
|
|
1953
|
+
issues.push(...unresolvedMissing);
|
|
1557
1954
|
if (hasEntry) {
|
|
1558
|
-
const defaults = findCreateNextAppDefaults(
|
|
1955
|
+
const defaults = findCreateNextAppDefaults(entry);
|
|
1559
1956
|
if (defaults.length > 0) issues.push(`create-next-app \uAE30\uBCF8 \uC815\uC758\uAC00 \uB0A8\uC544 \uC788\uC2B5\uB2C8\uB2E4(${defaults.join(" \xB7 ")}) \u2192 \uC9C0\uC6B0\uC138\uC694`);
|
|
1560
1957
|
if (versions.some((v) => v.name === TAILWIND4_AXIS_PACKAGES[0])) {
|
|
1561
1958
|
issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC788\uC9C0\uB9CC ${TAILWIND4_AXIS_PACKAGES[0]} \uBC84\uC804 \uD655\uC778\uC774 \uD544\uC694\uD569\uB2C8\uB2E4`);
|
|
1562
1959
|
}
|
|
1563
1960
|
}
|
|
1564
1961
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1565
|
-
if (hasComponentTailwindImport(
|
|
1566
|
-
|
|
1567
|
-
}
|
|
1962
|
+
if (!hasComponentTailwindImport(evidence, name)) continue;
|
|
1963
|
+
const unresolved = componentCssPresentIssue(baseDir, name, resolutions.get(name));
|
|
1964
|
+
const componentDir = cssDirOf(`${name}/tailwind.css`);
|
|
1965
|
+
if (unresolved !== void 0) issues.push(unresolved);
|
|
1966
|
+
else if (componentDir !== void 0 && outsideCssPackageResolution(baseDir, componentDir, name, "tailwind.css") === "unresolved") {
|
|
1967
|
+
issues.push(outsideCssUnresolvedIssue(`${name}/tailwind.css`, name));
|
|
1968
|
+
} else if (versions.some((v) => v.name === name)) issues.push(`${name}/tailwind.css import \uAC00 \uC788\uC9C0\uB9CC ${name} \uBC84\uC804 \uD655\uC778\uC774 \uD544\uC694\uD569\uB2C8\uB2E4`);
|
|
1568
1969
|
}
|
|
1569
1970
|
return issues;
|
|
1570
1971
|
}
|
|
1972
|
+
function componentInstallPhrase(baseDir, name, range) {
|
|
1973
|
+
const g = dependencyInstallGuide(baseDir, name, range);
|
|
1974
|
+
return g.kind === "install-at-root" ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${g.installCommand}` : g.installCommand;
|
|
1975
|
+
}
|
|
1976
|
+
function componentCssMissingIssue(baseDir, name, r) {
|
|
1977
|
+
const line = componentTailwindImportLine(name);
|
|
1978
|
+
switch (r.kind) {
|
|
1979
|
+
case "pnp-root-only":
|
|
1980
|
+
return `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD55C \uB4A4 ${line}`;
|
|
1981
|
+
case "root-not-installed":
|
|
1982
|
+
return `${name} \uAC00 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4 \u2192 \uC124\uCE58(${componentInstallPhrase(baseDir, name, r.range)}) \uB4A4 ${line}`;
|
|
1983
|
+
case "root-old":
|
|
1984
|
+
return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB41C ${name} \uC758 \uC124\uCE58\uBCF8(${r.installedVersion === "?" ? "\uBC84\uC804 \uBAA8\uB984" : r.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(${TAILWIND4_MIN_AXIS_VERSION} \uBD80\uD130 \uC81C\uACF5) \u2192 ${TAILWIND4_MIN_AXIS_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9B0 \uB4A4 ${line}`;
|
|
1985
|
+
case "root-missing-file":
|
|
1986
|
+
return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB41C ${name} \uC758 \uC124\uCE58\uBCF8(${r.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4(\uC124\uCE58\uAC00 \uC190\uC0C1\uB410\uC744 \uC218 \uC788\uC74C) \u2192 \uB2E4\uC2DC \uC124\uCE58(${componentInstallPhrase(baseDir, name, r.range)}) \uB4A4 ${line}`;
|
|
1987
|
+
default:
|
|
1988
|
+
return line;
|
|
1989
|
+
}
|
|
1990
|
+
}
|
|
1991
|
+
function componentCssPresentIssue(baseDir, name, r) {
|
|
1992
|
+
const head = `${name}/tailwind.css import \uAC00 \uC788\uC9C0\uB9CC`;
|
|
1993
|
+
switch (r.kind) {
|
|
1994
|
+
case "pnp-root-only":
|
|
1995
|
+
return `${head} ${name} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`;
|
|
1996
|
+
case "root-not-installed":
|
|
1997
|
+
return `${head} ${name} \uAC00 \uC124\uCE58\uB418\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC124\uCE58(${componentInstallPhrase(baseDir, name, r.range)})`;
|
|
1998
|
+
case "root-missing-file":
|
|
1999
|
+
return `${head} ${name} \uC124\uCE58\uBCF8(${r.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC5B4 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uB2E4\uC2DC \uC124\uCE58(${componentInstallPhrase(baseDir, name, r.range)})`;
|
|
2000
|
+
case "root-old":
|
|
2001
|
+
return r.installedVersion === "?" ? `${head} ${name} \uC124\uCE58\uBCF8(\uBC84\uC804 \uBAA8\uB984)\uC5D0 tailwind.css \uAC00 \uC5C6\uC5B4 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${TAILWIND4_MIN_AXIS_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9AC\uC138\uC694` : void 0;
|
|
2002
|
+
default:
|
|
2003
|
+
return void 0;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
1571
2006
|
function checkTailwindSetup(baseDirInput) {
|
|
1572
2007
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1573
2008
|
const pkg = readPackageJson(baseDir);
|
|
1574
2009
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
1575
2010
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
1576
2011
|
const label = `Tailwind ${tailwind.major}`;
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
const
|
|
1581
|
-
|
|
2012
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
2013
|
+
const note = globalCssSelectionNote(selection);
|
|
2014
|
+
if (selection.path !== void 0 && selection.rel !== void 0) {
|
|
2015
|
+
const candidate = selection.rel;
|
|
2016
|
+
const expanded = expandGlobalCss(baseDir, selection.path, candidate, outsideCssDir(selection));
|
|
2017
|
+
if (!hasTailwindImport(expanded.evidence)) {
|
|
1582
2018
|
return {
|
|
1583
2019
|
name: "tailwind.config",
|
|
1584
2020
|
severity: "warn",
|
|
1585
|
-
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2021
|
+
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4${note}`
|
|
1586
2022
|
};
|
|
1587
2023
|
}
|
|
2024
|
+
const via = cssImportViaNote(
|
|
2025
|
+
viaFiles([
|
|
2026
|
+
evidenceOrigin(expanded, hasTailwindImport),
|
|
2027
|
+
evidenceOrigin(expanded, hasTokensTailwind4Import),
|
|
2028
|
+
...TAILWIND4_COMPONENT_PACKAGES.flatMap((name) => [
|
|
2029
|
+
evidenceOrigin(expanded, (f) => hasComponentTailwindImport(f, name)),
|
|
2030
|
+
evidenceOrigin(expanded, (f) => hasComponentSource(f, name))
|
|
2031
|
+
])
|
|
2032
|
+
])
|
|
2033
|
+
);
|
|
1588
2034
|
const versions = axisPackagesBelowTailwind4(pkg, baseDir);
|
|
1589
|
-
const issues = tailwind4Issues(
|
|
2035
|
+
const issues = tailwind4Issues(
|
|
2036
|
+
{ entry: expanded.entry, evidence: expanded.evidence, cssDirOf: (spec) => packageLineCssDir(expanded, spec) },
|
|
2037
|
+
pkg,
|
|
2038
|
+
versions,
|
|
2039
|
+
baseDir
|
|
2040
|
+
);
|
|
1590
2041
|
if (issues.length > 0) {
|
|
1591
2042
|
return {
|
|
1592
2043
|
name: "tailwind.config",
|
|
1593
2044
|
severity: "warn",
|
|
1594
|
-
message: `${label}: ${candidate}\uC5D0 ${issues.join(" / ")}${tailwind4VersionNote(versions)}`
|
|
2045
|
+
message: `${label}: ${candidate}\uC5D0 ${issues.join(" / ")}${tailwind4VersionNote(versions)}${via}${note}`
|
|
1595
2046
|
};
|
|
1596
2047
|
}
|
|
1597
2048
|
return {
|
|
1598
2049
|
name: "tailwind.config",
|
|
1599
2050
|
severity: "pass",
|
|
1600
|
-
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uC640 AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC788\uC2B5\uB2C8\uB2E4`
|
|
2051
|
+
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uC640 AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC788\uC2B5\uB2C8\uB2E4${via}${note}`
|
|
1601
2052
|
};
|
|
1602
2053
|
}
|
|
1603
2054
|
return {
|
|
1604
2055
|
name: "tailwind.config",
|
|
1605
2056
|
severity: "warn",
|
|
1606
|
-
message: `${label}: @import "tailwindcss" \uB97C \uD655\uC778\uD560 CSS \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`
|
|
2057
|
+
message: `${label}: @import "tailwindcss" \uB97C \uD655\uC778\uD560 CSS \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4${note}`
|
|
1607
2058
|
};
|
|
1608
2059
|
}
|
|
1609
2060
|
for (const file of TAILWIND_CONFIG_FILES) {
|
|
@@ -1649,31 +2100,45 @@ function readAxisConfigLike(baseDir) {
|
|
|
1649
2100
|
return void 0;
|
|
1650
2101
|
}
|
|
1651
2102
|
}
|
|
1652
|
-
function
|
|
2103
|
+
function selectCheckGlobalCss(baseDir) {
|
|
2104
|
+
return selectGlobalCss(baseDir, readAxisConfigLike(baseDir)?.globalCss, TAILWIND_CSS_CANDIDATES, { requireStylesheet: true });
|
|
2105
|
+
}
|
|
2106
|
+
function contentGlobToRegExp(glob, opts = {}) {
|
|
2107
|
+
const noDot = opts.noDot === true;
|
|
1653
2108
|
const g = glob.trim().replace(/^\.\//, "");
|
|
2109
|
+
const lead = (i) => noDot && (i === 0 || g[i - 1] === "/") ? "(?!\\.)" : "";
|
|
1654
2110
|
let re = "";
|
|
1655
2111
|
for (let i = 0; i < g.length; i++) {
|
|
1656
2112
|
const c = g[i];
|
|
1657
2113
|
if (c === "*") {
|
|
1658
2114
|
if (g[i + 1] === "*") {
|
|
1659
2115
|
const slash = g[i + 2] === "/";
|
|
1660
|
-
re += slash ?
|
|
2116
|
+
if (noDot) re += slash ? `(?:${lead(i)}[^/]*/(?:(?!\\.)[^/]*/)*)?` : `${lead(i)}[^/]*(?:/(?!\\.)[^/]*)*`;
|
|
2117
|
+
else re += slash ? "(?:.*/)?" : ".*";
|
|
1661
2118
|
i += slash ? 2 : 1;
|
|
1662
|
-
} else re +=
|
|
1663
|
-
} else if (c === "?") re +=
|
|
2119
|
+
} else re += `${lead(i)}[^/]*`;
|
|
2120
|
+
} else if (c === "?") re += `${lead(i)}[^/]`;
|
|
1664
2121
|
else if (c === "{") {
|
|
1665
2122
|
const end = g.indexOf("}", i);
|
|
1666
2123
|
if (end === -1) {
|
|
1667
2124
|
re += "\\{";
|
|
1668
2125
|
continue;
|
|
1669
2126
|
}
|
|
1670
|
-
|
|
2127
|
+
const atStart = lead(i) !== "";
|
|
2128
|
+
re += `(?:${g.slice(i + 1, end).split(",").map((part) => {
|
|
2129
|
+
const body = part.replace(/[.+^$()|[\]\\]/g, "\\$&");
|
|
2130
|
+
if (!noDot) return body.replace(/\*/g, "[^/]*");
|
|
2131
|
+
return body.replace(
|
|
2132
|
+
/(\/)?\*/g,
|
|
2133
|
+
(_m, slash, off) => slash !== void 0 || off === 0 && atStart ? `${slash ?? ""}(?!\\.)[^/]*` : "[^/]*"
|
|
2134
|
+
);
|
|
2135
|
+
}).join("|")})`;
|
|
1671
2136
|
i = end;
|
|
1672
2137
|
} else if (c === "[") {
|
|
1673
2138
|
const end = g.indexOf("]", i);
|
|
1674
2139
|
if (end === -1) re += "\\[";
|
|
1675
2140
|
else {
|
|
1676
|
-
re += g.slice(i, end + 1);
|
|
2141
|
+
re += lead(i) + g.slice(i, end + 1);
|
|
1677
2142
|
i = end;
|
|
1678
2143
|
}
|
|
1679
2144
|
} else re += c.replace(/[.+^$()|\\]/g, "\\$&");
|
|
@@ -1742,22 +2207,46 @@ function realpathPosix(p) {
|
|
|
1742
2207
|
}
|
|
1743
2208
|
return void 0;
|
|
1744
2209
|
}
|
|
1745
|
-
function contentGlobBranchCovers(glob, sample, baseDir) {
|
|
2210
|
+
function contentGlobBranchCovers(glob, sample, baseDir, noDot) {
|
|
1746
2211
|
if (isAbsoluteGlob(glob)) {
|
|
1747
|
-
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"));
|
|
2212
|
+
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"), { noDot });
|
|
1748
2213
|
const absSample = resolve(baseDir, sample);
|
|
1749
2214
|
if (re.test(absSample.split(sep).join("/"))) return true;
|
|
1750
2215
|
const real = realpathPosix(absSample);
|
|
1751
2216
|
return real !== void 0 && re.test(real);
|
|
1752
2217
|
}
|
|
1753
|
-
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob).test(sample);
|
|
2218
|
+
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob, { noDot }).test(sample);
|
|
1754
2219
|
}
|
|
1755
|
-
function contentGlobCovers(glob, sample, baseDirInput) {
|
|
2220
|
+
function contentGlobCovers(glob, sample, baseDirInput, opts = {}) {
|
|
1756
2221
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1757
2222
|
const branches = expandBraces(glob.trim()) ?? [glob];
|
|
1758
|
-
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir));
|
|
2223
|
+
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir, opts.noDot === true));
|
|
2224
|
+
}
|
|
2225
|
+
var CONTENT_PARENT_PATH_NOTE = "\uC0C1\uC704 \uACBD\uB85C\uB294 Tailwind 3 \uAC00 \uBE4C\uB4DC\uB97C \uC2E4\uD589\uD55C \uB514\uB809\uD130\uB9AC \uAE30\uC900\uC73C\uB85C \uD480\uB9BD\uB2C8\uB2E4. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8 \uB4F1 \uC571 \uB514\uB809\uD130\uB9AC \uBC16\uC5D0\uC11C \uBE4C\uB4DC\uD558\uBA74 content: { relative: true, files: [...] } \uB85C \uC124\uC815 \uD30C\uC77C \uAE30\uC900\uC73C\uB85C \uBC14\uAFB8\uC138\uC694";
|
|
2226
|
+
function contentPnpNote(names, unplugged = []) {
|
|
2227
|
+
const list = [...new Set(typeof names === "string" ? [names] : names)];
|
|
2228
|
+
const dyn = list.map((n) => `path.join(path.dirname(require.resolve("${n}")), "..", "dist/**/*.{js,mjs}")`).join(", ");
|
|
2229
|
+
const needsSetup = list.filter((n) => !unplugged.includes(n));
|
|
2230
|
+
const meta = needsSetup.map((n) => `"${n}": { "unplugged": true }`).join(", ");
|
|
2231
|
+
const setup = needsSetup.length > 0 ? ` \uC815\uC801 \uACBD\uB85C\uB97C \uC4F0\uB824\uBA74 package.json \uC758 dependenciesMeta \uC5D0 ${meta} \uB97C \uB450\uACE0 yarn install \uB4A4 .yarn/unplugged \uACBD\uB85C\uB97C \uB123\uC73C\uC138\uC694` : "";
|
|
2232
|
+
return `Plug'n'Play \uC5D0\uB294 node_modules \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. content \uC5D0 ${dyn} \uCC98\uB7FC \uC2E4\uC81C \uC704\uCE58\uB97C \uB123\uC73C\uC138\uC694(\uC815\uC801\uC73C\uB85C \uD655\uC778\uD560 \uC218 \uC5C6\uC5B4 WARN \uC73C\uB85C \uB0A8\uC2B5\uB2C8\uB2E4).${setup}`;
|
|
2233
|
+
}
|
|
2234
|
+
function contentPnpNoteTargets(targets) {
|
|
2235
|
+
return targets.filter((t) => t.pnp !== void 0 && t.pnp.state !== "rootOnly").map((t) => t.label);
|
|
2236
|
+
}
|
|
2237
|
+
function contentPnpNoteFor(targets) {
|
|
2238
|
+
const names = contentPnpNoteTargets(targets);
|
|
2239
|
+
if (names.length === 0) return void 0;
|
|
2240
|
+
const unplugged = targets.filter((t) => t.pnp?.state === "unplugged").map((t) => t.label);
|
|
2241
|
+
return contentPnpNote(names, unplugged);
|
|
2242
|
+
}
|
|
2243
|
+
var CONTENT_PNP_ROOT_ONLY_ACTION = "\uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694";
|
|
2244
|
+
var CONTENT_PNP_NO_NODE_MODULES = "Plug'n'Play \uB77C node_modules \uACBD\uB85C\uAC00 \uC5C6\uC74C";
|
|
2245
|
+
function contentTargetText(t) {
|
|
2246
|
+
if (t.pnp?.state === "noNodeModules") return `${t.label}(${CONTENT_PNP_NO_NODE_MODULES})`;
|
|
2247
|
+
if (t.pnp?.state === "rootOnly") return `${t.label} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 ${CONTENT_PNP_ROOT_ONLY_ACTION}`;
|
|
2248
|
+
return `${t.label} \u2192 "${t.suggest}"${t.note === void 0 ? "" : ` (${t.note})`}`;
|
|
1759
2249
|
}
|
|
1760
|
-
var CONTENT_PARENT_PATH_NOTE = "\uC0C1\uC704 \uACBD\uB85C\uB294 Tailwind 3 \uAC00 \uBE4C\uB4DC\uB97C \uC2E4\uD589\uD55C \uB514\uB809\uD130\uB9AC \uAE30\uC900\uC73C\uB85C \uD480\uB824\uC694. \uBAA8\uB178\uB808\uD3EC \uB8E8\uD2B8 \uB4F1 \uC571 \uB514\uB809\uD130\uB9AC \uBC16\uC5D0\uC11C \uBE4C\uB4DC\uD558\uBA74 content: { relative: true, files: [...] } \uB85C \uC124\uC815 \uD30C\uC77C \uAE30\uC900\uC73C\uB85C \uBC14\uAFB8\uC138\uC694";
|
|
1761
2250
|
function relDirOf(baseDir, dir) {
|
|
1762
2251
|
const rel2 = relative(baseDir, dir);
|
|
1763
2252
|
return rel2 === "" || isAbsolute(rel2) ? void 0 : rel2.split(sep).join("/");
|
|
@@ -1777,8 +2266,26 @@ function packageVersion(dir) {
|
|
|
1777
2266
|
return void 0;
|
|
1778
2267
|
}
|
|
1779
2268
|
}
|
|
1780
|
-
function
|
|
1781
|
-
const
|
|
2269
|
+
function pnpPackageContentTarget(baseDir, name, pkg) {
|
|
2270
|
+
const legacySample = `node_modules/${name}/dist/index.js`;
|
|
2271
|
+
const none = { sample: "", suggest: "", alternates: [], others: [] };
|
|
2272
|
+
if (pnpRootOnlyDependency(baseDir, pkg, name) !== void 0) return { ...none, pnp: { state: "rootOnly", legacySample } };
|
|
2273
|
+
const range = pkg === void 0 ? void 0 : hasDependency(pkg, name);
|
|
2274
|
+
const rels = (range === void 0 ? [] : findPnpUnpluggedPackages(baseDir, name, range)).map((d) => relDirOf(baseDir, d)).filter((r) => r !== void 0);
|
|
2275
|
+
const root = pnpProjectRoot(baseDir);
|
|
2276
|
+
if (rels.length === 0 || root === void 0) return { ...none, pnp: { state: "noNodeModules", legacySample } };
|
|
2277
|
+
const rootRel = relDirOf(baseDir, root);
|
|
2278
|
+
return {
|
|
2279
|
+
sample: `${rels[0]}/dist/index.js`,
|
|
2280
|
+
suggest: `${rootRel === void 0 ? "." : rootRel}/.yarn/unplugged/*/node_modules/${name}/dist/**/*.{js,mjs}`,
|
|
2281
|
+
alternates: rels.slice(1).map((r) => `${r}/dist/index.js`),
|
|
2282
|
+
others: [],
|
|
2283
|
+
pnp: { state: "unplugged", legacySample }
|
|
2284
|
+
};
|
|
2285
|
+
}
|
|
2286
|
+
function packageContentTarget(baseDir, name, pkg) {
|
|
2287
|
+
if (isPnpProject(baseDir)) return pnpPackageContentTarget(baseDir, name, pkg);
|
|
2288
|
+
const found = findInstalledPackage(baseDir, name);
|
|
1782
2289
|
const relDir = (found === void 0 ? void 0 : relDirOf(baseDir, found.dir)) ?? `node_modules/${name}`;
|
|
1783
2290
|
const alternates = [];
|
|
1784
2291
|
const others = [];
|
|
@@ -1799,7 +2306,7 @@ function packageContentTarget(baseDir, name) {
|
|
|
1799
2306
|
const versions = theirs === void 0 || ours === void 0 ? "" : theirs === ours ? `(\uBC84\uC804\uC740 ${ours} \uB85C \uAC19\uC74C)` : `(${theirs}, \uC571 ${ours})`;
|
|
1800
2307
|
others.push({
|
|
1801
2308
|
sample: `${rel2}/dist/index.js`,
|
|
1802
|
-
note: `\uC0C1\uC704 \uACBD\uB85C ${rel2} \uB294 \uC571\uC774 \uC4F0\uB294 \uC124\uCE58\uBCF8\uACFC \uB2E4\uB978 \uC124\uCE58\uBCF8${versions}\uC774\uB77C \uB36E\uC74C\uC73C\uB85C \uBCF4\uC9C0 \uC54A\
|
|
2309
|
+
note: `\uC0C1\uC704 \uACBD\uB85C ${rel2} \uB294 \uC571\uC774 \uC4F0\uB294 \uC124\uCE58\uBCF8\uACFC \uB2E4\uB978 \uC124\uCE58\uBCF8${versions}\uC774\uB77C \uB36E\uC74C\uC73C\uB85C \uBCF4\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`
|
|
1803
2310
|
});
|
|
1804
2311
|
}
|
|
1805
2312
|
}
|
|
@@ -1876,7 +2383,7 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
1876
2383
|
}
|
|
1877
2384
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1878
2385
|
if (declaredRange(baseDir, pkg, name) !== void 0) {
|
|
1879
|
-
targets.push({ label: name, ...packageContentTarget(baseDir, name) });
|
|
2386
|
+
targets.push({ label: name, ...packageContentTarget(baseDir, name, pkg) });
|
|
1880
2387
|
}
|
|
1881
2388
|
}
|
|
1882
2389
|
if (targets.length === 0) return null;
|
|
@@ -1886,11 +2393,14 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
1886
2393
|
configFile,
|
|
1887
2394
|
unreadable: read === void 0,
|
|
1888
2395
|
dynamic: read?.dynamic ?? false,
|
|
1889
|
-
targets: targets.map(({ alternates = [], others = [], ...t }) => {
|
|
2396
|
+
targets: targets.map(({ alternates = [], others = [], pnp, ...t }) => {
|
|
1890
2397
|
const covers = (sample) => globs.some((g) => contentGlobCovers(g, sample, baseDir));
|
|
1891
|
-
const
|
|
2398
|
+
const samples = pnp !== void 0 && pnp.state !== "unplugged" ? [] : [t.sample, ...alternates];
|
|
2399
|
+
const coversSample = pnp?.state === "unplugged" ? (sample) => globs.some((g) => contentGlobCovers(g, sample, baseDir, { noDot: true })) : covers;
|
|
2400
|
+
const covered = samples.some(coversSample);
|
|
1892
2401
|
const note = covered ? void 0 : others.find((o) => covers(o.sample))?.note;
|
|
1893
|
-
|
|
2402
|
+
const base = note === void 0 ? { ...t, covered } : { ...t, covered, note };
|
|
2403
|
+
return pnp === void 0 ? base : { ...base, pnp: { state: pnp.state, legacyCovered: covers(pnp.legacySample) } };
|
|
1894
2404
|
})
|
|
1895
2405
|
};
|
|
1896
2406
|
}
|
|
@@ -1905,19 +2415,30 @@ function checkTailwindContent(baseDir) {
|
|
|
1905
2415
|
message: `${r.configFile}\uC758 content \uAC00 ${r.targets.map((t) => t.label).join(" \xB7 ")} \uB97C \uB36E\uC2B5\uB2C8\uB2E4`
|
|
1906
2416
|
};
|
|
1907
2417
|
}
|
|
1908
|
-
const list = missing.map(
|
|
2418
|
+
const list = missing.map(contentTargetText).join(" \xB7 ");
|
|
1909
2419
|
const note = missing.some((t) => t.suggest.startsWith("../")) ? ` (${CONTENT_PARENT_PATH_NOTE})` : "";
|
|
2420
|
+
const pnpText = contentPnpNoteFor(missing);
|
|
2421
|
+
const pnpNote = pnpText === void 0 ? "" : ` (${pnpText})`;
|
|
1910
2422
|
if (r.unreadable || r.dynamic) {
|
|
1911
2423
|
return {
|
|
1912
2424
|
name: "tailwind.content",
|
|
1913
2425
|
severity: "warn",
|
|
1914
|
-
message: `${r.configFile}\uC758 content \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${list}${note}`
|
|
2426
|
+
message: `${r.configFile}\uC758 content \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4: ${list}${note}${pnpNote}`
|
|
2427
|
+
};
|
|
2428
|
+
}
|
|
2429
|
+
if (missing.every((t) => t.pnp?.legacyCovered === true)) {
|
|
2430
|
+
const labels = missing.map((t) => t.label).join(" \xB7 ");
|
|
2431
|
+
const details = missing.filter((t) => t.pnp?.state !== "noNodeModules").map(contentTargetText);
|
|
2432
|
+
return {
|
|
2433
|
+
name: "tailwind.content",
|
|
2434
|
+
severity: "warn",
|
|
2435
|
+
message: `${r.configFile}\uC758 content \uAC00 Plug'n'Play \uC5D0\uC11C \uC2A4\uCE94\uB418\uC9C0 \uC54A\uB294 \uACBD\uB85C\uB85C ${labels} \uB97C \uB36E\uC2B5\uB2C8\uB2E4(node_modules \uACBD\uB85C \xB7 ./** \uB294 \uC2A4\uCE94\uB418\uC9C0 \uC54A\uC74C)${details.length > 0 ? `: ${details.join(" \xB7 ")}` : ""}${note}${pnpNote}`
|
|
1915
2436
|
};
|
|
1916
2437
|
}
|
|
1917
2438
|
return {
|
|
1918
2439
|
name: "tailwind.content",
|
|
1919
2440
|
severity: "fail",
|
|
1920
|
-
message: `${r.configFile}\uC758 content \uAC00 \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C\uB97C \uB36E\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC74C): ${list}${note}`
|
|
2441
|
+
message: `${r.configFile}\uC758 content \uAC00 \uCEF4\uD3EC\uB10C\uD2B8 \uACBD\uB85C\uB97C \uB36E\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uD074\uB798\uC2A4\uAC00 \uC0DD\uC131\uB418\uC9C0 \uC54A\uC74C): ${list}${note}${pnpNote}`
|
|
1921
2442
|
};
|
|
1922
2443
|
}
|
|
1923
2444
|
var ANIMATION_PLUGIN_TAILWIND3 = "tailwindcss-animate";
|
|
@@ -1934,7 +2455,7 @@ function componentsUseAnimation(baseDir, componentsDir) {
|
|
|
1934
2455
|
const [dir, depth] = stack.pop();
|
|
1935
2456
|
let names;
|
|
1936
2457
|
try {
|
|
1937
|
-
names =
|
|
2458
|
+
names = readdirSync2(dir);
|
|
1938
2459
|
} catch {
|
|
1939
2460
|
continue;
|
|
1940
2461
|
}
|
|
@@ -1975,24 +2496,30 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
1975
2496
|
return void 0;
|
|
1976
2497
|
};
|
|
1977
2498
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
1978
|
-
const
|
|
1979
|
-
const
|
|
2499
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
2500
|
+
const note = globalCssSelectionNote(selection);
|
|
2501
|
+
const file = selection.rel;
|
|
2502
|
+
const expanded = selection.path !== void 0 && selection.rel !== void 0 ? expandGlobalCss(baseDir, selection.path, selection.rel, outsideCssDir(selection)) : void 0;
|
|
2503
|
+
const css = expanded !== void 0 ? stripCssComments(expanded.evidence) : "";
|
|
2504
|
+
const twAnimate = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`);
|
|
2505
|
+
const animatePlugin = new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`);
|
|
1980
2506
|
const lines = [];
|
|
1981
|
-
if (
|
|
1982
|
-
if (
|
|
2507
|
+
if (twAnimate.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND4);
|
|
2508
|
+
if (animatePlugin.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND3);
|
|
2509
|
+
const via = expanded !== void 0 ? cssImportViaNote(viaFiles([evidenceOrigin(expanded, (f) => twAnimate.test(f)), evidenceOrigin(expanded, (f) => animatePlugin.test(f))])) : "";
|
|
1983
2510
|
if (lines.length === 0) {
|
|
1984
2511
|
return {
|
|
1985
2512
|
name: "animation",
|
|
1986
2513
|
severity: "warn",
|
|
1987
|
-
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND4} \uC124\uCE58 \uB4A4 @import "${ANIMATION_PLUGIN_TAILWIND4}"
|
|
2514
|
+
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC5C6\uC2B5\uB2C8\uB2E4(${by}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 ${ANIMATION_PLUGIN_TAILWIND4} \uC124\uCE58 \uB4A4 @import "${ANIMATION_PLUGIN_TAILWIND4}";${note}`
|
|
1988
2515
|
};
|
|
1989
2516
|
}
|
|
1990
2517
|
const problems = lines.map((name) => ({ name, why: pluginProblem(name) })).filter((x) => x.why !== void 0);
|
|
1991
|
-
if (problems.length === 0) return { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
2518
|
+
if (problems.length === 0) return { name: "animation", severity: "pass", message: `${file}\uC5D0 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC774 \uC788\uC2B5\uB2C8\uB2E4${via}${note}` };
|
|
1992
2519
|
return {
|
|
1993
2520
|
name: "animation",
|
|
1994
2521
|
severity: "warn",
|
|
1995
|
-
message: `${file}\uC758 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC744 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${by}, ${problems.map((x) => x.why).join(" \xB7 ")}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uACE0 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2192 ${problems.map((x) => x.name).join(" \xB7 ")} \uB97C package.json \uC5D0 \uC120\uC5B8 \xB7 \uC124\uCE58\uD558\uC138\uC694`
|
|
2522
|
+
message: `${file}\uC758 \uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778\uC744 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4(${by}, ${problems.map((x) => x.why).join(" \xB7 ")}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uACE0 \uBE4C\uB4DC\uAC00 \uC2E4\uD328\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4 \u2192 ${problems.map((x) => x.name).join(" \xB7 ")} \uB97C package.json \uC5D0 \uC120\uC5B8 \xB7 \uC124\uCE58\uD558\uC138\uC694${via}${note}`
|
|
1996
2523
|
};
|
|
1997
2524
|
}
|
|
1998
2525
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync3(join2(baseDir, f)));
|
|
@@ -2097,7 +2624,7 @@ function selectUtilsDependencies(tailwind) {
|
|
|
2097
2624
|
}
|
|
2098
2625
|
|
|
2099
2626
|
// ../axis-registry-core/src/add/safe-write.ts
|
|
2100
|
-
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as
|
|
2627
|
+
import { constants as fsConstants, existsSync as existsSync4, lstatSync as lstatSync2, realpathSync as realpathSync3, statSync as statSync3 } from "fs";
|
|
2101
2628
|
import path4 from "path";
|
|
2102
2629
|
import fs2 from "fs-extra";
|
|
2103
2630
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
@@ -2153,7 +2680,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
2153
2680
|
}
|
|
2154
2681
|
let followed;
|
|
2155
2682
|
try {
|
|
2156
|
-
followed =
|
|
2683
|
+
followed = statSync3(realTarget);
|
|
2157
2684
|
} catch {
|
|
2158
2685
|
return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
|
|
2159
2686
|
}
|
|
@@ -2425,7 +2952,7 @@ function relativeSpecifierResolves(fromFile, spec) {
|
|
|
2425
2952
|
const base = path5.resolve(path5.dirname(fromFile), spec);
|
|
2426
2953
|
return RESOLVE_EXTS.some((ext) => {
|
|
2427
2954
|
try {
|
|
2428
|
-
return
|
|
2955
|
+
return statSync4(base + ext).isFile();
|
|
2429
2956
|
} catch {
|
|
2430
2957
|
return false;
|
|
2431
2958
|
}
|
|
@@ -3208,7 +3735,7 @@ function formatTokenList(result) {
|
|
|
3208
3735
|
}
|
|
3209
3736
|
|
|
3210
3737
|
// src/tools/install.ts
|
|
3211
|
-
import { statSync as
|
|
3738
|
+
import { statSync as statSync5 } from "fs";
|
|
3212
3739
|
import path6 from "path";
|
|
3213
3740
|
var DEFAULT_LAYOUT_CONFIG = { componentsDir: "components/ui" };
|
|
3214
3741
|
var MCP_ADD_HINTS = {
|
|
@@ -3247,7 +3774,7 @@ async function handleInstallComponent(params, deps = {}) {
|
|
|
3247
3774
|
const root = path6.resolve(params.targetDir);
|
|
3248
3775
|
let isDir = false;
|
|
3249
3776
|
try {
|
|
3250
|
-
isDir =
|
|
3777
|
+
isDir = statSync5(root).isDirectory();
|
|
3251
3778
|
} catch {
|
|
3252
3779
|
isDir = false;
|
|
3253
3780
|
}
|
|
@@ -4752,7 +5279,7 @@ import fs6 from "fs-extra";
|
|
|
4752
5279
|
import path9 from "path";
|
|
4753
5280
|
|
|
4754
5281
|
// src/tools/brand-core.ts
|
|
4755
|
-
import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as
|
|
5282
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
4756
5283
|
import { createRequire } from "module";
|
|
4757
5284
|
import { dirname as dirname4, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
|
|
4758
5285
|
var TOKENS_PACKAGE = "@axis-ds/tokens";
|
|
@@ -4815,29 +5342,11 @@ function brandImportPath(entry) {
|
|
|
4815
5342
|
}
|
|
4816
5343
|
function isFile2(file) {
|
|
4817
5344
|
try {
|
|
4818
|
-
return
|
|
5345
|
+
return statSync6(file).isFile();
|
|
4819
5346
|
} catch {
|
|
4820
5347
|
return false;
|
|
4821
5348
|
}
|
|
4822
5349
|
}
|
|
4823
|
-
function findGlobalCss(baseDir, config) {
|
|
4824
|
-
const root = resolve3(baseDir);
|
|
4825
|
-
const result = {};
|
|
4826
|
-
const configured = config?.globalCss;
|
|
4827
|
-
if (typeof configured === "string" && configured.trim() !== "") {
|
|
4828
|
-
const file = resolve3(root, configured);
|
|
4829
|
-
if (isFile2(file)) return { path: file };
|
|
4830
|
-
result.configuredMissing = configured;
|
|
4831
|
-
}
|
|
4832
|
-
for (const candidate of GLOBAL_CSS_CANDIDATES) {
|
|
4833
|
-
const file = join4(root, candidate);
|
|
4834
|
-
if (isFile2(file)) {
|
|
4835
|
-
result.path = file;
|
|
4836
|
-
break;
|
|
4837
|
-
}
|
|
4838
|
-
}
|
|
4839
|
-
return result;
|
|
4840
|
-
}
|
|
4841
5350
|
function findBrandImports(css) {
|
|
4842
5351
|
const names = [];
|
|
4843
5352
|
const pattern = /@import\s+(?:url\(\s*)?["']?@axis-ds\/tokens\/css\/brands\/([a-z][a-z0-9-]*)(?:\.css)?["']?\s*\)?\s*(?=[;\s]|$)/g;
|
|
@@ -4862,18 +5371,24 @@ function inspectBrandImport(baseDir) {
|
|
|
4862
5371
|
const brand = config?.brand;
|
|
4863
5372
|
if (typeof brand !== "string" || brand.trim() === "") return null;
|
|
4864
5373
|
const root = resolve3(baseDir);
|
|
4865
|
-
const location =
|
|
5374
|
+
const location = selectGlobalCss(root, config?.globalCss, GLOBAL_CSS_CANDIDATES, { requireStylesheet: true });
|
|
4866
5375
|
const base = { brand };
|
|
4867
5376
|
if (location.configuredMissing !== void 0) base.configuredMissing = location.configuredMissing;
|
|
5377
|
+
if (location.configuredRejected !== void 0) base.configuredRejected = location.configuredRejected;
|
|
4868
5378
|
if (!location.path) {
|
|
4869
5379
|
return { ...base, state: "css-missing", imports: [] };
|
|
4870
5380
|
}
|
|
4871
5381
|
const cssFile = relative2(root, location.path).split(sep2).join("/");
|
|
4872
|
-
const
|
|
5382
|
+
const expanded = expandGlobalCss(root, location.path, cssFile);
|
|
5383
|
+
const imports = [...new Set(findBrandImports(expanded.evidence))];
|
|
4873
5384
|
let state;
|
|
4874
5385
|
if (imports.includes(brand)) state = "match";
|
|
4875
5386
|
else if (imports.length === 0) state = "import-missing";
|
|
4876
5387
|
else state = "other-brand";
|
|
5388
|
+
const sub = expanded.files.filter((f) => f.depth > 0);
|
|
5389
|
+
const via = state === "match" ? sub.filter((f) => findBrandImports(f.css).includes(brand)).slice(0, 1) : state === "other-brand" ? sub.filter((f) => findBrandImports(f.css).length > 0) : [];
|
|
5390
|
+
const entryHas = state === "match" && findBrandImports(expanded.files[0].css).includes(brand);
|
|
5391
|
+
if (via.length > 0 && !entryHas) return { ...base, state, cssFile, imports, importVia: via.map((f) => f.rel) };
|
|
4877
5392
|
return { ...base, state, cssFile, imports };
|
|
4878
5393
|
}
|
|
4879
5394
|
function isMissingBuildFile(err) {
|
|
@@ -5262,13 +5777,14 @@ async function handleDiffTemplate(params) {
|
|
|
5262
5777
|
}
|
|
5263
5778
|
function brandCheckResult(check) {
|
|
5264
5779
|
const { brand } = check;
|
|
5265
|
-
const suffix =
|
|
5780
|
+
const suffix = globalCssSelectionNote(check);
|
|
5781
|
+
const via = cssImportViaNote(check.importVia);
|
|
5266
5782
|
switch (check.state) {
|
|
5267
5783
|
case "match":
|
|
5268
5784
|
return {
|
|
5269
5785
|
name: "brand",
|
|
5270
5786
|
severity: "pass",
|
|
5271
|
-
message: `brand "${brand}" import \uAC00 ${check.cssFile}\uC5D0 \uC788\uC2B5\uB2C8\uB2E4${suffix}`
|
|
5787
|
+
message: `brand "${brand}" import \uAC00 ${check.cssFile}\uC5D0 \uC788\uC2B5\uB2C8\uB2E4${via}${suffix}`
|
|
5272
5788
|
};
|
|
5273
5789
|
case "css-missing":
|
|
5274
5790
|
return {
|
|
@@ -5286,7 +5802,7 @@ function brandCheckResult(check) {
|
|
|
5286
5802
|
return {
|
|
5287
5803
|
name: "brand",
|
|
5288
5804
|
severity: "warn",
|
|
5289
|
-
message: `brand "${brand}" \uC640 import(${check.imports.join(", ")})\uAC00 \uB2E4\uB985\uB2C8\uB2E4${suffix}`
|
|
5805
|
+
message: `brand "${brand}" \uC640 import(${check.imports.join(", ")})\uAC00 \uB2E4\uB985\uB2C8\uB2E4${via}${suffix}`
|
|
5290
5806
|
};
|
|
5291
5807
|
}
|
|
5292
5808
|
}
|