@axis-ds/cli 1.7.6 → 1.7.8
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 +13 -8
- package/dist/{chunk-I3HWV7Y5.js → chunk-C2T7NVDG.js} +322 -4
- package/dist/index.js +781 -164
- package/dist/monet.js +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,25 +4,37 @@ import {
|
|
|
4
4
|
MonetClient,
|
|
5
5
|
PNP_ROOT_ONLY_NOTE,
|
|
6
6
|
ROOT_LAYOUT_FILES,
|
|
7
|
+
TAILWIND4_MIN_AXIS_VERSION,
|
|
7
8
|
addCommandFor,
|
|
8
9
|
addCommandPrefix,
|
|
9
10
|
compareExactVersions,
|
|
11
|
+
componentCssResolution,
|
|
12
|
+
componentCssResolvable,
|
|
13
|
+
cssImportViaNote,
|
|
14
|
+
cssPackageLineResolution,
|
|
10
15
|
declaredDependency,
|
|
16
|
+
deferredComponentImportReason,
|
|
11
17
|
dependencyInstallGuide,
|
|
12
18
|
detectInstallCommand,
|
|
13
19
|
detectProjectPaths,
|
|
14
20
|
findInstalledPackage,
|
|
21
|
+
findPnpUnpluggedPackages,
|
|
22
|
+
globalCssSelectionNote,
|
|
15
23
|
hasDependency,
|
|
16
24
|
isPlainObject,
|
|
17
25
|
isPnpProject,
|
|
26
|
+
outsideCssPackageResolution,
|
|
27
|
+
pnpProjectRoot,
|
|
18
28
|
pnpRootOnlyDependency,
|
|
19
29
|
projectFileExists,
|
|
20
30
|
resolveBaseDir,
|
|
21
31
|
rootDeclarationsAllowed,
|
|
22
32
|
runScriptCommand,
|
|
33
|
+
selectGlobalCss,
|
|
34
|
+
tokensCssResolution,
|
|
23
35
|
workspaceRootPackage,
|
|
24
36
|
workspaceRunCommand
|
|
25
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-C2T7NVDG.js";
|
|
26
38
|
import {
|
|
27
39
|
V0Client
|
|
28
40
|
} from "./chunk-2PNCUPCG.js";
|
|
@@ -1928,7 +1940,7 @@ async function readAxisConfig(baseDir) {
|
|
|
1928
1940
|
}
|
|
1929
1941
|
|
|
1930
1942
|
// ../axis-registry-core/src/template/tailwind-core.ts
|
|
1931
|
-
import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync } from "fs";
|
|
1943
|
+
import { existsSync, lstatSync, readdirSync, readFileSync, realpathSync, statSync } from "fs";
|
|
1932
1944
|
import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "path";
|
|
1933
1945
|
function declaredRange(baseDir, pkg, name) {
|
|
1934
1946
|
return declaredDependency(baseDir, pkg, name)?.range;
|
|
@@ -2059,6 +2071,157 @@ var TOKENS_CSS_IMPORT = /@import\s+(?:url\(\s*)?["'](@axis-ds\/tokens\/css(?:\/s
|
|
|
2059
2071
|
function findTokensCssImport(css) {
|
|
2060
2072
|
return TOKENS_CSS_IMPORT.exec(stripCssComments(css))?.[1];
|
|
2061
2073
|
}
|
|
2074
|
+
var CSS_IMPORT_DEPTH_LIMIT = 32;
|
|
2075
|
+
var CSS_IMPORT_CYCLE_DEPTH_LIMIT = 100;
|
|
2076
|
+
var RELATIVE_CSS_IMPORT = /@import\s*(?:"(\.{1,2}\/[^"\n]*)"|'(\.{1,2}\/[^'\n]*)')(?=([^;{}]*))/g;
|
|
2077
|
+
function isConditionalCssImport(tail) {
|
|
2078
|
+
return tail !== void 0 && tail.trim() !== "";
|
|
2079
|
+
}
|
|
2080
|
+
function resolveRelativeCssImport(fromDir, spec) {
|
|
2081
|
+
if (spec.endsWith("/")) return void 0;
|
|
2082
|
+
const target = resolve(fromDir, spec);
|
|
2083
|
+
if (regularFile(target)) return target;
|
|
2084
|
+
if (regularFile(`${target}.css`)) return `${target}.css`;
|
|
2085
|
+
return void 0;
|
|
2086
|
+
}
|
|
2087
|
+
var CSS_IMPORT_SPEC = /@import\s+(?:url\(\s*)?(["'])([^"'\n]+)\1/g;
|
|
2088
|
+
function isPackageCssSpec(spec) {
|
|
2089
|
+
return !spec.startsWith("./") && !spec.startsWith("../") && !spec.startsWith("/") && !/^[a-zA-Z][a-zA-Z0-9+.-]*:/.test(spec);
|
|
2090
|
+
}
|
|
2091
|
+
function cssImportCycleIssue(files) {
|
|
2092
|
+
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`;
|
|
2093
|
+
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`;
|
|
2094
|
+
}
|
|
2095
|
+
function findImportCycle(start, edges) {
|
|
2096
|
+
const state = /* @__PURE__ */ new Map();
|
|
2097
|
+
const trail = [start];
|
|
2098
|
+
const stack = [{ node: start, next: 0 }];
|
|
2099
|
+
state.set(start, "open");
|
|
2100
|
+
while (stack.length > 0) {
|
|
2101
|
+
const top = stack[stack.length - 1];
|
|
2102
|
+
const out = edges.get(top.node) ?? [];
|
|
2103
|
+
if (top.next >= out.length) {
|
|
2104
|
+
state.set(top.node, "done");
|
|
2105
|
+
stack.pop();
|
|
2106
|
+
trail.pop();
|
|
2107
|
+
continue;
|
|
2108
|
+
}
|
|
2109
|
+
const to = out[top.next++];
|
|
2110
|
+
const s = state.get(to);
|
|
2111
|
+
if (s === "open") return trail.slice(trail.indexOf(to));
|
|
2112
|
+
if (s === "done") continue;
|
|
2113
|
+
state.set(to, "open");
|
|
2114
|
+
trail.push(to);
|
|
2115
|
+
stack.push({ node: to, next: 0 });
|
|
2116
|
+
}
|
|
2117
|
+
return void 0;
|
|
2118
|
+
}
|
|
2119
|
+
function regularFile(file) {
|
|
2120
|
+
try {
|
|
2121
|
+
return statSync(file).isFile();
|
|
2122
|
+
} catch {
|
|
2123
|
+
return false;
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
function expandGlobalCss(baseDirInput, entryPath, entryRel, entryCssDir) {
|
|
2127
|
+
const baseDir = resolveBaseDir(baseDirInput);
|
|
2128
|
+
const entry = readFileSync(entryPath, "utf8");
|
|
2129
|
+
let entryReal = entryPath;
|
|
2130
|
+
try {
|
|
2131
|
+
entryReal = realpathSync(entryPath);
|
|
2132
|
+
} catch {
|
|
2133
|
+
}
|
|
2134
|
+
const raws = /* @__PURE__ */ new Map([[entryReal, entry]]);
|
|
2135
|
+
const files = [];
|
|
2136
|
+
const packageLines = [];
|
|
2137
|
+
const evidenceWalk = walkRelativeCssImports(baseDir, entryReal, raws, CSS_IMPORT_DEPTH_LIMIT, false);
|
|
2138
|
+
const relOfReal = /* @__PURE__ */ new Map([[entryReal, entryRel]]);
|
|
2139
|
+
for (const node of evidenceWalk.order) {
|
|
2140
|
+
const isEntry = node.real === entryReal;
|
|
2141
|
+
const rel3 = isEntry ? entryRel : node.rel;
|
|
2142
|
+
const css = stripCssComments(raws.get(node.real) ?? "");
|
|
2143
|
+
const file = { rel: rel3, path: node.real, css, depth: node.depth };
|
|
2144
|
+
const cssDir = isEntry ? entryCssDir : dirname(node.real);
|
|
2145
|
+
if (cssDir !== void 0) file.cssDir = cssDir;
|
|
2146
|
+
files.push(file);
|
|
2147
|
+
relOfReal.set(node.real, rel3);
|
|
2148
|
+
for (const m of css.matchAll(CSS_IMPORT_SPEC)) {
|
|
2149
|
+
if (!isPackageCssSpec(m[2])) continue;
|
|
2150
|
+
const line = { spec: m[2], file: rel3 };
|
|
2151
|
+
if (cssDir !== void 0) line.cssDir = cssDir;
|
|
2152
|
+
packageLines.push(line);
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
const cycleWalk = walkRelativeCssImports(baseDir, entryReal, raws, CSS_IMPORT_CYCLE_DEPTH_LIMIT, true);
|
|
2156
|
+
const cycle = findImportCycle(entryReal, cycleWalk.edges);
|
|
2157
|
+
if (cycle !== void 0) {
|
|
2158
|
+
for (const node of cycleWalk.order) if (!relOfReal.has(node.real)) relOfReal.set(node.real, node.rel);
|
|
2159
|
+
const head = files[0];
|
|
2160
|
+
return {
|
|
2161
|
+
entry,
|
|
2162
|
+
evidence: entry,
|
|
2163
|
+
files: [head],
|
|
2164
|
+
packageLines: packageLines.filter((l) => l.file === head.rel),
|
|
2165
|
+
cycle: cycle.map((p) => relOfReal.get(p) ?? p)
|
|
2166
|
+
};
|
|
2167
|
+
}
|
|
2168
|
+
const evidence = files.length === 1 ? entry : files.map((f) => f.css).join("\n");
|
|
2169
|
+
return { entry, evidence, files, packageLines };
|
|
2170
|
+
}
|
|
2171
|
+
function walkRelativeCssImports(baseDir, entryReal, raws, limit, includeConditional) {
|
|
2172
|
+
const order = [];
|
|
2173
|
+
const edges = /* @__PURE__ */ new Map();
|
|
2174
|
+
const visited = /* @__PURE__ */ new Set([entryReal]);
|
|
2175
|
+
const queue = [{ real: entryReal, rel: "", depth: 0 }];
|
|
2176
|
+
while (queue.length > 0) {
|
|
2177
|
+
const cur = queue.shift();
|
|
2178
|
+
order.push(cur);
|
|
2179
|
+
const css = stripCssComments(raws.get(cur.real) ?? "");
|
|
2180
|
+
const out = [];
|
|
2181
|
+
edges.set(cur.real, out);
|
|
2182
|
+
for (const m of css.matchAll(RELATIVE_CSS_IMPORT)) {
|
|
2183
|
+
if (!includeConditional && isConditionalCssImport(m[3])) continue;
|
|
2184
|
+
const target = resolveRelativeCssImport(dirname(cur.real), m[1] ?? m[2]);
|
|
2185
|
+
if (target === void 0) continue;
|
|
2186
|
+
let real;
|
|
2187
|
+
try {
|
|
2188
|
+
real = realpathSync(target);
|
|
2189
|
+
} catch {
|
|
2190
|
+
continue;
|
|
2191
|
+
}
|
|
2192
|
+
if (visited.has(real)) {
|
|
2193
|
+
out.push(real);
|
|
2194
|
+
continue;
|
|
2195
|
+
}
|
|
2196
|
+
if (cur.depth >= limit) continue;
|
|
2197
|
+
const rel3 = relative(baseDir, real);
|
|
2198
|
+
if (rel3 === "" || rel3 === ".." || rel3.startsWith(`..${sep}`) || isAbsolute(rel3)) continue;
|
|
2199
|
+
if (!raws.has(real)) {
|
|
2200
|
+
try {
|
|
2201
|
+
raws.set(real, readFileSync(real, "utf8"));
|
|
2202
|
+
} catch {
|
|
2203
|
+
continue;
|
|
2204
|
+
}
|
|
2205
|
+
}
|
|
2206
|
+
visited.add(real);
|
|
2207
|
+
out.push(real);
|
|
2208
|
+
queue.push({ real, rel: rel3.split(sep).join("/"), depth: cur.depth + 1 });
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
return { order, edges };
|
|
2212
|
+
}
|
|
2213
|
+
function evidenceOrigin(expanded, test) {
|
|
2214
|
+
return expanded.files.find((f) => test(f.css));
|
|
2215
|
+
}
|
|
2216
|
+
function packageLineCssDir(expanded, spec) {
|
|
2217
|
+
const line = expanded.packageLines.find((l) => l.spec === spec);
|
|
2218
|
+
return line !== void 0 ? line.cssDir : expanded.files[0]?.cssDir;
|
|
2219
|
+
}
|
|
2220
|
+
function viaFiles(origins) {
|
|
2221
|
+
const out = [];
|
|
2222
|
+
for (const o of origins) if (o !== void 0 && o.depth > 0 && !out.includes(o.rel)) out.push(o.rel);
|
|
2223
|
+
return out;
|
|
2224
|
+
}
|
|
2062
2225
|
var TOKENS_CSS_JS_IMPORT = /(?:\bimport\s+|\bfrom\s+|\brequire\s*\(\s*)(["'])(@axis-ds\/tokens\/css(?:\/shadcn|\/tailwind4)?)\1/;
|
|
2063
2226
|
var AXIS_VARIABLE_DEFINITION = /(?<![\w-])--axis-[\w-]+\s*:/;
|
|
2064
2227
|
function findLayoutTokensCssImport(baseDirInput) {
|
|
@@ -2077,45 +2240,133 @@ function findLayoutTokensCssImport(baseDirInput) {
|
|
|
2077
2240
|
}
|
|
2078
2241
|
return void 0;
|
|
2079
2242
|
}
|
|
2243
|
+
var TOKENS_PACKAGE_NAME = "@axis-ds/tokens";
|
|
2244
|
+
function outsideCssDir(selection) {
|
|
2245
|
+
if (selection.path === void 0 || selection.rel === void 0) return void 0;
|
|
2246
|
+
const outside = selection.rel === ".." || selection.rel.startsWith("../") || isAbsolute(selection.rel);
|
|
2247
|
+
return outside ? dirname(selection.path) : void 0;
|
|
2248
|
+
}
|
|
2249
|
+
function outsideCssUnresolvedIssue(spec, name) {
|
|
2250
|
+
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`;
|
|
2251
|
+
}
|
|
2252
|
+
function tokensInstallPhrase(baseDir, range = `^${TAILWIND4_MIN_AXIS_VERSION}`) {
|
|
2253
|
+
const g = dependencyInstallGuide(baseDir, TOKENS_PACKAGE_NAME, range);
|
|
2254
|
+
if (g.kind === "install-at-root") return `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${g.installCommand}`;
|
|
2255
|
+
return g.kind === "install" ? g.installCommand : g.addCommand;
|
|
2256
|
+
}
|
|
2257
|
+
function tokensCssUnresolvedIssue(baseDir, pkg, spec, cssDir, lineIssue) {
|
|
2258
|
+
const r = tokensCssResolution(baseDir, pkg, TOKENS_PACKAGE_NAME);
|
|
2259
|
+
const head = `${spec} import \uAC00 \uC788\uC9C0\uB9CC`;
|
|
2260
|
+
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`;
|
|
2261
|
+
if (r.kind === "not-installed") {
|
|
2262
|
+
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)})`;
|
|
2263
|
+
}
|
|
2264
|
+
if (cssDir !== void 0 && outsideCssPackageResolution(baseDir, cssDir, TOKENS_PACKAGE_NAME) === "unresolved") {
|
|
2265
|
+
return outsideCssUnresolvedIssue(spec, TOKENS_PACKAGE_NAME);
|
|
2266
|
+
}
|
|
2267
|
+
return lineIssue?.();
|
|
2268
|
+
}
|
|
2269
|
+
function packageNameOfSpec(spec) {
|
|
2270
|
+
const parts = spec.split("/");
|
|
2271
|
+
return parts.slice(0, spec.startsWith("@") ? 2 : 1).join("/");
|
|
2272
|
+
}
|
|
2273
|
+
function displayRel(baseDir, p) {
|
|
2274
|
+
return relative(baseDir, p).split(sep).join("/");
|
|
2275
|
+
}
|
|
2276
|
+
function packageLineShadowIssue(baseDir, expanded, origin, spec) {
|
|
2277
|
+
const name = packageNameOfSpec(spec);
|
|
2278
|
+
const lineDir = dirname(origin.path);
|
|
2279
|
+
const others = () => [...new Set(expanded.files.map((f) => dirname(f.path)))].filter((d) => d !== lineDir);
|
|
2280
|
+
const r = cssPackageLineResolution(baseDir, lineDir, spec, others);
|
|
2281
|
+
const head = `${spec} import \uAC00 \uC788\uC9C0\uB9CC \uADF8 \uC904\uC774 \uC788\uB294 \uD30C\uC77C \uC704\uCE58\uC5D0\uC11C`;
|
|
2282
|
+
const label = (pkgDir, version) => `${displayRel(baseDir, pkgDir)}(${version ?? "\uBC84\uC804 \uBAA8\uB984"})`;
|
|
2283
|
+
switch (r.kind) {
|
|
2284
|
+
case "ok":
|
|
2285
|
+
return void 0;
|
|
2286
|
+
case "shadow-not-exported": {
|
|
2287
|
+
const current = r.version !== void 0 && (compareExactVersions(r.version, TAILWIND4_MIN_AXIS_VERSION) ?? -1) >= 0;
|
|
2288
|
+
const todo = current ? "\uB2E4\uC2DC \uC124\uCE58\uD558\uC138\uC694" : `${TAILWIND4_MIN_AXIS_VERSION} \uC774\uC0C1\uC73C\uB85C \uB9DE\uCD94\uC138\uC694`;
|
|
2289
|
+
return `${head} \uBA3C\uC800 \uC7A1\uD788\uB294 ${label(r.pkgDir, r.version)}\uAC00 ${r.subpath} \uB97C \uB0B4\uBCF4\uB0B4\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uADF8 \uC911\uCCA9 node_modules \uC758 ${name} \uB97C \uC9C0\uC6B0\uAC70\uB098 ${todo}`;
|
|
2290
|
+
}
|
|
2291
|
+
case "shadow-target-missing":
|
|
2292
|
+
return `${head} \uBA3C\uC800 \uC7A1\uD788\uB294 ${label(r.pkgDir, r.version)}\uC5D0 \uB0B4\uBCF4\uB0B8 \uD30C\uC77C(${r.target})\uC774 \uC5C6\uC5B4 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uADF8 \uC911\uCCA9 node_modules \uC758 ${name} \uB97C \uC9C0\uC6B0\uAC70\uB098 \uB2E4\uC2DC \uC124\uCE58\uD558\uC138\uC694`;
|
|
2293
|
+
case "not-visible": {
|
|
2294
|
+
const there = expanded.files.find((f) => dirname(f.path) === r.fromDir);
|
|
2295
|
+
const move = there !== void 0 ? `\uC774 \uC904(${origin.rel})\uC744 ${there.rel} \uB85C \uC62E\uAE30\uC138\uC694` : `\uC774 \uC904(${origin.rel})\uC744 \uADF8 \uC704\uCE58\uC758 CSS \uD30C\uC77C\uB85C \uC62E\uAE30\uC138\uC694`;
|
|
2296
|
+
return `${head} ${name} \uB97C \uCC3E\uC9C0 \uBABB\uD574 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4(\uC124\uCE58\uBCF8\uC774 ${displayRel(baseDir, r.pkgDir)} \uC5D0\uB9CC \uC788\uC74C) \u2192 \uC571 \uB610\uB294 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC124\uCE58\uD558\uAC70\uB098 ${move}`;
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
}
|
|
2300
|
+
function isOutsideEntry(origin) {
|
|
2301
|
+
return origin.depth === 0 && origin.cssDir !== void 0;
|
|
2302
|
+
}
|
|
2080
2303
|
function checkGlobalsCss(baseDirInput) {
|
|
2081
2304
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
const
|
|
2086
|
-
const
|
|
2087
|
-
const
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2305
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
2306
|
+
const note = globalCssSelectionNote(selection);
|
|
2307
|
+
if (selection.path !== void 0 && selection.rel !== void 0) {
|
|
2308
|
+
const candidate = selection.rel;
|
|
2309
|
+
const expanded = expandGlobalCss(baseDir, selection.path, candidate, outsideCssDir(selection));
|
|
2310
|
+
const judged = judgeGlobalsCss(baseDir, selection, candidate, expanded);
|
|
2311
|
+
if (expanded.cycle !== void 0) {
|
|
2312
|
+
return { name: "globals.css", severity: "warn", message: `${judged.message} / ${cssImportCycleIssue(expanded.cycle)}${note}` };
|
|
2313
|
+
}
|
|
2314
|
+
return { name: "globals.css", severity: judged.severity, message: `${judged.message}${note}` };
|
|
2315
|
+
}
|
|
2316
|
+
return { name: "globals.css", severity: "fail", message: `globals.css \uD30C\uC77C\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4${note}` };
|
|
2317
|
+
}
|
|
2318
|
+
function judgeGlobalsCss(baseDir, selection, candidate, expanded) {
|
|
2319
|
+
const content = expanded.entry;
|
|
2320
|
+
const css = stripCssComments(content);
|
|
2321
|
+
const imported = findTokensCssImport(expanded.evidence);
|
|
2322
|
+
const pkg = readPackageJson(baseDir);
|
|
2323
|
+
let pass;
|
|
2324
|
+
let unresolved;
|
|
2325
|
+
let via = "";
|
|
2326
|
+
if (imported !== void 0) {
|
|
2327
|
+
const origin = evidenceOrigin(expanded, (f) => findTokensCssImport(f) === imported);
|
|
2328
|
+
via = cssImportViaNote(viaFiles([origin]));
|
|
2329
|
+
const tailwind4 = (detectTailwind(baseDir, pkg).major ?? 0) >= 4;
|
|
2330
|
+
const issue = tailwind4 && origin !== void 0 && !isOutsideEntry(origin) ? tokensCssUnresolvedIssue(
|
|
2331
|
+
baseDir,
|
|
2332
|
+
pkg,
|
|
2333
|
+
imported,
|
|
2334
|
+
void 0,
|
|
2335
|
+
() => packageLineShadowIssue(baseDir, expanded, origin, imported)
|
|
2336
|
+
) : tokensCssUnresolvedIssue(baseDir, pkg, imported, origin !== void 0 ? origin.cssDir : outsideCssDir(selection));
|
|
2337
|
+
if (issue !== void 0) unresolved = `${candidate}\uC5D0 ${issue}`;
|
|
2338
|
+
else pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${imported} import)`;
|
|
2339
|
+
} else if (AXIS_VARIABLE_DEFINITION.test(stripCssComments(expanded.evidence))) {
|
|
2340
|
+
via = cssImportViaNote(viaFiles([evidenceOrigin(expanded, (f) => AXIS_VARIABLE_DEFINITION.test(f))]));
|
|
2341
|
+
pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218(--axis-*)\uAC00 \uC815\uC758\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4`;
|
|
2342
|
+
} else {
|
|
2343
|
+
const layout = findLayoutTokensCssImport(baseDir);
|
|
2344
|
+
if (layout) {
|
|
2345
|
+
const issue = tokensCssUnresolvedIssue(baseDir, pkg, layout.spec);
|
|
2346
|
+
if (issue !== void 0) unresolved = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC5C6\uACE0 ${layout.file}\uC758 ${issue}`;
|
|
2347
|
+
else pass = `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC788\uC2B5\uB2C8\uB2E4 (${layout.file}\uC758 ${layout.spec} import)`;
|
|
2348
|
+
}
|
|
2349
|
+
}
|
|
2350
|
+
const head = pass ?? unresolved;
|
|
2351
|
+
if (head !== void 0) {
|
|
2352
|
+
const tailwind = detectTailwind(baseDir, pkg);
|
|
2353
|
+
const tailwind4 = tailwind.major !== void 0 && tailwind.major >= 4;
|
|
2354
|
+
if (!tailwind4 && findCreateNextAppDefaults(content).some((d) => d.includes("font-family: Arial"))) {
|
|
2108
2355
|
return {
|
|
2109
|
-
name: "globals.css",
|
|
2110
2356
|
severity: "warn",
|
|
2111
|
-
message: `${
|
|
2357
|
+
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}`
|
|
2112
2358
|
};
|
|
2113
2359
|
}
|
|
2114
|
-
return {
|
|
2360
|
+
return { severity: pass !== void 0 ? "pass" : "warn", message: `${head}${via}` };
|
|
2361
|
+
}
|
|
2362
|
+
if (css.includes("--background") && css.includes("--primary")) {
|
|
2363
|
+
return {
|
|
2364
|
+
severity: "warn",
|
|
2365
|
+
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`
|
|
2366
|
+
};
|
|
2115
2367
|
}
|
|
2116
|
-
return {
|
|
2368
|
+
return { severity: "warn", message: `${candidate}\uC5D0 AXIS CSS \uBCC0\uC218\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4` };
|
|
2117
2369
|
}
|
|
2118
|
-
var TAILWIND4_MIN_AXIS_VERSION = "1.4.0";
|
|
2119
2370
|
var TAILWIND4_AXIS_PACKAGES = ["@axis-ds/tokens", "@axis-ds/ui-react", "@axis-ds/agentic-ui"];
|
|
2120
2371
|
function lowerOf(token) {
|
|
2121
2372
|
const v = versionParts(token);
|
|
@@ -2313,6 +2564,17 @@ function hasBareCjsPresetRequire(code) {
|
|
|
2313
2564
|
function isCommonJsConfig(file, source) {
|
|
2314
2565
|
return extname(file) === ".cjs" || /\bmodule\.exports\b/.test(source);
|
|
2315
2566
|
}
|
|
2567
|
+
function presetTokensUnresolvedMessage(baseDir, pkg, file, bareCjs) {
|
|
2568
|
+
const r = tokensCssResolution(baseDir, pkg, TOKENS_PACKAGE_NAME);
|
|
2569
|
+
const head = `${file}\uC5D0 AXIS preset \uCC38\uC870\uAC00 \uC788\uC9C0\uB9CC ${TOKENS_PACKAGE_NAME} \uAC00`;
|
|
2570
|
+
if (r.kind === "not-installed") {
|
|
2571
|
+
return `${head} \uC124\uCE58\uB418\uC9C0 \uC54A\uC544 \uD574\uC11D\uB418\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4 \u2192 \uC124\uCE58(${tokensInstallPhrase(baseDir, `^${TOKENS_CJS_PRESET_FIXED_VERSION}`)})`;
|
|
2572
|
+
}
|
|
2573
|
+
if (r.kind === "pnp-root-only" && !bareCjs) {
|
|
2574
|
+
return `${head} ${PNP_ROOT_ONLY_NOTE}(\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8 \uC120\uC5B8 ${r.range}) \u2192 \uC571 package.json \uC5D0 ${TOKENS_PACKAGE_NAME} \uB97C \uC120\uC5B8\uD558\uC138\uC694`;
|
|
2575
|
+
}
|
|
2576
|
+
return void 0;
|
|
2577
|
+
}
|
|
2316
2578
|
function packageVersionGate(baseDirInput, pkg, name, min, options = {}) {
|
|
2317
2579
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
2318
2580
|
if (!isPnpProject(baseDir)) {
|
|
@@ -2348,66 +2610,155 @@ function readPackageJson(baseDir) {
|
|
|
2348
2610
|
return void 0;
|
|
2349
2611
|
}
|
|
2350
2612
|
}
|
|
2351
|
-
function tailwind4Issues(
|
|
2613
|
+
function tailwind4Issues(input, pkg, versions, baseDir) {
|
|
2614
|
+
const { entry, evidence } = input;
|
|
2615
|
+
const cssDirOf = input.cssDirOf ?? (() => void 0);
|
|
2352
2616
|
const issues = [];
|
|
2353
|
-
const
|
|
2617
|
+
const tailwindDir = cssDirOf("tailwindcss");
|
|
2618
|
+
if (tailwindDir !== void 0 && outsideCssPackageResolution(baseDir, tailwindDir, "tailwindcss") === "unresolved") {
|
|
2619
|
+
issues.push(outsideCssUnresolvedIssue("tailwindcss", "tailwindcss"));
|
|
2620
|
+
}
|
|
2621
|
+
const hasEntry = hasTokensTailwind4Import(evidence);
|
|
2354
2622
|
if (!hasEntry) issues.push(`AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${TOKENS_TAILWIND4_IMPORT_LINE}`);
|
|
2355
|
-
const
|
|
2356
|
-
|
|
2357
|
-
|
|
2623
|
+
const resolutions = new Map(TAILWIND4_COMPONENT_PACKAGES.map((name) => [name, componentCssResolution(baseDir, pkg, name)]));
|
|
2624
|
+
const missing = [];
|
|
2625
|
+
const unresolvedMissing = [];
|
|
2626
|
+
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
2627
|
+
const r = resolutions.get(name);
|
|
2628
|
+
if (r.kind === "undeclared" || r.kind === "app-lockfile") continue;
|
|
2629
|
+
if (hasComponentTailwindImport(evidence, name) || hasComponentSource(evidence, name)) continue;
|
|
2630
|
+
if (componentCssResolvable(r)) missing.push(name);
|
|
2631
|
+
else unresolvedMissing.push(componentCssMissingIssue(baseDir, name, r));
|
|
2632
|
+
}
|
|
2358
2633
|
if (missing.length > 0) {
|
|
2359
2634
|
issues.push(`\uCEF4\uD3EC\uB10C\uD2B8 \uC2A4\uCE94 \uACBD\uB85C(tailwind.css)\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4 \u2192 ${missing.map(componentTailwindImportLine).join(" ")}`);
|
|
2360
2635
|
}
|
|
2636
|
+
issues.push(...unresolvedMissing);
|
|
2361
2637
|
if (hasEntry) {
|
|
2362
|
-
const defaults = findCreateNextAppDefaults(
|
|
2638
|
+
const defaults = findCreateNextAppDefaults(entry);
|
|
2363
2639
|
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`);
|
|
2364
2640
|
if (versions.some((v) => v.name === TAILWIND4_AXIS_PACKAGES[0])) {
|
|
2365
2641
|
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`);
|
|
2366
2642
|
}
|
|
2367
2643
|
}
|
|
2368
2644
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
2369
|
-
if (hasComponentTailwindImport(
|
|
2370
|
-
|
|
2645
|
+
if (!hasComponentTailwindImport(evidence, name)) continue;
|
|
2646
|
+
const unresolved = componentCssPresentIssue(baseDir, name, resolutions.get(name));
|
|
2647
|
+
const spec = `${name}/tailwind.css`;
|
|
2648
|
+
if (unresolved !== void 0) {
|
|
2649
|
+
issues.push(unresolved);
|
|
2650
|
+
continue;
|
|
2651
|
+
}
|
|
2652
|
+
const shadow = input.lineIssue === void 0 ? false : input.lineIssue(spec);
|
|
2653
|
+
let lineProblem;
|
|
2654
|
+
if (shadow !== false) lineProblem = shadow;
|
|
2655
|
+
else {
|
|
2656
|
+
const componentDir = cssDirOf(spec);
|
|
2657
|
+
if (componentDir !== void 0 && outsideCssPackageResolution(baseDir, componentDir, name, "tailwind.css") === "unresolved") {
|
|
2658
|
+
lineProblem = outsideCssUnresolvedIssue(spec, name);
|
|
2659
|
+
}
|
|
2371
2660
|
}
|
|
2661
|
+
if (lineProblem !== void 0) issues.push(lineProblem);
|
|
2662
|
+
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`);
|
|
2372
2663
|
}
|
|
2373
2664
|
return issues;
|
|
2374
2665
|
}
|
|
2666
|
+
function componentInstallPhrase(baseDir, name, range) {
|
|
2667
|
+
const g = dependencyInstallGuide(baseDir, name, range);
|
|
2668
|
+
return g.kind === "install-at-root" ? `\uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0\uC11C ${g.installCommand}` : g.installCommand;
|
|
2669
|
+
}
|
|
2670
|
+
function componentCssMissingIssue(baseDir, name, r) {
|
|
2671
|
+
const line = componentTailwindImportLine(name);
|
|
2672
|
+
switch (r.kind) {
|
|
2673
|
+
case "pnp-root-only":
|
|
2674
|
+
return `${name} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD55C \uB4A4 ${line}`;
|
|
2675
|
+
case "root-not-installed":
|
|
2676
|
+
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}`;
|
|
2677
|
+
case "root-old":
|
|
2678
|
+
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}`;
|
|
2679
|
+
case "root-missing-file":
|
|
2680
|
+
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}`;
|
|
2681
|
+
default:
|
|
2682
|
+
return line;
|
|
2683
|
+
}
|
|
2684
|
+
}
|
|
2685
|
+
function componentCssPresentIssue(baseDir, name, r) {
|
|
2686
|
+
const head = `${name}/tailwind.css import \uAC00 \uC788\uC9C0\uB9CC`;
|
|
2687
|
+
switch (r.kind) {
|
|
2688
|
+
case "pnp-root-only":
|
|
2689
|
+
return `${head} ${name} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 \uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694`;
|
|
2690
|
+
case "root-not-installed":
|
|
2691
|
+
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)})`;
|
|
2692
|
+
case "root-missing-file":
|
|
2693
|
+
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)})`;
|
|
2694
|
+
case "root-old":
|
|
2695
|
+
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;
|
|
2696
|
+
default:
|
|
2697
|
+
return void 0;
|
|
2698
|
+
}
|
|
2699
|
+
}
|
|
2375
2700
|
function checkTailwindSetup(baseDirInput) {
|
|
2376
2701
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
2377
2702
|
const pkg = readPackageJson(baseDir);
|
|
2378
2703
|
const tailwind = detectTailwind(baseDir, pkg);
|
|
2379
2704
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
2380
2705
|
const label = `Tailwind ${tailwind.major}`;
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
const
|
|
2385
|
-
|
|
2706
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
2707
|
+
const note = globalCssSelectionNote(selection);
|
|
2708
|
+
if (selection.path !== void 0 && selection.rel !== void 0) {
|
|
2709
|
+
const candidate = selection.rel;
|
|
2710
|
+
const expanded = expandGlobalCss(baseDir, selection.path, candidate, outsideCssDir(selection));
|
|
2711
|
+
if (!hasTailwindImport(expanded.evidence)) {
|
|
2386
2712
|
return {
|
|
2387
2713
|
name: "tailwind.config",
|
|
2388
2714
|
severity: "warn",
|
|
2389
|
-
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4`
|
|
2715
|
+
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uAC00 \uC5C6\uC2B5\uB2C8\uB2E4${note}`
|
|
2390
2716
|
};
|
|
2391
2717
|
}
|
|
2718
|
+
const via = cssImportViaNote(
|
|
2719
|
+
viaFiles([
|
|
2720
|
+
evidenceOrigin(expanded, hasTailwindImport),
|
|
2721
|
+
evidenceOrigin(expanded, hasTokensTailwind4Import),
|
|
2722
|
+
...TAILWIND4_COMPONENT_PACKAGES.flatMap((name) => [
|
|
2723
|
+
evidenceOrigin(expanded, (f) => hasComponentTailwindImport(f, name)),
|
|
2724
|
+
evidenceOrigin(expanded, (f) => hasComponentSource(f, name))
|
|
2725
|
+
])
|
|
2726
|
+
])
|
|
2727
|
+
);
|
|
2392
2728
|
const versions = axisPackagesBelowTailwind4(pkg, baseDir);
|
|
2393
|
-
const issues = tailwind4Issues(
|
|
2729
|
+
const issues = tailwind4Issues(
|
|
2730
|
+
{
|
|
2731
|
+
entry: expanded.entry,
|
|
2732
|
+
evidence: expanded.evidence,
|
|
2733
|
+
cssDirOf: (spec) => packageLineCssDir(expanded, spec),
|
|
2734
|
+
lineIssue: (spec) => {
|
|
2735
|
+
const line = expanded.packageLines.find((l) => l.spec === spec);
|
|
2736
|
+
const origin = line !== void 0 ? expanded.files.find((f) => f.rel === line.file) : void 0;
|
|
2737
|
+
if (origin === void 0 || isOutsideEntry(origin)) return false;
|
|
2738
|
+
return packageLineShadowIssue(baseDir, expanded, origin, spec);
|
|
2739
|
+
}
|
|
2740
|
+
},
|
|
2741
|
+
pkg,
|
|
2742
|
+
versions,
|
|
2743
|
+
baseDir
|
|
2744
|
+
);
|
|
2394
2745
|
if (issues.length > 0) {
|
|
2395
2746
|
return {
|
|
2396
2747
|
name: "tailwind.config",
|
|
2397
2748
|
severity: "warn",
|
|
2398
|
-
message: `${label}: ${candidate}\uC5D0 ${issues.join(" / ")}${tailwind4VersionNote(versions)}`
|
|
2749
|
+
message: `${label}: ${candidate}\uC5D0 ${issues.join(" / ")}${tailwind4VersionNote(versions)}${via}${note}`
|
|
2399
2750
|
};
|
|
2400
2751
|
}
|
|
2401
2752
|
return {
|
|
2402
2753
|
name: "tailwind.config",
|
|
2403
2754
|
severity: "pass",
|
|
2404
|
-
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uC640 AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC788\uC2B5\uB2C8\uB2E4`
|
|
2755
|
+
message: `${label}: ${candidate}\uC5D0 @import "tailwindcss" \uC640 AXIS \uD1A0\uD070 \uC9C4\uC785\uC810\uC774 \uC788\uC2B5\uB2C8\uB2E4${via}${note}`
|
|
2405
2756
|
};
|
|
2406
2757
|
}
|
|
2407
2758
|
return {
|
|
2408
2759
|
name: "tailwind.config",
|
|
2409
2760
|
severity: "warn",
|
|
2410
|
-
message: `${label}: @import "tailwindcss" \uB97C \uD655\uC778\uD560 CSS \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4`
|
|
2761
|
+
message: `${label}: @import "tailwindcss" \uB97C \uD655\uC778\uD560 CSS \uD30C\uC77C\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4${note}`
|
|
2411
2762
|
};
|
|
2412
2763
|
}
|
|
2413
2764
|
for (const file of TAILWIND_CONFIG_FILES) {
|
|
@@ -2416,7 +2767,10 @@ function checkTailwindSetup(baseDirInput) {
|
|
|
2416
2767
|
const content = readFileSync(path17, "utf8");
|
|
2417
2768
|
if (hasTokensPresetReference(content)) {
|
|
2418
2769
|
const code = stripJsComments(content);
|
|
2419
|
-
|
|
2770
|
+
const bareCjs = isCommonJsConfig(file, code) && hasBareCjsPresetRequire(code);
|
|
2771
|
+
const unresolved = presetTokensUnresolvedMessage(baseDir, pkg, file, bareCjs);
|
|
2772
|
+
if (unresolved !== void 0) return { name: "tailwind.config", severity: "warn", message: unresolved };
|
|
2773
|
+
if (bareCjs) {
|
|
2420
2774
|
const gate = packageVersionGate(baseDir, pkg, "@axis-ds/tokens", TOKENS_CJS_PRESET_FIXED_VERSION, { appOnlyInPnp: true });
|
|
2421
2775
|
if (gate.status === "unresolved") {
|
|
2422
2776
|
return {
|
|
@@ -2453,31 +2807,45 @@ function readAxisConfigLike(baseDir) {
|
|
|
2453
2807
|
return void 0;
|
|
2454
2808
|
}
|
|
2455
2809
|
}
|
|
2456
|
-
function
|
|
2810
|
+
function selectCheckGlobalCss(baseDir) {
|
|
2811
|
+
return selectGlobalCss(baseDir, readAxisConfigLike(baseDir)?.globalCss, TAILWIND_CSS_CANDIDATES, { requireStylesheet: true });
|
|
2812
|
+
}
|
|
2813
|
+
function contentGlobToRegExp(glob, opts = {}) {
|
|
2814
|
+
const noDot = opts.noDot === true;
|
|
2457
2815
|
const g = glob.trim().replace(/^\.\//, "");
|
|
2816
|
+
const lead = (i) => noDot && (i === 0 || g[i - 1] === "/") ? "(?!\\.)" : "";
|
|
2458
2817
|
let re = "";
|
|
2459
2818
|
for (let i = 0; i < g.length; i++) {
|
|
2460
2819
|
const c = g[i];
|
|
2461
2820
|
if (c === "*") {
|
|
2462
2821
|
if (g[i + 1] === "*") {
|
|
2463
2822
|
const slash = g[i + 2] === "/";
|
|
2464
|
-
re += slash ?
|
|
2823
|
+
if (noDot) re += slash ? `(?:${lead(i)}[^/]*/(?:(?!\\.)[^/]*/)*)?` : `${lead(i)}[^/]*(?:/(?!\\.)[^/]*)*`;
|
|
2824
|
+
else re += slash ? "(?:.*/)?" : ".*";
|
|
2465
2825
|
i += slash ? 2 : 1;
|
|
2466
|
-
} else re +=
|
|
2467
|
-
} else if (c === "?") re +=
|
|
2826
|
+
} else re += `${lead(i)}[^/]*`;
|
|
2827
|
+
} else if (c === "?") re += `${lead(i)}[^/]`;
|
|
2468
2828
|
else if (c === "{") {
|
|
2469
2829
|
const end = g.indexOf("}", i);
|
|
2470
2830
|
if (end === -1) {
|
|
2471
2831
|
re += "\\{";
|
|
2472
2832
|
continue;
|
|
2473
2833
|
}
|
|
2474
|
-
|
|
2834
|
+
const atStart = lead(i) !== "";
|
|
2835
|
+
re += `(?:${g.slice(i + 1, end).split(",").map((part) => {
|
|
2836
|
+
const body = part.replace(/[.+^$()|[\]\\]/g, "\\$&");
|
|
2837
|
+
if (!noDot) return body.replace(/\*/g, "[^/]*");
|
|
2838
|
+
return body.replace(
|
|
2839
|
+
/(\/)?\*/g,
|
|
2840
|
+
(_m, slash, off) => slash !== void 0 || off === 0 && atStart ? `${slash ?? ""}(?!\\.)[^/]*` : "[^/]*"
|
|
2841
|
+
);
|
|
2842
|
+
}).join("|")})`;
|
|
2475
2843
|
i = end;
|
|
2476
2844
|
} else if (c === "[") {
|
|
2477
2845
|
const end = g.indexOf("]", i);
|
|
2478
2846
|
if (end === -1) re += "\\[";
|
|
2479
2847
|
else {
|
|
2480
|
-
re += g.slice(i, end + 1);
|
|
2848
|
+
re += lead(i) + g.slice(i, end + 1);
|
|
2481
2849
|
i = end;
|
|
2482
2850
|
}
|
|
2483
2851
|
} else re += c.replace(/[.+^$()|\\]/g, "\\$&");
|
|
@@ -2546,22 +2914,46 @@ function realpathPosix(p) {
|
|
|
2546
2914
|
}
|
|
2547
2915
|
return void 0;
|
|
2548
2916
|
}
|
|
2549
|
-
function contentGlobBranchCovers(glob, sample, baseDir) {
|
|
2917
|
+
function contentGlobBranchCovers(glob, sample, baseDir, noDot) {
|
|
2550
2918
|
if (isAbsoluteGlob(glob)) {
|
|
2551
|
-
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"));
|
|
2919
|
+
const re = contentGlobToRegExp(glob.trim().replace(/\\/g, "/"), { noDot });
|
|
2552
2920
|
const absSample = resolve(baseDir, sample);
|
|
2553
2921
|
if (re.test(absSample.split(sep).join("/"))) return true;
|
|
2554
2922
|
const real = realpathPosix(absSample);
|
|
2555
2923
|
return real !== void 0 && re.test(real);
|
|
2556
2924
|
}
|
|
2557
|
-
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob).test(sample);
|
|
2925
|
+
return leadingParentSegments(glob) === leadingParentSegments(sample) && contentGlobToRegExp(glob, { noDot }).test(sample);
|
|
2558
2926
|
}
|
|
2559
|
-
function contentGlobCovers(glob, sample, baseDirInput) {
|
|
2927
|
+
function contentGlobCovers(glob, sample, baseDirInput, opts = {}) {
|
|
2560
2928
|
const baseDir = resolveBaseDir(baseDirInput);
|
|
2561
2929
|
const branches = expandBraces(glob.trim()) ?? [glob];
|
|
2562
|
-
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir));
|
|
2930
|
+
return branches.some((b) => contentGlobBranchCovers(b, sample, baseDir, opts.noDot === true));
|
|
2931
|
+
}
|
|
2932
|
+
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";
|
|
2933
|
+
function contentPnpNote(names, unplugged = []) {
|
|
2934
|
+
const list = [...new Set(typeof names === "string" ? [names] : names)];
|
|
2935
|
+
const dyn = list.map((n) => `path.join(path.dirname(require.resolve("${n}")), "..", "dist/**/*.{js,mjs}")`).join(", ");
|
|
2936
|
+
const needsSetup = list.filter((n) => !unplugged.includes(n));
|
|
2937
|
+
const meta = needsSetup.map((n) => `"${n}": { "unplugged": true }`).join(", ");
|
|
2938
|
+
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` : "";
|
|
2939
|
+
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}`;
|
|
2940
|
+
}
|
|
2941
|
+
function contentPnpNoteTargets(targets) {
|
|
2942
|
+
return targets.filter((t) => t.pnp !== void 0 && t.pnp.state !== "rootOnly").map((t) => t.label);
|
|
2943
|
+
}
|
|
2944
|
+
function contentPnpNoteFor(targets) {
|
|
2945
|
+
const names = contentPnpNoteTargets(targets);
|
|
2946
|
+
if (names.length === 0) return void 0;
|
|
2947
|
+
const unplugged = targets.filter((t) => t.pnp?.state === "unplugged").map((t) => t.label);
|
|
2948
|
+
return contentPnpNote(names, unplugged);
|
|
2949
|
+
}
|
|
2950
|
+
var CONTENT_PNP_ROOT_ONLY_ACTION = "\uC571 package.json \uC5D0 \uC120\uC5B8\uD558\uC138\uC694";
|
|
2951
|
+
var CONTENT_PNP_NO_NODE_MODULES = "Plug'n'Play \uB77C node_modules \uACBD\uB85C\uAC00 \uC5C6\uC74C";
|
|
2952
|
+
function contentTargetText(t) {
|
|
2953
|
+
if (t.pnp?.state === "noNodeModules") return `${t.label}(${CONTENT_PNP_NO_NODE_MODULES})`;
|
|
2954
|
+
if (t.pnp?.state === "rootOnly") return `${t.label} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 ${CONTENT_PNP_ROOT_ONLY_ACTION}`;
|
|
2955
|
+
return `${t.label} \u2192 "${t.suggest}"${t.note === void 0 ? "" : ` (${t.note})`}`;
|
|
2563
2956
|
}
|
|
2564
|
-
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";
|
|
2565
2957
|
function relDirOf(baseDir, dir) {
|
|
2566
2958
|
const rel3 = relative(baseDir, dir);
|
|
2567
2959
|
return rel3 === "" || isAbsolute(rel3) ? void 0 : rel3.split(sep).join("/");
|
|
@@ -2581,8 +2973,26 @@ function packageVersion(dir) {
|
|
|
2581
2973
|
return void 0;
|
|
2582
2974
|
}
|
|
2583
2975
|
}
|
|
2584
|
-
function
|
|
2585
|
-
const
|
|
2976
|
+
function pnpPackageContentTarget(baseDir, name, pkg) {
|
|
2977
|
+
const legacySample = `node_modules/${name}/dist/index.js`;
|
|
2978
|
+
const none = { sample: "", suggest: "", alternates: [], others: [] };
|
|
2979
|
+
if (pnpRootOnlyDependency(baseDir, pkg, name) !== void 0) return { ...none, pnp: { state: "rootOnly", legacySample } };
|
|
2980
|
+
const range = pkg === void 0 ? void 0 : hasDependency(pkg, name);
|
|
2981
|
+
const rels = (range === void 0 ? [] : findPnpUnpluggedPackages(baseDir, name, range)).map((d) => relDirOf(baseDir, d)).filter((r) => r !== void 0);
|
|
2982
|
+
const root = pnpProjectRoot(baseDir);
|
|
2983
|
+
if (rels.length === 0 || root === void 0) return { ...none, pnp: { state: "noNodeModules", legacySample } };
|
|
2984
|
+
const rootRel = relDirOf(baseDir, root);
|
|
2985
|
+
return {
|
|
2986
|
+
sample: `${rels[0]}/dist/index.js`,
|
|
2987
|
+
suggest: `${rootRel === void 0 ? "." : rootRel}/.yarn/unplugged/*/node_modules/${name}/dist/**/*.{js,mjs}`,
|
|
2988
|
+
alternates: rels.slice(1).map((r) => `${r}/dist/index.js`),
|
|
2989
|
+
others: [],
|
|
2990
|
+
pnp: { state: "unplugged", legacySample }
|
|
2991
|
+
};
|
|
2992
|
+
}
|
|
2993
|
+
function packageContentTarget(baseDir, name, pkg) {
|
|
2994
|
+
if (isPnpProject(baseDir)) return pnpPackageContentTarget(baseDir, name, pkg);
|
|
2995
|
+
const found = findInstalledPackage(baseDir, name);
|
|
2586
2996
|
const relDir = (found === void 0 ? void 0 : relDirOf(baseDir, found.dir)) ?? `node_modules/${name}`;
|
|
2587
2997
|
const alternates = [];
|
|
2588
2998
|
const others = [];
|
|
@@ -2603,7 +3013,7 @@ function packageContentTarget(baseDir, name) {
|
|
|
2603
3013
|
const versions = theirs === void 0 || ours === void 0 ? "" : theirs === ours ? `(\uBC84\uC804\uC740 ${ours} \uB85C \uAC19\uC74C)` : `(${theirs}, \uC571 ${ours})`;
|
|
2604
3014
|
others.push({
|
|
2605
3015
|
sample: `${rel3}/dist/index.js`,
|
|
2606
|
-
note: `\uC0C1\uC704 \uACBD\uB85C ${rel3} \uB294 \uC571\uC774 \uC4F0\uB294 \uC124\uCE58\uBCF8\uACFC \uB2E4\uB978 \uC124\uCE58\uBCF8${versions}\uC774\uB77C \uB36E\uC74C\uC73C\uB85C \uBCF4\uC9C0 \uC54A\
|
|
3016
|
+
note: `\uC0C1\uC704 \uACBD\uB85C ${rel3} \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`
|
|
2607
3017
|
});
|
|
2608
3018
|
}
|
|
2609
3019
|
}
|
|
@@ -2680,7 +3090,7 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
2680
3090
|
}
|
|
2681
3091
|
for (const name of TAILWIND4_COMPONENT_PACKAGES) {
|
|
2682
3092
|
if (declaredRange(baseDir, pkg, name) !== void 0) {
|
|
2683
|
-
targets.push({ label: name, ...packageContentTarget(baseDir, name) });
|
|
3093
|
+
targets.push({ label: name, ...packageContentTarget(baseDir, name, pkg) });
|
|
2684
3094
|
}
|
|
2685
3095
|
}
|
|
2686
3096
|
if (targets.length === 0) return null;
|
|
@@ -2690,11 +3100,14 @@ function inspectTailwindContent(baseDirInput) {
|
|
|
2690
3100
|
configFile,
|
|
2691
3101
|
unreadable: read === void 0,
|
|
2692
3102
|
dynamic: read?.dynamic ?? false,
|
|
2693
|
-
targets: targets.map(({ alternates = [], others = [], ...t }) => {
|
|
3103
|
+
targets: targets.map(({ alternates = [], others = [], pnp, ...t }) => {
|
|
2694
3104
|
const covers = (sample) => globs.some((g) => contentGlobCovers(g, sample, baseDir));
|
|
2695
|
-
const
|
|
3105
|
+
const samples = pnp !== void 0 && pnp.state !== "unplugged" ? [] : [t.sample, ...alternates];
|
|
3106
|
+
const coversSample = pnp?.state === "unplugged" ? (sample) => globs.some((g) => contentGlobCovers(g, sample, baseDir, { noDot: true })) : covers;
|
|
3107
|
+
const covered = samples.some(coversSample);
|
|
2696
3108
|
const note = covered ? void 0 : others.find((o) => covers(o.sample))?.note;
|
|
2697
|
-
|
|
3109
|
+
const base = note === void 0 ? { ...t, covered } : { ...t, covered, note };
|
|
3110
|
+
return pnp === void 0 ? base : { ...base, pnp: { state: pnp.state, legacyCovered: covers(pnp.legacySample) } };
|
|
2698
3111
|
})
|
|
2699
3112
|
};
|
|
2700
3113
|
}
|
|
@@ -2709,19 +3122,30 @@ function checkTailwindContent(baseDir) {
|
|
|
2709
3122
|
message: `${r.configFile}\uC758 content \uAC00 ${r.targets.map((t) => t.label).join(" \xB7 ")} \uB97C \uB36E\uC2B5\uB2C8\uB2E4`
|
|
2710
3123
|
};
|
|
2711
3124
|
}
|
|
2712
|
-
const list = missing.map(
|
|
3125
|
+
const list = missing.map(contentTargetText).join(" \xB7 ");
|
|
2713
3126
|
const note = missing.some((t) => t.suggest.startsWith("../")) ? ` (${CONTENT_PARENT_PATH_NOTE})` : "";
|
|
3127
|
+
const pnpText = contentPnpNoteFor(missing);
|
|
3128
|
+
const pnpNote = pnpText === void 0 ? "" : ` (${pnpText})`;
|
|
2714
3129
|
if (r.unreadable || r.dynamic) {
|
|
2715
3130
|
return {
|
|
2716
3131
|
name: "tailwind.content",
|
|
2717
3132
|
severity: "warn",
|
|
2718
|
-
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}`
|
|
3133
|
+
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}`
|
|
3134
|
+
};
|
|
3135
|
+
}
|
|
3136
|
+
if (missing.every((t) => t.pnp?.legacyCovered === true)) {
|
|
3137
|
+
const labels = missing.map((t) => t.label).join(" \xB7 ");
|
|
3138
|
+
const details = missing.filter((t) => t.pnp?.state !== "noNodeModules").map(contentTargetText);
|
|
3139
|
+
return {
|
|
3140
|
+
name: "tailwind.content",
|
|
3141
|
+
severity: "warn",
|
|
3142
|
+
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}`
|
|
2719
3143
|
};
|
|
2720
3144
|
}
|
|
2721
3145
|
return {
|
|
2722
3146
|
name: "tailwind.content",
|
|
2723
3147
|
severity: "fail",
|
|
2724
|
-
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}`
|
|
3148
|
+
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}`
|
|
2725
3149
|
};
|
|
2726
3150
|
}
|
|
2727
3151
|
var ANIMATION_PLUGIN_TAILWIND3 = "tailwindcss-animate";
|
|
@@ -2779,24 +3203,30 @@ function checkAnimationPlugin(baseDirInput) {
|
|
|
2779
3203
|
return void 0;
|
|
2780
3204
|
};
|
|
2781
3205
|
if (tailwind.major !== void 0 && tailwind.major >= 4) {
|
|
2782
|
-
const
|
|
2783
|
-
const
|
|
3206
|
+
const selection = selectCheckGlobalCss(baseDir);
|
|
3207
|
+
const note = globalCssSelectionNote(selection);
|
|
3208
|
+
const file = selection.rel;
|
|
3209
|
+
const expanded = selection.path !== void 0 && selection.rel !== void 0 ? expandGlobalCss(baseDir, selection.path, selection.rel, outsideCssDir(selection)) : void 0;
|
|
3210
|
+
const css = expanded !== void 0 ? stripCssComments(expanded.evidence) : "";
|
|
3211
|
+
const twAnimate = new RegExp(`@import\\s+(?:url\\(\\s*)?["']${ANIMATION_PLUGIN_TAILWIND4}["']`);
|
|
3212
|
+
const animatePlugin = new RegExp(`@plugin\\s+["']${ANIMATION_PLUGIN_TAILWIND3}["']`);
|
|
2784
3213
|
const lines = [];
|
|
2785
|
-
if (
|
|
2786
|
-
if (
|
|
3214
|
+
if (twAnimate.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND4);
|
|
3215
|
+
if (animatePlugin.test(css)) lines.push(ANIMATION_PLUGIN_TAILWIND3);
|
|
3216
|
+
const via = expanded !== void 0 ? cssImportViaNote(viaFiles([evidenceOrigin(expanded, (f) => twAnimate.test(f)), evidenceOrigin(expanded, (f) => animatePlugin.test(f))])) : "";
|
|
2787
3217
|
if (lines.length === 0) {
|
|
2788
3218
|
return {
|
|
2789
3219
|
name: "animation",
|
|
2790
3220
|
severity: "warn",
|
|
2791
|
-
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}"
|
|
3221
|
+
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}`
|
|
2792
3222
|
};
|
|
2793
3223
|
}
|
|
2794
3224
|
const problems = lines.map((name) => ({ name, why: pluginProblem(name) })).filter((x) => x.why !== void 0);
|
|
2795
|
-
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` };
|
|
3225
|
+
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}` };
|
|
2796
3226
|
return {
|
|
2797
3227
|
name: "animation",
|
|
2798
3228
|
severity: "warn",
|
|
2799
|
-
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`
|
|
3229
|
+
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}`
|
|
2800
3230
|
};
|
|
2801
3231
|
}
|
|
2802
3232
|
const configFile = TAILWIND_CONFIG_FILES.find((f) => existsSync(join(baseDir, f)));
|
|
@@ -3227,9 +3657,11 @@ import path10 from "path";
|
|
|
3227
3657
|
import chalk7 from "chalk";
|
|
3228
3658
|
|
|
3229
3659
|
// src/theme/brand-core.ts
|
|
3230
|
-
import {
|
|
3660
|
+
import { createHash } from "crypto";
|
|
3661
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, statSync as statSync2 } from "fs";
|
|
3231
3662
|
import { createRequire } from "module";
|
|
3232
3663
|
import { dirname as dirname2, join as join2, relative as relative2, resolve as resolve2, sep as sep2 } from "path";
|
|
3664
|
+
import { MessageChannel, Worker, receiveMessageOnPort } from "worker_threads";
|
|
3233
3665
|
var TOKENS_PACKAGE = "@axis-ds/tokens";
|
|
3234
3666
|
var BRAND_NAME_PATTERN = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
|
|
3235
3667
|
var MIN_BRAND_TOKENS_VERSION = "1.3.0";
|
|
@@ -3255,13 +3687,15 @@ function readJsonFile(file) {
|
|
|
3255
3687
|
function errorCode(err) {
|
|
3256
3688
|
return typeof err === "object" && err !== null && "code" in err ? String(err.code) : void 0;
|
|
3257
3689
|
}
|
|
3258
|
-
function
|
|
3690
|
+
function tokensPackageJsonCandidates(baseDir) {
|
|
3691
|
+
const candidates = [];
|
|
3259
3692
|
let dir = resolve2(baseDir);
|
|
3260
3693
|
for (; ; ) {
|
|
3261
3694
|
const candidate = join2(dir, "node_modules", TOKENS_PACKAGE, "package.json");
|
|
3262
|
-
|
|
3695
|
+
candidates.push(candidate);
|
|
3696
|
+
if (existsSync2(candidate)) return { found: candidate, candidates };
|
|
3263
3697
|
const parent = dirname2(dir);
|
|
3264
|
-
if (parent === dir) return
|
|
3698
|
+
if (parent === dir) return { candidates };
|
|
3265
3699
|
dir = parent;
|
|
3266
3700
|
}
|
|
3267
3701
|
}
|
|
@@ -3271,47 +3705,218 @@ function projectRequire(baseDir) {
|
|
|
3271
3705
|
function tokensSpecifier(subpath) {
|
|
3272
3706
|
return `${TOKENS_PACKAGE}/${subpath.replace(/^\.\//, "")}`;
|
|
3273
3707
|
}
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
|
|
3277
|
-
|
|
3278
|
-
|
|
3708
|
+
var nodeSeenStates = /* @__PURE__ */ new Map();
|
|
3709
|
+
var ABSENT = "absent";
|
|
3710
|
+
var UNKNOWN = "unknown";
|
|
3711
|
+
var isolationDisabled = false;
|
|
3712
|
+
var isolatedStats = { workers: 0, resolves: 0, fallbacks: 0 };
|
|
3713
|
+
var ISOLATED_RESOLVE_TIMEOUT_MS = 5e3;
|
|
3714
|
+
var ISOLATED_RESOLVE_SOURCE = `
|
|
3715
|
+
const { workerData } = require("node:worker_threads");
|
|
3716
|
+
const { createRequire } = require("node:module");
|
|
3717
|
+
const { port, signal, from } = workerData;
|
|
3718
|
+
const req = createRequire(from);
|
|
3719
|
+
port.on("message", (spec) => {
|
|
3720
|
+
let reply;
|
|
3721
|
+
try {
|
|
3722
|
+
reply = { path: req.resolve(spec) };
|
|
3723
|
+
} catch (err) {
|
|
3724
|
+
const code = err && typeof err === "object" && "code" in err ? String(err.code) : undefined;
|
|
3725
|
+
reply = { code, message: err && err.message ? String(err.message) : String(err) };
|
|
3726
|
+
}
|
|
3727
|
+
port.postMessage(reply);
|
|
3728
|
+
Atomics.store(signal, 0, 1);
|
|
3729
|
+
Atomics.notify(signal, 0);
|
|
3730
|
+
});
|
|
3731
|
+
`;
|
|
3732
|
+
var IsolationFailure = class extends Error {
|
|
3733
|
+
};
|
|
3734
|
+
function createWorkerResolveSession(from, source, timeoutMs) {
|
|
3735
|
+
const { port1, port2 } = new MessageChannel();
|
|
3736
|
+
const signal = new Int32Array(new SharedArrayBuffer(4));
|
|
3737
|
+
const worker = new Worker(source, {
|
|
3738
|
+
eval: true,
|
|
3739
|
+
workerData: { port: port2, signal, from },
|
|
3740
|
+
transferList: [port2]
|
|
3741
|
+
});
|
|
3742
|
+
worker.on("error", () => {
|
|
3743
|
+
});
|
|
3744
|
+
worker.unref();
|
|
3745
|
+
return {
|
|
3746
|
+
resolve(spec) {
|
|
3747
|
+
Atomics.store(signal, 0, 0);
|
|
3748
|
+
port1.postMessage(spec);
|
|
3749
|
+
const waited = Atomics.wait(signal, 0, 0, timeoutMs);
|
|
3750
|
+
const received = receiveMessageOnPort(port1);
|
|
3751
|
+
if (waited === "timed-out" || !received) throw new IsolationFailure("\uACA9\uB9AC \uD574\uC11D\uC774 \uC751\uB2F5\uD558\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4");
|
|
3752
|
+
const reply = received.message;
|
|
3753
|
+
if (typeof reply.path === "string") return reply.path;
|
|
3754
|
+
throw Object.assign(new Error(reply.message ?? spec), reply.code === void 0 ? {} : { code: reply.code });
|
|
3755
|
+
},
|
|
3756
|
+
close() {
|
|
3757
|
+
port1.close();
|
|
3758
|
+
void worker.terminate();
|
|
3759
|
+
}
|
|
3760
|
+
};
|
|
3761
|
+
}
|
|
3762
|
+
function workerResolveSession(from) {
|
|
3763
|
+
return createWorkerResolveSession(from, ISOLATED_RESOLVE_SOURCE, ISOLATED_RESOLVE_TIMEOUT_MS);
|
|
3764
|
+
}
|
|
3765
|
+
var isolatedFactory = workerResolveSession;
|
|
3766
|
+
function sha256(text) {
|
|
3767
|
+
return createHash("sha256").update(text).digest("hex");
|
|
3768
|
+
}
|
|
3769
|
+
function openTokensResolver(baseDir, candidates, pkgJson, pkgText) {
|
|
3770
|
+
const nodeRequire = projectRequire(baseDir);
|
|
3771
|
+
const key = sha256(pkgText);
|
|
3772
|
+
const current = candidates.map((c) => c === pkgJson ? key : ABSENT);
|
|
3773
|
+
const changed = candidates.some((c, i) => {
|
|
3774
|
+
const seen = nodeSeenStates.get(c);
|
|
3775
|
+
return seen !== void 0 && seen !== current[i];
|
|
3776
|
+
});
|
|
3777
|
+
let mode = changed ? "isolated" : "node";
|
|
3778
|
+
if (mode === "node") {
|
|
3779
|
+
candidates.forEach((c, i) => {
|
|
3780
|
+
if (!nodeSeenStates.has(c)) nodeSeenStates.set(c, current[i]);
|
|
3781
|
+
});
|
|
3782
|
+
}
|
|
3783
|
+
let session = null;
|
|
3784
|
+
let stale = false;
|
|
3785
|
+
let raced = false;
|
|
3786
|
+
let postChecked = false;
|
|
3787
|
+
const markStale = () => {
|
|
3788
|
+
if (!stale) isolatedStats.fallbacks += 1;
|
|
3789
|
+
stale = true;
|
|
3790
|
+
};
|
|
3791
|
+
const fallBack = () => {
|
|
3792
|
+
markStale();
|
|
3793
|
+
isolationDisabled = true;
|
|
3794
|
+
session?.close();
|
|
3795
|
+
session = null;
|
|
3796
|
+
};
|
|
3797
|
+
const startIsolation = () => {
|
|
3798
|
+
if (isolationDisabled) {
|
|
3799
|
+
markStale();
|
|
3800
|
+
return;
|
|
3801
|
+
}
|
|
3802
|
+
try {
|
|
3803
|
+
session = isolatedFactory(join2(resolve2(baseDir), "package.json"));
|
|
3804
|
+
isolatedStats.workers += 1;
|
|
3805
|
+
} catch {
|
|
3806
|
+
fallBack();
|
|
3807
|
+
}
|
|
3808
|
+
};
|
|
3809
|
+
if (mode === "isolated") startIsolation();
|
|
3810
|
+
const isolatedResolve = (spec) => {
|
|
3811
|
+
if (session) {
|
|
3812
|
+
try {
|
|
3813
|
+
const resolved = session.resolve(spec);
|
|
3814
|
+
isolatedStats.resolves += 1;
|
|
3815
|
+
return resolved;
|
|
3816
|
+
} catch (err) {
|
|
3817
|
+
if (!(err instanceof IsolationFailure)) {
|
|
3818
|
+
isolatedStats.resolves += 1;
|
|
3819
|
+
throw err;
|
|
3820
|
+
}
|
|
3821
|
+
fallBack();
|
|
3822
|
+
}
|
|
3823
|
+
}
|
|
3824
|
+
return nodeRequire.resolve(spec);
|
|
3825
|
+
};
|
|
3826
|
+
return {
|
|
3827
|
+
resolve(spec) {
|
|
3828
|
+
if (mode === "isolated") return isolatedResolve(spec);
|
|
3829
|
+
let resolved;
|
|
3830
|
+
let failure;
|
|
3831
|
+
let failed = false;
|
|
3832
|
+
try {
|
|
3833
|
+
resolved = nodeRequire.resolve(spec);
|
|
3834
|
+
} catch (err) {
|
|
3835
|
+
failed = true;
|
|
3836
|
+
failure = err;
|
|
3837
|
+
}
|
|
3838
|
+
if (!postChecked) {
|
|
3839
|
+
postChecked = true;
|
|
3840
|
+
let after;
|
|
3841
|
+
try {
|
|
3842
|
+
after = sha256(readFileSync2(pkgJson, "utf8"));
|
|
3843
|
+
} catch {
|
|
3844
|
+
after = UNKNOWN;
|
|
3845
|
+
}
|
|
3846
|
+
if (after !== key) {
|
|
3847
|
+
nodeSeenStates.set(pkgJson, UNKNOWN);
|
|
3848
|
+
raced = true;
|
|
3849
|
+
mode = "isolated";
|
|
3850
|
+
startIsolation();
|
|
3851
|
+
return isolatedResolve(spec);
|
|
3852
|
+
}
|
|
3853
|
+
}
|
|
3854
|
+
if (failed) throw failure;
|
|
3855
|
+
return resolved;
|
|
3856
|
+
},
|
|
3857
|
+
get stale() {
|
|
3858
|
+
return stale;
|
|
3859
|
+
},
|
|
3860
|
+
get raced() {
|
|
3861
|
+
return raced;
|
|
3862
|
+
},
|
|
3863
|
+
close() {
|
|
3864
|
+
session?.close();
|
|
3865
|
+
session = null;
|
|
3866
|
+
}
|
|
3867
|
+
};
|
|
3868
|
+
}
|
|
3869
|
+
function readVersion(pkgText) {
|
|
3870
|
+
const pkg = JSON.parse(pkgText);
|
|
3871
|
+
return typeof pkg.version === "string" ? pkg.version : void 0;
|
|
3872
|
+
}
|
|
3873
|
+
function openTokens(baseDir) {
|
|
3874
|
+
const { found: pkgJson, candidates } = tokensPackageJsonCandidates(baseDir);
|
|
3875
|
+
if (!pkgJson) return { resolution: { status: "not-installed" } };
|
|
3876
|
+
const pkgText = readFileSync2(pkgJson, "utf8");
|
|
3877
|
+
let version = readVersion(pkgText);
|
|
3878
|
+
const resolver = openTokensResolver(baseDir, candidates, pkgJson, pkgText);
|
|
3879
|
+
const finish = (status, indexPath) => {
|
|
3880
|
+
if (resolver.raced) {
|
|
3881
|
+
try {
|
|
3882
|
+
version = readVersion(readFileSync2(pkgJson, "utf8"));
|
|
3883
|
+
} catch {
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
const resolution = indexPath === void 0 ? { status, version } : { status, version, indexPath };
|
|
3887
|
+
return { resolution: resolver.stale ? { ...resolution, stale: true } : resolution, resolver };
|
|
3888
|
+
};
|
|
3279
3889
|
try {
|
|
3280
|
-
const indexPath =
|
|
3281
|
-
return
|
|
3890
|
+
const indexPath = resolver.resolve(tokensSpecifier("./brands"));
|
|
3891
|
+
return finish("ok", indexPath);
|
|
3282
3892
|
} catch (err) {
|
|
3283
3893
|
const code = errorCode(err);
|
|
3284
|
-
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") return
|
|
3285
|
-
if (code === "MODULE_NOT_FOUND") return
|
|
3894
|
+
if (code === "ERR_PACKAGE_PATH_NOT_EXPORTED") return finish("unsupported");
|
|
3895
|
+
if (code === "MODULE_NOT_FOUND") return finish("not-built");
|
|
3896
|
+
resolver.close();
|
|
3286
3897
|
throw err;
|
|
3287
3898
|
}
|
|
3288
3899
|
}
|
|
3900
|
+
function resolveTokens(baseDir) {
|
|
3901
|
+
const { resolution, resolver } = openTokens(baseDir);
|
|
3902
|
+
resolver?.close();
|
|
3903
|
+
return resolution;
|
|
3904
|
+
}
|
|
3289
3905
|
function brandImportPath(entry) {
|
|
3290
3906
|
return tokensSpecifier(entry.css);
|
|
3291
3907
|
}
|
|
3292
3908
|
function isFile(file) {
|
|
3293
3909
|
try {
|
|
3294
|
-
return
|
|
3910
|
+
return statSync2(file).isFile();
|
|
3295
3911
|
} catch {
|
|
3296
3912
|
return false;
|
|
3297
3913
|
}
|
|
3298
3914
|
}
|
|
3299
3915
|
function findGlobalCss(baseDir, config) {
|
|
3300
|
-
const
|
|
3916
|
+
const selection = selectGlobalCss(resolve2(baseDir), config?.globalCss, GLOBAL_CSS_CANDIDATES);
|
|
3301
3917
|
const result = {};
|
|
3302
|
-
|
|
3303
|
-
if (
|
|
3304
|
-
const file = resolve2(root, configured);
|
|
3305
|
-
if (isFile(file)) return { path: file };
|
|
3306
|
-
result.configuredMissing = configured;
|
|
3307
|
-
}
|
|
3308
|
-
for (const candidate of GLOBAL_CSS_CANDIDATES) {
|
|
3309
|
-
const file = join2(root, candidate);
|
|
3310
|
-
if (isFile(file)) {
|
|
3311
|
-
result.path = file;
|
|
3312
|
-
break;
|
|
3313
|
-
}
|
|
3314
|
-
}
|
|
3918
|
+
if (selection.configuredMissing !== void 0) result.configuredMissing = selection.configuredMissing;
|
|
3919
|
+
if (selection.path !== void 0) result.path = selection.path;
|
|
3315
3920
|
return result;
|
|
3316
3921
|
}
|
|
3317
3922
|
function findBrandImports(css) {
|
|
@@ -3338,18 +3943,24 @@ function inspectBrandImport(baseDir) {
|
|
|
3338
3943
|
const brand = config?.brand;
|
|
3339
3944
|
if (typeof brand !== "string" || brand.trim() === "") return null;
|
|
3340
3945
|
const root = resolve2(baseDir);
|
|
3341
|
-
const location =
|
|
3946
|
+
const location = selectGlobalCss(root, config?.globalCss, GLOBAL_CSS_CANDIDATES, { requireStylesheet: true });
|
|
3342
3947
|
const base = { brand };
|
|
3343
3948
|
if (location.configuredMissing !== void 0) base.configuredMissing = location.configuredMissing;
|
|
3949
|
+
if (location.configuredRejected !== void 0) base.configuredRejected = location.configuredRejected;
|
|
3344
3950
|
if (!location.path) {
|
|
3345
3951
|
return { ...base, state: "css-missing", imports: [] };
|
|
3346
3952
|
}
|
|
3347
3953
|
const cssFile = relative2(root, location.path).split(sep2).join("/");
|
|
3348
|
-
const
|
|
3954
|
+
const expanded = expandGlobalCss(root, location.path, cssFile);
|
|
3955
|
+
const imports = [...new Set(findBrandImports(expanded.evidence))];
|
|
3349
3956
|
let state;
|
|
3350
3957
|
if (imports.includes(brand)) state = "match";
|
|
3351
3958
|
else if (imports.length === 0) state = "import-missing";
|
|
3352
3959
|
else state = "other-brand";
|
|
3960
|
+
const sub = expanded.files.filter((f) => f.depth > 0);
|
|
3961
|
+
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) : [];
|
|
3962
|
+
const entryHas = state === "match" && findBrandImports(expanded.files[0].css).includes(brand);
|
|
3963
|
+
if (via.length > 0 && !entryHas) return { ...base, state, cssFile, imports, importVia: via.map((f) => f.rel) };
|
|
3353
3964
|
return { ...base, state, cssFile, imports };
|
|
3354
3965
|
}
|
|
3355
3966
|
function isMissingBuildFile(err) {
|
|
@@ -3363,8 +3974,8 @@ function readBrandIndex(indexPath) {
|
|
|
3363
3974
|
}
|
|
3364
3975
|
return data.brands;
|
|
3365
3976
|
}
|
|
3366
|
-
function readSummary(
|
|
3367
|
-
const metaPath =
|
|
3977
|
+
function readSummary(resolver, entry) {
|
|
3978
|
+
const metaPath = resolver.resolve(tokensSpecifier(entry.meta));
|
|
3368
3979
|
const meta = readJsonFile(metaPath);
|
|
3369
3980
|
return {
|
|
3370
3981
|
name: entry.name,
|
|
@@ -3375,20 +3986,33 @@ function readSummary(baseDir, entry) {
|
|
|
3375
3986
|
};
|
|
3376
3987
|
}
|
|
3377
3988
|
function listBrands(baseDir) {
|
|
3378
|
-
const tokens =
|
|
3379
|
-
|
|
3989
|
+
const { resolution: tokens, resolver } = openTokens(baseDir);
|
|
3990
|
+
try {
|
|
3991
|
+
return withStaleOf(resolver, listBrandsWith(tokens, resolver));
|
|
3992
|
+
} finally {
|
|
3993
|
+
resolver?.close();
|
|
3994
|
+
}
|
|
3995
|
+
}
|
|
3996
|
+
function listBrandsWith(tokens, resolver) {
|
|
3997
|
+
if (tokens.status !== "ok" || !tokens.indexPath || !resolver) {
|
|
3380
3998
|
return { status: tokens.status, version: tokens.version, brands: [] };
|
|
3381
3999
|
}
|
|
3382
4000
|
const entries = readBrandIndex(tokens.indexPath);
|
|
3383
|
-
|
|
3384
|
-
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
|
|
4001
|
+
const brands = [];
|
|
4002
|
+
for (const entry of entries) {
|
|
4003
|
+
try {
|
|
4004
|
+
brands.push(readSummary(resolver, entry));
|
|
4005
|
+
} catch (err) {
|
|
4006
|
+
if (isMissingBuildFile(err)) return { status: "not-built", version: tokens.version, brands: [] };
|
|
4007
|
+
if (resolver.stale && errorCode(err) === "ERR_PACKAGE_PATH_NOT_EXPORTED") continue;
|
|
4008
|
+
throw err;
|
|
4009
|
+
}
|
|
3389
4010
|
}
|
|
3390
4011
|
return { status: "ok", version: tokens.version, brands };
|
|
3391
4012
|
}
|
|
4013
|
+
function withStaleOf(resolver, result) {
|
|
4014
|
+
return resolver?.stale ? { ...result, stale: true } : result;
|
|
4015
|
+
}
|
|
3392
4016
|
function stripComments(css) {
|
|
3393
4017
|
return css.replace(/\/\*[\s\S]*?\*\//g, "");
|
|
3394
4018
|
}
|
|
@@ -3500,8 +4124,15 @@ function readProjectPackageJson(baseDir) {
|
|
|
3500
4124
|
}
|
|
3501
4125
|
}
|
|
3502
4126
|
function getBrand(baseDir, name) {
|
|
3503
|
-
const tokens =
|
|
3504
|
-
|
|
4127
|
+
const { resolution: tokens, resolver } = openTokens(baseDir);
|
|
4128
|
+
try {
|
|
4129
|
+
return withStaleOf(resolver, getBrandWith(tokens, resolver, name));
|
|
4130
|
+
} finally {
|
|
4131
|
+
resolver?.close();
|
|
4132
|
+
}
|
|
4133
|
+
}
|
|
4134
|
+
function getBrandWith(tokens, resolver, name) {
|
|
4135
|
+
if (tokens.status !== "ok" || !tokens.indexPath || !resolver) {
|
|
3505
4136
|
return { status: tokens.status, version: tokens.version, brand: null, available: [] };
|
|
3506
4137
|
}
|
|
3507
4138
|
const entries = readBrandIndex(tokens.indexPath);
|
|
@@ -3513,11 +4144,14 @@ function getBrand(baseDir, name) {
|
|
|
3513
4144
|
let summary;
|
|
3514
4145
|
let parsed;
|
|
3515
4146
|
try {
|
|
3516
|
-
summary = readSummary(
|
|
3517
|
-
const cssPath =
|
|
4147
|
+
summary = readSummary(resolver, entry);
|
|
4148
|
+
const cssPath = resolver.resolve(summary.importPath);
|
|
3518
4149
|
parsed = parseBrandCss(readFileSync2(cssPath, "utf8"), name);
|
|
3519
4150
|
} catch (err) {
|
|
3520
4151
|
if (isMissingBuildFile(err)) return { status: "not-built", version: tokens.version, brand: null, available: [] };
|
|
4152
|
+
if (resolver.stale && errorCode(err) === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
4153
|
+
return { status: "ok", version: tokens.version, brand: null, available: available.filter((n) => n !== name) };
|
|
4154
|
+
}
|
|
3521
4155
|
throw err;
|
|
3522
4156
|
}
|
|
3523
4157
|
return {
|
|
@@ -3707,13 +4341,14 @@ function checkBrand(baseDir) {
|
|
|
3707
4341
|
}
|
|
3708
4342
|
function brandCheckResult(check) {
|
|
3709
4343
|
const { brand } = check;
|
|
3710
|
-
const suffix =
|
|
4344
|
+
const suffix = globalCssSelectionNote(check);
|
|
4345
|
+
const via = cssImportViaNote(check.importVia);
|
|
3711
4346
|
switch (check.state) {
|
|
3712
4347
|
case "match":
|
|
3713
4348
|
return {
|
|
3714
4349
|
name: "brand",
|
|
3715
4350
|
severity: "pass",
|
|
3716
|
-
message: `brand "${brand}" import \uAC00 ${check.cssFile}\uC5D0 \uC788\uC2B5\uB2C8\uB2E4${suffix}`
|
|
4351
|
+
message: `brand "${brand}" import \uAC00 ${check.cssFile}\uC5D0 \uC788\uC2B5\uB2C8\uB2E4${via}${suffix}`
|
|
3717
4352
|
};
|
|
3718
4353
|
case "css-missing":
|
|
3719
4354
|
return {
|
|
@@ -3731,7 +4366,7 @@ function brandCheckResult(check) {
|
|
|
3731
4366
|
return {
|
|
3732
4367
|
name: "brand",
|
|
3733
4368
|
severity: "warn",
|
|
3734
|
-
message: `brand "${brand}" \uC640 import(${check.imports.join(", ")})\uAC00 \uB2E4\uB985\uB2C8\uB2E4${suffix}`
|
|
4369
|
+
message: `brand "${brand}" \uC640 import(${check.imports.join(", ")})\uAC00 \uB2E4\uB985\uB2C8\uB2E4${via}${suffix}`
|
|
3735
4370
|
};
|
|
3736
4371
|
}
|
|
3737
4372
|
}
|
|
@@ -3876,12 +4511,11 @@ import chalk9 from "chalk";
|
|
|
3876
4511
|
import path12 from "path";
|
|
3877
4512
|
|
|
3878
4513
|
// src/theme/theme-add.ts
|
|
3879
|
-
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync4, realpathSync as realpathSync2,
|
|
4514
|
+
import { accessSync, constants, existsSync as existsSync3, readFileSync as readFileSync4, realpathSync as realpathSync2, unlinkSync, writeFileSync } from "fs";
|
|
3880
4515
|
import path11 from "path";
|
|
3881
4516
|
var TOKENS_DEPENDENCY_RANGE = `^${TOKENS_DEPENDENCY_MIN_VERSION}`;
|
|
3882
4517
|
var TAILWIND3_BASE_IMPORTS = [`${TOKENS_PACKAGE}/css`, `${TOKENS_PACKAGE}/css/shadcn`];
|
|
3883
4518
|
var THEME_MIN_VERSION = "1.3.0";
|
|
3884
|
-
var COMPONENT_TAILWIND_CSS_MIN_VERSION = "1.4.0";
|
|
3885
4519
|
function readText(file) {
|
|
3886
4520
|
return existsSync3(file) ? readFileSync4(file, "utf8") : null;
|
|
3887
4521
|
}
|
|
@@ -3980,13 +4614,6 @@ function realPathInside(baseDir, file) {
|
|
|
3980
4614
|
const inside = relPath !== "" && !relPath.startsWith("..") && !path11.isAbsolute(relPath);
|
|
3981
4615
|
return { inside, realPath };
|
|
3982
4616
|
}
|
|
3983
|
-
function isFile2(file) {
|
|
3984
|
-
try {
|
|
3985
|
-
return statSync2(file).isFile();
|
|
3986
|
-
} catch {
|
|
3987
|
-
return false;
|
|
3988
|
-
}
|
|
3989
|
-
}
|
|
3990
4617
|
function isStylesheet(realPath) {
|
|
3991
4618
|
return path11.extname(realPath).toLowerCase() === ".css";
|
|
3992
4619
|
}
|
|
@@ -4062,16 +4689,11 @@ function planThemeAdd(baseDirInput, brand) {
|
|
|
4062
4689
|
const deferredComponentImports = [];
|
|
4063
4690
|
if (tailwind4 && pkg !== void 0) {
|
|
4064
4691
|
for (const n of TAILWIND4_COMPONENT_PACKAGES) {
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
const installed2 = findInstalledPackage(baseDir, n);
|
|
4071
|
-
if (installed2 !== void 0 && isFile2(path11.join(installed2.dir, "tailwind.css"))) {
|
|
4072
|
-
componentImports.push(n);
|
|
4073
|
-
} else {
|
|
4074
|
-
deferredComponentImports.push(installed2 === void 0 ? { name: n } : { name: n, installedVersion: installed2.version ?? "?" });
|
|
4692
|
+
const r = componentCssResolution(baseDir, pkg, n);
|
|
4693
|
+
if (r.kind === "app" || r.kind === "root-ok") componentImports.push(n);
|
|
4694
|
+
else if (r.kind === "root-not-installed") deferredComponentImports.push({ name: n });
|
|
4695
|
+
else if (r.kind === "root-old" || r.kind === "root-missing-file") {
|
|
4696
|
+
deferredComponentImports.push({ name: n, installedVersion: r.installedVersion });
|
|
4075
4697
|
}
|
|
4076
4698
|
}
|
|
4077
4699
|
}
|
|
@@ -4487,13 +5109,7 @@ function renderThemeAdd(plan, written) {
|
|
|
4487
5109
|
);
|
|
4488
5110
|
}
|
|
4489
5111
|
for (const d of css?.deferredComponentImports ?? []) {
|
|
4490
|
-
|
|
4491
|
-
const current = d.installedVersion !== void 0 && d.installedVersion !== "?" && (compareExactVersions(d.installedVersion, COMPONENT_TAILWIND_CSS_MIN_VERSION) ?? -1) >= 0;
|
|
4492
|
-
lines.push(
|
|
4493
|
-
chalk9.yellow(
|
|
4494
|
-
d.installedVersion === void 0 ? ` ! ${d.name} \uAC00 \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB410\uC9C0\uB9CC \uC124\uCE58\uB418\uC9C0 \uC54A\uC544 ${line} \uB97C \uB123\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58(${plan.installCommand}) \uB4A4 theme add \uB97C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uB123\uC73C\uC138\uC694.` : current ? ` ! \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB41C ${d.name} \uC758 \uC124\uCE58\uBCF8(${d.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC5B4 ${line} \uB97C \uB123\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uAC00 \uC190\uC0C1\uB410\uC744 \uC218 \uC788\uC73C\uB2C8 \uB2E4\uC2DC \uC124\uCE58(${plan.installCommand}) \uB4A4 theme add \uB97C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uB123\uC73C\uC138\uC694.` : ` ! \uC6CC\uD06C\uC2A4\uD398\uC774\uC2A4 \uB8E8\uD2B8\uC5D0 \uC120\uC5B8\uB41C ${d.name} \uC758 \uC124\uCE58\uBCF8(${d.installedVersion === "?" ? "\uBC84\uC804 \uBAA8\uB984" : d.installedVersion})\uC5D0 tailwind.css \uAC00 \uC5C6\uC5B4(${COMPONENT_TAILWIND_CSS_MIN_VERSION} \uBD80\uD130 \uC81C\uACF5) ${line} \uB97C \uB123\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. ${COMPONENT_TAILWIND_CSS_MIN_VERSION} \uC774\uC0C1\uC73C\uB85C \uC62C\uB9B0 \uB4A4 theme add \uB97C \uB2E4\uC2DC \uC2E4\uD589\uD558\uAC70\uB098 \uC9C1\uC811 \uB123\uC73C\uC138\uC694.`
|
|
4495
|
-
)
|
|
4496
|
-
);
|
|
5112
|
+
lines.push(chalk9.yellow(` ! ${deferredComponentImportReason(d, plan.installCommand)}`));
|
|
4497
5113
|
}
|
|
4498
5114
|
if (css && css.otherBrands.length > 0) {
|
|
4499
5115
|
lines.push(
|
|
@@ -4551,13 +5167,14 @@ function renderThemeAdd(plan, written) {
|
|
|
4551
5167
|
);
|
|
4552
5168
|
}
|
|
4553
5169
|
for (const t of tw.contentMissing) {
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
);
|
|
5170
|
+
const not = tw.contentUnknown ? "\uC54A\uB294 \uAC83\uC73C\uB85C \uBCF4\uC785\uB2C8\uB2E4(\uC815\uC801 \uD310\uB3C5)" : "\uC54A\uC2B5\uB2C8\uB2E4";
|
|
5171
|
+
if (t.pnp?.state === "noNodeModules") lines.push(chalk9.yellow(` ! content \uAC00 ${t.label} \uB97C Plug'n'Play \uC5D0\uC11C \uC2A4\uCE94\uB418\uB294 \uACBD\uB85C\uB85C \uB36E\uC9C0 ${not}`));
|
|
5172
|
+
else if (t.pnp?.state === "rootOnly") lines.push(chalk9.yellow(` ! ${t.label} \uAC00 ${PNP_ROOT_ONLY_NOTE} \u2192 ${CONTENT_PNP_ROOT_ONLY_ACTION}`));
|
|
5173
|
+
else lines.push(chalk9.yellow(` ! content \uAC00 ${t.label} \uB97C \uB36E\uC9C0 ${not}. \uB123\uC73C\uC138\uC694: "${t.suggest}"`));
|
|
4559
5174
|
}
|
|
4560
5175
|
if (tw.contentMissing.some((t) => t.suggest.startsWith("../"))) lines.push(chalk9.gray(` ${CONTENT_PARENT_PATH_NOTE}`));
|
|
5176
|
+
const pnpNote = contentPnpNoteFor(tw.contentMissing);
|
|
5177
|
+
if (pnpNote !== void 0) lines.push(chalk9.gray(` ${pnpNote}`));
|
|
4561
5178
|
}
|
|
4562
5179
|
const act = plan.activation;
|
|
4563
5180
|
lines.push("", chalk9.bold(`\uBE0C\uB79C\uB4DC \uCF1C\uAE30 (ThemeProvider \uB294 ${THEME_PACKAGE} ${THEME_MIN_VERSION} \uC774\uC0C1)`));
|
|
@@ -4639,7 +5256,7 @@ function registerThemeCommand(program2) {
|
|
|
4639
5256
|
import chalk11 from "chalk";
|
|
4640
5257
|
|
|
4641
5258
|
// ../axis-registry-core/src/registry/schema.ts
|
|
4642
|
-
import { createHash } from "crypto";
|
|
5259
|
+
import { createHash as createHash2 } from "crypto";
|
|
4643
5260
|
var REGISTRY_NAME_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
4644
5261
|
var REGISTRY_NAME_MAX_LENGTH = 64;
|
|
4645
5262
|
function isValidRegistryName(name) {
|
|
@@ -4772,8 +5389,8 @@ function validateRegistryIndex(data, where = "index.json") {
|
|
|
4772
5389
|
if (!isValidRegistryName(raw.name)) throw new Error(`${at}: name \uC774 slug \uADDC\uCE59\uC5D0 \uB9DE\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4`);
|
|
4773
5390
|
if (seen.has(raw.name)) throw new Error(`${at}: name '${raw.name}' \uAC00 \uC911\uBCF5\uC785\uB2C8\uB2E4`);
|
|
4774
5391
|
seen.add(raw.name);
|
|
4775
|
-
const
|
|
4776
|
-
if (
|
|
5392
|
+
const sha2562 = optionalString(raw, "sha256", at);
|
|
5393
|
+
if (sha2562 !== void 0 && !/^[0-9a-f]{64}$/.test(sha2562)) {
|
|
4777
5394
|
throw new Error(`${at}: sha256 \uD615\uC2DD\uC774 \uC544\uB2D9\uB2C8\uB2E4`);
|
|
4778
5395
|
}
|
|
4779
5396
|
return {
|
|
@@ -4781,7 +5398,7 @@ function validateRegistryIndex(data, where = "index.json") {
|
|
|
4781
5398
|
type: requireType(raw, at),
|
|
4782
5399
|
title: optionalString(raw, "title", at),
|
|
4783
5400
|
description: optionalString(raw, "description", at),
|
|
4784
|
-
...
|
|
5401
|
+
...sha2562 !== void 0 ? { sha256: sha2562 } : {}
|
|
4785
5402
|
};
|
|
4786
5403
|
});
|
|
4787
5404
|
return {
|
|
@@ -4829,7 +5446,7 @@ function validateRegistryItem(data, expectedName, where = `${expectedName}.json`
|
|
|
4829
5446
|
};
|
|
4830
5447
|
}
|
|
4831
5448
|
function sha256Hex(text) {
|
|
4832
|
-
return
|
|
5449
|
+
return createHash2("sha256").update(text, "utf8").digest("hex");
|
|
4833
5450
|
}
|
|
4834
5451
|
function checkItemSha256(item, entry, where = `${item.name}.json`) {
|
|
4835
5452
|
if (entry.sha256 === void 0) return;
|