@axis-ds/mcp 1.4.4 → 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/README.md +1 -0
- package/dist/index.js +777 -149
- 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);
|
|
@@ -970,14 +970,56 @@ function workspaceRootPackage(baseDirInput) {
|
|
|
970
970
|
return void 0;
|
|
971
971
|
}
|
|
972
972
|
}
|
|
973
|
-
function declaredDependency(baseDir, pkg, name, rootPkg) {
|
|
973
|
+
function declaredDependency(baseDir, pkg, name, rootPkg, options = {}) {
|
|
974
974
|
if (pkg === void 0) return void 0;
|
|
975
975
|
const own = hasDependency(pkg, name);
|
|
976
976
|
if (own !== void 0) return { range: own, source: "app" };
|
|
977
|
+
if (options.appOnlyInPnp && isPnpProject(baseDir)) return void 0;
|
|
977
978
|
const root = rootPkg === void 0 ? workspaceRootPackage(baseDir) : rootPkg ?? void 0;
|
|
978
979
|
const fromRoot = root !== void 0 ? hasDependency(root, name) : void 0;
|
|
979
980
|
return fromRoot !== void 0 ? { range: fromRoot, source: "root" } : void 0;
|
|
980
981
|
}
|
|
982
|
+
function pnpRootOnlyDependency(baseDir, pkg, name, rootPkg) {
|
|
983
|
+
if (pkg === void 0 || hasDependency(pkg, name) !== void 0 || !isPnpProject(baseDir)) return void 0;
|
|
984
|
+
const found = declaredDependency(baseDir, pkg, name, rootPkg);
|
|
985
|
+
return found?.source === "root" ? found : void 0;
|
|
986
|
+
}
|
|
987
|
+
var PNP_ROOT_ONLY_NOTE = "\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uB9CC \uC120\uC5B8\uB3FC Plug'n'Play \uC5D0\uC11C \uC571\uC774 \uD574\uC11D\uD558\uC9C0 \uBABB\uD569\uB2C8\uB2E4";
|
|
988
|
+
var APP_LOCKFILES = ["package-lock.json", "pnpm-lock.yaml", "yarn.lock", "bun.lockb", "bun.lock"];
|
|
989
|
+
function hasAppLockfile(baseDirInput) {
|
|
990
|
+
const baseDir = path3.resolve(baseDirInput);
|
|
991
|
+
return APP_LOCKFILES.some((f) => existsSync2(path3.join(baseDir, f)));
|
|
992
|
+
}
|
|
993
|
+
function rootDeclarationsAllowed(baseDir, pkg) {
|
|
994
|
+
return pkg !== void 0 && !isPnpProject(baseDir) && !hasAppLockfile(baseDir);
|
|
995
|
+
}
|
|
996
|
+
function readPackageJsonAt(dir) {
|
|
997
|
+
try {
|
|
998
|
+
const parsed = JSON.parse(readFileSync3(path3.join(dir, "package.json"), "utf8"));
|
|
999
|
+
return isPlainObject(parsed) ? parsed : void 0;
|
|
1000
|
+
} catch {
|
|
1001
|
+
return void 0;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
function dependencyInstallGuide(baseDirInput, name, range) {
|
|
1005
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
1006
|
+
const installCommand = detectInstallCommand(baseDir);
|
|
1007
|
+
const base = { installCommand, addCommand: addCommandFor(installCommand, { [name]: range }) };
|
|
1008
|
+
const pkg = readPackageJsonAt(baseDir);
|
|
1009
|
+
if (pkg === void 0) return { kind: "add", ...base };
|
|
1010
|
+
const own = hasDependency(pkg, name);
|
|
1011
|
+
if (isPnpProject(baseDir)) return own !== void 0 ? { kind: "pnp", source: "app", range: own, ...base } : { kind: "add", ...base };
|
|
1012
|
+
if (own !== void 0) return { kind: "install", source: "app", range: own, ...base };
|
|
1013
|
+
if (!rootDeclarationsAllowed(baseDir, pkg)) return { kind: "add", ...base };
|
|
1014
|
+
const declared = declaredDependency(baseDir, pkg, name);
|
|
1015
|
+
if (declared?.source !== "root") return { kind: "add", ...base };
|
|
1016
|
+
return {
|
|
1017
|
+
kind: packageManagerOf(installCommand) === "npm" ? "install-at-root" : "install",
|
|
1018
|
+
source: "root",
|
|
1019
|
+
range: declared.range,
|
|
1020
|
+
...base
|
|
1021
|
+
};
|
|
1022
|
+
}
|
|
981
1023
|
function isPlainObject(value) {
|
|
982
1024
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
983
1025
|
}
|
|
@@ -1020,6 +1062,32 @@ function isFile(file) {
|
|
|
1020
1062
|
return false;
|
|
1021
1063
|
}
|
|
1022
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
|
+
}
|
|
1023
1091
|
var ROOT_LAYOUT_FILES = [
|
|
1024
1092
|
"app/layout.tsx",
|
|
1025
1093
|
"app/layout.jsx",
|
|
@@ -1063,14 +1131,174 @@ function findInstalledPackage(baseDirInput, name) {
|
|
|
1063
1131
|
}
|
|
1064
1132
|
}
|
|
1065
1133
|
function isPnpProject(baseDirInput) {
|
|
1134
|
+
return pnpProjectRoot(baseDirInput) !== void 0;
|
|
1135
|
+
}
|
|
1136
|
+
function pnpProjectRoot(baseDirInput) {
|
|
1066
1137
|
let dir = resolveBaseDir(baseDirInput);
|
|
1067
1138
|
for (; ; ) {
|
|
1068
|
-
if (isFile(path3.join(dir, ".pnp.cjs")) || isFile(path3.join(dir, ".pnp.js"))) 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;
|
|
1069
1141
|
const parent = path3.dirname(dir);
|
|
1070
|
-
if (parent === dir) return
|
|
1142
|
+
if (parent === dir) return void 0;
|
|
1071
1143
|
dir = parent;
|
|
1072
1144
|
}
|
|
1073
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
|
+
}
|
|
1074
1302
|
function compareExactVersions(a, b) {
|
|
1075
1303
|
const parse = (v) => {
|
|
1076
1304
|
const m = /^v?(\d+)\.(\d+)\.(\d+)(-[0-9A-Za-z.-]+)?/.exec(v.trim());
|
|
@@ -1084,11 +1312,14 @@ function compareExactVersions(a, b) {
|
|
|
1084
1312
|
}
|
|
1085
1313
|
|
|
1086
1314
|
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
1087
|
-
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";
|
|
1088
1316
|
import { basename, dirname as dirname2, extname, isAbsolute, join as join2, relative, resolve, sep } from "path";
|
|
1089
1317
|
function declaredRange(baseDir, pkg, name) {
|
|
1090
1318
|
return declaredDependency(baseDir, pkg, name)?.range;
|
|
1091
1319
|
}
|
|
1320
|
+
function declaredRangeForCheck(baseDir, pkg, name) {
|
|
1321
|
+
return declaredDependency(baseDir, pkg, name, void 0, { appOnlyInPnp: true })?.range;
|
|
1322
|
+
}
|
|
1092
1323
|
function isPlainObject2(value) {
|
|
1093
1324
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1094
1325
|
}
|
|
@@ -1209,6 +1440,157 @@ var TOKENS_CSS_IMPORT = /@import\s+(?:url\(\s*)?["'](@axis-ds\/tokens\/css(?:\/s
|
|
|
1209
1440
|
function findTokensCssImport(css) {
|
|
1210
1441
|
return TOKENS_CSS_IMPORT.exec(stripCssComments(css))?.[1];
|
|
1211
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
|
+
}
|
|
1212
1594
|
var TOKENS_CSS_JS_IMPORT = /(?:\bimport\s+|\bfrom\s+|\brequire\s*\(\s*)(["'])(@axis-ds\/tokens\/css(?:\/shadcn|\/tailwind4)?)\1/;
|
|
1213
1595
|
var AXIS_VARIABLE_DEFINITION = /(?<![\w-])--axis-[\w-]+\s*:/;
|
|
1214
1596
|
function findLayoutTokensCssImport(baseDirInput) {
|
|
@@ -1227,45 +1609,92 @@ function findLayoutTokensCssImport(baseDirInput) {
|
|
|
1227
1609
|
}
|
|
1228
1610
|
return void 0;
|
|
1229
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
|
+
}
|
|
1230
1638
|
function checkGlobalsCss(baseDirInput) {
|
|
1231
1639
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
const
|
|
1236
|
-
const
|
|
1237
|
-
const
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
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"))) {
|
|
1258
1683
|
return {
|
|
1259
|
-
name: "globals.css",
|
|
1260
1684
|
severity: "warn",
|
|
1261
|
-
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}`
|
|
1262
1686
|
};
|
|
1263
1687
|
}
|
|
1264
|
-
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
|
+
};
|
|
1265
1695
|
}
|
|
1266
|
-
return {
|
|
1696
|
+
return { severity: "warn", message: `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4` };
|
|
1267
1697
|
}
|
|
1268
|
-
var TAILWIND4_MIN_AXIS_VERSION = "1.4.0";
|
|
1269
1698
|
var TAILWIND4_AXIS_PACKAGES = ["@axis-ds/tokens", "@axis-ds/ui-react", "@axis-ds/agentic-ui"];
|
|
1270
1699
|
function lowerOf(token) {
|
|
1271
1700
|
const v = versionParts(token);
|
|
@@ -1463,7 +1892,7 @@ function hasBareCjsPresetRequire(code) {
|
|
|
1463
1892
|
function isCommonJsConfig(file, source) {
|
|
1464
1893
|
return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
|
|
1465
1894
|
}
|
|
1466
|
-
function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
1895
|
+
function packageVersionGate(baseDirInput, pkg, name, min, options = {}) {
|
|
1467
1896
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1468
1897
|
if (!isPnpProject(baseDir)) {
|
|
1469
1898
|
const installed = findInstalledPackage(baseDir, name)?.version;
|
|
@@ -1472,7 +1901,11 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
1472
1901
|
if (cmp !== void 0) return { status: cmp >= 0 ? "ok" : "below", source: "installed", value: installed };
|
|
1473
1902
|
}
|
|
1474
1903
|
}
|
|
1475
|
-
const declared = pkg ?
|
|
1904
|
+
const declared = pkg ? declaredDependency(baseDir, pkg, name, void 0, options)?.range : void 0;
|
|
1905
|
+
if (declared === void 0 && options.appOnlyInPnp) {
|
|
1906
|
+
const rootOnly = pnpRootOnlyDependency(baseDir, pkg, name);
|
|
1907
|
+
if (rootOnly !== void 0) return { status: "unresolved", source: "declared", value: rootOnly.range };
|
|
1908
|
+
}
|
|
1476
1909
|
if (declared !== void 0) {
|
|
1477
1910
|
const atLeast = rangeLowerAtLeast(declared, min);
|
|
1478
1911
|
if (atLeast !== void 0) return { status: atLeast ? "ok" : "below", source: "declared", value: declared };
|
|
@@ -1481,6 +1914,7 @@ function packageVersionGate(baseDirInput, pkg, name, min) {
|
|
|
1481
1914
|
return { status: "unknown", source: "none" };
|
|
1482
1915
|
}
|
|
1483
1916
|
function versionGateLabel(gate) {
|
|
1917
|
+
if (gate.status === "unresolved") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uC120\uC5B8 ${gate.value}`;
|
|
1484
1918
|
if (gate.source === "installed") return `\uC124\uCE58\uBCF8 ${gate.value}`;
|
|
1485
1919
|
if (gate.source === "declared") return `\uC120\uC5B8 ${gate.value}`;
|
|
1486
1920
|
return "\uC124\uCE58\uBCF8 \xB7 \uC120\uC5B8 \uC5C6\uC74C";
|
|
@@ -1493,66 +1927,134 @@ function readPackageJson(baseDir) {
|
|
|
1493
1927
|
return void 0;
|
|
1494
1928
|
}
|
|
1495
1929
|
}
|
|
1496
|
-
function tailwind4Issues(
|
|
1930
|
+
function tailwind4Issues(input, pkg, versions, baseDir) {
|
|
1931
|
+
const { entry, evidence } = input;
|
|
1932
|
+
const cssDirOf = input.cssDirOf ?? (() => void 0);
|
|
1497
1933
|
const issues = [];
|
|
1498
|
-
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);
|
|
1499
1939
|
if (!hasEntry) issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${TOKENS_TAILWIND4_IMPORT_LINE}`);
|
|
1500
|
-
const
|
|
1501
|
-
|
|
1502
|
-
|
|
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
|
+
}
|
|
1503
1950
|
if (missing.length > 0) {
|
|
1504
1951
|
issues.push(`\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C(tailwind.css)\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${missing.map(componentTailwindImportLine).join(" ")}`);
|
|
1505
1952
|
}
|
|
1953
|
+
issues.push(...unresolvedMissing);
|
|
1506
1954
|
if (hasEntry) {
|
|
1507
|
-
const defaults = findCreateNextAppDefaults(
|
|
1955
|
+
const defaults = findCreateNextAppDefaults(entry);
|
|
1508
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`);
|
|
1509
1957
|
if (versions.some((v) => v.name === TAILWIND4_AXIS_PACKAGES[0])) {
|
|
1510
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`);
|
|
1511
1959
|
}
|
|
1512
1960
|
}
|
|
1513
1961
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1514
|
-
if (hasComponentTailwindImport(
|
|
1515
|
-
|
|
1516
|
-
}
|
|
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`);
|
|
1517
1969
|
}
|
|
1518
1970
|
return issues;
|
|
1519
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
|
+
}
|
|
1520
2006
|
function checkTailwindSetup(baseDirInput) {
|
|
1521
2007
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1522
2008
|
const pkg = readPackageJson(baseDir);
|
|
1523
2009
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
1524
2010
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
1525
2011
|
const label = `Tailwind ${tailwind.major}`;
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
const
|
|
1530
|
-
|
|
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)) {
|
|
1531
2018
|
return {
|
|
1532
2019
|
name: "tailwind.config",
|
|
1533
2020
|
severity: "warn",
|
|
1534
|
-
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2021
|
+
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4${note}`
|
|
1535
2022
|
};
|
|
1536
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
|
+
);
|
|
1537
2034
|
const versions = axisPackagesBelowTailwind4(pkg, baseDir);
|
|
1538
|
-
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
|
+
);
|
|
1539
2041
|
if (issues.length > 0) {
|
|
1540
2042
|
return {
|
|
1541
2043
|
name: "tailwind.config",
|
|
1542
2044
|
severity: "warn",
|
|
1543
|
-
message: `${label}: ${candidate}\uC5D0 ${issues.join(" / ")}${tailwind4VersionNote(versions)}`
|
|
2045
|
+
message: `${label}: ${candidate}\uC5D0 ${issues.join(" / ")}${tailwind4VersionNote(versions)}${via}${note}`
|
|
1544
2046
|
};
|
|
1545
2047
|
}
|
|
1546
2048
|
return {
|
|
1547
2049
|
name: "tailwind.config",
|
|
1548
2050
|
severity: "pass",
|
|
1549
|
-
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}`
|
|
1550
2052
|
};
|
|
1551
2053
|
}
|
|
1552
2054
|
return {
|
|
1553
2055
|
name: "tailwind.config",
|
|
1554
2056
|
severity: "warn",
|
|
1555
|
-
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}`
|
|
1556
2058
|
};
|
|
1557
2059
|
}
|
|
1558
2060
|
for (const file of TAILWIND_CONFIG_FILES) {
|
|
@@ -1562,7 +2064,14 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
1562
2064
|
if (hasTokensPresetReference(content)) {
|
|
1563
2065
|
const code = stripJsComments(content);
|
|
1564
2066
|
if (isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code)) {
|
|
1565
|
-
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION);
|
|
2067
|
+
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION, { appOnlyInPnp: true });
|
|
2068
|
+
if (gate.status === "unresolved") {
|
|
2069
|
+
return {
|
|
2070
|
+
name: "tailwind.config",
|
|
2071
|
+
severity: "warn",
|
|
2072
|
+
message: `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC @axis-ds/tokens \uAC00 ${PNP_ROOT_ONLY_NOTE}(${versionGateLabel(gate)}) \u2192 \uC571 package.json \uC5D0 @axis-ds/tokens ${TOKENS_CJS_PRESET_FIXED_VERSION} \uC774\uC0C1\uC744 \uC120\uC5B8\uD558\uC138\uC694`
|
|
2073
|
+
};
|
|
2074
|
+
}
|
|
1566
2075
|
if (gate.status !== "ok") {
|
|
1567
2076
|
const why = gate.status === "below" ? `@axis-ds/tokens ${versionGateLabel(gate)} \uC5D0\uC11C\uB294 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uAC00 preset \uC774 \uC544\uB2C8\uB77C { default } \uB97C \uB3CC\uB824\uC918 \uC0C9 \xB7 keyframes \uAC00 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4` : `@axis-ds/tokens \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${versionGateLabel(gate)}). ${TOKENS_CJS_PRESET_FIXED_VERSION} \uBBF8\uB9CC\uC774\uBA74 CommonJS \uC758 require("${TOKENS_TAILWIND3_PRESET}") \uB85C\uB294 preset \uC774 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`;
|
|
1568
2077
|
return {
|
|
@@ -1591,31 +2100,45 @@ function readAxisConfigLike(baseDir) {
|
|
|
1591
2100
|
return void 0;
|
|
1592
2101
|
}
|
|
1593
2102
|
}
|
|
1594
|
-
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;
|
|
1595
2108
|
const g = glob.trim().replace(/^\.\//, "");
|
|
2109
|
+
const lead = (i) => noDot && (i === 0 || g[i - 1] === "/") ? "(?!\\.)" : "";
|
|
1596
2110
|
let re = "";
|
|
1597
2111
|
for (let i = 0; i < g.length; i++) {
|
|
1598
2112
|
const c = g[i];
|
|
1599
2113
|
if (c === "*") {
|
|
1600
2114
|
if (g[i + 1] === "*") {
|
|
1601
2115
|
const slash = g[i + 2] === "/";
|
|
1602
|
-
re += slash ?
|
|
2116
|
+
if (noDot) re += slash ? `(?:${lead(i)}[^/]*/(?:(?!\\.)[^/]*/)*)?` : `${lead(i)}[^/]*(?:/(?!\\.)[^/]*)*`;
|
|
2117
|
+
else re += slash ? "(?:.*/)?" : ".*";
|
|
1603
2118
|
i += slash ? 2 : 1;
|
|
1604
|
-
} else re +=
|
|
1605
|
-
} else if (c === "?") re +=
|
|
2119
|
+
} else re += `${lead(i)}[^/]*`;
|
|
2120
|
+
} else if (c === "?") re += `${lead(i)}[^/]`;
|
|
1606
2121
|
else if (c === "{") {
|
|
1607
2122
|
const end = g.indexOf("}", i);
|
|
1608
2123
|
if (end === -1) {
|
|
1609
2124
|
re += "\\{";
|
|
1610
2125
|
continue;
|
|
1611
2126
|
}
|
|
1612
|
-
|
|
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("|")})`;
|
|
1613
2136
|
i = end;
|
|
1614
2137
|
} else if (c === "[") {
|
|
1615
2138
|
const end = g.indexOf("]", i);
|
|
1616
2139
|
if (end === -1) re += "\\[";
|
|
1617
2140
|
else {
|
|
1618
|
-
re += g.slice(i, end + 1);
|
|
2141
|
+
re += lead(i) + g.slice(i, end + 1);
|
|
1619
2142
|
i = end;
|
|
1620
2143
|
}
|
|
1621
2144
|
} else re += c.replace(/[.+^$()|\\]/g, "\\$&");
|
|
@@ -1684,22 +2207,46 @@ function realpathPosix(p) {
|
|
|
1684
2207
|
}
|
|
1685
2208
|
return void 0;
|
|
1686
2209
|
}
|
|
1687
|
-
function contentGlobBranchCovers(glob, sample, baseDir) {
|
|
2210
|
+
function contentGlobBranchCovers(glob, sample, baseDir, noDot) {
|
|
1688
2211
|
if (isAbsoluteGlob(glob)) {
|
|
1689
|
-
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"));
|
|
2212
|
+
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"), { noDot });
|
|
1690
2213
|
const absSample = resolve(baseDir, sample);
|
|
1691
2214
|
if (re.test(absSample.split(sep).join("/"))) return true;
|
|
1692
2215
|
const real = realpathPosix(absSample);
|
|
1693
2216
|
return real !== void 0 && re.test(real);
|
|
1694
2217
|
}
|
|
1695
|
-
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob).test(sample);
|
|
2218
|
+
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob, { noDot }).test(sample);
|
|
1696
2219
|
}
|
|
1697
|
-
function contentGlobCovers(glob, sample, baseDirInput) {
|
|
2220
|
+
function contentGlobCovers(glob, sample, baseDirInput, opts = {}) {
|
|
1698
2221
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
1699
2222
|
const branches = expandBraces(glob.trim()) ?? [glob];
|
|
1700
|
-
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})`}`;
|
|
1701
2249
|
}
|
|
1702
|
-
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";
|
|
1703
2250
|
function relDirOf(baseDir, dir) {
|
|
1704
2251
|
const rel2 = relative(baseDir, dir);
|
|
1705
2252
|
return rel2 === "" || isAbsolute(rel2) ? void 0 : rel2.split(sep).join("/");
|
|
@@ -1719,8 +2266,26 @@ function packageVersion(dir) {
|
|
|
1719
2266
|
return void 0;
|
|
1720
2267
|
}
|
|
1721
2268
|
}
|
|
1722
|
-
function
|
|
1723
|
-
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);
|
|
1724
2289
|
const relDir = (found === void 0 ? void 0 : relDirOf(baseDir, found.dir)) ?? `node_modules/${name}`;
|
|
1725
2290
|
const alternates = [];
|
|
1726
2291
|
const others = [];
|
|
@@ -1741,7 +2306,7 @@ function packageContentTarget(baseDir, name) {
|
|
|
1741
2306
|
const versions = theirs === void 0 || ours === void 0 ? "" : theirs === ours ? `(\uBC84\uC804\uC740 ${ours} \uB85C \uAC19\uC74C)` : `(${theirs}, \uC571 ${ours})`;
|
|
1742
2307
|
others.push({
|
|
1743
2308
|
sample: `${rel2}/dist/index.js`,
|
|
1744
|
-
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`
|
|
1745
2310
|
});
|
|
1746
2311
|
}
|
|
1747
2312
|
}
|
|
@@ -1818,7 +2383,7 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
1818
2383
|
}
|
|
1819
2384
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
1820
2385
|
if (declaredRange(baseDir, pkg, name) !== void 0) {
|
|
1821
|
-
targets.push({ label: name, ...packageContentTarget(baseDir, name) });
|
|
2386
|
+
targets.push({ label: name, ...packageContentTarget(baseDir, name, pkg) });
|
|
1822
2387
|
}
|
|
1823
2388
|
}
|
|
1824
2389
|
if (targets.length === 0) return null;
|
|
@@ -1828,11 +2393,14 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
1828
2393
|
configFile,
|
|
1829
2394
|
unreadable: read === void 0,
|
|
1830
2395
|
dynamic: read?.dynamic ?? false,
|
|
1831
|
-
targets: targets.map(({ alternates = [], others = [], ...t }) => {
|
|
2396
|
+
targets: targets.map(({ alternates = [], others = [], pnp, ...t }) => {
|
|
1832
2397
|
const covers = (sample) => globs.some((g) => contentGlobCovers(g, sample, baseDir));
|
|
1833
|
-
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);
|
|
1834
2401
|
const note = covered ? void 0 : others.find((o) => covers(o.sample))?.note;
|
|
1835
|
-
|
|
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) } };
|
|
1836
2404
|
})
|
|
1837
2405
|
};
|
|
1838
2406
|
}
|
|
@@ -1847,19 +2415,30 @@ function checkTailwindContent(baseDir) {
|
|
|
1847
2415
|
message: `${r.configFile}\uC758 content \uAC00 ${r.targets.map((t) => t.label).join(" \xB7 ")} \uB97C \uB36E\uC2B5\uB2C8\uB2E4`
|
|
1848
2416
|
};
|
|
1849
2417
|
}
|
|
1850
|
-
const list = missing.map(
|
|
2418
|
+
const list = missing.map(contentTargetText).join(" \xB7 ");
|
|
1851
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})`;
|
|
1852
2422
|
if (r.unreadable || r.dynamic) {
|
|
1853
2423
|
return {
|
|
1854
2424
|
name: "tailwind.content",
|
|
1855
2425
|
severity: "warn",
|
|
1856
|
-
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}`
|
|
1857
2436
|
};
|
|
1858
2437
|
}
|
|
1859
2438
|
return {
|
|
1860
2439
|
name: "tailwind.content",
|
|
1861
2440
|
severity: "fail",
|
|
1862
|
-
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}`
|
|
1863
2442
|
};
|
|
1864
2443
|
}
|
|
1865
2444
|
var ANIMATION_PLUGIN_TAILWIND3 = "tailwindcss-animate";
|
|
@@ -1876,7 +2455,7 @@ function componentsUseAnimation(baseDir, componentsDir) {
|
|
|
1876
2455
|
const [dir, depth] = stack.pop();
|
|
1877
2456
|
let names;
|
|
1878
2457
|
try {
|
|
1879
|
-
names =
|
|
2458
|
+
names = readdirSync2(dir);
|
|
1880
2459
|
} catch {
|
|
1881
2460
|
continue;
|
|
1882
2461
|
}
|
|
@@ -1908,30 +2487,62 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
1908
2487
|
if (!declared && !copied) return null;
|
|
1909
2488
|
const by = declared ? "@axis-ds/ui-react \uC120\uC5B8" : "componentsDir \uC758 animate-in \uB958 \uD074\uB798\uC2A4";
|
|
1910
2489
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
2490
|
+
const pnp = isPnpProject(baseDir);
|
|
2491
|
+
const pluginProblem = (name) => {
|
|
2492
|
+
if (declaredRangeForCheck(baseDir, pkg, name) === void 0) {
|
|
2493
|
+
return pnpRootOnlyDependency(baseDir, pkg, name) !== void 0 ? `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE}` : `${name} \uC120\uC5B8 \uC5C6\uC74C`;
|
|
2494
|
+
}
|
|
2495
|
+
if (!pnp && findInstalledPackage(baseDir, name) === void 0) return `${name} \uBBF8\uC124\uCE58(\uC120\uC5B8\uB9CC \uC788\uC74C)`;
|
|
2496
|
+
return void 0;
|
|
2497
|
+
};
|
|
1911
2498
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
1912
|
-
const
|
|
1913
|
-
const
|
|
1914
|
-
const
|
|
1915
|
-
|
|
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}["']`);
|
|
2506
|
+
const lines = [];
|
|
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))])) : "";
|
|
2510
|
+
if (lines.length === 0) {
|
|
2511
|
+
return {
|
|
2512
|
+
name: "animation",
|
|
2513
|
+
severity: "warn",
|
|
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}`
|
|
2515
|
+
};
|
|
2516
|
+
}
|
|
2517
|
+
const problems = lines.map((name) => ({ name, why: pluginProblem(name) })).filter((x) => x.why !== void 0);
|
|
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}` };
|
|
2519
|
+
return {
|
|
1916
2520
|
name: "animation",
|
|
1917
2521
|
severity: "warn",
|
|
1918
|
-
message:
|
|
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}`
|
|
1919
2523
|
};
|
|
1920
2524
|
}
|
|
1921
2525
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync3(join2(baseDir, f)));
|
|
1922
2526
|
const source = configFile !== void 0 ? stripJsComments(readFileSync4(join2(baseDir, configFile), "utf8")) : "";
|
|
1923
2527
|
const plugins = configFile !== void 0 ? readAnimationPluginUse(source) : "absent";
|
|
1924
|
-
const
|
|
1925
|
-
|
|
1926
|
-
if (plugins === "found" && pluginDeclared && pluginInstalled) {
|
|
2528
|
+
const pluginReason = pluginProblem(ANIMATION_PLUGIN_TAILWIND3);
|
|
2529
|
+
if (plugins === "found" && pluginReason === void 0) {
|
|
1927
2530
|
return { name: "animation", severity: "pass", message: `${configFile}\uC758 plugins \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 \uC788\uC2B5\uB2C8\uB2E4` };
|
|
1928
2531
|
}
|
|
1929
2532
|
const cfg = configFile ?? "tailwind.config";
|
|
2533
|
+
const configReason = plugins === "dynamic" ? `${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568` : plugins !== "found" ? `${cfg} plugins \uC5D0 \uC5C6\uC74C` : void 0;
|
|
2534
|
+
if (pluginReason !== void 0 && pnpRootOnlyDependency(baseDir, pkg, ANIMATION_PLUGIN_TAILWIND3) !== void 0) {
|
|
2535
|
+
const extra = configReason !== void 0 ? `, ${configReason}` : "";
|
|
2536
|
+
const plug = configReason !== void 0 ? ` \xB7 plugins \uC5D0 require("${ANIMATION_PLUGIN_TAILWIND3}")` : "";
|
|
2537
|
+
return {
|
|
2538
|
+
name: "animation",
|
|
2539
|
+
severity: "warn",
|
|
2540
|
+
message: `\uC560\uB2C8\uBA54\uC774\uC158 \uD50C\uB7EC\uADF8\uC778 ${ANIMATION_PLUGIN_TAILWIND3} \uAC00 ${PNP_ROOT_ONLY_NOTE}(${by}${extra}): Dialog \xB7 Select \uB4F1\uC758 \uC5F4\uACE0 \uB2EB\uB294 \uC560\uB2C8\uBA54\uC774\uC158\uC774 \uB3D9\uC791\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC571 package.json \uC5D0 ${ANIMATION_PLUGIN_TAILWIND3} \uB97C \uC120\uC5B8\uD558\uC138\uC694${plug}`
|
|
2541
|
+
};
|
|
2542
|
+
}
|
|
1930
2543
|
const reasons = [];
|
|
1931
|
-
if (
|
|
1932
|
-
|
|
1933
|
-
if (plugins === "dynamic") reasons.push(`${cfg} plugins \uB97C \uC815\uC801\uC73C\uB85C \uB2E4 \uC77D\uC9C0 \uBABB\uD574 \uD655\uC778\uD558\uC9C0 \uBABB\uD568`);
|
|
1934
|
-
else if (plugins !== "found") reasons.push(`${cfg} plugins \uC5D0 \uC5C6\uC74C`);
|
|
2544
|
+
if (pluginReason !== void 0) reasons.push(pluginReason);
|
|
2545
|
+
if (configReason !== void 0) reasons.push(configReason);
|
|
1935
2546
|
return {
|
|
1936
2547
|
name: "animation",
|
|
1937
2548
|
severity: "warn",
|
|
@@ -2013,7 +2624,7 @@ function selectUtilsDependencies(tailwind) {
|
|
|
2013
2624
|
}
|
|
2014
2625
|
|
|
2015
2626
|
// ../axis-registry-core/src/add/safe-write.ts
|
|
2016
|
-
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";
|
|
2017
2628
|
import path4 from "path";
|
|
2018
2629
|
import fs2 from "fs-extra";
|
|
2019
2630
|
var NEW_FILE_FLAGS = fsConstants.O_WRONLY | fsConstants.O_CREAT | fsConstants.O_EXCL | (fsConstants.O_NOFOLLOW ?? 0);
|
|
@@ -2069,7 +2680,7 @@ function escapeReason(root, target, options = {}) {
|
|
|
2069
2680
|
}
|
|
2070
2681
|
let followed;
|
|
2071
2682
|
try {
|
|
2072
|
-
followed =
|
|
2683
|
+
followed = statSync3(realTarget);
|
|
2073
2684
|
} catch {
|
|
2074
2685
|
return `\uAE30\uC874 \uD30C\uC77C \uC815\uBCF4\uB97C \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${target})`;
|
|
2075
2686
|
}
|
|
@@ -2341,7 +2952,7 @@ function relativeSpecifierResolves(fromFile, spec) {
|
|
|
2341
2952
|
const base = path5.resolve(path5.dirname(fromFile), spec);
|
|
2342
2953
|
return RESOLVE_EXTS.some((ext) => {
|
|
2343
2954
|
try {
|
|
2344
|
-
return
|
|
2955
|
+
return statSync4(base + ext).isFile();
|
|
2345
2956
|
} catch {
|
|
2346
2957
|
return false;
|
|
2347
2958
|
}
|
|
@@ -3124,7 +3735,7 @@ function formatTokenList(result) {
|
|
|
3124
3735
|
}
|
|
3125
3736
|
|
|
3126
3737
|
// src/tools/install.ts
|
|
3127
|
-
import { statSync as
|
|
3738
|
+
import { statSync as statSync5 } from "fs";
|
|
3128
3739
|
import path6 from "path";
|
|
3129
3740
|
var DEFAULT_LAYOUT_CONFIG = { componentsDir: "components/ui" };
|
|
3130
3741
|
var MCP_ADD_HINTS = {
|
|
@@ -3163,7 +3774,7 @@ async function handleInstallComponent(params, deps = {}) {
|
|
|
3163
3774
|
const root = path6.resolve(params.targetDir);
|
|
3164
3775
|
let isDir = false;
|
|
3165
3776
|
try {
|
|
3166
|
-
isDir =
|
|
3777
|
+
isDir = statSync5(root).isDirectory();
|
|
3167
3778
|
} catch {
|
|
3168
3779
|
isDir = false;
|
|
3169
3780
|
}
|
|
@@ -4668,7 +5279,7 @@ import fs6 from "fs-extra";
|
|
|
4668
5279
|
import path9 from "path";
|
|
4669
5280
|
|
|
4670
5281
|
// src/tools/brand-core.ts
|
|
4671
|
-
import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as
|
|
5282
|
+
import { existsSync as existsSync8, readFileSync as readFileSync8, statSync as statSync6 } from "fs";
|
|
4672
5283
|
import { createRequire } from "module";
|
|
4673
5284
|
import { dirname as dirname4, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "path";
|
|
4674
5285
|
var TOKENS_PACKAGE = "@axis-ds/tokens";
|
|
@@ -4731,29 +5342,11 @@ function brandImportPath(entry) {
|
|
|
4731
5342
|
}
|
|
4732
5343
|
function isFile2(file) {
|
|
4733
5344
|
try {
|
|
4734
|
-
return
|
|
5345
|
+
return statSync6(file).isFile();
|
|
4735
5346
|
} catch {
|
|
4736
5347
|
return false;
|
|
4737
5348
|
}
|
|
4738
5349
|
}
|
|
4739
|
-
function findGlobalCss(baseDir, config) {
|
|
4740
|
-
const root = resolve3(baseDir);
|
|
4741
|
-
const result = {};
|
|
4742
|
-
const configured = config?.globalCss;
|
|
4743
|
-
if (typeof configured === "string" && configured.trim() !== "") {
|
|
4744
|
-
const file = resolve3(root, configured);
|
|
4745
|
-
if (isFile2(file)) return { path: file };
|
|
4746
|
-
result.configuredMissing = configured;
|
|
4747
|
-
}
|
|
4748
|
-
for (const candidate of GLOBAL_CSS_CANDIDATES) {
|
|
4749
|
-
const file = join4(root, candidate);
|
|
4750
|
-
if (isFile2(file)) {
|
|
4751
|
-
result.path = file;
|
|
4752
|
-
break;
|
|
4753
|
-
}
|
|
4754
|
-
}
|
|
4755
|
-
return result;
|
|
4756
|
-
}
|
|
4757
5350
|
function findBrandImports(css) {
|
|
4758
5351
|
const names = [];
|
|
4759
5352
|
const pattern = /@import\s+(?:url\(\s*)?["']?@axis-ds\/tokens\/css\/brands\/([a-z][a-z0-9-]*)(?:\.css)?["']?\s*\)?\s*(?=[;\s]|$)/g;
|
|
@@ -4778,18 +5371,24 @@ function inspectBrandImport(baseDir) {
|
|
|
4778
5371
|
const brand = config?.brand;
|
|
4779
5372
|
if (typeof brand !== "string" || brand.trim() === "") return null;
|
|
4780
5373
|
const root = resolve3(baseDir);
|
|
4781
|
-
const location =
|
|
5374
|
+
const location = selectGlobalCss(root, config?.globalCss, GLOBAL_CSS_CANDIDATES, { requireStylesheet: true });
|
|
4782
5375
|
const base = { brand };
|
|
4783
5376
|
if (location.configuredMissing !== void 0) base.configuredMissing = location.configuredMissing;
|
|
5377
|
+
if (location.configuredRejected !== void 0) base.configuredRejected = location.configuredRejected;
|
|
4784
5378
|
if (!location.path) {
|
|
4785
5379
|
return { ...base, state: "css-missing", imports: [] };
|
|
4786
5380
|
}
|
|
4787
5381
|
const cssFile = relative2(root, location.path).split(sep2).join("/");
|
|
4788
|
-
const
|
|
5382
|
+
const expanded = expandGlobalCss(root, location.path, cssFile);
|
|
5383
|
+
const imports = [...new Set(findBrandImports(expanded.evidence))];
|
|
4789
5384
|
let state;
|
|
4790
5385
|
if (imports.includes(brand)) state = "match";
|
|
4791
5386
|
else if (imports.length === 0) state = "import-missing";
|
|
4792
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) };
|
|
4793
5392
|
return { ...base, state, cssFile, imports };
|
|
4794
5393
|
}
|
|
4795
5394
|
function isMissingBuildFile(err) {
|
|
@@ -4924,7 +5523,11 @@ function inspectBrandActivation(baseDir) {
|
|
|
4924
5523
|
if (typeof brand !== "string" || brand.trim() === "") return null;
|
|
4925
5524
|
const location = findBrandActivation(baseDir);
|
|
4926
5525
|
if (!location.markupWithProvider) return { brand, ...location };
|
|
4927
|
-
return {
|
|
5526
|
+
return {
|
|
5527
|
+
brand,
|
|
5528
|
+
...location,
|
|
5529
|
+
theme: packageVersionGate(baseDir, readProjectPackageJson(baseDir), THEME_PACKAGE, THEME_MARKUP_BRAND_MIN_VERSION, { appOnlyInPnp: true })
|
|
5530
|
+
};
|
|
4928
5531
|
}
|
|
4929
5532
|
var THEME_PACKAGE = "@axis-ds/theme";
|
|
4930
5533
|
function readProjectPackageJson(baseDir) {
|
|
@@ -4997,25 +5600,43 @@ function checkDependencies(baseDirInput) {
|
|
|
4997
5600
|
return { name: "dependencies", severity: "fail", message: "package.json \uC744 \uC77D\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(JSON \uD655\uC778)" };
|
|
4998
5601
|
}
|
|
4999
5602
|
const rootPkg = workspaceRootPackage(baseDir) ?? null;
|
|
5000
|
-
const
|
|
5603
|
+
const pnp = isPnpProject(baseDir);
|
|
5604
|
+
const declared = (d) => declaredDependency(baseDir, pkg, d, rootPkg, { appOnlyInPnp: true });
|
|
5605
|
+
const pnpRootOnly = (d) => pnpRootOnlyDependency(baseDir, pkg, d, rootPkg) !== void 0;
|
|
5001
5606
|
const fromRoot = (d) => declared(d)?.source === "root";
|
|
5002
|
-
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0);
|
|
5003
|
-
|
|
5004
|
-
|
|
5005
|
-
|
|
5006
|
-
|
|
5007
|
-
|
|
5607
|
+
const missingRequired = REQUIRED_DEPENDENCIES.filter((d) => declared(d) === void 0 && !pnpRootOnly(d));
|
|
5608
|
+
const pnpRootRequired = REQUIRED_DEPENDENCIES.filter((d) => pnpRootOnly(d));
|
|
5609
|
+
if (missingRequired.length > 0 || pnpRootRequired.length > 0) {
|
|
5610
|
+
const fails = [];
|
|
5611
|
+
if (missingRequired.length > 0) fails.push(`\uD544\uC218 \uC758\uC874\uC131 \uB204\uB77D: ${missingRequired.join(", ")}`);
|
|
5612
|
+
if (pnpRootRequired.length > 0) fails.push(`\uD544\uC218 \uC758\uC874\uC131 ${pnpRootRequired.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
5613
|
+
return { name: "dependencies", severity: "fail", message: fails.join(" / ") };
|
|
5614
|
+
}
|
|
5615
|
+
const missingRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => declared(d) === void 0 && !pnpRootOnly(d));
|
|
5616
|
+
const pnpRootRecommended = RECOMMENDED_DEPENDENCIES.filter((d) => pnpRootOnly(d));
|
|
5617
|
+
const appAxis = declaredAxisPackages(pkg);
|
|
5618
|
+
const rootOnlyAxis = rootPkg !== null ? declaredAxisPackages(rootPkg).filter((d) => !appAxis.includes(d)) : [];
|
|
5619
|
+
const rootAxis = pnp ? [] : rootOnlyAxis;
|
|
5620
|
+
const pnpRootAxis = pnp ? rootOnlyAxis : [];
|
|
5621
|
+
const rootDeclared = [...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => fromRoot(d)), ...rootAxis];
|
|
5008
5622
|
const rootNote = rootDeclared.length > 0 ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8: ${rootDeclared.join(", ")}` : void 0;
|
|
5009
5623
|
const targets = [
|
|
5010
5624
|
...[...REQUIRED_DEPENDENCIES, ...RECOMMENDED_DEPENDENCIES].filter((d) => declared(d) !== void 0),
|
|
5011
|
-
...
|
|
5625
|
+
...appAxis,
|
|
5626
|
+
...rootAxis
|
|
5012
5627
|
];
|
|
5013
|
-
const pnp = isPnpProject(baseDir);
|
|
5014
5628
|
const notInstalled = pnp ? [] : targets.filter((d) => findInstalledPackage(baseDir, d) === void 0);
|
|
5629
|
+
const notInstalledRoot = notInstalled.filter((d) => rootAxis.includes(d));
|
|
5630
|
+
const notInstalledOther = notInstalled.filter((d) => !rootAxis.includes(d));
|
|
5015
5631
|
const problems = [];
|
|
5016
5632
|
if (missingRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 \uB204\uB77D: ${missingRecommended.join(", ")}`);
|
|
5017
|
-
if (
|
|
5018
|
-
|
|
5633
|
+
if (pnpRootRecommended.length > 0) problems.push(`\uAD8C\uC7A5 \uC758\uC874\uC131 ${pnpRootRecommended.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
5634
|
+
if (pnpRootAxis.length > 0) problems.push(`${pnpRootAxis.join(", ")} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`);
|
|
5635
|
+
if (notInstalledOther.length > 0) {
|
|
5636
|
+
problems.push(`\uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC740 \uC758\uC874\uC131: ${notInstalledOther.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
5637
|
+
}
|
|
5638
|
+
if (notInstalledRoot.length > 0) {
|
|
5639
|
+
problems.push(`\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4: ${notInstalledRoot.join(", ")} \u2192 ${detectInstallCommand(baseDir)}`);
|
|
5019
5640
|
}
|
|
5020
5641
|
if (problems.length > 0) {
|
|
5021
5642
|
return { name: "dependencies", severity: "warn", message: problems.join(" / ") + (rootNote ? ` (${rootNote})` : "") };
|
|
@@ -5156,13 +5777,14 @@ async function handleDiffTemplate(params) {
|
|
|
5156
5777
|
}
|
|
5157
5778
|
function brandCheckResult(check) {
|
|
5158
5779
|
const { brand } = check;
|
|
5159
|
-
const suffix =
|
|
5780
|
+
const suffix = globalCssSelectionNote(check);
|
|
5781
|
+
const via = cssImportViaNote(check.importVia);
|
|
5160
5782
|
switch (check.state) {
|
|
5161
5783
|
case "match":
|
|
5162
5784
|
return {
|
|
5163
5785
|
name: "brand",
|
|
5164
5786
|
severity: "pass",
|
|
5165
|
-
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}`
|
|
5166
5788
|
};
|
|
5167
5789
|
case "css-missing":
|
|
5168
5790
|
return {
|
|
@@ -5180,11 +5802,18 @@ function brandCheckResult(check) {
|
|
|
5180
5802
|
return {
|
|
5181
5803
|
name: "brand",
|
|
5182
5804
|
severity: "warn",
|
|
5183
|
-
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}`
|
|
5184
5806
|
};
|
|
5185
5807
|
}
|
|
5186
5808
|
}
|
|
5187
5809
|
function brandActivationResult(check) {
|
|
5810
|
+
if (check.found && check.theme?.status === "unresolved") {
|
|
5811
|
+
return {
|
|
5812
|
+
name: "brand.activation",
|
|
5813
|
+
severity: "warn",
|
|
5814
|
+
message: `${check.found}\uC758 <html data-brand> \uB97C ThemeProvider \uC640 \uD568\uAED8 \uC4F0\uB294\uB370 @axis-ds/theme \uAC00 ${PNP_ROOT_ONLY_NOTE}(${versionGateLabel(check.theme)}) \u2192 \uC571 package.json \uC5D0 @axis-ds/theme ${THEME_MARKUP_BRAND_MIN_VERSION} \uC774\uC0C1\uC744 \uC120\uC5B8\uD558\uAC70\uB098 setBrand("${check.brand}")`
|
|
5815
|
+
};
|
|
5816
|
+
}
|
|
5188
5817
|
if (check.found && check.theme && check.theme.status !== "ok") {
|
|
5189
5818
|
const label = versionGateLabel(check.theme);
|
|
5190
5819
|
const why = check.theme.status === "below" ? `@axis-ds/theme ${label} \uC758 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4` : `@axis-ds/theme \uBC84\uC804\uC744 \uD655\uC778\uD558\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4(${label}). ${THEME_MARKUP_BRAND_MIN_VERSION} \uBBF8\uB9CC\uC774\uBA74 ThemeProvider \uAC00 \uB9C8\uC6B4\uD2B8 \uB54C \uC9C0\uC6C1\uB2C8\uB2E4`;
|
|
@@ -5378,10 +6007,8 @@ var TOKENS_INSTALL_COMMAND = addCommandFor("pnpm install", { [TOKENS_PACKAGE]: `
|
|
|
5378
6007
|
function baseDirOf(targetDir) {
|
|
5379
6008
|
return path10.resolve(targetDir || process.cwd());
|
|
5380
6009
|
}
|
|
5381
|
-
function
|
|
5382
|
-
return
|
|
5383
|
-
[TOKENS_PACKAGE]: `^${TOKENS_DEPENDENCY_MIN_VERSION}`
|
|
5384
|
-
});
|
|
6010
|
+
function tokensInstallGuideFor(targetDir) {
|
|
6011
|
+
return dependencyInstallGuide(baseDirOf(targetDir), TOKENS_PACKAGE, `^${TOKENS_DEPENDENCY_MIN_VERSION}`);
|
|
5385
6012
|
}
|
|
5386
6013
|
async function handleListBrands(params) {
|
|
5387
6014
|
return listBrands(baseDirOf(params.targetDir));
|
|
@@ -5394,24 +6021,25 @@ async function handleGetBrand(params) {
|
|
|
5394
6021
|
return getBrand(baseDirOf(params.targetDir), name);
|
|
5395
6022
|
}
|
|
5396
6023
|
function formatTokensStatusGuide(status, version, installCommand = TOKENS_INSTALL_COMMAND) {
|
|
6024
|
+
const g = typeof installCommand === "string" ? { kind: "add", installCommand, addCommand: installCommand } : installCommand;
|
|
6025
|
+
if (g.kind === "pnp") {
|
|
6026
|
+
return `${TOKENS_PACKAGE}${g.range ? ` ${g.range}` : ""} \uAC00 package.json \uC5D0 \uC120\uC5B8\uB3FC \uC788\uC9C0\uB9CC Plug'n'Play \uC124\uCE58\uB77C \uC124\uCE58\uBCF8\uC744 \uD310\uC815\uD558\uC9C0 \uBABB\uD574 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`;
|
|
6027
|
+
}
|
|
6028
|
+
const install = g.kind === "install-at-root" ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C \`${g.installCommand}\`` : `\`${g.kind === "install" ? g.installCommand : g.addCommand}\``;
|
|
5397
6029
|
switch (status) {
|
|
5398
6030
|
case "not-installed":
|
|
5399
|
-
return [
|
|
5400
|
-
`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`,
|
|
5401
|
-
"",
|
|
5402
|
-
`- \uC124\uCE58: \`${installCommand}\``
|
|
5403
|
-
].join("\n");
|
|
6031
|
+
return [`${TOKENS_PACKAGE} \uAC00 \uC124\uCE58\uB3FC \uC788\uC9C0 \uC54A\uC544 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`, "", `- \uC124\uCE58: ${install}`].join("\n");
|
|
5404
6032
|
case "unsupported":
|
|
5405
6033
|
return [
|
|
5406
6034
|
`${TOKENS_PACKAGE} ${version ?? "(\uBC84\uC804 \uBAA8\uB984)"} \uC740 \uBE0C\uB79C\uB4DC\uB97C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1 \uD544\uC694).`,
|
|
5407
6035
|
"",
|
|
5408
|
-
`- \uC5C5\uADF8\uB808\uC774\uB4DC: \`${
|
|
6036
|
+
g.source === "root" ? `- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 package.json \uC758 ${TOKENS_PACKAGE} \uC120\uC5B8\uC744 ^${MIN_BRAND_TOKENS_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9AC\uACE0 \uC124\uCE58\uD558\uC138\uC694.` : `- \uC5C5\uADF8\uB808\uC774\uB4DC: \`${g.addCommand}\``
|
|
5409
6037
|
].join("\n");
|
|
5410
6038
|
case "not-built":
|
|
5411
6039
|
return [
|
|
5412
6040
|
`${TOKENS_PACKAGE}${version ? ` ${version}` : ""} \uB294 \uC788\uC9C0\uB9CC \uBE4C\uB4DC \uC0B0\uCD9C\uBB3C\uC774 \uC5C6\uC5B4 \uBE0C\uB79C\uB4DC\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`,
|
|
5413
6041
|
"",
|
|
5414
|
-
`- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 \`${workspaceRunCommand(installCommand, TOKENS_PACKAGE, "build")}\`, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58:
|
|
6042
|
+
`- \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4\uBA74 \`${workspaceRunCommand(g.installCommand, TOKENS_PACKAGE, "build")}\`, \uC544\uB2C8\uBA74 \uC7AC\uC124\uCE58: ${install}`
|
|
5415
6043
|
].join("\n");
|
|
5416
6044
|
}
|
|
5417
6045
|
}
|
|
@@ -6069,7 +6697,7 @@ server.tool(
|
|
|
6069
6697
|
async ({ targetDir }) => {
|
|
6070
6698
|
try {
|
|
6071
6699
|
const result = await handleListBrands({ targetDir });
|
|
6072
|
-
const formatted = formatListBrandsResult(result,
|
|
6700
|
+
const formatted = formatListBrandsResult(result, tokensInstallGuideFor(targetDir));
|
|
6073
6701
|
return {
|
|
6074
6702
|
content: [
|
|
6075
6703
|
{
|
|
@@ -6102,7 +6730,7 @@ server.tool(
|
|
|
6102
6730
|
async ({ name, targetDir }) => {
|
|
6103
6731
|
try {
|
|
6104
6732
|
const result = await handleGetBrand({ name, targetDir });
|
|
6105
|
-
const formatted = formatGetBrandResult(result, name,
|
|
6733
|
+
const formatted = formatGetBrandResult(result, name, tokensInstallGuideFor(targetDir));
|
|
6106
6734
|
return {
|
|
6107
6735
|
content: [
|
|
6108
6736
|
{
|