tailwind-styled-v4 5.0.9 → 5.0.10
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/CHANGELOG.md +15 -1
- package/dist/{analyzeWorkspace-DuJKh7Ty.d.mts → analyzeWorkspace-BS5O4rhC.d.mts} +47 -2
- package/dist/{analyzeWorkspace-Ct_NTAWt.d.ts → analyzeWorkspace-DDOQdzzI.d.ts} +47 -2
- package/dist/analyzer.d.mts +5 -3
- package/dist/analyzer.d.ts +5 -3
- package/dist/analyzer.js +563 -468
- package/dist/analyzer.js.map +1 -1
- package/dist/analyzer.mjs +562 -467
- package/dist/analyzer.mjs.map +1 -1
- package/dist/animate.d.mts +4 -7
- package/dist/animate.d.ts +4 -7
- package/dist/animate.js +171 -265
- package/dist/animate.js.map +1 -1
- package/dist/animate.mjs +165 -264
- package/dist/animate.mjs.map +1 -1
- package/dist/atomic.d.mts +22 -1
- package/dist/atomic.d.ts +22 -1
- package/dist/atomic.js +221 -165
- package/dist/atomic.js.map +1 -1
- package/dist/atomic.mjs +200 -165
- package/dist/atomic.mjs.map +1 -1
- package/dist/cli.d.mts +60 -1
- package/dist/cli.d.ts +60 -1
- package/dist/cli.js +1261 -1517
- package/dist/cli.js.map +1 -1
- package/dist/cli.mjs +1238 -1513
- package/dist/cli.mjs.map +1 -1
- package/dist/compiler.d.mts +38 -7
- package/dist/compiler.d.ts +38 -7
- package/dist/compiler.js +174 -197
- package/dist/compiler.js.map +1 -1
- package/dist/compiler.mjs +151 -194
- package/dist/compiler.mjs.map +1 -1
- package/dist/devtools.js +7 -31
- package/dist/devtools.js.map +1 -1
- package/dist/devtools.mjs +7 -31
- package/dist/devtools.mjs.map +1 -1
- package/dist/engine.d.mts +134 -63
- package/dist/engine.d.ts +134 -63
- package/dist/engine.js +2863 -2482
- package/dist/engine.js.map +1 -1
- package/dist/engine.mjs +2852 -2485
- package/dist/engine.mjs.map +1 -1
- package/dist/{index-eWAocnD2.d.mts → index-NDINUhLN.d.mts} +3 -1
- package/dist/{index-eWAocnD2.d.ts → index-NDINUhLN.d.ts} +3 -1
- package/dist/index.d.mts +45 -32
- package/dist/index.d.ts +45 -32
- package/dist/index.js +271 -158
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +251 -158
- package/dist/index.mjs.map +1 -1
- package/dist/{liveTokenEngine-DSUk88P6.d.ts → liveTokenEngine-CN9ian1R.d.ts} +1 -1
- package/dist/{liveTokenEngine-CX5_0c4q.d.mts → liveTokenEngine-DKoWRtqH.d.mts} +1 -1
- package/dist/next.js +20 -39
- package/dist/next.js.map +1 -1
- package/dist/next.mjs +18 -37
- package/dist/next.mjs.map +1 -1
- package/dist/plugin-api.d.mts +8 -2
- package/dist/plugin-api.d.ts +8 -2
- package/dist/plugin-api.js +14 -2
- package/dist/plugin-api.js.map +1 -1
- package/dist/plugin-api.mjs +14 -3
- package/dist/plugin-api.mjs.map +1 -1
- package/dist/plugin-registry.js +51 -11
- package/dist/plugin-registry.js.map +1 -1
- package/dist/plugin-registry.mjs +51 -11
- package/dist/plugin-registry.mjs.map +1 -1
- package/dist/plugin.d.mts +5 -7
- package/dist/plugin.d.ts +5 -7
- package/dist/plugin.js +16 -15
- package/dist/plugin.js.map +1 -1
- package/dist/plugin.mjs +16 -16
- package/dist/plugin.mjs.map +1 -1
- package/dist/rspack.js +17 -38
- package/dist/rspack.js.map +1 -1
- package/dist/rspack.mjs +15 -36
- package/dist/rspack.mjs.map +1 -1
- package/dist/runtime.d.mts +2 -2
- package/dist/runtime.d.ts +2 -2
- package/dist/scanner.d.mts +10 -1
- package/dist/scanner.d.ts +10 -1
- package/dist/scanner.js +298 -124
- package/dist/scanner.js.map +1 -1
- package/dist/scanner.mjs +296 -124
- package/dist/scanner.mjs.map +1 -1
- package/dist/shared.d.mts +1 -1
- package/dist/shared.d.ts +1 -1
- package/dist/shared.js +104 -176
- package/dist/shared.js.map +1 -1
- package/dist/shared.mjs +85 -176
- package/dist/shared.mjs.map +1 -1
- package/dist/storybook-addon.d.mts +1 -1
- package/dist/storybook-addon.d.ts +1 -1
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +166 -3
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +143 -1
- package/dist/svelte.mjs.map +1 -1
- package/dist/syntax.js +21 -21
- package/dist/syntax.js.map +1 -1
- package/dist/syntax.mjs +21 -21
- package/dist/syntax.mjs.map +1 -1
- package/dist/testing.js +9 -1
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +9 -1
- package/dist/testing.mjs.map +1 -1
- package/dist/theme.d.mts +2 -2
- package/dist/theme.d.ts +2 -2
- package/dist/theme.js +40 -112
- package/dist/theme.js.map +1 -1
- package/dist/theme.mjs +37 -110
- package/dist/theme.mjs.map +1 -1
- package/dist/turbopackLoader.js +79 -124
- package/dist/turbopackLoader.js.map +1 -1
- package/dist/turbopackLoader.mjs +63 -122
- package/dist/turbopackLoader.mjs.map +1 -1
- package/dist/tw.js +1256 -1517
- package/dist/tw.js.map +1 -1
- package/dist/tw.mjs +1236 -1513
- package/dist/tw.mjs.map +1 -1
- package/dist/vite.js +1783 -823
- package/dist/vite.js.map +1 -1
- package/dist/vite.mjs +1767 -821
- package/dist/vite.mjs.map +1 -1
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +165 -4
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +141 -1
- package/dist/vue.mjs.map +1 -1
- package/dist/webpackLoader.js +65 -108
- package/dist/webpackLoader.js.map +1 -1
- package/dist/webpackLoader.mjs +45 -104
- package/dist/webpackLoader.mjs.map +1 -1
- package/native/tailwind-styled-native.node +0 -0
- package/package.json +22 -24
package/dist/cli.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var path3 = require('path');
|
|
4
|
-
var url = require('url');
|
|
5
|
-
var zod = require('zod');
|
|
6
|
-
var fs8 = require('fs');
|
|
7
3
|
var module$1 = require('module');
|
|
4
|
+
var fs11 = require('fs');
|
|
5
|
+
var path6 = require('path');
|
|
6
|
+
require('crypto');
|
|
7
|
+
var url = require('url');
|
|
8
8
|
var worker_threads = require('worker_threads');
|
|
9
|
-
var
|
|
9
|
+
var os = require('os');
|
|
10
|
+
var zod = require('zod');
|
|
11
|
+
var fs7 = require('fs/promises');
|
|
10
12
|
var prompts = require('@clack/prompts');
|
|
11
13
|
var util = require('util');
|
|
12
14
|
var child_process = require('child_process');
|
|
@@ -14,9 +16,27 @@ var child_process = require('child_process');
|
|
|
14
16
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
15
17
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
var
|
|
19
|
+
function _interopNamespace(e) {
|
|
20
|
+
if (e && e.__esModule) return e;
|
|
21
|
+
var n = Object.create(null);
|
|
22
|
+
if (e) {
|
|
23
|
+
Object.keys(e).forEach(function (k) {
|
|
24
|
+
if (k !== 'default') {
|
|
25
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
26
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
get: function () { return e[k]; }
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
n.default = e;
|
|
34
|
+
return Object.freeze(n);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
var fs11__namespace = /*#__PURE__*/_interopNamespace(fs11);
|
|
38
|
+
var path6__namespace = /*#__PURE__*/_interopNamespace(path6);
|
|
39
|
+
var fs7__default = /*#__PURE__*/_interopDefault(fs7);
|
|
20
40
|
|
|
21
41
|
/* tailwind-styled-v4 v5.0.4 | MIT | https://github.com/dictionar32/tailwind-styled-v4 */
|
|
22
42
|
var __create = Object.create;
|
|
@@ -992,8 +1012,8 @@ var require_command = __commonJS({
|
|
|
992
1012
|
"packages/infrastructure/cli/node_modules/commander/lib/command.js"(exports$1) {
|
|
993
1013
|
var EventEmitter = __require("events").EventEmitter;
|
|
994
1014
|
var childProcess = __require("child_process");
|
|
995
|
-
var
|
|
996
|
-
var
|
|
1015
|
+
var path29 = __require("path");
|
|
1016
|
+
var fs15 = __require("fs");
|
|
997
1017
|
var process2 = __require("process");
|
|
998
1018
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
999
1019
|
var { CommanderError: CommanderError2 } = require_error();
|
|
@@ -1924,11 +1944,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1924
1944
|
let launchWithNode = false;
|
|
1925
1945
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
1926
1946
|
function findFile(baseDir, baseName) {
|
|
1927
|
-
const localBin =
|
|
1928
|
-
if (
|
|
1929
|
-
if (sourceExt.includes(
|
|
1947
|
+
const localBin = path29.resolve(baseDir, baseName);
|
|
1948
|
+
if (fs15.existsSync(localBin)) return localBin;
|
|
1949
|
+
if (sourceExt.includes(path29.extname(baseName))) return void 0;
|
|
1930
1950
|
const foundExt = sourceExt.find(
|
|
1931
|
-
(ext) =>
|
|
1951
|
+
(ext) => fs15.existsSync(`${localBin}${ext}`)
|
|
1932
1952
|
);
|
|
1933
1953
|
if (foundExt) return `${localBin}${foundExt}`;
|
|
1934
1954
|
return void 0;
|
|
@@ -1940,21 +1960,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1940
1960
|
if (this._scriptPath) {
|
|
1941
1961
|
let resolvedScriptPath;
|
|
1942
1962
|
try {
|
|
1943
|
-
resolvedScriptPath =
|
|
1963
|
+
resolvedScriptPath = fs15.realpathSync(this._scriptPath);
|
|
1944
1964
|
} catch (err) {
|
|
1945
1965
|
resolvedScriptPath = this._scriptPath;
|
|
1946
1966
|
}
|
|
1947
|
-
executableDir =
|
|
1948
|
-
|
|
1967
|
+
executableDir = path29.resolve(
|
|
1968
|
+
path29.dirname(resolvedScriptPath),
|
|
1949
1969
|
executableDir
|
|
1950
1970
|
);
|
|
1951
1971
|
}
|
|
1952
1972
|
if (executableDir) {
|
|
1953
1973
|
let localFile = findFile(executableDir, executableFile);
|
|
1954
1974
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
1955
|
-
const legacyName =
|
|
1975
|
+
const legacyName = path29.basename(
|
|
1956
1976
|
this._scriptPath,
|
|
1957
|
-
|
|
1977
|
+
path29.extname(this._scriptPath)
|
|
1958
1978
|
);
|
|
1959
1979
|
if (legacyName !== this._name) {
|
|
1960
1980
|
localFile = findFile(
|
|
@@ -1965,7 +1985,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1965
1985
|
}
|
|
1966
1986
|
executableFile = localFile || executableFile;
|
|
1967
1987
|
}
|
|
1968
|
-
launchWithNode = sourceExt.includes(
|
|
1988
|
+
launchWithNode = sourceExt.includes(path29.extname(executableFile));
|
|
1969
1989
|
let proc;
|
|
1970
1990
|
if (process2.platform !== "win32") {
|
|
1971
1991
|
if (launchWithNode) {
|
|
@@ -2805,7 +2825,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2805
2825
|
* @return {Command}
|
|
2806
2826
|
*/
|
|
2807
2827
|
nameFromFilename(filename) {
|
|
2808
|
-
this._name =
|
|
2828
|
+
this._name = path29.basename(filename, path29.extname(filename));
|
|
2809
2829
|
return this;
|
|
2810
2830
|
}
|
|
2811
2831
|
/**
|
|
@@ -2819,9 +2839,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2819
2839
|
* @param {string} [path]
|
|
2820
2840
|
* @return {(string|null|Command)}
|
|
2821
2841
|
*/
|
|
2822
|
-
executableDir(
|
|
2823
|
-
if (
|
|
2824
|
-
this._executableDir =
|
|
2842
|
+
executableDir(path30) {
|
|
2843
|
+
if (path30 === void 0) return this._executableDir;
|
|
2844
|
+
this._executableDir = path30;
|
|
2825
2845
|
return this;
|
|
2826
2846
|
}
|
|
2827
2847
|
/**
|
|
@@ -3161,45 +3181,6 @@ var init_esmHelpers = __esm({
|
|
|
3161
3181
|
_nodeUrl = null;
|
|
3162
3182
|
}
|
|
3163
3183
|
});
|
|
3164
|
-
|
|
3165
|
-
// packages/domain/shared/src/native-resolution.ts
|
|
3166
|
-
function getNodeModuleRef2() {
|
|
3167
|
-
if (isBrowser2) return null;
|
|
3168
|
-
if (nodeModuleRef2 !== null) return nodeModuleRef2;
|
|
3169
|
-
try {
|
|
3170
|
-
const test = typeof __require === "function" ? __require("module") : null;
|
|
3171
|
-
nodeModuleRef2 = test;
|
|
3172
|
-
return test;
|
|
3173
|
-
} catch {
|
|
3174
|
-
nodeModuleRef2 = null;
|
|
3175
|
-
return null;
|
|
3176
|
-
}
|
|
3177
|
-
}
|
|
3178
|
-
function getNodeFs() {
|
|
3179
|
-
if (isBrowser2) return { existsSync: () => false };
|
|
3180
|
-
const nodeRequire = getNodeModuleRef2();
|
|
3181
|
-
if (!nodeRequire) return { existsSync: () => false };
|
|
3182
|
-
if (!_nodeFs) _nodeFs = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)))("node:fs");
|
|
3183
|
-
return _nodeFs;
|
|
3184
|
-
}
|
|
3185
|
-
function getNodePath2() {
|
|
3186
|
-
if (isBrowser2) return { resolve: () => "", dirname: "" };
|
|
3187
|
-
const nodeRequire = getNodeModuleRef2();
|
|
3188
|
-
if (!nodeRequire) return { resolve: () => "", dirname: "" };
|
|
3189
|
-
if (!_nodePath2) _nodePath2 = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)))("node:path");
|
|
3190
|
-
return _nodePath2;
|
|
3191
|
-
}
|
|
3192
|
-
function getRequire(_importMetaUrl) {
|
|
3193
|
-
if (isBrowser2) return () => {
|
|
3194
|
-
throw new Error("node:module not available");
|
|
3195
|
-
};
|
|
3196
|
-
const nodeRequire = getNodeModuleRef2();
|
|
3197
|
-
if (!nodeRequire) return () => {
|
|
3198
|
-
throw new Error("require not available");
|
|
3199
|
-
};
|
|
3200
|
-
if (!_require) _require = nodeRequire.createRequire(_importMetaUrl);
|
|
3201
|
-
return _require;
|
|
3202
|
-
}
|
|
3203
3184
|
function platformKey() {
|
|
3204
3185
|
if (isBrowser2) return "browser";
|
|
3205
3186
|
return `${process.platform}-${process.arch}`;
|
|
@@ -3210,24 +3191,21 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
3210
3191
|
if (isBrowser2) {
|
|
3211
3192
|
return { path: null, source: "not-found", platform, tried: ["not available in browser"] };
|
|
3212
3193
|
}
|
|
3213
|
-
|
|
3214
|
-
|
|
3215
|
-
|
|
3194
|
+
if (process.env.TWS_DISABLE_NATIVE === "1") {
|
|
3195
|
+
return { path: null, source: "not-found", platform, tried: [] };
|
|
3196
|
+
}
|
|
3216
3197
|
const envPath = process.env.TW_NATIVE_PATH?.trim();
|
|
3217
3198
|
if (envPath) {
|
|
3218
|
-
if (
|
|
3199
|
+
if (fs11__namespace.existsSync(envPath)) {
|
|
3219
3200
|
return { path: envPath, source: "env", platform, tried };
|
|
3220
3201
|
}
|
|
3221
3202
|
tried.push(`env:${envPath} (not found)`);
|
|
3222
3203
|
}
|
|
3223
|
-
if (process.env.TWS_NO_NATIVE === "1" || process.env.TWS_NO_RUST === "1" || process.env.TWS_DISABLE_NATIVE === "1") {
|
|
3224
|
-
return { path: null, source: "not-found", platform, tried: ["disabled by env"] };
|
|
3225
|
-
}
|
|
3226
3204
|
const prebuiltPkgs = PLATFORM_MAP[platform] ?? [];
|
|
3227
3205
|
for (const pkg of prebuiltPkgs) {
|
|
3228
3206
|
try {
|
|
3229
|
-
const candidate =
|
|
3230
|
-
if (
|
|
3207
|
+
const candidate = _require.resolve(`${pkg}/tailwind_styled_parser.node`);
|
|
3208
|
+
if (fs11__namespace.existsSync(candidate)) {
|
|
3231
3209
|
return { path: candidate, source: "prebuilt", platform, tried };
|
|
3232
3210
|
}
|
|
3233
3211
|
tried.push(`prebuilt:${pkg} (resolved but missing)`);
|
|
@@ -3237,30 +3215,43 @@ function resolveNativeBinary(runtimeDir) {
|
|
|
3237
3215
|
}
|
|
3238
3216
|
const cwd2 = process.cwd();
|
|
3239
3217
|
const base = runtimeDir ?? cwd2;
|
|
3240
|
-
const
|
|
3241
|
-
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3218
|
+
const napiPlatform = platform === "linux-x64" ? "linux-x64-gnu" : platform === "linux-arm64" ? "linux-arm64-gnu" : platform;
|
|
3219
|
+
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
3220
|
+
const localCandidates = [];
|
|
3221
|
+
for (const bin of BINARY_NAMES) {
|
|
3222
|
+
localCandidates.push(path6__namespace.resolve(base, `${bin}.node`));
|
|
3223
|
+
localCandidates.push(path6__namespace.resolve(base, "..", `${bin}.node`));
|
|
3224
|
+
localCandidates.push(path6__namespace.resolve(base, `${bin}.${platform}.node`));
|
|
3225
|
+
localCandidates.push(path6__namespace.resolve(base, `${bin}.${napiPlatform}.node`));
|
|
3226
|
+
}
|
|
3227
|
+
for (const startDir of [cwd2, base]) {
|
|
3228
|
+
let dir = startDir;
|
|
3229
|
+
for (let i = 0; i < 6; i++) {
|
|
3230
|
+
const nativeDir = path6__namespace.resolve(dir, "native");
|
|
3231
|
+
for (const bin of BINARY_NAMES) {
|
|
3232
|
+
localCandidates.push(path6__namespace.resolve(nativeDir, `${bin}.node`));
|
|
3233
|
+
localCandidates.push(path6__namespace.resolve(nativeDir, `${bin}.${platform}.node`));
|
|
3234
|
+
localCandidates.push(path6__namespace.resolve(nativeDir, `${bin}.${napiPlatform}.node`));
|
|
3235
|
+
localCandidates.push(path6__namespace.resolve(nativeDir, "target", "release", `${bin}.node`));
|
|
3236
|
+
}
|
|
3237
|
+
const parent = path6__namespace.resolve(dir, "..");
|
|
3238
|
+
if (parent === dir) break;
|
|
3239
|
+
dir = parent;
|
|
3240
|
+
}
|
|
3241
|
+
}
|
|
3248
3242
|
for (const candidate of localCandidates) {
|
|
3249
3243
|
tried.push(`local:${candidate}`);
|
|
3250
|
-
if (
|
|
3244
|
+
if (fs11__namespace.existsSync(candidate)) {
|
|
3251
3245
|
return { path: candidate, source: "local", platform, tried };
|
|
3252
3246
|
}
|
|
3253
3247
|
}
|
|
3254
3248
|
return { path: null, source: "not-found", platform, tried };
|
|
3255
3249
|
}
|
|
3256
|
-
var isBrowser2,
|
|
3250
|
+
var isBrowser2, _require, PLATFORM_MAP;
|
|
3257
3251
|
var init_native_resolution = __esm({
|
|
3258
3252
|
"packages/domain/shared/src/native-resolution.ts"() {
|
|
3259
3253
|
isBrowser2 = typeof window !== "undefined" || typeof document !== "undefined";
|
|
3260
|
-
|
|
3261
|
-
_nodeFs = null;
|
|
3262
|
-
_nodePath2 = null;
|
|
3263
|
-
_require = null;
|
|
3254
|
+
_require = typeof __require !== "undefined" ? __require : module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
3264
3255
|
PLATFORM_MAP = {
|
|
3265
3256
|
"linux-x64": ["@tailwind-styled/native-linux-x64"],
|
|
3266
3257
|
"linux-arm64": ["@tailwind-styled/native-linux-arm64"],
|
|
@@ -3271,41 +3262,6 @@ var init_native_resolution = __esm({
|
|
|
3271
3262
|
};
|
|
3272
3263
|
}
|
|
3273
3264
|
});
|
|
3274
|
-
|
|
3275
|
-
// packages/domain/shared/src/index.ts
|
|
3276
|
-
function getNodeModuleRef3() {
|
|
3277
|
-
if (isBrowser3) return null;
|
|
3278
|
-
if (nodeModuleRef3 !== null) return nodeModuleRef3;
|
|
3279
|
-
try {
|
|
3280
|
-
const test = typeof __require === "function" ? __require("module") : null;
|
|
3281
|
-
nodeModuleRef3 = test;
|
|
3282
|
-
return test;
|
|
3283
|
-
} catch {
|
|
3284
|
-
nodeModuleRef3 = null;
|
|
3285
|
-
return null;
|
|
3286
|
-
}
|
|
3287
|
-
}
|
|
3288
|
-
function getNodeFs2() {
|
|
3289
|
-
if (isBrowser3) throw new Error("node:fs not available in browser");
|
|
3290
|
-
const nodeRequire = getNodeModuleRef3();
|
|
3291
|
-
if (!nodeRequire) throw new Error("require not available");
|
|
3292
|
-
if (!_nodeFs2) _nodeFs2 = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)))("node:fs");
|
|
3293
|
-
return _nodeFs2;
|
|
3294
|
-
}
|
|
3295
|
-
function getNodePath3() {
|
|
3296
|
-
if (isBrowser3) throw new Error("node:path not available in browser");
|
|
3297
|
-
const nodeRequire = getNodeModuleRef3();
|
|
3298
|
-
if (!nodeRequire) throw new Error("require not available");
|
|
3299
|
-
if (!_nodePath3) _nodePath3 = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)))("node:path");
|
|
3300
|
-
return _nodePath3;
|
|
3301
|
-
}
|
|
3302
|
-
function getNodeUrl2() {
|
|
3303
|
-
if (isBrowser3) throw new Error("node:url not available in browser");
|
|
3304
|
-
const nodeRequire = getNodeModuleRef3();
|
|
3305
|
-
if (!nodeRequire) throw new Error("require not available");
|
|
3306
|
-
if (!_nodeUrl2) _nodeUrl2 = nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)))("node:url");
|
|
3307
|
-
return _nodeUrl2;
|
|
3308
|
-
}
|
|
3309
3265
|
function createLogger(namespace) {
|
|
3310
3266
|
const prefix = `[${namespace}]`;
|
|
3311
3267
|
return {
|
|
@@ -3335,9 +3291,9 @@ function createDebugLogger(namespace, label) {
|
|
|
3335
3291
|
}
|
|
3336
3292
|
};
|
|
3337
3293
|
}
|
|
3338
|
-
function formatIssuePath(
|
|
3339
|
-
if (!
|
|
3340
|
-
return
|
|
3294
|
+
function formatIssuePath(path29) {
|
|
3295
|
+
if (!path29 || path29.length === 0) return "(root)";
|
|
3296
|
+
return path29.map(
|
|
3341
3297
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
3342
3298
|
).join(".");
|
|
3343
3299
|
}
|
|
@@ -3345,17 +3301,12 @@ function wrapUnknownError(domain, code, error) {
|
|
|
3345
3301
|
return TwError.wrap(domain, code, error);
|
|
3346
3302
|
}
|
|
3347
3303
|
function loadNativeBinding(options) {
|
|
3348
|
-
if (isBrowser3) {
|
|
3349
|
-
return { binding: null, loadErrors: [{ path: "", message: "Native bindings not available in browser" }] };
|
|
3350
|
-
}
|
|
3351
3304
|
const { runtimeDir, candidates, isValid } = options;
|
|
3352
3305
|
const loadErrors = [];
|
|
3353
|
-
const path26 = getNodePath3();
|
|
3354
|
-
const fs12 = getNodeFs2();
|
|
3355
3306
|
for (const candidate of candidates) {
|
|
3356
|
-
const candidatePath =
|
|
3307
|
+
const candidatePath = path6__namespace.default.resolve(runtimeDir, candidate);
|
|
3357
3308
|
try {
|
|
3358
|
-
if (!
|
|
3309
|
+
if (!fs11__namespace.default.existsSync(candidatePath) && !fs11__namespace.default.existsSync(candidatePath + ".node")) {
|
|
3359
3310
|
continue;
|
|
3360
3311
|
}
|
|
3361
3312
|
const mod = requireNativeModule(candidatePath);
|
|
@@ -3369,74 +3320,58 @@ function loadNativeBinding(options) {
|
|
|
3369
3320
|
}
|
|
3370
3321
|
return { binding: null, loadErrors };
|
|
3371
3322
|
}
|
|
3372
|
-
function
|
|
3373
|
-
|
|
3374
|
-
throw new Error("require not available in browser");
|
|
3375
|
-
});
|
|
3376
|
-
const nodeRequire = getNodeModuleRef3();
|
|
3377
|
-
if (!nodeRequire) return (() => {
|
|
3378
|
-
throw new Error("require not available");
|
|
3379
|
-
});
|
|
3380
|
-
return nodeRequire.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
3381
|
-
}
|
|
3382
|
-
function requireNativeModule(path26) {
|
|
3383
|
-
return _require2(path26);
|
|
3323
|
+
function requireNativeModule(p) {
|
|
3324
|
+
return _require2(p);
|
|
3384
3325
|
}
|
|
3385
3326
|
function resolveNativeBindingCandidates(options) {
|
|
3386
|
-
|
|
3387
|
-
|
|
3327
|
+
const {
|
|
3328
|
+
envVarNames = ["TW_NATIVE_PATH", "TWS_NATIVE_PATH"],
|
|
3329
|
+
includeDefaultCandidates = true,
|
|
3330
|
+
enforceNodeExtensionForEnvPath = false
|
|
3331
|
+
} = options;
|
|
3332
|
+
const runtimeDir = options.runtimeDir || process.cwd();
|
|
3388
3333
|
const candidates = [];
|
|
3389
|
-
const path26 = getNodePath3();
|
|
3390
|
-
const fs12 = getNodeFs2();
|
|
3391
3334
|
for (const envVar of envVarNames) {
|
|
3392
3335
|
const envPath = process.env[envVar];
|
|
3393
3336
|
if (envPath) {
|
|
3394
|
-
|
|
3395
|
-
candidates.push(envPath + ".node");
|
|
3396
|
-
} else {
|
|
3397
|
-
candidates.push(envPath);
|
|
3398
|
-
}
|
|
3337
|
+
candidates.push(enforceNodeExtensionForEnvPath && !envPath.endsWith(".node") ? envPath + ".node" : envPath);
|
|
3399
3338
|
}
|
|
3400
3339
|
}
|
|
3401
3340
|
if (!includeDefaultCandidates) return candidates;
|
|
3402
|
-
if (
|
|
3341
|
+
if (fs11__namespace.default.existsSync(runtimeDir)) {
|
|
3403
3342
|
try {
|
|
3404
|
-
const
|
|
3405
|
-
|
|
3406
|
-
if (entry.endsWith(".node")) {
|
|
3407
|
-
candidates.push(entry);
|
|
3408
|
-
}
|
|
3343
|
+
for (const entry of fs11__namespace.default.readdirSync(runtimeDir)) {
|
|
3344
|
+
if (entry.endsWith(".node")) candidates.push(entry);
|
|
3409
3345
|
}
|
|
3410
3346
|
} catch {
|
|
3411
3347
|
}
|
|
3412
3348
|
}
|
|
3413
|
-
const
|
|
3414
|
-
const
|
|
3415
|
-
const
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3349
|
+
const BINARY_NAMES = ["tailwind-styled-native", "tailwind_styled_parser"];
|
|
3350
|
+
const napiPlatform = process.platform === "linux" && process.arch === "x64" ? "linux-x64-gnu" : process.platform === "linux" && process.arch === "arm64" ? "linux-arm64-gnu" : `${process.platform}-${process.arch}`;
|
|
3351
|
+
for (const bin of BINARY_NAMES) {
|
|
3352
|
+
candidates.push(path6__namespace.default.resolve(runtimeDir, `${bin}.node`));
|
|
3353
|
+
candidates.push(path6__namespace.default.resolve(runtimeDir, `${bin}.${napiPlatform}.node`));
|
|
3354
|
+
candidates.push(path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.node`));
|
|
3355
|
+
candidates.push(path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "..", "native", `${bin}.${napiPlatform}.node`));
|
|
3356
|
+
candidates.push(path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "native", `${bin}.node`));
|
|
3357
|
+
candidates.push(path6__namespace.default.resolve(process.cwd(), "native", `${bin}.node`));
|
|
3358
|
+
candidates.push(path6__namespace.default.resolve(process.cwd(), "native", `${bin}.${napiPlatform}.node`));
|
|
3359
|
+
}
|
|
3419
3360
|
return Array.from(new Set(candidates));
|
|
3420
3361
|
}
|
|
3421
3362
|
function resolveRuntimeDir(dir, importMetaUrl) {
|
|
3422
|
-
if (
|
|
3423
|
-
if (dir) return getNodePath3().resolve(dir);
|
|
3363
|
+
if (dir) return path6__namespace.default.resolve(dir);
|
|
3424
3364
|
try {
|
|
3425
|
-
return
|
|
3365
|
+
return path6__namespace.default.dirname(url.fileURLToPath(importMetaUrl));
|
|
3426
3366
|
} catch {
|
|
3427
3367
|
return process.cwd();
|
|
3428
3368
|
}
|
|
3429
3369
|
}
|
|
3430
|
-
var
|
|
3370
|
+
var TwError, _require2;
|
|
3431
3371
|
var init_src = __esm({
|
|
3432
3372
|
"packages/domain/shared/src/index.ts"() {
|
|
3433
3373
|
init_esmHelpers();
|
|
3434
3374
|
init_native_resolution();
|
|
3435
|
-
isBrowser3 = typeof window !== "undefined" || typeof document !== "undefined";
|
|
3436
|
-
nodeModuleRef3 = null;
|
|
3437
|
-
_nodeFs2 = null;
|
|
3438
|
-
_nodePath3 = null;
|
|
3439
|
-
_nodeUrl2 = null;
|
|
3440
3375
|
TwError = class _TwError extends Error {
|
|
3441
3376
|
/** @deprecated Gunakan source */
|
|
3442
3377
|
domain;
|
|
@@ -3470,8 +3405,8 @@ var init_src = __esm({
|
|
|
3470
3405
|
/** Buat TwError dari ZodError — dukung shape Zod v3 (`errors`) dan v4 (`issues`). */
|
|
3471
3406
|
static fromZod(err) {
|
|
3472
3407
|
const first = err.issues?.[0] ?? err.errors?.[0];
|
|
3473
|
-
const
|
|
3474
|
-
const message = first ? `${
|
|
3408
|
+
const path29 = formatIssuePath(first?.path);
|
|
3409
|
+
const message = first ? `${path29}: ${first.message}` : "Schema validation failed";
|
|
3475
3410
|
return new _TwError("validation", "SCHEMA_VALIDATION_FAILED", message, err);
|
|
3476
3411
|
}
|
|
3477
3412
|
static wrap(source, code, err) {
|
|
@@ -3489,21 +3424,33 @@ var init_src = __esm({
|
|
|
3489
3424
|
return `[${this.source.toUpperCase()}:${this.code}] ${this.message}`;
|
|
3490
3425
|
}
|
|
3491
3426
|
};
|
|
3492
|
-
_require2 =
|
|
3427
|
+
_require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
3493
3428
|
}
|
|
3494
3429
|
});
|
|
3495
3430
|
|
|
3496
3431
|
// packages/domain/scanner/src/native-bridge.ts
|
|
3497
3432
|
var native_bridge_exports = {};
|
|
3498
3433
|
__export(native_bridge_exports, {
|
|
3434
|
+
batchExtractClassesNative: () => batchExtractClassesNative,
|
|
3499
3435
|
cachePriorityNative: () => cachePriorityNative,
|
|
3500
3436
|
cacheReadNative: () => cacheReadNative,
|
|
3501
3437
|
cacheWriteNative: () => cacheWriteNative,
|
|
3438
|
+
collectFilesNative: () => collectFilesNative,
|
|
3439
|
+
computeCacheStatsNative: () => computeCacheStatsNative,
|
|
3502
3440
|
extractClassesNative: () => extractClassesNative,
|
|
3441
|
+
generateSubComponentTypesNative: () => generateSubComponentTypesNative,
|
|
3503
3442
|
hasNativeScannerBinding: () => hasNativeScannerBinding,
|
|
3504
3443
|
hashContentNative: () => hashContentNative,
|
|
3505
3444
|
isRustCacheAvailable: () => isRustCacheAvailable,
|
|
3445
|
+
pruneStaleEntriesNative: () => pruneStaleEntriesNative,
|
|
3446
|
+
rebuildWorkspaceResultNative: () => rebuildWorkspaceResultNative,
|
|
3506
3447
|
resetScannerBridgeCache: () => resetScannerBridgeCache,
|
|
3448
|
+
scanCacheGet: () => scanCacheGet,
|
|
3449
|
+
scanCacheInvalidate: () => scanCacheInvalidate,
|
|
3450
|
+
scanCachePut: () => scanCachePut,
|
|
3451
|
+
scanCacheStats: () => scanCacheStats,
|
|
3452
|
+
scanFileNative: () => scanFileNative,
|
|
3453
|
+
scanFilesBatchNative: () => scanFilesBatchNative,
|
|
3507
3454
|
scanWorkspaceNative: () => scanWorkspaceNative
|
|
3508
3455
|
});
|
|
3509
3456
|
function getDirname2() {
|
|
@@ -3511,7 +3458,7 @@ function getDirname2() {
|
|
|
3511
3458
|
return __dirname;
|
|
3512
3459
|
}
|
|
3513
3460
|
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)) }) !== "undefined" && (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))) {
|
|
3514
|
-
return
|
|
3461
|
+
return path6__namespace.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))));
|
|
3515
3462
|
}
|
|
3516
3463
|
return process.cwd();
|
|
3517
3464
|
}
|
|
@@ -3592,6 +3539,95 @@ function cachePriorityNative(mtimeMs, size, cachedMtimeMs, cachedSize, cachedHit
|
|
|
3592
3539
|
}
|
|
3593
3540
|
return result;
|
|
3594
3541
|
}
|
|
3542
|
+
function batchExtractClassesNative(filePaths) {
|
|
3543
|
+
const binding = scannerGetBinding();
|
|
3544
|
+
if (!binding.batchExtractClasses) {
|
|
3545
|
+
throw new Error("FATAL: Native binding 'batchExtractClasses' is required but not available.");
|
|
3546
|
+
}
|
|
3547
|
+
return binding.batchExtractClasses(filePaths) ?? [];
|
|
3548
|
+
}
|
|
3549
|
+
function scanCacheGet(filePath, contentHash) {
|
|
3550
|
+
const binding = scannerGetBinding();
|
|
3551
|
+
if (!binding.scanCacheGet) {
|
|
3552
|
+
throw new Error("FATAL: Native binding 'scanCacheGet' is required but not available.");
|
|
3553
|
+
}
|
|
3554
|
+
return binding.scanCacheGet(filePath, contentHash) ?? null;
|
|
3555
|
+
}
|
|
3556
|
+
function scanCachePut(filePath, contentHash, classes, mtimeMs, size) {
|
|
3557
|
+
const binding = scannerGetBinding();
|
|
3558
|
+
if (!binding.scanCachePut) {
|
|
3559
|
+
throw new Error("FATAL: Native binding 'scanCachePut' is required but not available.");
|
|
3560
|
+
}
|
|
3561
|
+
binding.scanCachePut(filePath, contentHash, classes, mtimeMs, size);
|
|
3562
|
+
}
|
|
3563
|
+
function scanCacheInvalidate(filePath) {
|
|
3564
|
+
const binding = scannerGetBinding();
|
|
3565
|
+
if (!binding.scanCacheInvalidate) {
|
|
3566
|
+
throw new Error("FATAL: Native binding 'scanCacheInvalidate' is required but not available.");
|
|
3567
|
+
}
|
|
3568
|
+
binding.scanCacheInvalidate(filePath);
|
|
3569
|
+
}
|
|
3570
|
+
function scanCacheStats() {
|
|
3571
|
+
const binding = scannerGetBinding();
|
|
3572
|
+
if (!binding.scanCacheStats) {
|
|
3573
|
+
throw new Error("FATAL: Native binding 'scanCacheStats' is required but not available.");
|
|
3574
|
+
}
|
|
3575
|
+
return binding.scanCacheStats();
|
|
3576
|
+
}
|
|
3577
|
+
function scanFileNative(filePath) {
|
|
3578
|
+
const binding = scannerGetBinding();
|
|
3579
|
+
if (!binding.scanFile) {
|
|
3580
|
+
throw new Error("FATAL: Native binding 'scanFile' is required but not available.");
|
|
3581
|
+
}
|
|
3582
|
+
return binding.scanFile(filePath);
|
|
3583
|
+
}
|
|
3584
|
+
function collectFilesNative(root, extensions, ignoreDirs) {
|
|
3585
|
+
const binding = scannerGetBinding();
|
|
3586
|
+
if (!binding.collectFiles) return null;
|
|
3587
|
+
return binding.collectFiles(root, extensions, ignoreDirs);
|
|
3588
|
+
}
|
|
3589
|
+
function scanFilesBatchNative(filePaths) {
|
|
3590
|
+
const binding = scannerGetBinding();
|
|
3591
|
+
if (!binding.scanFilesBatch) {
|
|
3592
|
+
return filePaths.map((fp) => {
|
|
3593
|
+
try {
|
|
3594
|
+
const r = binding.scanFile?.(fp);
|
|
3595
|
+
return r ? { file: r.file, classes: r.classes, hash: r.hash ?? "" } : { file: fp, classes: [], hash: "" };
|
|
3596
|
+
} catch {
|
|
3597
|
+
return { file: fp, classes: [], hash: "" };
|
|
3598
|
+
}
|
|
3599
|
+
});
|
|
3600
|
+
}
|
|
3601
|
+
return binding.scanFilesBatch(filePaths);
|
|
3602
|
+
}
|
|
3603
|
+
function generateSubComponentTypesNative(root, outputPath) {
|
|
3604
|
+
const binding = scannerGetBinding();
|
|
3605
|
+
if (!binding.generateSubComponentTypes) return null;
|
|
3606
|
+
return binding.generateSubComponentTypes(root, outputPath ?? null);
|
|
3607
|
+
}
|
|
3608
|
+
function pruneStaleEntriesNative(entries, maxAgeMs, checkExists) {
|
|
3609
|
+
const binding = scannerGetBinding();
|
|
3610
|
+
if (!binding.pruneStaleEntries) return null;
|
|
3611
|
+
return binding.pruneStaleEntries(
|
|
3612
|
+
entries.map((e) => ({ file: e.file, lastSeenMs: e.lastSeenMs ?? 0 })),
|
|
3613
|
+
maxAgeMs ?? null,
|
|
3614
|
+
checkExists ?? null
|
|
3615
|
+
);
|
|
3616
|
+
}
|
|
3617
|
+
function rebuildWorkspaceResultNative(files) {
|
|
3618
|
+
const binding = scannerBridgeLoader.get();
|
|
3619
|
+
if (!binding?.rebuildWorkspaceResult) return null;
|
|
3620
|
+
try {
|
|
3621
|
+
return binding.rebuildWorkspaceResult(files);
|
|
3622
|
+
} catch {
|
|
3623
|
+
return null;
|
|
3624
|
+
}
|
|
3625
|
+
}
|
|
3626
|
+
function computeCacheStatsNative(filesClasses, sizes, top) {
|
|
3627
|
+
const binding = scannerGetBinding();
|
|
3628
|
+
if (!binding.computeCacheStats) return null;
|
|
3629
|
+
return binding.computeCacheStats(filesClasses, sizes, top ?? null);
|
|
3630
|
+
}
|
|
3595
3631
|
var log, isValidScannerBinding, createScannerBridgeLoader, scannerBridgeLoader, scannerGetBinding, resetScannerBridgeCache;
|
|
3596
3632
|
var init_native_bridge = __esm({
|
|
3597
3633
|
"packages/domain/scanner/src/native-bridge.ts"() {
|
|
@@ -3676,8 +3712,8 @@ var init_native_bridge = __esm({
|
|
|
3676
3712
|
}
|
|
3677
3713
|
});
|
|
3678
3714
|
function defaultCachePath(rootDir, cacheDir) {
|
|
3679
|
-
const dir = cacheDir ?
|
|
3680
|
-
return
|
|
3715
|
+
const dir = cacheDir ? path6__namespace.default.resolve(rootDir, cacheDir) : path6__namespace.default.join(process.cwd(), ".cache", "tailwind-styled");
|
|
3716
|
+
return path6__namespace.default.join(dir, "scanner-cache.json");
|
|
3681
3717
|
}
|
|
3682
3718
|
function readCache(rootDir, cacheDir) {
|
|
3683
3719
|
const cachePath = defaultCachePath(rootDir, cacheDir);
|
|
@@ -3718,16 +3754,117 @@ var init_cache_native = __esm({
|
|
|
3718
3754
|
init_native_bridge();
|
|
3719
3755
|
}
|
|
3720
3756
|
});
|
|
3757
|
+
function collectFiles(rootDir, extensions, ignoreDirs) {
|
|
3758
|
+
const native = collectFilesNative(rootDir, extensions, ignoreDirs);
|
|
3759
|
+
if (native !== null) return native;
|
|
3760
|
+
const files = [];
|
|
3761
|
+
function walk(dir) {
|
|
3762
|
+
let entries;
|
|
3763
|
+
try {
|
|
3764
|
+
entries = fs11__namespace.default.readdirSync(dir, { withFileTypes: true });
|
|
3765
|
+
} catch {
|
|
3766
|
+
return;
|
|
3767
|
+
}
|
|
3768
|
+
for (const entry of entries) {
|
|
3769
|
+
const fullPath = path6__namespace.default.join(dir, entry.name);
|
|
3770
|
+
const rel = path6__namespace.default.relative(rootDir, fullPath);
|
|
3771
|
+
if (entry.isDirectory()) {
|
|
3772
|
+
const ignored = ignoreDirs.some((d) => entry.name === d || rel.startsWith(d + path6__namespace.default.sep));
|
|
3773
|
+
if (!ignored) walk(fullPath);
|
|
3774
|
+
} else if (isScannableFile(entry.name, extensions)) {
|
|
3775
|
+
files.push(fullPath);
|
|
3776
|
+
}
|
|
3777
|
+
}
|
|
3778
|
+
}
|
|
3779
|
+
walk(rootDir);
|
|
3780
|
+
return files;
|
|
3781
|
+
}
|
|
3782
|
+
function mergeResults(batchResults) {
|
|
3783
|
+
const files = batchResults.map((r) => ({
|
|
3784
|
+
file: r.file,
|
|
3785
|
+
classes: r.classes,
|
|
3786
|
+
hash: r.content_hash
|
|
3787
|
+
}));
|
|
3788
|
+
const native = rebuildWorkspaceResultNative(files);
|
|
3789
|
+
if (native) return native;
|
|
3790
|
+
const unique = new Set(files.flatMap((f) => f.classes));
|
|
3791
|
+
return { files, totalFiles: files.length, uniqueClasses: Array.from(unique).sort() };
|
|
3792
|
+
}
|
|
3793
|
+
function runChunkInWorker(filePaths) {
|
|
3794
|
+
return new Promise((resolve2, reject) => {
|
|
3795
|
+
const worker = new worker_threads.Worker(_workerFilename, {
|
|
3796
|
+
workerData: { filePaths }
|
|
3797
|
+
});
|
|
3798
|
+
worker.once("message", (payload) => {
|
|
3799
|
+
if (payload.ok) {
|
|
3800
|
+
resolve2(payload.results);
|
|
3801
|
+
} else {
|
|
3802
|
+
reject(new Error(payload.error ?? "parallel-scanner worker failed"));
|
|
3803
|
+
}
|
|
3804
|
+
});
|
|
3805
|
+
worker.once("error", reject);
|
|
3806
|
+
worker.once("exit", (code) => {
|
|
3807
|
+
if (code !== 0) reject(new Error(`parallel-scanner worker exited with code ${code}`));
|
|
3808
|
+
});
|
|
3809
|
+
});
|
|
3810
|
+
}
|
|
3811
|
+
async function scanWorkspaceParallel(rootDir, options = {}) {
|
|
3812
|
+
const {
|
|
3813
|
+
extensions = DEFAULT_EXTENSIONS,
|
|
3814
|
+
ignoreDirs = DEFAULT_IGNORES,
|
|
3815
|
+
maxWorkers = Math.max(1, os.availableParallelism() - 1),
|
|
3816
|
+
chunkSize = DEFAULT_CHUNK_SIZE
|
|
3817
|
+
} = options;
|
|
3818
|
+
const files = collectFiles(path6__namespace.default.resolve(rootDir), extensions, ignoreDirs);
|
|
3819
|
+
if (files.length < PARALLEL_THRESHOLD) {
|
|
3820
|
+
return mergeResults(batchExtractClassesNative(files));
|
|
3821
|
+
}
|
|
3822
|
+
const chunks = [];
|
|
3823
|
+
for (let i = 0; i < files.length; i += chunkSize) {
|
|
3824
|
+
chunks.push(files.slice(i, i + chunkSize));
|
|
3825
|
+
}
|
|
3826
|
+
const allResults = [];
|
|
3827
|
+
for (let i = 0; i < chunks.length; i += maxWorkers) {
|
|
3828
|
+
const batch = chunks.slice(i, i + maxWorkers);
|
|
3829
|
+
const batchResults = await Promise.all(batch.map(runChunkInWorker));
|
|
3830
|
+
allResults.push(...batchResults.flat());
|
|
3831
|
+
}
|
|
3832
|
+
return mergeResults(allResults);
|
|
3833
|
+
}
|
|
3834
|
+
var PARALLEL_THRESHOLD, DEFAULT_CHUNK_SIZE, _workerFilename;
|
|
3835
|
+
var init_parallel_scanner = __esm({
|
|
3836
|
+
"packages/domain/scanner/src/parallel-scanner.ts"() {
|
|
3837
|
+
init_src2();
|
|
3838
|
+
init_native_bridge();
|
|
3839
|
+
PARALLEL_THRESHOLD = 50;
|
|
3840
|
+
DEFAULT_CHUNK_SIZE = 150;
|
|
3841
|
+
if (!worker_threads.isMainThread && worker_threads.parentPort) {
|
|
3842
|
+
const { filePaths } = worker_threads.workerData;
|
|
3843
|
+
try {
|
|
3844
|
+
const results = batchExtractClassesNative(filePaths);
|
|
3845
|
+
const msg = { ok: true, results };
|
|
3846
|
+
worker_threads.parentPort.postMessage(msg);
|
|
3847
|
+
} catch (error) {
|
|
3848
|
+
const msg = {
|
|
3849
|
+
ok: false,
|
|
3850
|
+
error: error instanceof Error ? error.message : String(error)
|
|
3851
|
+
};
|
|
3852
|
+
worker_threads.parentPort.postMessage(msg);
|
|
3853
|
+
}
|
|
3854
|
+
}
|
|
3855
|
+
_workerFilename = typeof __filename !== "undefined" ? __filename : url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
3856
|
+
}
|
|
3857
|
+
});
|
|
3721
3858
|
var formatIssuePath2, formatIssues, parseWithSchema, NonNegativeIntegerSchema, ScanWorkspaceOptionsSchema, ScanFileResultSchema, ScanWorkspaceResultSchema, ScannerWorkerSuccessMessageSchema, ScannerWorkerErrorMessageSchema, ScannerWorkerMessageSchema, parseScanWorkspaceOptions, parseScanWorkspaceResult, parseScannerWorkerMessage;
|
|
3722
3859
|
var init_schemas = __esm({
|
|
3723
3860
|
"packages/domain/scanner/src/schemas.ts"() {
|
|
3724
3861
|
init_src();
|
|
3725
|
-
formatIssuePath2 = (
|
|
3862
|
+
formatIssuePath2 = (path29) => path29.length > 0 ? path29.map(
|
|
3726
3863
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
3727
3864
|
).join(".") : "<root>";
|
|
3728
3865
|
formatIssues = (error) => error.issues.map((issue) => {
|
|
3729
|
-
const
|
|
3730
|
-
return `${
|
|
3866
|
+
const path29 = formatIssuePath2(issue.path);
|
|
3867
|
+
return `${path29}: ${issue.message}`;
|
|
3731
3868
|
}).join("; ");
|
|
3732
3869
|
parseWithSchema = (schema, data, label) => {
|
|
3733
3870
|
const parsed = schema.safeParse(data);
|
|
@@ -3782,12 +3919,29 @@ var init_schemas = __esm({
|
|
|
3782
3919
|
parseScannerWorkerMessage = (message) => parseWithSchema(ScannerWorkerMessageSchema, message, "scanner worker message is invalid");
|
|
3783
3920
|
}
|
|
3784
3921
|
});
|
|
3922
|
+
|
|
3923
|
+
// packages/domain/scanner/src/index.ts
|
|
3924
|
+
var src_exports = {};
|
|
3925
|
+
__export(src_exports, {
|
|
3926
|
+
DEFAULT_EXTENSIONS: () => DEFAULT_EXTENSIONS,
|
|
3927
|
+
DEFAULT_IGNORES: () => DEFAULT_IGNORES,
|
|
3928
|
+
batchExtractClassesNative: () => batchExtractClassesNative,
|
|
3929
|
+
extractClassesNative: () => extractClassesNative,
|
|
3930
|
+
isScannableFile: () => isScannableFile,
|
|
3931
|
+
parseScanWorkspaceOptions: () => parseScanWorkspaceOptions,
|
|
3932
|
+
parseScanWorkspaceResult: () => parseScanWorkspaceResult,
|
|
3933
|
+
parseScannerWorkerMessage: () => parseScannerWorkerMessage,
|
|
3934
|
+
scanFile: () => scanFile,
|
|
3935
|
+
scanSource: () => scanSource,
|
|
3936
|
+
scanWorkspace: () => scanWorkspace,
|
|
3937
|
+
scanWorkspaceAsync: () => scanWorkspaceAsync
|
|
3938
|
+
});
|
|
3785
3939
|
function getRuntimeDir() {
|
|
3786
3940
|
if (typeof __dirname !== "undefined" && __dirname.length > 0) {
|
|
3787
3941
|
return __dirname;
|
|
3788
3942
|
}
|
|
3789
3943
|
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)) }) !== "undefined" && (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))) {
|
|
3790
|
-
return
|
|
3944
|
+
return path6__namespace.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))));
|
|
3791
3945
|
}
|
|
3792
3946
|
return process.cwd();
|
|
3793
3947
|
}
|
|
@@ -3797,17 +3951,17 @@ function resolveScannerWorkerModulePath() {
|
|
|
3797
3951
|
return __dirname;
|
|
3798
3952
|
}
|
|
3799
3953
|
if (typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)) }) !== "undefined" && (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))) {
|
|
3800
|
-
return
|
|
3954
|
+
return path6__namespace.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href))));
|
|
3801
3955
|
}
|
|
3802
3956
|
return process.cwd();
|
|
3803
3957
|
})();
|
|
3804
3958
|
const candidates = [
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3959
|
+
path6__namespace.default.resolve(runtimeDir, "worker.cjs"),
|
|
3960
|
+
path6__namespace.default.resolve(runtimeDir, "worker.js"),
|
|
3961
|
+
path6__namespace.default.resolve(runtimeDir, "worker.ts")
|
|
3808
3962
|
];
|
|
3809
3963
|
for (const candidate of candidates) {
|
|
3810
|
-
if (
|
|
3964
|
+
if (fs11__namespace.default.existsSync(candidate)) return candidate;
|
|
3811
3965
|
}
|
|
3812
3966
|
return null;
|
|
3813
3967
|
}
|
|
@@ -3817,7 +3971,7 @@ function scanWorkspaceInWorker(rootDir, options) {
|
|
|
3817
3971
|
if (!modulePath) {
|
|
3818
3972
|
return Promise.reject(new Error("scanner worker module path could not be resolved"));
|
|
3819
3973
|
}
|
|
3820
|
-
return new Promise((
|
|
3974
|
+
return new Promise((resolve2, reject) => {
|
|
3821
3975
|
const settleState = { settled: false };
|
|
3822
3976
|
const worker = new worker_threads.Worker(modulePath, { workerData: { rootDir, options: normalizedOptions } });
|
|
3823
3977
|
const timeout = setTimeout(() => {
|
|
@@ -3837,7 +3991,7 @@ function scanWorkspaceInWorker(rootDir, options) {
|
|
|
3837
3991
|
const message = parseScannerWorkerMessage(payload);
|
|
3838
3992
|
finish(() => {
|
|
3839
3993
|
if (message?.ok) {
|
|
3840
|
-
|
|
3994
|
+
resolve2(parseScanWorkspaceResult(message.result));
|
|
3841
3995
|
return;
|
|
3842
3996
|
}
|
|
3843
3997
|
reject(new Error(message?.error ?? "scanner worker failed without an error message"));
|
|
@@ -3864,19 +4018,19 @@ function collectCandidates(rootDir, ignoreDirectories, extensionSet) {
|
|
|
3864
4018
|
if (!currentDir) continue;
|
|
3865
4019
|
const entries = (() => {
|
|
3866
4020
|
try {
|
|
3867
|
-
return
|
|
4021
|
+
return fs11__namespace.default.readdirSync(currentDir, { withFileTypes: true });
|
|
3868
4022
|
} catch {
|
|
3869
4023
|
return [];
|
|
3870
4024
|
}
|
|
3871
4025
|
})();
|
|
3872
4026
|
for (const entry of entries) {
|
|
3873
|
-
const fullPath =
|
|
4027
|
+
const fullPath = path6__namespace.default.join(currentDir, entry.name);
|
|
3874
4028
|
if (entry.isDirectory()) {
|
|
3875
4029
|
if (!ignoreDirectories.has(entry.name)) directories.push(fullPath);
|
|
3876
4030
|
continue;
|
|
3877
4031
|
}
|
|
3878
4032
|
if (!entry.isFile()) continue;
|
|
3879
|
-
if (!extensionSet.has(
|
|
4033
|
+
if (!extensionSet.has(path6__namespace.default.extname(entry.name))) continue;
|
|
3880
4034
|
candidates.push(fullPath);
|
|
3881
4035
|
}
|
|
3882
4036
|
}
|
|
@@ -3890,9 +4044,12 @@ function toCacheSize(size) {
|
|
|
3890
4044
|
function scanSource(source) {
|
|
3891
4045
|
const nativeBinding = nativeParserLoader.get();
|
|
3892
4046
|
if (nativeBinding?.extractClassesFromSource) {
|
|
3893
|
-
const
|
|
3894
|
-
if (Array.isArray(
|
|
3895
|
-
return Array.from(new Set(
|
|
4047
|
+
const result = nativeBinding.extractClassesFromSource(source);
|
|
4048
|
+
if (Array.isArray(result)) {
|
|
4049
|
+
return Array.from(new Set(result.filter(Boolean)));
|
|
4050
|
+
}
|
|
4051
|
+
if (result !== null && result !== void 0 && Array.isArray(result.classes)) {
|
|
4052
|
+
return Array.from(new Set(result.classes.filter(Boolean)));
|
|
3896
4053
|
}
|
|
3897
4054
|
}
|
|
3898
4055
|
throw new Error(
|
|
@@ -3900,15 +4057,18 @@ function scanSource(source) {
|
|
|
3900
4057
|
);
|
|
3901
4058
|
}
|
|
3902
4059
|
function isScannableFile(filePath, includeExtensions = DEFAULT_EXTENSIONS) {
|
|
3903
|
-
return includeExtensions.includes(
|
|
4060
|
+
return includeExtensions.includes(path6__namespace.default.extname(filePath));
|
|
3904
4061
|
}
|
|
3905
4062
|
function scanFile(filePath) {
|
|
3906
|
-
const
|
|
3907
|
-
const
|
|
4063
|
+
const { scanFileNative: scanFileNative2 } = (init_native_bridge(), __toCommonJS(native_bridge_exports));
|
|
4064
|
+
const result = scanFileNative2(filePath);
|
|
4065
|
+
if (!result.ok) {
|
|
4066
|
+
throw new Error(`scanFile failed for ${filePath}: ${result.error ?? "unknown error"}`);
|
|
4067
|
+
}
|
|
3908
4068
|
return {
|
|
3909
|
-
file:
|
|
3910
|
-
classes:
|
|
3911
|
-
...hash ? { hash } : {}
|
|
4069
|
+
file: result.file,
|
|
4070
|
+
classes: result.classes,
|
|
4071
|
+
...result.hash ? { hash: result.hash } : {}
|
|
3912
4072
|
};
|
|
3913
4073
|
}
|
|
3914
4074
|
function scanWorkspace(rootDir, options = {}) {
|
|
@@ -3957,7 +4117,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
3957
4117
|
for (const filePath of candidates) {
|
|
3958
4118
|
const stat = (() => {
|
|
3959
4119
|
try {
|
|
3960
|
-
return
|
|
4120
|
+
return fs11__namespace.default.statSync(filePath);
|
|
3961
4121
|
} catch {
|
|
3962
4122
|
return null;
|
|
3963
4123
|
}
|
|
@@ -3983,7 +4143,7 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
3983
4143
|
for (const { filePath, stat, size, cached } of ranked) {
|
|
3984
4144
|
const content = (() => {
|
|
3985
4145
|
try {
|
|
3986
|
-
return
|
|
4146
|
+
return fs11__namespace.default.readFileSync(filePath, "utf8");
|
|
3987
4147
|
} catch {
|
|
3988
4148
|
return null;
|
|
3989
4149
|
}
|
|
@@ -4045,14 +4205,21 @@ function scanWorkspace(rootDir, options = {}) {
|
|
|
4045
4205
|
}
|
|
4046
4206
|
async function scanWorkspaceAsync(rootDir, options = {}) {
|
|
4047
4207
|
const normalizedOptions = parseScanWorkspaceOptions(options);
|
|
4048
|
-
|
|
4049
|
-
return
|
|
4208
|
+
try {
|
|
4209
|
+
return await scanWorkspaceParallel(rootDir, {
|
|
4210
|
+
extensions: normalizedOptions.includeExtensions,
|
|
4211
|
+
ignoreDirs: normalizedOptions.ignoreDirectories
|
|
4212
|
+
});
|
|
4213
|
+
} catch (parallelError) {
|
|
4214
|
+
log2.debug(
|
|
4215
|
+
`parallel scan failed, retrying with single worker: ${parallelError instanceof Error ? parallelError.message : String(parallelError)}`
|
|
4216
|
+
);
|
|
4050
4217
|
}
|
|
4051
4218
|
try {
|
|
4052
4219
|
return await scanWorkspaceInWorker(rootDir, normalizedOptions);
|
|
4053
4220
|
} catch (error) {
|
|
4054
4221
|
log2.debug(
|
|
4055
|
-
`worker scan failed,
|
|
4222
|
+
`worker scan failed, retrying with sync native scanner: ${error instanceof Error ? error.message : String(error)}`
|
|
4056
4223
|
);
|
|
4057
4224
|
return scanWorkspace(rootDir, normalizedOptions);
|
|
4058
4225
|
}
|
|
@@ -4063,7 +4230,10 @@ var init_src2 = __esm({
|
|
|
4063
4230
|
init_src();
|
|
4064
4231
|
init_cache_native();
|
|
4065
4232
|
init_native_bridge();
|
|
4233
|
+
init_parallel_scanner();
|
|
4066
4234
|
init_schemas();
|
|
4235
|
+
init_schemas();
|
|
4236
|
+
init_native_bridge();
|
|
4067
4237
|
log2 = createLogger("scanner");
|
|
4068
4238
|
SCAN_WORKER_TIMEOUT_MS = 12e4;
|
|
4069
4239
|
createNativeParserLoader = () => {
|
|
@@ -4077,12 +4247,25 @@ var init_src2 = __esm({
|
|
|
4077
4247
|
const loadNativeParserBinding = () => {
|
|
4078
4248
|
if (_state.binding !== void 0) return _state.binding;
|
|
4079
4249
|
const runtimeDir = getRuntimeDir();
|
|
4080
|
-
const req = module$1.createRequire(
|
|
4250
|
+
const req = module$1.createRequire(path6__namespace.default.join(runtimeDir, "noop.cjs"));
|
|
4081
4251
|
const candidates = [
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4252
|
+
// ── binaryName baru: tailwind-styled-native (napi-rs naming) ──
|
|
4253
|
+
// cwd = repo root saat run dari root, atau package dir saat workspaces
|
|
4254
|
+
path6__namespace.default.resolve(process.cwd(), "native", "tailwind-styled-native.node"),
|
|
4255
|
+
path6__namespace.default.resolve(process.cwd(), "native", `tailwind-styled-native.${process.platform}-${process.arch}.node`),
|
|
4256
|
+
path6__namespace.default.resolve(process.cwd(), "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
|
|
4257
|
+
// runtimeDir = dist/ → naik 4 level ke repo root
|
|
4258
|
+
path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
4259
|
+
path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "..", "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
|
|
4260
|
+
// 3 level fallback (jika package di-nest lebih dangkal)
|
|
4261
|
+
path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind-styled-native.node"),
|
|
4262
|
+
path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "native", `tailwind-styled-native.${process.platform}-${process.arch}-gnu.node`),
|
|
4263
|
+
// ── binaryName lama: tailwind_styled_parser (backward compat) ──
|
|
4264
|
+
path6__namespace.default.resolve(process.cwd(), "native/tailwind_styled_parser.node"),
|
|
4265
|
+
path6__namespace.default.resolve(process.cwd(), "native/build/Release/tailwind_styled_parser.node"),
|
|
4266
|
+
path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
4267
|
+
path6__namespace.default.resolve(runtimeDir, "..", "..", "..", "native", "tailwind_styled_parser.node"),
|
|
4268
|
+
path6__namespace.default.resolve(
|
|
4086
4269
|
runtimeDir,
|
|
4087
4270
|
"..",
|
|
4088
4271
|
"..",
|
|
@@ -4094,7 +4277,7 @@ var init_src2 = __esm({
|
|
|
4094
4277
|
)
|
|
4095
4278
|
];
|
|
4096
4279
|
for (const fullPath of candidates) {
|
|
4097
|
-
if (!
|
|
4280
|
+
if (!fs11__namespace.default.existsSync(fullPath)) continue;
|
|
4098
4281
|
try {
|
|
4099
4282
|
const required = req(fullPath);
|
|
4100
4283
|
if (required && (typeof required.extractClassesFromSource === "function" || typeof required.parseClasses === "function" || typeof required.parse_classes === "function")) {
|
|
@@ -4136,7 +4319,7 @@ function isRecord(value) {
|
|
|
4136
4319
|
}
|
|
4137
4320
|
async function pathExists(filePath) {
|
|
4138
4321
|
try {
|
|
4139
|
-
await
|
|
4322
|
+
await fs11__namespace.default.promises.access(filePath, fs11__namespace.default.constants.F_OK);
|
|
4140
4323
|
return true;
|
|
4141
4324
|
} catch {
|
|
4142
4325
|
return false;
|
|
@@ -4162,6 +4345,9 @@ var init_utils = __esm({
|
|
|
4162
4345
|
});
|
|
4163
4346
|
|
|
4164
4347
|
// packages/domain/analyzer/src/binding.ts
|
|
4348
|
+
async function getNativeBinding() {
|
|
4349
|
+
return analyzerBindingLoader.get();
|
|
4350
|
+
}
|
|
4165
4351
|
async function requireNativeBinding() {
|
|
4166
4352
|
const binding = await analyzerBindingLoader.get();
|
|
4167
4353
|
if (binding?.analyzeClasses) return binding;
|
|
@@ -4254,7 +4440,7 @@ var formatIssuePath3, isPlainObject, formatIssues2, parseWithSchema2, CountSchem
|
|
|
4254
4440
|
var init_schemas2 = __esm({
|
|
4255
4441
|
"packages/domain/analyzer/src/schemas.ts"() {
|
|
4256
4442
|
init_src();
|
|
4257
|
-
formatIssuePath3 = (
|
|
4443
|
+
formatIssuePath3 = (path29) => path29.length > 0 ? path29.map(
|
|
4258
4444
|
(segment) => typeof segment === "symbol" ? segment.description ?? segment.toString() : String(segment)
|
|
4259
4445
|
).join(".") : "<root>";
|
|
4260
4446
|
isPlainObject = (value) => {
|
|
@@ -4263,8 +4449,8 @@ var init_schemas2 = __esm({
|
|
|
4263
4449
|
return proto === Object.prototype || proto === null;
|
|
4264
4450
|
};
|
|
4265
4451
|
formatIssues2 = (error) => error.issues.map((issue) => {
|
|
4266
|
-
const
|
|
4267
|
-
return `${
|
|
4452
|
+
const path29 = formatIssuePath3(issue.path);
|
|
4453
|
+
return `${path29}: ${issue.message}`;
|
|
4268
4454
|
}).join("; ");
|
|
4269
4455
|
parseWithSchema2 = (schema, data, label) => {
|
|
4270
4456
|
const parsed = schema.safeParse(data);
|
|
@@ -4360,117 +4546,12 @@ var init_schemas2 = __esm({
|
|
|
4360
4546
|
parseClassToCssOptions = (options) => parseWithSchema2(ClassToCssOptionsSchema, options ?? {}, "classToCss options are invalid");
|
|
4361
4547
|
}
|
|
4362
4548
|
});
|
|
4363
|
-
var SUPPORTED_TAILWIND_CONFIG_EXTENSIONS,
|
|
4549
|
+
var SUPPORTED_TAILWIND_CONFIG_EXTENSIONS, tailwindConfigCache, splitVariantAndBase, isArbitraryUtility, resolveConflictGroup, detectConflicts, isSupportedTailwindConfigPath, resolveTailwindConfigPath, collectSafelistFromConfig, collectCustomUtilities, collectSafelistFromSource, loadTailwindConfig, utilityPrefix, buildSemanticReport;
|
|
4364
4550
|
var init_semantic = __esm({
|
|
4365
4551
|
"packages/domain/analyzer/src/semantic.ts"() {
|
|
4552
|
+
init_binding();
|
|
4366
4553
|
init_utils();
|
|
4367
4554
|
SUPPORTED_TAILWIND_CONFIG_EXTENSIONS = /* @__PURE__ */ new Set([".ts", ".js", ".cjs", ".mjs"]);
|
|
4368
|
-
KNOWN_UTILITY_PREFIXES = /* @__PURE__ */ new Set([
|
|
4369
|
-
"absolute",
|
|
4370
|
-
"align",
|
|
4371
|
-
"animate",
|
|
4372
|
-
"arbitrary",
|
|
4373
|
-
"aspect",
|
|
4374
|
-
"backdrop",
|
|
4375
|
-
"basis",
|
|
4376
|
-
"bg",
|
|
4377
|
-
"block",
|
|
4378
|
-
"border",
|
|
4379
|
-
"bottom",
|
|
4380
|
-
"col",
|
|
4381
|
-
"container",
|
|
4382
|
-
"contents",
|
|
4383
|
-
"cursor",
|
|
4384
|
-
"dark",
|
|
4385
|
-
"display",
|
|
4386
|
-
"divide",
|
|
4387
|
-
"fill",
|
|
4388
|
-
"fixed",
|
|
4389
|
-
"flex",
|
|
4390
|
-
"float",
|
|
4391
|
-
"font",
|
|
4392
|
-
"from",
|
|
4393
|
-
"gap",
|
|
4394
|
-
"grid",
|
|
4395
|
-
"grow",
|
|
4396
|
-
"h",
|
|
4397
|
-
"hidden",
|
|
4398
|
-
"inset",
|
|
4399
|
-
"inline",
|
|
4400
|
-
"isolate",
|
|
4401
|
-
"items",
|
|
4402
|
-
"justify",
|
|
4403
|
-
"left",
|
|
4404
|
-
"leading",
|
|
4405
|
-
"line",
|
|
4406
|
-
"list",
|
|
4407
|
-
"m",
|
|
4408
|
-
"max-h",
|
|
4409
|
-
"max-w",
|
|
4410
|
-
"mb",
|
|
4411
|
-
"min-h",
|
|
4412
|
-
"min-w",
|
|
4413
|
-
"ml",
|
|
4414
|
-
"mr",
|
|
4415
|
-
"mt",
|
|
4416
|
-
"mx",
|
|
4417
|
-
"my",
|
|
4418
|
-
"object",
|
|
4419
|
-
"opacity",
|
|
4420
|
-
"order",
|
|
4421
|
-
"origin",
|
|
4422
|
-
"outline",
|
|
4423
|
-
"overflow",
|
|
4424
|
-
"overscroll",
|
|
4425
|
-
"p",
|
|
4426
|
-
"pb",
|
|
4427
|
-
"pe",
|
|
4428
|
-
"perspective",
|
|
4429
|
-
"place",
|
|
4430
|
-
"pl",
|
|
4431
|
-
"pointer",
|
|
4432
|
-
"position",
|
|
4433
|
-
"pr",
|
|
4434
|
-
"ps",
|
|
4435
|
-
"pt",
|
|
4436
|
-
"px",
|
|
4437
|
-
"py",
|
|
4438
|
-
"relative",
|
|
4439
|
-
"right",
|
|
4440
|
-
"ring",
|
|
4441
|
-
"rotate",
|
|
4442
|
-
"rounded",
|
|
4443
|
-
"row",
|
|
4444
|
-
"scale",
|
|
4445
|
-
"shadow",
|
|
4446
|
-
"shrink",
|
|
4447
|
-
"size",
|
|
4448
|
-
"skew",
|
|
4449
|
-
"snap",
|
|
4450
|
-
"space-x",
|
|
4451
|
-
"space-y",
|
|
4452
|
-
"sr",
|
|
4453
|
-
"start",
|
|
4454
|
-
"static",
|
|
4455
|
-
"sticky",
|
|
4456
|
-
"stroke",
|
|
4457
|
-
"table",
|
|
4458
|
-
"text",
|
|
4459
|
-
"to",
|
|
4460
|
-
"top",
|
|
4461
|
-
"touch",
|
|
4462
|
-
"tracking",
|
|
4463
|
-
"transform",
|
|
4464
|
-
"transition",
|
|
4465
|
-
"translate",
|
|
4466
|
-
"truncate",
|
|
4467
|
-
"underline",
|
|
4468
|
-
"via",
|
|
4469
|
-
"visible",
|
|
4470
|
-
"w",
|
|
4471
|
-
"whitespace",
|
|
4472
|
-
"z"
|
|
4473
|
-
]);
|
|
4474
4555
|
tailwindConfigCache = /* @__PURE__ */ new Map();
|
|
4475
4556
|
splitVariantAndBase = (className) => {
|
|
4476
4557
|
const parts = className.split(":");
|
|
@@ -4500,48 +4581,28 @@ var init_semantic = __esm({
|
|
|
4500
4581
|
if (base.startsWith("m-") || base.startsWith("mx-") || base.startsWith("my-")) return "margin";
|
|
4501
4582
|
return null;
|
|
4502
4583
|
};
|
|
4503
|
-
detectConflicts = (usages) => {
|
|
4504
|
-
const
|
|
4505
|
-
|
|
4506
|
-
|
|
4507
|
-
const group = resolveConflictGroup(base);
|
|
4508
|
-
if (!group) continue;
|
|
4509
|
-
const key = `${variantKey}::${group}`;
|
|
4510
|
-
const bucket = buckets.get(key) ?? {
|
|
4511
|
-
variantKey,
|
|
4512
|
-
group,
|
|
4513
|
-
classes: /* @__PURE__ */ new Set()
|
|
4514
|
-
};
|
|
4515
|
-
bucket.classes.add(usage.name);
|
|
4516
|
-
buckets.set(key, bucket);
|
|
4517
|
-
}
|
|
4518
|
-
const conflicts = [];
|
|
4519
|
-
const conflictedClassNames = /* @__PURE__ */ new Set();
|
|
4520
|
-
for (const bucket of buckets.values()) {
|
|
4521
|
-
if (bucket.classes.size <= 1) continue;
|
|
4522
|
-
const classes = Array.from(bucket.classes).sort();
|
|
4523
|
-
for (const className of classes) conflictedClassNames.add(className);
|
|
4524
|
-
const variantLabel = bucket.variantKey.length > 0 ? bucket.variantKey : "base";
|
|
4525
|
-
conflicts.push({
|
|
4526
|
-
className: bucket.group,
|
|
4527
|
-
variants: bucket.variantKey.length > 0 ? bucket.variantKey.split(":") : [],
|
|
4528
|
-
classes,
|
|
4529
|
-
message: `Multiple ${bucket.group} utilities detected for "${variantLabel}".`
|
|
4530
|
-
});
|
|
4584
|
+
detectConflicts = async (usages) => {
|
|
4585
|
+
const native = await getNativeBinding();
|
|
4586
|
+
if (!native?.detectClassConflicts) {
|
|
4587
|
+
throw new Error("FATAL: Native binding 'detectClassConflicts' is required but not available.");
|
|
4531
4588
|
}
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4589
|
+
const result = native.detectClassConflicts(JSON.stringify(usages.map((u) => ({ name: u.name, count: u.count }))));
|
|
4590
|
+
return {
|
|
4591
|
+
conflicts: result.conflicts.map((c) => ({
|
|
4592
|
+
className: c.group,
|
|
4593
|
+
variants: c.variantKey.length > 0 ? c.variantKey.split(":") : [],
|
|
4594
|
+
classes: c.classes,
|
|
4595
|
+
message: c.message
|
|
4596
|
+
})),
|
|
4597
|
+
conflictedClassNames: new Set(result.conflictedClassNames)
|
|
4598
|
+
};
|
|
4538
4599
|
};
|
|
4539
4600
|
isSupportedTailwindConfigPath = (configPath) => {
|
|
4540
|
-
return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(
|
|
4601
|
+
return SUPPORTED_TAILWIND_CONFIG_EXTENSIONS.has(path6__namespace.default.extname(configPath).toLowerCase());
|
|
4541
4602
|
};
|
|
4542
4603
|
resolveTailwindConfigPath = async (root, explicitPath) => {
|
|
4543
4604
|
if (explicitPath) {
|
|
4544
|
-
const resolved =
|
|
4605
|
+
const resolved = path6__namespace.default.resolve(root, explicitPath);
|
|
4545
4606
|
if (!await pathExists(resolved)) return null;
|
|
4546
4607
|
return resolved;
|
|
4547
4608
|
}
|
|
@@ -4552,7 +4613,7 @@ var init_semantic = __esm({
|
|
|
4552
4613
|
"tailwind.config.mjs"
|
|
4553
4614
|
];
|
|
4554
4615
|
for (const candidate of candidates) {
|
|
4555
|
-
const fullPath =
|
|
4616
|
+
const fullPath = path6__namespace.default.resolve(root, candidate);
|
|
4556
4617
|
if (await pathExists(fullPath)) return fullPath;
|
|
4557
4618
|
}
|
|
4558
4619
|
return null;
|
|
@@ -4606,15 +4667,19 @@ var init_semantic = __esm({
|
|
|
4606
4667
|
return out;
|
|
4607
4668
|
};
|
|
4608
4669
|
collectSafelistFromSource = async (configPath) => {
|
|
4609
|
-
const source = await
|
|
4610
|
-
const
|
|
4611
|
-
|
|
4612
|
-
const
|
|
4613
|
-
|
|
4670
|
+
const source = await fs11__namespace.default.promises.readFile(configPath, "utf8");
|
|
4671
|
+
const { extractClassesNative: extractClassesNative2 } = await Promise.resolve().then(() => (init_src2(), src_exports));
|
|
4672
|
+
const allTokens = extractClassesNative2(source);
|
|
4673
|
+
const hasSafelist = source.includes("safelist");
|
|
4674
|
+
if (!hasSafelist) return [];
|
|
4675
|
+
const safelistMatch = source.match(/safelist\s*:\s*\[([\s\S]*?)\]/m)?.[1];
|
|
4676
|
+
if (!safelistMatch) return [];
|
|
4677
|
+
const safelistSet = /* @__PURE__ */ new Set();
|
|
4678
|
+
for (const token of safelistMatch.matchAll(/["'`]([^"'`]+)["'`]/g)) {
|
|
4614
4679
|
const value = token[1].trim();
|
|
4615
|
-
if (value.length > 0)
|
|
4680
|
+
if (value.length > 0) safelistSet.add(value);
|
|
4616
4681
|
}
|
|
4617
|
-
return
|
|
4682
|
+
return allTokens.filter((t) => safelistSet.has(t));
|
|
4618
4683
|
};
|
|
4619
4684
|
loadTailwindConfig = async (root, semanticOption) => {
|
|
4620
4685
|
const startMs = Date.now();
|
|
@@ -4629,7 +4694,7 @@ var init_semantic = __esm({
|
|
|
4629
4694
|
customUtilities: /* @__PURE__ */ new Set()
|
|
4630
4695
|
};
|
|
4631
4696
|
}
|
|
4632
|
-
const configStat = await
|
|
4697
|
+
const configStat = await fs11__namespace.default.promises.stat(configPath).catch(() => null);
|
|
4633
4698
|
if (configStat) {
|
|
4634
4699
|
const cached = tailwindConfigCache.get(configPath);
|
|
4635
4700
|
if (cached && cached.mtimeMs === configStat.mtimeMs && cached.size === configStat.size) {
|
|
@@ -4715,21 +4780,27 @@ var init_semantic = __esm({
|
|
|
4715
4780
|
if (hyphen < 0) return normalized;
|
|
4716
4781
|
return normalized.slice(0, hyphen);
|
|
4717
4782
|
};
|
|
4718
|
-
isKnownTailwindClass = (className, safelist, customUtilities) => {
|
|
4719
|
-
if (safelist.has(className) || customUtilities.has(className)) return true;
|
|
4720
|
-
const { base } = splitVariantAndBase(className);
|
|
4721
|
-
if (customUtilities.has(base)) return true;
|
|
4722
|
-
const prefix = utilityPrefix(base);
|
|
4723
|
-
return KNOWN_UTILITY_PREFIXES.has(prefix);
|
|
4724
|
-
};
|
|
4725
4783
|
buildSemanticReport = async (usages, root, semanticOption) => {
|
|
4726
4784
|
const loadedConfig = await loadTailwindConfig(root, semanticOption);
|
|
4727
4785
|
const safelist = loadedConfig?.safelist ?? /* @__PURE__ */ new Set();
|
|
4728
4786
|
const customUtilities = loadedConfig?.customUtilities ?? /* @__PURE__ */ new Set();
|
|
4729
4787
|
const usageNames = new Set(usages.map((usage) => usage.name));
|
|
4730
4788
|
const unusedClasses = Array.from(safelist).filter((className) => !usageNames.has(className)).sort().map((className) => ({ name: className, count: 0, isUnused: true }));
|
|
4731
|
-
const
|
|
4732
|
-
|
|
4789
|
+
const native = await getNativeBinding();
|
|
4790
|
+
if (!native?.classifyKnownClasses) {
|
|
4791
|
+
throw new Error("FATAL: Native binding 'classifyKnownClasses' is required but not available.");
|
|
4792
|
+
}
|
|
4793
|
+
const classNames = usages.map((u) => u.name);
|
|
4794
|
+
const results = native.classifyKnownClasses(
|
|
4795
|
+
classNames,
|
|
4796
|
+
Array.from(safelist),
|
|
4797
|
+
Array.from(customUtilities)
|
|
4798
|
+
);
|
|
4799
|
+
const unknownSet = new Set(
|
|
4800
|
+
results.filter((r) => !r.isKnown).map((r) => r.className)
|
|
4801
|
+
);
|
|
4802
|
+
const unknownClasses = usages.filter((usage) => unknownSet.has(usage.name)).map((usage) => ({ ...usage, isUnused: true }));
|
|
4803
|
+
const { conflicts } = await detectConflicts(usages);
|
|
4733
4804
|
return {
|
|
4734
4805
|
unusedClasses,
|
|
4735
4806
|
unknownClasses,
|
|
@@ -4765,13 +4836,17 @@ function normalizeScan(scan, includeClass) {
|
|
|
4765
4836
|
uniqueClasses: Array.from(unique).sort()
|
|
4766
4837
|
};
|
|
4767
4838
|
}
|
|
4768
|
-
function collectClassCounts(scan) {
|
|
4769
|
-
const
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
counts.set(className, (counts.get(className) ?? 0) + 1);
|
|
4773
|
-
}
|
|
4839
|
+
async function collectClassCounts(scan) {
|
|
4840
|
+
const native = await requireNativeBinding();
|
|
4841
|
+
if (!native?.collectClassCounts) {
|
|
4842
|
+
throw new Error("FATAL: Native binding 'collectClassCounts' is required but not available.");
|
|
4774
4843
|
}
|
|
4844
|
+
const filesJson = JSON.stringify(
|
|
4845
|
+
scan.files.map((f) => ({ file: f.file ?? "", classes: f.classes }))
|
|
4846
|
+
);
|
|
4847
|
+
const result = native.collectClassCounts(filesJson);
|
|
4848
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4849
|
+
for (const entry of result) counts.set(entry.name, entry.count);
|
|
4775
4850
|
return counts;
|
|
4776
4851
|
}
|
|
4777
4852
|
function buildClassUsage(counts) {
|
|
@@ -4780,29 +4855,24 @@ function buildClassUsage(counts) {
|
|
|
4780
4855
|
return left.name.localeCompare(right.name);
|
|
4781
4856
|
});
|
|
4782
4857
|
}
|
|
4783
|
-
function buildDistribution(usages) {
|
|
4784
|
-
const
|
|
4785
|
-
|
|
4786
|
-
"
|
|
4787
|
-
"4-7": 0,
|
|
4788
|
-
"8+": 0
|
|
4789
|
-
};
|
|
4790
|
-
for (const usage of usages) {
|
|
4791
|
-
if (usage.count === 1) {
|
|
4792
|
-
distribution["1"] += 1;
|
|
4793
|
-
} else if (usage.count <= 3) {
|
|
4794
|
-
distribution["2-3"] += 1;
|
|
4795
|
-
} else if (usage.count <= 7) {
|
|
4796
|
-
distribution["4-7"] += 1;
|
|
4797
|
-
} else {
|
|
4798
|
-
distribution["8+"] += 1;
|
|
4799
|
-
}
|
|
4858
|
+
async function buildDistribution(usages, native) {
|
|
4859
|
+
const binding = native ?? await requireNativeBinding();
|
|
4860
|
+
if (!binding?.buildDistribution) {
|
|
4861
|
+
throw new Error("FATAL: Native binding 'buildDistribution' is required but not available.");
|
|
4800
4862
|
}
|
|
4801
|
-
|
|
4863
|
+
const result = binding.buildDistribution(
|
|
4864
|
+
JSON.stringify(usages.map((u) => ({ name: u.name, count: u.count })))
|
|
4865
|
+
);
|
|
4866
|
+
return {
|
|
4867
|
+
"1": result.once,
|
|
4868
|
+
"2-3": result.few,
|
|
4869
|
+
"4-7": result.moderate,
|
|
4870
|
+
"8+": result.frequent
|
|
4871
|
+
};
|
|
4802
4872
|
}
|
|
4803
4873
|
async function analyzeWorkspace(root, options = {}) {
|
|
4804
4874
|
const startedAtMs = Date.now();
|
|
4805
|
-
const resolvedRoot =
|
|
4875
|
+
const resolvedRoot = path6__namespace.default.resolve(root);
|
|
4806
4876
|
const normalizedOptions = parseAnalyzerOptions(options);
|
|
4807
4877
|
const scan = await (async () => {
|
|
4808
4878
|
const scanStartedAtMs = Date.now();
|
|
@@ -4846,7 +4916,7 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
4846
4916
|
);
|
|
4847
4917
|
}
|
|
4848
4918
|
})();
|
|
4849
|
-
const counts = collectClassCounts(normalizedScan);
|
|
4919
|
+
const counts = await collectClassCounts(normalizedScan);
|
|
4850
4920
|
const baseAll = buildClassUsage(counts);
|
|
4851
4921
|
const { all, semanticReport } = await (async () => {
|
|
4852
4922
|
if (!normalizedOptions.semantic) {
|
|
@@ -4872,13 +4942,19 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
4872
4942
|
);
|
|
4873
4943
|
}
|
|
4874
4944
|
})();
|
|
4875
|
-
const
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4945
|
+
const classStatsNative = binding?.computeClassStats?.(
|
|
4946
|
+
JSON.stringify(all),
|
|
4947
|
+
topLimit,
|
|
4948
|
+
frequentThreshold
|
|
4949
|
+
);
|
|
4950
|
+
const top = classStatsNative ? JSON.parse(classStatsNative.topJson) : all.slice(0, topLimit);
|
|
4951
|
+
const frequent = classStatsNative ? JSON.parse(classStatsNative.frequentJson) : all.filter((usage) => usage.count >= frequentThreshold).slice(0, topLimit);
|
|
4952
|
+
const unique = classStatsNative ? JSON.parse(classStatsNative.uniqueJson) : all.filter((usage) => usage.count === 1);
|
|
4953
|
+
const totalClassOccurrences = classStatsNative ? classStatsNative.totalClassOccurrences : all.reduce((sum, usage) => sum + usage.count, 0);
|
|
4879
4954
|
debugLog(
|
|
4880
4955
|
`analyzeWorkspace completed in ${Date.now() - startedAtMs}ms (files=${normalizedScan.totalFiles}, uniqueClasses=${all.length})`
|
|
4881
4956
|
);
|
|
4957
|
+
const distribution = await buildDistribution(all, binding);
|
|
4882
4958
|
return {
|
|
4883
4959
|
root: nativeReport.root || resolvedRoot,
|
|
4884
4960
|
totalFiles: nativeReport.totalFiles,
|
|
@@ -4889,8 +4965,10 @@ async function analyzeWorkspace(root, options = {}) {
|
|
|
4889
4965
|
top,
|
|
4890
4966
|
frequent,
|
|
4891
4967
|
unique,
|
|
4892
|
-
distribution
|
|
4968
|
+
distribution
|
|
4893
4969
|
},
|
|
4970
|
+
// topClasses — alias for classStats.top (test contract & backward compat)
|
|
4971
|
+
topClasses: top,
|
|
4894
4972
|
safelist: all.map((usage) => usage.name),
|
|
4895
4973
|
...semanticReport ? { semantic: semanticReport } : {}
|
|
4896
4974
|
};
|
|
@@ -4912,8 +4990,11 @@ var init_classToCss = __esm({
|
|
|
4912
4990
|
init_binding();
|
|
4913
4991
|
init_schemas2();
|
|
4914
4992
|
init_utils();
|
|
4915
|
-
normalizeClassInput = (input) => {
|
|
4993
|
+
normalizeClassInput = (input, _binding) => {
|
|
4916
4994
|
if (typeof input === "string") {
|
|
4995
|
+
if (_binding?.normalizeClassInput) {
|
|
4996
|
+
return _binding.normalizeClassInput(input);
|
|
4997
|
+
}
|
|
4917
4998
|
return input.split(/\s+/).map((item) => item.trim()).filter((item) => item.length > 0);
|
|
4918
4999
|
}
|
|
4919
5000
|
if (!Array.isArray(input)) {
|
|
@@ -4935,27 +5016,26 @@ var init_classToCss = __esm({
|
|
|
4935
5016
|
const prefix = parsed.prefix ?? null;
|
|
4936
5017
|
return { prefix, strict };
|
|
4937
5018
|
};
|
|
4938
|
-
mergeDeclarationMap = (target, css) => {
|
|
4939
|
-
|
|
4940
|
-
|
|
4941
|
-
|
|
4942
|
-
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
const property = declaration.slice(0, colonIndex).trim();
|
|
4947
|
-
const value = declaration.slice(colonIndex + 1).trim();
|
|
4948
|
-
if (property.length === 0 || value.length === 0) continue;
|
|
4949
|
-
if (target.has(property)) target.delete(property);
|
|
4950
|
-
target.set(property, value);
|
|
4951
|
-
}
|
|
5019
|
+
mergeDeclarationMap = (target, css, binding) => {
|
|
5020
|
+
if (!binding.parseCssRules) {
|
|
5021
|
+
throw new Error("FATAL: Native binding 'parseCssRules' is required but not available.");
|
|
5022
|
+
}
|
|
5023
|
+
const rules = binding.parseCssRules(css);
|
|
5024
|
+
for (const rule of rules) {
|
|
5025
|
+
if (target.has(rule.property)) target.delete(rule.property);
|
|
5026
|
+
target.set(rule.property, rule.isImportant ? `${rule.value} !important` : rule.value);
|
|
4952
5027
|
}
|
|
4953
5028
|
};
|
|
4954
|
-
declarationMapToString = (declarationMap) => {
|
|
4955
|
-
|
|
5029
|
+
declarationMapToString = (declarationMap, binding) => {
|
|
5030
|
+
const entries = Array.from(declarationMap.entries()).map(([property, value]) => ({ property, value }));
|
|
5031
|
+
if (binding?.declarationMapToString) {
|
|
5032
|
+
return binding.declarationMapToString(entries);
|
|
5033
|
+
}
|
|
5034
|
+
return entries.map(({ property, value }) => `${property}: ${value}`).join("; ");
|
|
4956
5035
|
};
|
|
4957
5036
|
classToCss = async (input, options = {}) => {
|
|
4958
|
-
const
|
|
5037
|
+
const binding = await requireNativeCssCompiler();
|
|
5038
|
+
const inputClasses = normalizeClassInput(input, binding);
|
|
4959
5039
|
const normalizedOptions = normalizeClassToCssOptions(options);
|
|
4960
5040
|
if (inputClasses.length === 0) {
|
|
4961
5041
|
return {
|
|
@@ -4967,7 +5047,6 @@ var init_classToCss = __esm({
|
|
|
4967
5047
|
sizeBytes: 0
|
|
4968
5048
|
};
|
|
4969
5049
|
}
|
|
4970
|
-
const binding = await requireNativeCssCompiler();
|
|
4971
5050
|
const prefix = normalizedOptions.prefix;
|
|
4972
5051
|
const results = await Promise.all(
|
|
4973
5052
|
inputClasses.map(async (className) => {
|
|
@@ -5000,7 +5079,7 @@ var init_classToCss = __esm({
|
|
|
5000
5079
|
const sizeBytes = results.reduce((sum, r) => sum + r.sizeBytes, 0);
|
|
5001
5080
|
const declarationMap = /* @__PURE__ */ new Map();
|
|
5002
5081
|
for (const result of results) {
|
|
5003
|
-
mergeDeclarationMap(declarationMap, result.css);
|
|
5082
|
+
mergeDeclarationMap(declarationMap, result.css, binding);
|
|
5004
5083
|
}
|
|
5005
5084
|
const uniqueUnknown = Array.from(new Set(unknownClasses));
|
|
5006
5085
|
if (normalizedOptions.strict && uniqueUnknown.length > 0) {
|
|
@@ -5009,7 +5088,7 @@ var init_classToCss = __esm({
|
|
|
5009
5088
|
return {
|
|
5010
5089
|
inputClasses,
|
|
5011
5090
|
css: cssChunks.filter((chunk) => chunk.length > 0).join("\n"),
|
|
5012
|
-
declarations: declarationMapToString(declarationMap),
|
|
5091
|
+
declarations: declarationMapToString(declarationMap, binding),
|
|
5013
5092
|
resolvedClasses: Array.from(new Set(resolvedClasses)),
|
|
5014
5093
|
unknownClasses: uniqueUnknown,
|
|
5015
5094
|
sizeBytes
|
|
@@ -5019,8 +5098,8 @@ var init_classToCss = __esm({
|
|
|
5019
5098
|
});
|
|
5020
5099
|
|
|
5021
5100
|
// packages/domain/analyzer/src/index.ts
|
|
5022
|
-
var
|
|
5023
|
-
__export(
|
|
5101
|
+
var src_exports2 = {};
|
|
5102
|
+
__export(src_exports2, {
|
|
5024
5103
|
__internal: () => __internal,
|
|
5025
5104
|
analyzeWorkspace: () => analyzeWorkspace,
|
|
5026
5105
|
classToCss: () => classToCss
|
|
@@ -5048,7 +5127,7 @@ var init_src3 = __esm({
|
|
|
5048
5127
|
});
|
|
5049
5128
|
async function pathExists2(filePath) {
|
|
5050
5129
|
try {
|
|
5051
|
-
await
|
|
5130
|
+
await fs7__default.default.access(filePath);
|
|
5052
5131
|
return true;
|
|
5053
5132
|
} catch {
|
|
5054
5133
|
return false;
|
|
@@ -5056,7 +5135,7 @@ async function pathExists2(filePath) {
|
|
|
5056
5135
|
}
|
|
5057
5136
|
async function readFileSafe(filePath) {
|
|
5058
5137
|
try {
|
|
5059
|
-
return await
|
|
5138
|
+
return await fs7__default.default.readFile(filePath, "utf8");
|
|
5060
5139
|
} catch {
|
|
5061
5140
|
return null;
|
|
5062
5141
|
}
|
|
@@ -5075,8 +5154,8 @@ async function writeFileSafe(filePath, content, options = {}) {
|
|
|
5075
5154
|
options.onDryRun?.(`write ${filePath}`);
|
|
5076
5155
|
return;
|
|
5077
5156
|
}
|
|
5078
|
-
await
|
|
5079
|
-
await
|
|
5157
|
+
await fs7__default.default.mkdir(path6__namespace.default.dirname(filePath), { recursive: true });
|
|
5158
|
+
await fs7__default.default.writeFile(filePath, content, "utf8");
|
|
5080
5159
|
}
|
|
5081
5160
|
async function ensureFileSafe(filePath, content, options = {}) {
|
|
5082
5161
|
if (await pathExists2(filePath)) return "skipped";
|
|
@@ -5364,11 +5443,11 @@ var init_args = __esm({
|
|
|
5364
5443
|
});
|
|
5365
5444
|
function runtimeDirFromImportMeta(importMetaUrl) {
|
|
5366
5445
|
const filename = url.fileURLToPath(importMetaUrl);
|
|
5367
|
-
return
|
|
5446
|
+
return path6__namespace.default.dirname(filename);
|
|
5368
5447
|
}
|
|
5369
5448
|
async function resolveMonorepoPath(runtimeDir, relativeToRepoRoot) {
|
|
5370
|
-
const fromRuntime =
|
|
5371
|
-
const fromCwd =
|
|
5449
|
+
const fromRuntime = path6__namespace.default.resolve(runtimeDir, "..", "..", "..", relativeToRepoRoot);
|
|
5450
|
+
const fromCwd = path6__namespace.default.resolve(process.cwd(), relativeToRepoRoot);
|
|
5372
5451
|
return await pathExists2(fromRuntime) ? fromRuntime : fromCwd;
|
|
5373
5452
|
}
|
|
5374
5453
|
async function firstExistingPath(paths) {
|
|
@@ -5444,7 +5523,8 @@ async function runCliMain(options) {
|
|
|
5444
5523
|
await program2.parseAsync(argv);
|
|
5445
5524
|
} catch (error) {
|
|
5446
5525
|
const isHelpError = isHelpExit(error);
|
|
5447
|
-
|
|
5526
|
+
const isVersionError = isVersionExit(error);
|
|
5527
|
+
if (isHelpError || isVersionError) return;
|
|
5448
5528
|
const normalized = normalizeCliError(error);
|
|
5449
5529
|
const isJson = input.json;
|
|
5450
5530
|
if (isJson) {
|
|
@@ -5459,7 +5539,7 @@ async function runCliMain(options) {
|
|
|
5459
5539
|
process.exitCode = errorExitCode(normalized);
|
|
5460
5540
|
}
|
|
5461
5541
|
}
|
|
5462
|
-
var isCommanderLikeError, isHelpExit, normalizeCliError, findCommandByPath, resolveCommandHelp, resolveHelpPath, walkCommands;
|
|
5542
|
+
var isCommanderLikeError, isHelpExit, isVersionExit, normalizeCliError, findCommandByPath, resolveCommandHelp, resolveHelpPath, walkCommands;
|
|
5463
5543
|
var init_runtime = __esm({
|
|
5464
5544
|
"packages/infrastructure/cli/src/utils/runtime.ts"() {
|
|
5465
5545
|
init_args();
|
|
@@ -5472,6 +5552,9 @@ var init_runtime = __esm({
|
|
|
5472
5552
|
isHelpExit = (error) => {
|
|
5473
5553
|
return isCommanderLikeError(error) && error.code === "commander.helpDisplayed";
|
|
5474
5554
|
};
|
|
5555
|
+
isVersionExit = (error) => {
|
|
5556
|
+
return isCommanderLikeError(error) && error.code === "commander.version";
|
|
5557
|
+
};
|
|
5475
5558
|
normalizeCliError = (error) => {
|
|
5476
5559
|
if (!isCommanderLikeError(error)) return error;
|
|
5477
5560
|
if (!error.code?.startsWith("commander.")) return error;
|
|
@@ -5552,7 +5635,7 @@ async function resolveCreateInput(options) {
|
|
|
5552
5635
|
return { name: resolvedName, template: templateValue };
|
|
5553
5636
|
}
|
|
5554
5637
|
async function writeProjectFile(context, relativePath, content) {
|
|
5555
|
-
const filePath =
|
|
5638
|
+
const filePath = path6__namespace.default.join(context.projectDir, relativePath);
|
|
5556
5639
|
await writeFileSafe(filePath, content, { dryRun: context.dryRun });
|
|
5557
5640
|
context.writtenFiles.push(relativePath.replaceAll("\\", "/"));
|
|
5558
5641
|
}
|
|
@@ -5671,7 +5754,6 @@ async function createViteVueApp(context) {
|
|
|
5671
5754
|
scripts: { dev: "vite", build: "vite build", preview: "vite preview" },
|
|
5672
5755
|
dependencies: {
|
|
5673
5756
|
vue: "^3.4.0",
|
|
5674
|
-
"tailwind-merge": "^3.5.0",
|
|
5675
5757
|
"tailwind-styled-v4/vue": "^5.0.0"
|
|
5676
5758
|
},
|
|
5677
5759
|
devDependencies: {
|
|
@@ -5768,7 +5850,7 @@ async function createViteSvelteApp(context) {
|
|
|
5768
5850
|
private: true,
|
|
5769
5851
|
type: "module",
|
|
5770
5852
|
scripts: { dev: "vite", build: "vite build", preview: "vite preview" },
|
|
5771
|
-
dependencies: { "tailwind-
|
|
5853
|
+
dependencies: { "tailwind-styled-v4/svelte": "^5.0.0" },
|
|
5772
5854
|
devDependencies: {
|
|
5773
5855
|
svelte: "^5.0.0",
|
|
5774
5856
|
"@sveltejs/vite-plugin-svelte": "^3.0.0",
|
|
@@ -5869,7 +5951,7 @@ async function createSimpleApp(context) {
|
|
|
5869
5951
|
}
|
|
5870
5952
|
async function createProject(options, output) {
|
|
5871
5953
|
const { name, template } = await resolveCreateInput(options);
|
|
5872
|
-
const projectDir =
|
|
5954
|
+
const projectDir = path6__namespace.default.resolve(process.cwd(), name);
|
|
5873
5955
|
if (await pathExists2(projectDir)) {
|
|
5874
5956
|
throw new CliUsageError(`Directory ${name} already exists.`);
|
|
5875
5957
|
}
|
|
@@ -5940,10 +6022,13 @@ var init_createApp = __esm({
|
|
|
5940
6022
|
};
|
|
5941
6023
|
}
|
|
5942
6024
|
});
|
|
5943
|
-
|
|
6025
|
+
|
|
6026
|
+
// packages/domain/compiler/src/nativeBridge.ts
|
|
6027
|
+
var _loadNative, log3, NATIVE_UNAVAILABLE_MESSAGE, nativeBridge, bridgeLoadAttempted, bridgeLoadError, isValidNativeBridge, getNativeBridge;
|
|
5944
6028
|
var init_nativeBridge = __esm({
|
|
5945
6029
|
"packages/domain/compiler/src/nativeBridge.ts"() {
|
|
5946
6030
|
init_src();
|
|
6031
|
+
_loadNative = (path29) => __require(path29);
|
|
5947
6032
|
log3 = (...args) => {
|
|
5948
6033
|
if (process.env.DEBUG?.includes("compiler:native")) {
|
|
5949
6034
|
console.log("[compiler:native]", ...args);
|
|
@@ -5970,11 +6055,10 @@ var init_nativeBridge = __esm({
|
|
|
5970
6055
|
bridgeLoadAttempted = true;
|
|
5971
6056
|
try {
|
|
5972
6057
|
const runtimeDir = resolveRuntimeDir(void 0, (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
5973
|
-
const require2 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
5974
6058
|
const result = resolveNativeBinary(runtimeDir);
|
|
5975
6059
|
if (result.path && result.path.endsWith(".node")) {
|
|
5976
6060
|
try {
|
|
5977
|
-
const binding =
|
|
6061
|
+
const binding = _loadNative(result.path);
|
|
5978
6062
|
if (isValidNativeBridge(binding)) {
|
|
5979
6063
|
nativeBridge = binding;
|
|
5980
6064
|
log3("Native bridge loaded successfully from:", result.path);
|
|
@@ -6009,7 +6093,7 @@ init_esm();
|
|
|
6009
6093
|
init_errors();
|
|
6010
6094
|
async function loadAnalyzerModule() {
|
|
6011
6095
|
try {
|
|
6012
|
-
const mod = await Promise.resolve().then(() => (init_src3(),
|
|
6096
|
+
const mod = await Promise.resolve().then(() => (init_src3(), src_exports2));
|
|
6013
6097
|
if (typeof mod.analyzeWorkspace !== "function") {
|
|
6014
6098
|
throw new Error("analyzeWorkspace export not found");
|
|
6015
6099
|
}
|
|
@@ -6076,7 +6160,7 @@ async function runAnalyzeCli(args) {
|
|
|
6076
6160
|
verbose: process.env.TWS_VERBOSE === "1" || process.env.VERBOSE === "1"
|
|
6077
6161
|
});
|
|
6078
6162
|
const dirArg = parsed.positionals[0] ?? ".";
|
|
6079
|
-
const dir =
|
|
6163
|
+
const dir = path6__namespace.default.resolve(process.cwd(), dirArg);
|
|
6080
6164
|
if (!await pathExists2(dir)) {
|
|
6081
6165
|
throw new CliUsageError(`Directory not found: ${dir}`);
|
|
6082
6166
|
}
|
|
@@ -6132,7 +6216,7 @@ async function runExtractCli(args) {
|
|
|
6132
6216
|
const parsedMin = parseInt(minRaw, 10);
|
|
6133
6217
|
const minCount = Number.isFinite(parsedMin) && parsedMin > 0 ? parsedMin : 2;
|
|
6134
6218
|
const dirArg = parsed.positionals[0] ?? ".";
|
|
6135
|
-
const dir =
|
|
6219
|
+
const dir = path6__namespace.default.resolve(process.cwd(), dirArg);
|
|
6136
6220
|
if (!await pathExists2(dir)) {
|
|
6137
6221
|
throw new CliUsageError(`Directory not found: ${dir}`);
|
|
6138
6222
|
}
|
|
@@ -6205,15 +6289,15 @@ async function runInitCli(rawArgs) {
|
|
|
6205
6289
|
verbose: process.env.TWS_VERBOSE === "1" || process.env.VERBOSE === "1"
|
|
6206
6290
|
});
|
|
6207
6291
|
const target = rawArgs.find((arg) => !arg.startsWith("-")) ?? ".";
|
|
6208
|
-
const root =
|
|
6292
|
+
const root = path6__namespace.default.resolve(process.cwd(), target);
|
|
6209
6293
|
const report = { created: [], skipped: [] };
|
|
6210
6294
|
await ensureFile(
|
|
6211
|
-
|
|
6295
|
+
path6__namespace.default.join(root, "src", "tailwind.css"),
|
|
6212
6296
|
'@import "tailwindcss";\n\n@theme {\n --color-primary: #3b82f6;\n --spacing-section: 3rem;\n}\n',
|
|
6213
6297
|
report
|
|
6214
6298
|
);
|
|
6215
6299
|
await ensureFile(
|
|
6216
|
-
|
|
6300
|
+
path6__namespace.default.join(root, "tailwind-styled.config.json"),
|
|
6217
6301
|
`${JSON.stringify(
|
|
6218
6302
|
{
|
|
6219
6303
|
version: 1,
|
|
@@ -6232,12 +6316,12 @@ async function runInitCli(rawArgs) {
|
|
|
6232
6316
|
output.writeText("\nInit complete");
|
|
6233
6317
|
output.writeText(`Created: ${report.created.length}`);
|
|
6234
6318
|
for (const filePath of report.created) {
|
|
6235
|
-
output.writeText(` + ${
|
|
6319
|
+
output.writeText(` + ${path6__namespace.default.relative(root, filePath)}`);
|
|
6236
6320
|
}
|
|
6237
6321
|
if (report.skipped.length > 0) {
|
|
6238
6322
|
output.writeText(`Skipped: ${report.skipped.length}`);
|
|
6239
6323
|
for (const filePath of report.skipped) {
|
|
6240
|
-
output.writeText(` - ${
|
|
6324
|
+
output.writeText(` - ${path6__namespace.default.relative(root, filePath)} (exists)`);
|
|
6241
6325
|
}
|
|
6242
6326
|
}
|
|
6243
6327
|
}
|
|
@@ -6298,15 +6382,15 @@ async function findSourceFiles(dir) {
|
|
|
6298
6382
|
const out = [];
|
|
6299
6383
|
async function walk(currentDir) {
|
|
6300
6384
|
if (!await pathExists2(currentDir)) return;
|
|
6301
|
-
const entries = await
|
|
6385
|
+
const entries = await fs7__default.default.readdir(currentDir, { withFileTypes: true });
|
|
6302
6386
|
for (const entry of entries) {
|
|
6303
|
-
const fullPath =
|
|
6387
|
+
const fullPath = path6__namespace.default.join(currentDir, entry.name);
|
|
6304
6388
|
if (entry.isDirectory()) {
|
|
6305
6389
|
if (IGNORED_DIRS.has(entry.name)) continue;
|
|
6306
6390
|
await walk(fullPath);
|
|
6307
6391
|
continue;
|
|
6308
6392
|
}
|
|
6309
|
-
if (SOURCE_EXTENSIONS.has(
|
|
6393
|
+
if (SOURCE_EXTENSIONS.has(path6__namespace.default.extname(entry.name))) {
|
|
6310
6394
|
out.push(fullPath);
|
|
6311
6395
|
}
|
|
6312
6396
|
}
|
|
@@ -6327,7 +6411,7 @@ function migrateSource(source, options) {
|
|
|
6327
6411
|
return { output, classRenames: 0, importRenames };
|
|
6328
6412
|
}
|
|
6329
6413
|
async function migrateConfig(root, dryRun) {
|
|
6330
|
-
const cssPath =
|
|
6414
|
+
const cssPath = path6__namespace.default.join(root, "src", "tailwind.css");
|
|
6331
6415
|
if (await pathExists2(cssPath)) return 0;
|
|
6332
6416
|
await writeFileSafe(cssPath, DEFAULT_TAILWIND_CSS, { dryRun });
|
|
6333
6417
|
return 1;
|
|
@@ -6340,7 +6424,7 @@ async function runMigrateCli(rawArgs) {
|
|
|
6340
6424
|
verbose: process.env.TWS_VERBOSE === "1" || process.env.VERBOSE === "1"
|
|
6341
6425
|
});
|
|
6342
6426
|
const target = firstPositional(rawArgs) ?? ".";
|
|
6343
|
-
const root =
|
|
6427
|
+
const root = path6__namespace.default.resolve(process.cwd(), target);
|
|
6344
6428
|
const dryRunFlag = hasFlag("dry-run", rawArgs);
|
|
6345
6429
|
const wizardOptions = hasFlag("wizard", rawArgs) ? await runMigrationWizard() : null;
|
|
6346
6430
|
const { dryRun, includeConfig, includeClasses, includeImports } = wizardOptions ? {
|
|
@@ -6364,12 +6448,12 @@ async function runMigrateCli(rawArgs) {
|
|
|
6364
6448
|
report.configWrites += await migrateConfig(root, dryRun);
|
|
6365
6449
|
}
|
|
6366
6450
|
for (const filePath of files) {
|
|
6367
|
-
const source = await
|
|
6451
|
+
const source = await fs7__default.default.readFile(filePath, "utf8");
|
|
6368
6452
|
const migrated = migrateSource(source, { includeImports, includeClasses });
|
|
6369
6453
|
if (migrated.output !== source) {
|
|
6370
6454
|
report.updatedFiles++;
|
|
6371
6455
|
if (!dryRun) {
|
|
6372
|
-
await
|
|
6456
|
+
await fs7__default.default.writeFile(filePath, migrated.output, "utf8");
|
|
6373
6457
|
}
|
|
6374
6458
|
}
|
|
6375
6459
|
report.classRenames += migrated.classRenames;
|
|
@@ -6433,10 +6517,10 @@ function buildClassNames(files, uniqueClasses) {
|
|
|
6433
6517
|
});
|
|
6434
6518
|
}
|
|
6435
6519
|
function writeScanCache(root, cacheData) {
|
|
6436
|
-
const cacheDir =
|
|
6437
|
-
const cachePath =
|
|
6438
|
-
|
|
6439
|
-
|
|
6520
|
+
const cacheDir = path6__namespace.default.join(root, ".tailwind-styled");
|
|
6521
|
+
const cachePath = path6__namespace.default.join(cacheDir, "scan-cache.json");
|
|
6522
|
+
fs11__namespace.default.mkdirSync(cacheDir, { recursive: true });
|
|
6523
|
+
fs11__namespace.default.writeFileSync(cachePath, JSON.stringify(cacheData, null, 2), "utf-8");
|
|
6440
6524
|
return cachePath;
|
|
6441
6525
|
}
|
|
6442
6526
|
async function runScanCli(rawArgs) {
|
|
@@ -6448,7 +6532,7 @@ async function runScanCli(rawArgs) {
|
|
|
6448
6532
|
debug: process.env.TWS_DEBUG === "1" || process.env.DEBUG === "1",
|
|
6449
6533
|
verbose: process.env.TWS_VERBOSE === "1" || process.env.VERBOSE === "1"
|
|
6450
6534
|
});
|
|
6451
|
-
const root =
|
|
6535
|
+
const root = path6__namespace.default.resolve(process.cwd(), target);
|
|
6452
6536
|
const spinner = output.spinner();
|
|
6453
6537
|
spinner.start(`Scanning ${root}`);
|
|
6454
6538
|
const scanned = await scanWorkspaceAsync(root);
|
|
@@ -6738,7 +6822,7 @@ var writeVerboseLine = (binary, args) => {
|
|
|
6738
6822
|
console.error(` [verbose] $ ${formatCommand(binary, args)}`);
|
|
6739
6823
|
};
|
|
6740
6824
|
var runCommand = async (binary, args, options = {}) => {
|
|
6741
|
-
return new Promise((
|
|
6825
|
+
return new Promise((resolve2, reject) => {
|
|
6742
6826
|
if (isVerboseEnabled(options)) {
|
|
6743
6827
|
writeVerboseLine(binary, args);
|
|
6744
6828
|
}
|
|
@@ -6765,7 +6849,7 @@ var runCommand = async (binary, args, options = {}) => {
|
|
|
6765
6849
|
);
|
|
6766
6850
|
return;
|
|
6767
6851
|
}
|
|
6768
|
-
|
|
6852
|
+
resolve2(exitCode);
|
|
6769
6853
|
});
|
|
6770
6854
|
});
|
|
6771
6855
|
};
|
|
@@ -6794,7 +6878,7 @@ var formatCommandFailureOutput = (stdout, stderr) => {
|
|
|
6794
6878
|
return "Command failed with no output.";
|
|
6795
6879
|
};
|
|
6796
6880
|
var runCommandCapture = async (binary, args, options = {}) => {
|
|
6797
|
-
return new Promise((
|
|
6881
|
+
return new Promise((resolve2, reject) => {
|
|
6798
6882
|
if (isVerboseEnabled(options)) {
|
|
6799
6883
|
writeVerboseLine(binary, args);
|
|
6800
6884
|
}
|
|
@@ -6837,7 +6921,7 @@ ${formatCommandFailureOutput(stdout, stderr)}`,
|
|
|
6837
6921
|
);
|
|
6838
6922
|
return;
|
|
6839
6923
|
}
|
|
6840
|
-
|
|
6924
|
+
resolve2({
|
|
6841
6925
|
exitCode,
|
|
6842
6926
|
stdout,
|
|
6843
6927
|
stderr
|
|
@@ -6875,12 +6959,12 @@ function configureSetupFlags(rawArgs) {
|
|
|
6875
6959
|
};
|
|
6876
6960
|
}
|
|
6877
6961
|
async function readPackageJson(cwd2) {
|
|
6878
|
-
return readJsonSafe(
|
|
6962
|
+
return readJsonSafe(path6__namespace.default.join(cwd2, "package.json"));
|
|
6879
6963
|
}
|
|
6880
6964
|
async function detectPm(cwd2) {
|
|
6881
|
-
if (await pathExists2(
|
|
6882
|
-
if (await pathExists2(
|
|
6883
|
-
if (await pathExists2(
|
|
6965
|
+
if (await pathExists2(path6__namespace.default.join(cwd2, "bun.lockb"))) return "bun";
|
|
6966
|
+
if (await pathExists2(path6__namespace.default.join(cwd2, "pnpm-lock.yaml"))) return "pnpm";
|
|
6967
|
+
if (await pathExists2(path6__namespace.default.join(cwd2, "yarn.lock"))) return "yarn";
|
|
6884
6968
|
return "npm";
|
|
6885
6969
|
}
|
|
6886
6970
|
async function detectBundler(cwd2) {
|
|
@@ -6901,7 +6985,7 @@ async function alreadyInstalled(cwd2, pkgName) {
|
|
|
6901
6985
|
}
|
|
6902
6986
|
async function findExisting(cwd2, names) {
|
|
6903
6987
|
for (const name of names) {
|
|
6904
|
-
const resolved =
|
|
6988
|
+
const resolved = path6__namespace.default.join(cwd2, name);
|
|
6905
6989
|
if (await pathExists2(resolved)) return resolved;
|
|
6906
6990
|
}
|
|
6907
6991
|
return null;
|
|
@@ -7041,16 +7125,10 @@ var runSetupCli = async (rawArgs) => {
|
|
|
7041
7125
|
output.writeText(import_picocolors3.default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
7042
7126
|
output.writeText("");
|
|
7043
7127
|
output.writeText(import_picocolors3.default.bold(" [1/4]") + import_picocolors3.default.cyan(" packages"));
|
|
7044
|
-
const
|
|
7045
|
-
|
|
7046
|
-
alreadyInstalled(cwd, "tailwind-merge")
|
|
7047
|
-
]);
|
|
7048
|
-
const toInstall = [
|
|
7049
|
-
hasCorePkg ? null : "tailwind-styled-v4",
|
|
7050
|
-
hasMergePkg ? null : "tailwind-merge"
|
|
7051
|
-
].filter(Boolean);
|
|
7128
|
+
const hasCorePkg = await alreadyInstalled(cwd, "tailwind-styled-v4");
|
|
7129
|
+
const toInstall = hasCorePkg ? [] : ["tailwind-styled-v4"];
|
|
7052
7130
|
if (toInstall.length > 0) await installPackages(cwd, pm, toInstall, false, setupFlags, logger);
|
|
7053
|
-
else logger.skip("tailwind-styled-v4
|
|
7131
|
+
else logger.skip("tailwind-styled-v4 sudah terpasang");
|
|
7054
7132
|
output.writeText("\n" + import_picocolors3.default.bold(" [2/4]") + import_picocolors3.default.cyan(" bundler config"));
|
|
7055
7133
|
const bundlerConfigMap = {
|
|
7056
7134
|
next: {
|
|
@@ -7073,7 +7151,7 @@ var runSetupCli = async (rawArgs) => {
|
|
|
7073
7151
|
if (bundlerConfig) {
|
|
7074
7152
|
const cfg = await findExisting(cwd, bundlerConfig.files);
|
|
7075
7153
|
if (cfg)
|
|
7076
|
-
await patchFileWithDryRun(cfg, bundlerConfig.patcher,
|
|
7154
|
+
await patchFileWithDryRun(cfg, bundlerConfig.patcher, path6__namespace.default.basename(cfg), setupFlags, logger);
|
|
7077
7155
|
else logger.warn(bundlerConfig.warnMsg);
|
|
7078
7156
|
} else {
|
|
7079
7157
|
logger.skip("React tanpa bundler - tidak ada bundler config yang di-patch");
|
|
@@ -7092,8 +7170,8 @@ var runSetupCli = async (rawArgs) => {
|
|
|
7092
7170
|
if (cssFile) {
|
|
7093
7171
|
await patchFileWithDryRun(
|
|
7094
7172
|
cssFile,
|
|
7095
|
-
(src) => patchTailwindCss(src, bundler,
|
|
7096
|
-
|
|
7173
|
+
(src) => patchTailwindCss(src, bundler, path6__namespace.default.relative(cwd, cssFile), cwd),
|
|
7174
|
+
path6__namespace.default.relative(cwd, cssFile),
|
|
7097
7175
|
setupFlags,
|
|
7098
7176
|
logger
|
|
7099
7177
|
);
|
|
@@ -7101,7 +7179,7 @@ var runSetupCli = async (rawArgs) => {
|
|
|
7101
7179
|
logger.warn('CSS entry tidak ditemukan \u2014 tambahkan @import "tailwindcss" manual ke globals.css');
|
|
7102
7180
|
}
|
|
7103
7181
|
output.writeText("\n" + import_picocolors3.default.bold(" [4/4]") + import_picocolors3.default.cyan(" tsconfig.json"));
|
|
7104
|
-
const tsCfg =
|
|
7182
|
+
const tsCfg = path6__namespace.default.join(cwd, "tsconfig.json");
|
|
7105
7183
|
const hasTsConfig = await findExisting(cwd, ["tsconfig.json"]);
|
|
7106
7184
|
if (hasTsConfig) {
|
|
7107
7185
|
await patchFileWithDryRun(tsCfg, patchTsConfig, "tsconfig.json", setupFlags, logger);
|
|
@@ -7167,7 +7245,7 @@ async function runStatsCli(args) {
|
|
|
7167
7245
|
verbose: process.env.TWS_VERBOSE === "1" || process.env.VERBOSE === "1"
|
|
7168
7246
|
});
|
|
7169
7247
|
const dirArg = parsed.positionals[0] ?? ".";
|
|
7170
|
-
const dir =
|
|
7248
|
+
const dir = path6__namespace.default.resolve(process.cwd(), dirArg);
|
|
7171
7249
|
if (!await pathExists2(dir)) {
|
|
7172
7250
|
throw new CliUsageError(`Directory not found: ${dir}`);
|
|
7173
7251
|
}
|
|
@@ -7221,13 +7299,13 @@ async function runStatsCli(args) {
|
|
|
7221
7299
|
init_runtime();
|
|
7222
7300
|
function collectTsFiles(dir, extensions) {
|
|
7223
7301
|
const files = [];
|
|
7224
|
-
const entries =
|
|
7302
|
+
const entries = fs11.readdirSync(dir, { withFileTypes: true });
|
|
7225
7303
|
for (const entry of entries) {
|
|
7226
|
-
const full =
|
|
7304
|
+
const full = path6.join(dir, entry.name);
|
|
7227
7305
|
if (entry.isDirectory()) {
|
|
7228
7306
|
if (entry.name === "node_modules" || entry.name === "dist" || entry.name === ".next") continue;
|
|
7229
7307
|
files.push(...collectTsFiles(full, extensions));
|
|
7230
|
-
} else if (extensions.has(
|
|
7308
|
+
} else if (extensions.has(path6.extname(entry.name))) {
|
|
7231
7309
|
files.push(full);
|
|
7232
7310
|
}
|
|
7233
7311
|
}
|
|
@@ -7304,7 +7382,7 @@ async function runBoundaryCli(args, context) {
|
|
|
7304
7382
|
for (const file of files) {
|
|
7305
7383
|
let source;
|
|
7306
7384
|
try {
|
|
7307
|
-
source =
|
|
7385
|
+
source = fs11.readFileSync(file, "utf8");
|
|
7308
7386
|
} catch {
|
|
7309
7387
|
continue;
|
|
7310
7388
|
}
|
|
@@ -7379,7 +7457,7 @@ function enumerateVariantProps(matrix) {
|
|
|
7379
7457
|
}
|
|
7380
7458
|
async function resolveScript(context, relativeToRepoRoot) {
|
|
7381
7459
|
const fromRuntime = await resolveMonorepoPath(context.runtimeDir, relativeToRepoRoot);
|
|
7382
|
-
const fromCwd =
|
|
7460
|
+
const fromCwd = path6__namespace.default.resolve(process.cwd(), relativeToRepoRoot);
|
|
7383
7461
|
const resolved = await firstExistingPath([fromRuntime, fromCwd]);
|
|
7384
7462
|
if (!resolved) {
|
|
7385
7463
|
throw new CliUsageError(`Required script not found: ${relativeToRepoRoot}`);
|
|
@@ -7393,13 +7471,13 @@ async function loadRegistry(context) {
|
|
|
7393
7471
|
);
|
|
7394
7472
|
const candidates = [
|
|
7395
7473
|
runtimeRegistryPath,
|
|
7396
|
-
|
|
7474
|
+
path6__namespace.default.resolve(process.cwd(), "packages/domain/plugin-registry/registry.json")
|
|
7397
7475
|
];
|
|
7398
7476
|
const registryPath = await firstExistingPath(candidates);
|
|
7399
7477
|
if (!registryPath) {
|
|
7400
7478
|
throw new CliUsageError("Plugin registry file not found.");
|
|
7401
7479
|
}
|
|
7402
|
-
const raw = await
|
|
7480
|
+
const raw = await fs7__default.default.readFile(registryPath, "utf8");
|
|
7403
7481
|
const data = JSON.parse(raw);
|
|
7404
7482
|
return [
|
|
7405
7483
|
...data.official.map((item) => ({ ...item, official: true })),
|
|
@@ -7449,7 +7527,7 @@ init_json();
|
|
|
7449
7527
|
var postJson = async (url, body, token) => {
|
|
7450
7528
|
const { default: https } = await import('https');
|
|
7451
7529
|
const { default: http } = await import('http');
|
|
7452
|
-
return new Promise((
|
|
7530
|
+
return new Promise((resolve2, reject) => {
|
|
7453
7531
|
const client = url.protocol === "https:" ? https : http;
|
|
7454
7532
|
const req = client.request(
|
|
7455
7533
|
url,
|
|
@@ -7467,9 +7545,9 @@ var postJson = async (url, body, token) => {
|
|
|
7467
7545
|
res.on("end", () => {
|
|
7468
7546
|
const raw = Buffer.concat(chunks).toString("utf8");
|
|
7469
7547
|
try {
|
|
7470
|
-
|
|
7548
|
+
resolve2({ status: res.statusCode, body: JSON.parse(raw) });
|
|
7471
7549
|
} catch {
|
|
7472
|
-
|
|
7550
|
+
resolve2({ status: res.statusCode, body: raw });
|
|
7473
7551
|
}
|
|
7474
7552
|
});
|
|
7475
7553
|
}
|
|
@@ -7498,7 +7576,7 @@ var deployCommand = {
|
|
|
7498
7576
|
const version = typeof parsed.values.version === "string" ? parsed.values.version : "0.1.0";
|
|
7499
7577
|
const tag = typeof parsed.values.tag === "string" ? parsed.values.tag : "latest";
|
|
7500
7578
|
const registryUrl = typeof parsed.values.registry === "string" ? parsed.values.registry : process.env.TW_REGISTRY_URL ?? null;
|
|
7501
|
-
const pkgPath =
|
|
7579
|
+
const pkgPath = path6__namespace.default.join(process.cwd(), "package.json");
|
|
7502
7580
|
if (!await pathExists2(pkgPath)) {
|
|
7503
7581
|
throw new CliUsageError("[tw deploy] No package.json found in current directory");
|
|
7504
7582
|
}
|
|
@@ -7533,10 +7611,10 @@ var deployCommand = {
|
|
|
7533
7611
|
}
|
|
7534
7612
|
return;
|
|
7535
7613
|
}
|
|
7536
|
-
const cacheDir =
|
|
7537
|
-
await
|
|
7538
|
-
await
|
|
7539
|
-
|
|
7614
|
+
const cacheDir = path6__namespace.default.join(process.cwd(), ".tw-cache");
|
|
7615
|
+
await fs7__default.default.mkdir(cacheDir, { recursive: true });
|
|
7616
|
+
await fs7__default.default.writeFile(
|
|
7617
|
+
path6__namespace.default.join(cacheDir, "deploy-manifest.json"),
|
|
7540
7618
|
JSON.stringify(manifest, null, 2)
|
|
7541
7619
|
);
|
|
7542
7620
|
if (!registryUrl) {
|
|
@@ -7636,24 +7714,24 @@ function addIssue(issues, severity, type, message, suggestion, location) {
|
|
|
7636
7714
|
issues.push({ severity, type, message, suggestion, location });
|
|
7637
7715
|
}
|
|
7638
7716
|
function readJsonFile(filePath) {
|
|
7639
|
-
if (!
|
|
7717
|
+
if (!fs11__namespace.default.existsSync(filePath)) return null;
|
|
7640
7718
|
try {
|
|
7641
|
-
return JSON.parse(
|
|
7719
|
+
return JSON.parse(fs11__namespace.default.readFileSync(filePath, "utf8"));
|
|
7642
7720
|
} catch {
|
|
7643
7721
|
return null;
|
|
7644
7722
|
}
|
|
7645
7723
|
}
|
|
7646
7724
|
function findWorkspacePackageJsonFiles(root) {
|
|
7647
|
-
const packagesDir =
|
|
7648
|
-
if (!
|
|
7649
|
-
return
|
|
7725
|
+
const packagesDir = path6__namespace.default.join(root, "packages");
|
|
7726
|
+
if (!fs11__namespace.default.existsSync(packagesDir)) return [];
|
|
7727
|
+
return fs11__namespace.default.readdirSync(packagesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => path6__namespace.default.join(packagesDir, entry.name, "package.json")).filter((filePath) => fs11__namespace.default.existsSync(filePath));
|
|
7650
7728
|
}
|
|
7651
7729
|
function findFiles(dir, ext) {
|
|
7652
7730
|
const files = [];
|
|
7653
7731
|
try {
|
|
7654
|
-
const entries =
|
|
7732
|
+
const entries = fs11__namespace.default.readdirSync(dir, { withFileTypes: true });
|
|
7655
7733
|
for (const entry of entries) {
|
|
7656
|
-
const fullPath =
|
|
7734
|
+
const fullPath = path6__namespace.default.join(dir, entry.name);
|
|
7657
7735
|
if (entry.isDirectory() && !entry.name.startsWith(".") && entry.name !== "node_modules") {
|
|
7658
7736
|
files.push(...findFiles(fullPath, ext));
|
|
7659
7737
|
} else if (entry.isFile() && entry.name.endsWith(ext)) {
|
|
@@ -7666,7 +7744,7 @@ function findFiles(dir, ext) {
|
|
|
7666
7744
|
return files;
|
|
7667
7745
|
}
|
|
7668
7746
|
function runWorkspaceDiagnostics(root, issues, checks) {
|
|
7669
|
-
const rootPackageJsonPath =
|
|
7747
|
+
const rootPackageJsonPath = path6__namespace.default.join(root, "package.json");
|
|
7670
7748
|
const rootPackageJson = readJsonFile(rootPackageJsonPath);
|
|
7671
7749
|
if (!rootPackageJson) {
|
|
7672
7750
|
addCheck(
|
|
@@ -7719,7 +7797,7 @@ function runWorkspaceDiagnostics(root, issues, checks) {
|
|
|
7719
7797
|
const scripts = typeof manifest.scripts === "object" && manifest.scripts !== null ? manifest.scripts : {};
|
|
7720
7798
|
const missing = requiredScripts.filter((name) => typeof scripts[name] !== "string");
|
|
7721
7799
|
if (missing.length === 0) return [];
|
|
7722
|
-
const packageName = typeof manifest.name === "string" && manifest.name.length > 0 ? manifest.name :
|
|
7800
|
+
const packageName = typeof manifest.name === "string" && manifest.name.length > 0 ? manifest.name : path6__namespace.default.basename(path6__namespace.default.dirname(filePath));
|
|
7723
7801
|
return [{ packageName, missing }];
|
|
7724
7802
|
});
|
|
7725
7803
|
if (missingScripts.length === 0) {
|
|
@@ -7754,7 +7832,7 @@ function runWorkspaceDiagnostics(root, issues, checks) {
|
|
|
7754
7832
|
);
|
|
7755
7833
|
}
|
|
7756
7834
|
function runTailwindProjectDiagnostics(root, issues, checks) {
|
|
7757
|
-
const packageJsonPath =
|
|
7835
|
+
const packageJsonPath = path6__namespace.default.join(root, "package.json");
|
|
7758
7836
|
const packageJson = readJsonFile(packageJsonPath);
|
|
7759
7837
|
if (!packageJson) {
|
|
7760
7838
|
addCheck(
|
|
@@ -7813,7 +7891,7 @@ function runTailwindProjectDiagnostics(root, issues, checks) {
|
|
|
7813
7891
|
const cssFiles = findFiles(root, ".css");
|
|
7814
7892
|
const hasTailwindImport = cssFiles.slice(0, 10).some((filePath) => {
|
|
7815
7893
|
try {
|
|
7816
|
-
const content =
|
|
7894
|
+
const content = fs11__namespace.default.readFileSync(filePath, "utf8");
|
|
7817
7895
|
return content.includes("@tailwind") || content.includes('@import "tailwindcss"');
|
|
7818
7896
|
} catch {
|
|
7819
7897
|
return false;
|
|
@@ -7837,7 +7915,7 @@ function runTailwindProjectDiagnostics(root, issues, checks) {
|
|
|
7837
7915
|
);
|
|
7838
7916
|
}
|
|
7839
7917
|
const configFiles = ["tailwind.config.js", "tailwind.config.ts", "tailwind.config.mjs"];
|
|
7840
|
-
const hasConfig = configFiles.some((name) =>
|
|
7918
|
+
const hasConfig = configFiles.some((name) => fs11__namespace.default.existsSync(path6__namespace.default.join(root, name)));
|
|
7841
7919
|
addCheck(
|
|
7842
7920
|
checks,
|
|
7843
7921
|
"tailwind",
|
|
@@ -7846,7 +7924,7 @@ function runTailwindProjectDiagnostics(root, issues, checks) {
|
|
|
7846
7924
|
"info",
|
|
7847
7925
|
hasConfig ? "Tailwind config file detected." : "No tailwind.config file found."
|
|
7848
7926
|
);
|
|
7849
|
-
const tsconfig = readJsonFile(
|
|
7927
|
+
const tsconfig = readJsonFile(path6__namespace.default.join(root, "tsconfig.json"));
|
|
7850
7928
|
const jsx = tsconfig?.compilerOptions?.jsx;
|
|
7851
7929
|
addCheck(
|
|
7852
7930
|
checks,
|
|
@@ -8012,7 +8090,7 @@ async function runAnalysisDiagnostics(root, issues, checks, verbose) {
|
|
|
8012
8090
|
}
|
|
8013
8091
|
}
|
|
8014
8092
|
var runDiagnostics = async (options = {}) => {
|
|
8015
|
-
const root =
|
|
8093
|
+
const root = path6__namespace.default.resolve(options.root ?? process.cwd());
|
|
8016
8094
|
const includes = parseIncludes(options.include);
|
|
8017
8095
|
const issues = [];
|
|
8018
8096
|
const checks = [];
|
|
@@ -8162,7 +8240,7 @@ var shareCommand = {
|
|
|
8162
8240
|
name: "share",
|
|
8163
8241
|
async run(args, context) {
|
|
8164
8242
|
const name = args.find((arg) => !arg.startsWith("-")) ?? "component-name";
|
|
8165
|
-
const manifestPath =
|
|
8243
|
+
const manifestPath = path6__namespace.default.join(process.cwd(), ".tw-cache", "deploy-manifest.json");
|
|
8166
8244
|
const defaultManifest = {
|
|
8167
8245
|
name,
|
|
8168
8246
|
version: "0.1.0"
|
|
@@ -8248,14 +8326,14 @@ var isVersionOutdated = (currentVersion, latestVersion) => {
|
|
|
8248
8326
|
};
|
|
8249
8327
|
var resolveCurrentCliVersion = async (context) => {
|
|
8250
8328
|
const candidates = [
|
|
8251
|
-
|
|
8252
|
-
|
|
8253
|
-
|
|
8329
|
+
path6__namespace.default.resolve(context.runtimeDir, "..", "package.json"),
|
|
8330
|
+
path6__namespace.default.resolve(process.cwd(), "packages", "cli", "package.json"),
|
|
8331
|
+
path6__namespace.default.resolve(process.cwd(), "package.json")
|
|
8254
8332
|
];
|
|
8255
8333
|
for (const candidate of candidates) {
|
|
8256
8334
|
if (!await pathExists2(candidate)) continue;
|
|
8257
8335
|
const pkg = await readJsonSafe(candidate);
|
|
8258
|
-
const isCliPackage = pkg?.version && (pkg.name === CLI_PACKAGE_NAME || candidate.includes(`${
|
|
8336
|
+
const isCliPackage = pkg?.version && (pkg.name === CLI_PACKAGE_NAME || candidate.includes(`${path6__namespace.default.sep}packages${path6__namespace.default.sep}cli${path6__namespace.default.sep}`));
|
|
8259
8337
|
if (isCliPackage) return pkg.version ?? "0.0.0";
|
|
8260
8338
|
}
|
|
8261
8339
|
return "0.0.0";
|
|
@@ -8528,7 +8606,7 @@ function resolveCliEntry(scriptPath) {
|
|
|
8528
8606
|
async function hasTailwindCssImport(cwd2) {
|
|
8529
8607
|
const cssFiles = ["src/app/globals.css", "src/index.css", "src/style.css", "app/globals.css"];
|
|
8530
8608
|
for (const file of cssFiles) {
|
|
8531
|
-
const raw = await readFileSafe(
|
|
8609
|
+
const raw = await readFileSafe(path6__namespace.default.join(cwd2, file));
|
|
8532
8610
|
if (raw?.includes("tailwindcss")) return true;
|
|
8533
8611
|
}
|
|
8534
8612
|
return false;
|
|
@@ -8544,7 +8622,7 @@ async function hasSafelistSource(cwd2) {
|
|
|
8544
8622
|
"app/globals.css"
|
|
8545
8623
|
];
|
|
8546
8624
|
for (const file of cssFiles) {
|
|
8547
|
-
const raw = await readFileSafe(
|
|
8625
|
+
const raw = await readFileSafe(path6__namespace.default.join(cwd2, file));
|
|
8548
8626
|
if (raw === null) continue;
|
|
8549
8627
|
if (raw.includes("tw-classes")) return { found: true, cssFile: file };
|
|
8550
8628
|
if (raw.includes("tailwindcss")) return { found: false, cssFile: file };
|
|
@@ -8552,8 +8630,8 @@ async function hasSafelistSource(cwd2) {
|
|
|
8552
8630
|
return { found: false, cssFile: null };
|
|
8553
8631
|
}
|
|
8554
8632
|
async function applyTailwindInit(cwd2) {
|
|
8555
|
-
await ensureFileSafe(
|
|
8556
|
-
await ensureFileSafe(
|
|
8633
|
+
await ensureFileSafe(path6__namespace.default.join(cwd2, "src", "tailwind.css"), DEFAULT_TAILWIND_CSS2);
|
|
8634
|
+
await ensureFileSafe(path6__namespace.default.join(cwd2, "tailwind-styled.config.json"), DEFAULT_TW_CONFIG);
|
|
8557
8635
|
}
|
|
8558
8636
|
function check(results, id, label, pass, message, fix) {
|
|
8559
8637
|
results.push({ id, label, pass, message, fix });
|
|
@@ -8575,7 +8653,7 @@ async function runPreflightCli(rawArgs) {
|
|
|
8575
8653
|
node.major >= 20 ? `Node ${node.full} OK` : `Node ${node.full} - requires >=20. Download: https://nodejs.org`,
|
|
8576
8654
|
node.major < 20 ? "Install Node.js 20 LTS or newer from https://nodejs.org" : void 0
|
|
8577
8655
|
);
|
|
8578
|
-
const pkg = await readJsonSafe(
|
|
8656
|
+
const pkg = await readJsonSafe(path6__namespace.default.join(cwd2, "package.json"));
|
|
8579
8657
|
check(
|
|
8580
8658
|
results,
|
|
8581
8659
|
"package-json",
|
|
@@ -8606,19 +8684,10 @@ async function runPreflightCli(rawArgs) {
|
|
|
8606
8684
|
hasBundler ? `${bundlerName} detected OK` : "No supported bundler (Vite/Next.js/Rspack) found",
|
|
8607
8685
|
"Install a bundler: npm install vite @vitejs/plugin-react OR npx create-next-app"
|
|
8608
8686
|
);
|
|
8609
|
-
const hasMerge = pkgHasDep(pkg, "tailwind-merge");
|
|
8610
|
-
check(
|
|
8611
|
-
results,
|
|
8612
|
-
"tailwind-merge",
|
|
8613
|
-
"tailwind-merge installed",
|
|
8614
|
-
hasMerge,
|
|
8615
|
-
hasMerge ? "tailwind-merge found OK" : "Missing peer dep - run: npm install tailwind-merge",
|
|
8616
|
-
"npm install tailwind-merge"
|
|
8617
|
-
);
|
|
8618
8687
|
}
|
|
8619
8688
|
const twConfigFiles = ["tailwind.config.ts", "tailwind.config.js", "tailwind.config.mjs"];
|
|
8620
8689
|
const twConfigChecks = await Promise.all(
|
|
8621
|
-
twConfigFiles.map(async (file) => ({ file, exists: await pathExists2(
|
|
8690
|
+
twConfigFiles.map(async (file) => ({ file, exists: await pathExists2(path6__namespace.default.join(cwd2, file)) }))
|
|
8622
8691
|
);
|
|
8623
8692
|
const foundTwConfig = twConfigChecks.find((item) => item.exists)?.file ?? null;
|
|
8624
8693
|
const hasCssConfig = await hasTailwindCssImport(cwd2);
|
|
@@ -8630,7 +8699,7 @@ async function runPreflightCli(rawArgs) {
|
|
|
8630
8699
|
foundTwConfig ? `${foundTwConfig} found OK` : hasCssConfig ? "@import tailwindcss found in CSS OK" : "No Tailwind config found - run: tw init",
|
|
8631
8700
|
"tw init"
|
|
8632
8701
|
);
|
|
8633
|
-
const oldConfig = await readJsonSafe(
|
|
8702
|
+
const oldConfig = await readJsonSafe(path6__namespace.default.join(cwd2, "tailwind.config.js")) ?? await readJsonSafe(path6__namespace.default.join(cwd2, "tailwind.config.ts"));
|
|
8634
8703
|
if (oldConfig) {
|
|
8635
8704
|
const hasOldJit = oldConfig.mode === "jit";
|
|
8636
8705
|
const hasOldPurge = "purge" in oldConfig;
|
|
@@ -8644,7 +8713,7 @@ async function runPreflightCli(rawArgs) {
|
|
|
8644
8713
|
"Run: tw migrate --dry-run to see migration steps"
|
|
8645
8714
|
);
|
|
8646
8715
|
}
|
|
8647
|
-
const hasTsConfig = await pathExists2(
|
|
8716
|
+
const hasTsConfig = await pathExists2(path6__namespace.default.join(cwd2, "tsconfig.json"));
|
|
8648
8717
|
check(
|
|
8649
8718
|
results,
|
|
8650
8719
|
"typescript",
|
|
@@ -9038,7 +9107,7 @@ var storybookCommand = {
|
|
|
9038
9107
|
context.output.writeText(
|
|
9039
9108
|
`[tw storybook] Tip: use --variants='{"size":["sm","lg"]}' to enumerate variant combinations`
|
|
9040
9109
|
);
|
|
9041
|
-
const localBin =
|
|
9110
|
+
const localBin = path6__namespace.default.join(
|
|
9042
9111
|
process.cwd(),
|
|
9043
9112
|
"node_modules",
|
|
9044
9113
|
".bin",
|
|
@@ -9235,418 +9304,269 @@ function getNativeEngineBinding() {
|
|
|
9235
9304
|
// packages/domain/engine/src/bundleAnalyzer.ts
|
|
9236
9305
|
var BundleAnalyzer = class {
|
|
9237
9306
|
analyzeClass(className, scanResult, css) {
|
|
9238
|
-
if (!className || className.trim() === "")
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9307
|
+
if (!className || className.trim() === "") throw new Error("Class name cannot be empty");
|
|
9308
|
+
if (!scanResult) throw new Error("Scan result is required for analysis");
|
|
9309
|
+
if (typeof css !== "string") throw new Error("CSS string is required for analysis");
|
|
9310
|
+
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9311
|
+
const native = getNativeEngineBinding();
|
|
9312
|
+
if (!native.analyzeClassUsage) {
|
|
9313
|
+
throw new Error("FATAL: Native binding 'analyzeClassUsage' is required but not available.");
|
|
9243
9314
|
}
|
|
9244
|
-
if (
|
|
9245
|
-
throw new Error("
|
|
9315
|
+
if (!native.buildDependencyChain) {
|
|
9316
|
+
throw new Error("FATAL: Native binding 'buildDependencyChain' is required but not available.");
|
|
9246
9317
|
}
|
|
9247
|
-
const
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
const
|
|
9253
|
-
const
|
|
9318
|
+
const results = native.analyzeClassUsage(
|
|
9319
|
+
[normalizedClass],
|
|
9320
|
+
JSON.stringify(scanResult),
|
|
9321
|
+
css
|
|
9322
|
+
);
|
|
9323
|
+
const info = results[0];
|
|
9324
|
+
const files = info ? JSON.parse(info.filesJson).map((f) => ({ file: f, line: 1, column: 1 })) : [];
|
|
9325
|
+
const dependencies = native.buildDependencyChain(normalizedClass);
|
|
9254
9326
|
return {
|
|
9255
9327
|
className: normalizedClass,
|
|
9256
|
-
totalUsage: usageCount,
|
|
9328
|
+
totalUsage: info?.usageCount ?? 0,
|
|
9257
9329
|
files,
|
|
9258
|
-
bundleSizeBytes:
|
|
9259
|
-
variantChains,
|
|
9260
|
-
isDeadCode,
|
|
9330
|
+
bundleSizeBytes: info?.bundleSizeBytes ?? 0,
|
|
9331
|
+
variantChains: [],
|
|
9332
|
+
isDeadCode: info?.isDeadCode ?? true,
|
|
9261
9333
|
dependencies
|
|
9262
9334
|
};
|
|
9263
9335
|
}
|
|
9264
9336
|
analyzeAll(scanResult, css) {
|
|
9265
|
-
if (!scanResult)
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
if (
|
|
9269
|
-
throw new Error("
|
|
9270
|
-
}
|
|
9271
|
-
|
|
9272
|
-
|
|
9273
|
-
|
|
9274
|
-
|
|
9275
|
-
|
|
9276
|
-
|
|
9277
|
-
|
|
9278
|
-
|
|
9279
|
-
|
|
9280
|
-
|
|
9281
|
-
|
|
9282
|
-
|
|
9283
|
-
|
|
9337
|
+
if (!scanResult) throw new Error("Scan result is required for analysis");
|
|
9338
|
+
if (typeof css !== "string") throw new Error("CSS string is required for analysis");
|
|
9339
|
+
const native = getNativeEngineBinding();
|
|
9340
|
+
if (!native.analyzeClassUsage) {
|
|
9341
|
+
throw new Error("FATAL: Native binding 'analyzeClassUsage' is required but not available.");
|
|
9342
|
+
}
|
|
9343
|
+
if (!native.buildDependencyChain) {
|
|
9344
|
+
throw new Error("FATAL: Native binding 'buildDependencyChain' is required but not available.");
|
|
9345
|
+
}
|
|
9346
|
+
const allClasses = Array.from(/* @__PURE__ */ new Set([
|
|
9347
|
+
...scanResult.uniqueClasses,
|
|
9348
|
+
...native.extractAllClasses ? native.extractAllClasses(css) : []
|
|
9349
|
+
]));
|
|
9350
|
+
const results = native.analyzeClassUsage(
|
|
9351
|
+
allClasses,
|
|
9352
|
+
JSON.stringify(scanResult),
|
|
9353
|
+
css
|
|
9354
|
+
);
|
|
9355
|
+
const map = /* @__PURE__ */ new Map();
|
|
9356
|
+
for (const info of results) {
|
|
9357
|
+
const files = JSON.parse(info.filesJson).map((f) => ({
|
|
9358
|
+
file: f,
|
|
9359
|
+
line: 1,
|
|
9360
|
+
column: 1
|
|
9361
|
+
}));
|
|
9362
|
+
const dependencies = native.buildDependencyChain ? native.buildDependencyChain(info.className) : [];
|
|
9363
|
+
map.set(info.className, {
|
|
9364
|
+
className: info.className,
|
|
9365
|
+
totalUsage: info.usageCount,
|
|
9366
|
+
files,
|
|
9367
|
+
bundleSizeBytes: info.bundleSizeBytes,
|
|
9368
|
+
variantChains: [],
|
|
9369
|
+
isDeadCode: info.isDeadCode,
|
|
9370
|
+
dependencies
|
|
9371
|
+
});
|
|
9284
9372
|
}
|
|
9285
|
-
return
|
|
9373
|
+
return map;
|
|
9286
9374
|
}
|
|
9287
9375
|
calculateBundleContribution(className, css) {
|
|
9288
9376
|
if (!className || className.trim() === "") throw new Error("Class name cannot be empty");
|
|
9289
9377
|
if (typeof css !== "string") throw new Error("CSS string is required");
|
|
9290
|
-
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
return getNativeEngineBinding();
|
|
9294
|
-
} catch {
|
|
9295
|
-
return null;
|
|
9296
|
-
}
|
|
9297
|
-
})();
|
|
9298
|
-
if (native?.calculateBundleContributionsNative) {
|
|
9299
|
-
const r = native.calculateBundleContributionsNative([className], css);
|
|
9300
|
-
return r?.[0]?.sizeBytes ?? 0;
|
|
9301
|
-
}
|
|
9302
|
-
} catch (err) {
|
|
9378
|
+
const native = getNativeEngineBinding();
|
|
9379
|
+
if (!native.calculateBundleContributions) {
|
|
9380
|
+
throw new Error("FATAL: Native binding 'calculateBundleContributions' is required but not available.");
|
|
9303
9381
|
}
|
|
9304
|
-
const
|
|
9305
|
-
|
|
9306
|
-
const selectorPattern = new RegExp(`\\.${escapedClass}([\\s:{]|$)`, "g");
|
|
9307
|
-
if (!css.match(selectorPattern)) return 0;
|
|
9308
|
-
const classSelector = `.${normalizedClass}`;
|
|
9309
|
-
return css.split("\n").filter((l) => l.includes(classSelector)).reduce((sum, l) => {
|
|
9310
|
-
const s = l.indexOf("{");
|
|
9311
|
-
return s !== -1 ? sum + l.substring(s).length + 1 : sum;
|
|
9312
|
-
}, 0);
|
|
9382
|
+
const r = native.calculateBundleContributions([className], css);
|
|
9383
|
+
return r?.[0]?.sizeBytes ?? 0;
|
|
9313
9384
|
}
|
|
9314
9385
|
detectDeadCode(scanResult, css) {
|
|
9315
9386
|
if (!scanResult) throw new Error("Scan result is required for dead code detection");
|
|
9316
9387
|
if (typeof css !== "string") throw new Error("CSS string is required for dead code detection");
|
|
9317
|
-
|
|
9318
|
-
|
|
9319
|
-
|
|
9320
|
-
return getNativeEngineBinding();
|
|
9321
|
-
} catch {
|
|
9322
|
-
return null;
|
|
9323
|
-
}
|
|
9324
|
-
})();
|
|
9325
|
-
if (native?.detectDeadCodeNative) {
|
|
9326
|
-
const r = native.detectDeadCodeNative(JSON.stringify(scanResult), css);
|
|
9327
|
-
return r?.deadInCss ?? [];
|
|
9328
|
-
}
|
|
9329
|
-
} catch (err) {
|
|
9330
|
-
}
|
|
9331
|
-
const cssClasses = this.extractClassesFromCss(css);
|
|
9332
|
-
const usedClasses = new Set(scanResult.uniqueClasses);
|
|
9333
|
-
return cssClasses.filter((c) => !usedClasses.has(c));
|
|
9334
|
-
}
|
|
9335
|
-
countClassUsage(className, scanResult) {
|
|
9336
|
-
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9337
|
-
const count = scanResult.files.reduce((sum, file) => {
|
|
9338
|
-
return sum + file.classes.filter((fileClass) => {
|
|
9339
|
-
const normalizedFileClass = fileClass.startsWith(".") ? fileClass.slice(1) : fileClass;
|
|
9340
|
-
return normalizedFileClass === normalizedClass;
|
|
9341
|
-
}).length;
|
|
9342
|
-
}, 0);
|
|
9343
|
-
return count;
|
|
9344
|
-
}
|
|
9345
|
-
getFilesUsingClass(className, scanResult) {
|
|
9346
|
-
const files = [];
|
|
9347
|
-
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9348
|
-
for (const file of scanResult.files) {
|
|
9349
|
-
for (const fileClass of file.classes) {
|
|
9350
|
-
const normalizedFileClass = fileClass.startsWith(".") ? fileClass.slice(1) : fileClass;
|
|
9351
|
-
if (normalizedFileClass === normalizedClass) {
|
|
9352
|
-
files.push({
|
|
9353
|
-
file: file.file,
|
|
9354
|
-
line: 1,
|
|
9355
|
-
column: 1
|
|
9356
|
-
});
|
|
9357
|
-
break;
|
|
9358
|
-
}
|
|
9359
|
-
}
|
|
9360
|
-
}
|
|
9361
|
-
return files;
|
|
9362
|
-
}
|
|
9363
|
-
extractVariantChains(className, css) {
|
|
9364
|
-
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9365
|
-
const variantChains = [];
|
|
9366
|
-
const escapedClass = normalizedClass.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
9367
|
-
const variantPattern = new RegExp(`([\\w-]+:${escapedClass}|${escapedClass})`, "g");
|
|
9368
|
-
const lines = css.split("\n");
|
|
9369
|
-
for (const line of lines) {
|
|
9370
|
-
const matches = line.match(variantPattern);
|
|
9371
|
-
if (matches) {
|
|
9372
|
-
for (const match of matches) {
|
|
9373
|
-
if (match.includes(":")) {
|
|
9374
|
-
variantChains.push(match);
|
|
9375
|
-
}
|
|
9376
|
-
}
|
|
9377
|
-
}
|
|
9378
|
-
}
|
|
9379
|
-
return [...new Set(variantChains)];
|
|
9380
|
-
}
|
|
9381
|
-
extractDependencies(className, _css) {
|
|
9382
|
-
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9383
|
-
const parts = normalizedClass.split(":");
|
|
9384
|
-
const dependencies = parts.slice(0, -1).map((_, i) => parts.slice(0, i + 1).join(":"));
|
|
9385
|
-
return dependencies;
|
|
9386
|
-
}
|
|
9387
|
-
checkIsDeadCode(className, scanResult, css) {
|
|
9388
|
-
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9389
|
-
const cssClasses = this.extractClassesFromCss(css);
|
|
9390
|
-
if (!cssClasses.includes(normalizedClass)) {
|
|
9391
|
-
return true;
|
|
9392
|
-
}
|
|
9393
|
-
const usageCount = this.countClassUsage(normalizedClass, scanResult);
|
|
9394
|
-
return usageCount === 0;
|
|
9395
|
-
}
|
|
9396
|
-
extractClassesFromCss(css) {
|
|
9397
|
-
const classes = [];
|
|
9398
|
-
const classPattern = /\.([a-zA-Z0-9_-]+(?::[a-zA-Z0-9_-]+)*)/g;
|
|
9399
|
-
for (const match of css.matchAll(classPattern)) {
|
|
9400
|
-
const className = match[1];
|
|
9401
|
-
if (!classes.includes(className)) {
|
|
9402
|
-
classes.push(className);
|
|
9403
|
-
}
|
|
9388
|
+
const native = getNativeEngineBinding();
|
|
9389
|
+
if (!native.detectDeadCode) {
|
|
9390
|
+
throw new Error("FATAL: Native binding 'detectDeadCode' is required but not available.");
|
|
9404
9391
|
}
|
|
9405
|
-
|
|
9392
|
+
const r = native.detectDeadCode(JSON.stringify(scanResult), css);
|
|
9393
|
+
return r?.deadInCss ?? [];
|
|
9406
9394
|
}
|
|
9407
9395
|
};
|
|
9408
9396
|
|
|
9409
9397
|
// packages/domain/engine/src/impactTracker.ts
|
|
9410
9398
|
var ImpactTracker = class {
|
|
9411
9399
|
bundleAnalyzer;
|
|
9412
|
-
criticalPatterns = [
|
|
9413
|
-
"fixed",
|
|
9414
|
-
"absolute",
|
|
9415
|
-
"sticky",
|
|
9416
|
-
"z-50",
|
|
9417
|
-
"z-index",
|
|
9418
|
-
"top-0",
|
|
9419
|
-
"right-0",
|
|
9420
|
-
"bottom-0",
|
|
9421
|
-
"left-0",
|
|
9422
|
-
"w-full",
|
|
9423
|
-
"h-full",
|
|
9424
|
-
"min-h-screen",
|
|
9425
|
-
"flex",
|
|
9426
|
-
"grid",
|
|
9427
|
-
"block",
|
|
9428
|
-
"inline",
|
|
9429
|
-
"hidden",
|
|
9430
|
-
"visible",
|
|
9431
|
-
"opacity",
|
|
9432
|
-
"pointer-events",
|
|
9433
|
-
"cursor"
|
|
9434
|
-
];
|
|
9435
9400
|
constructor() {
|
|
9436
9401
|
this.bundleAnalyzer = new BundleAnalyzer();
|
|
9437
9402
|
}
|
|
9438
|
-
/**
|
|
9439
|
-
* Analisis impact sebuah class menggunakan BundleAnalyzer untuk dapat
|
|
9440
|
-
* data akurat tentang bundle size contribution.
|
|
9441
|
-
*
|
|
9442
|
-
* @param className - Tailwind class yang ingin dianalisis
|
|
9443
|
-
* @param scanResult - Hasil scan workspace
|
|
9444
|
-
* @param css - CSS string dari build output (opsional — jika tidak ada, gunakan estimasi)
|
|
9445
|
-
*/
|
|
9446
9403
|
analyzeWithBundle(className, scanResult, css = "") {
|
|
9447
9404
|
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9469
|
-
|
|
9470
|
-
dependencies: []
|
|
9471
|
-
};
|
|
9472
|
-
})();
|
|
9473
|
-
return this.calculateImpact(normalizedClass, resolvedBundleAnalysis, scanResult);
|
|
9405
|
+
const native = getNativeEngineBinding();
|
|
9406
|
+
if (!native?.calculateImpactScores) {
|
|
9407
|
+
throw new Error("FATAL: Native binding 'calculateImpactScores' is required but not available.");
|
|
9408
|
+
}
|
|
9409
|
+
const scores = native.calculateImpactScores(
|
|
9410
|
+
[normalizedClass],
|
|
9411
|
+
JSON.stringify(scanResult),
|
|
9412
|
+
css,
|
|
9413
|
+
0.6,
|
|
9414
|
+
0.4
|
|
9415
|
+
);
|
|
9416
|
+
const score = scores[0];
|
|
9417
|
+
const bundleAnalysis = {
|
|
9418
|
+
className: normalizedClass,
|
|
9419
|
+
totalUsage: score?.usageCount ?? 0,
|
|
9420
|
+
files: [],
|
|
9421
|
+
bundleSizeBytes: score?.sizeBytes ?? 0,
|
|
9422
|
+
variantChains: [],
|
|
9423
|
+
isDeadCode: (score?.usageCount ?? 0) === 0,
|
|
9424
|
+
dependencies: []
|
|
9425
|
+
};
|
|
9426
|
+
return this.calculateImpact(normalizedClass, bundleAnalysis, scanResult, score);
|
|
9474
9427
|
}
|
|
9475
|
-
/**
|
|
9476
|
-
* Analisis semua class dalam workspace sekaligus.
|
|
9477
|
-
*/
|
|
9478
9428
|
analyzeAll(scanResult, css = "") {
|
|
9479
|
-
const
|
|
9429
|
+
const native = getNativeEngineBinding();
|
|
9430
|
+
if (!native?.calculateImpactScores) {
|
|
9431
|
+
throw new Error("FATAL: Native binding 'calculateImpactScores' is required but not available.");
|
|
9432
|
+
}
|
|
9480
9433
|
const classes = scanResult?.uniqueClasses ?? [];
|
|
9434
|
+
const scores = native.calculateImpactScores(
|
|
9435
|
+
classes,
|
|
9436
|
+
JSON.stringify(scanResult),
|
|
9437
|
+
css,
|
|
9438
|
+
0.6,
|
|
9439
|
+
0.4
|
|
9440
|
+
);
|
|
9441
|
+
const scoreMap = new Map(scores.map((s) => [s.className, s]));
|
|
9442
|
+
const results = /* @__PURE__ */ new Map();
|
|
9481
9443
|
for (const cls of classes) {
|
|
9482
|
-
|
|
9483
|
-
|
|
9484
|
-
|
|
9485
|
-
|
|
9444
|
+
const score = scoreMap.get(cls);
|
|
9445
|
+
const bundleAnalysis = {
|
|
9446
|
+
className: cls,
|
|
9447
|
+
totalUsage: score?.usageCount ?? 0,
|
|
9448
|
+
files: [],
|
|
9449
|
+
bundleSizeBytes: score?.sizeBytes ?? 0,
|
|
9450
|
+
variantChains: [],
|
|
9451
|
+
isDeadCode: (score?.usageCount ?? 0) === 0,
|
|
9452
|
+
dependencies: []
|
|
9453
|
+
};
|
|
9454
|
+
results.set(cls, this.calculateImpact(cls, bundleAnalysis, scanResult, score));
|
|
9486
9455
|
}
|
|
9487
9456
|
return results;
|
|
9488
9457
|
}
|
|
9489
|
-
calculateImpact(className, bundleAnalysis, scanResult) {
|
|
9490
|
-
if (!className || className.trim() === "")
|
|
9491
|
-
|
|
9492
|
-
}
|
|
9493
|
-
if (!bundleAnalysis) {
|
|
9494
|
-
return this.createEmptyReport(className);
|
|
9495
|
-
}
|
|
9458
|
+
calculateImpact(className, bundleAnalysis, scanResult, nativeScore) {
|
|
9459
|
+
if (!className || className.trim() === "") return this.createEmptyReport(className);
|
|
9460
|
+
if (!bundleAnalysis) return this.createEmptyReport(className);
|
|
9496
9461
|
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9497
|
-
const
|
|
9498
|
-
const directUsage =
|
|
9499
|
-
const indirectUsage =
|
|
9500
|
-
const totalComponents = affectedComponents.length;
|
|
9462
|
+
const totalComponents = nativeScore?.usageCount ?? bundleAnalysis.totalUsage ?? 0;
|
|
9463
|
+
const directUsage = totalComponents;
|
|
9464
|
+
const indirectUsage = 0;
|
|
9501
9465
|
const bundleSizeBytes = bundleAnalysis.bundleSizeBytes || 0;
|
|
9502
|
-
const
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9511
|
-
|
|
9512
|
-
|
|
9513
|
-
|
|
9514
|
-
|
|
9515
|
-
|
|
9466
|
+
const native = getNativeEngineBinding();
|
|
9467
|
+
if (native?.computeImpactMetadata) {
|
|
9468
|
+
const impactJson = JSON.stringify({
|
|
9469
|
+
className: normalizedClass,
|
|
9470
|
+
totalComponents,
|
|
9471
|
+
indirectUsage,
|
|
9472
|
+
bundleSizeBytes
|
|
9473
|
+
});
|
|
9474
|
+
const result = JSON.parse(native.computeImpactMetadata(normalizedClass, impactJson));
|
|
9475
|
+
return {
|
|
9476
|
+
className: normalizedClass,
|
|
9477
|
+
totalComponents,
|
|
9478
|
+
directUsage,
|
|
9479
|
+
indirectUsage,
|
|
9480
|
+
bundleSizeBytes,
|
|
9481
|
+
estimatedSavings: result.estimatedSavings,
|
|
9482
|
+
riskLevel: result.riskLevel,
|
|
9483
|
+
suggestions: result.suggestions
|
|
9484
|
+
};
|
|
9485
|
+
}
|
|
9486
|
+
if (native?.calculateImpact) {
|
|
9487
|
+
const impactJson = JSON.stringify({
|
|
9488
|
+
className: normalizedClass,
|
|
9489
|
+
totalComponents,
|
|
9490
|
+
indirectUsage,
|
|
9491
|
+
bundleSizeBytes
|
|
9492
|
+
});
|
|
9493
|
+
const result = JSON.parse(native.calculateImpact(impactJson));
|
|
9494
|
+
return {
|
|
9495
|
+
className: normalizedClass,
|
|
9496
|
+
totalComponents,
|
|
9497
|
+
directUsage,
|
|
9498
|
+
indirectUsage,
|
|
9499
|
+
bundleSizeBytes,
|
|
9500
|
+
estimatedSavings: result.estimatedSavings,
|
|
9501
|
+
riskLevel: result.riskLevel,
|
|
9502
|
+
suggestions: result.suggestions
|
|
9503
|
+
};
|
|
9504
|
+
}
|
|
9505
|
+
throw new Error("FATAL: Native binding 'computeImpactMetadata' or 'calculateImpact' is required but not available.");
|
|
9516
9506
|
}
|
|
9517
9507
|
findAffectedComponents(className, scanResult) {
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
if (!scanResult || !Array.isArray(scanResult.files)) {
|
|
9523
|
-
return components;
|
|
9508
|
+
if (!className || !scanResult) return [];
|
|
9509
|
+
const native = getNativeEngineBinding();
|
|
9510
|
+
if (!native?.calculateImpactScores) {
|
|
9511
|
+
throw new Error("FATAL: Native binding 'calculateImpactScores' is required but not available.");
|
|
9524
9512
|
}
|
|
9525
9513
|
const normalizedClass = className.startsWith(".") ? className.slice(1) : className;
|
|
9526
|
-
const
|
|
9514
|
+
const scores = native.calculateImpactScores(
|
|
9515
|
+
[normalizedClass],
|
|
9516
|
+
JSON.stringify(scanResult),
|
|
9517
|
+
"",
|
|
9518
|
+
1,
|
|
9519
|
+
0
|
|
9520
|
+
);
|
|
9521
|
+
if (!scores[0]?.usageCount) return [];
|
|
9522
|
+
const components = [];
|
|
9527
9523
|
for (const file of scanResult.files) {
|
|
9528
|
-
if (!file
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
|
|
9535
|
-
if (normalizedFileClass === normalizedClass) {
|
|
9536
|
-
components.push({
|
|
9537
|
-
file: filePath,
|
|
9538
|
-
line: file.lineNumbers?.[i] || 1,
|
|
9539
|
-
column: file.columnNumbers?.[i] || 1,
|
|
9540
|
-
usageType: "direct"
|
|
9541
|
-
});
|
|
9542
|
-
} else if (normalizedFileClass.includes(normalizedClass)) {
|
|
9543
|
-
const variant = classParts.length > 1 ? classParts[0] : void 0;
|
|
9544
|
-
components.push({
|
|
9545
|
-
file: filePath,
|
|
9546
|
-
line: file.lineNumbers?.[i] || 1,
|
|
9547
|
-
column: file.columnNumbers?.[i] || 1,
|
|
9548
|
-
usageType: "variant",
|
|
9549
|
-
variant
|
|
9550
|
-
});
|
|
9551
|
-
}
|
|
9552
|
-
}
|
|
9553
|
-
for (const [i, variant] of variants.entries()) {
|
|
9554
|
-
if (!variant) continue;
|
|
9555
|
-
if (variant.includes(normalizedClass)) {
|
|
9556
|
-
const baseClass = variant.split(":").pop();
|
|
9557
|
-
if (baseClass === normalizedClass) {
|
|
9558
|
-
components.push({
|
|
9559
|
-
file: filePath,
|
|
9560
|
-
line: file.lineNumbers?.[i] || 1,
|
|
9561
|
-
column: file.columnNumbers?.[i] || 1,
|
|
9562
|
-
usageType: "variant",
|
|
9563
|
-
variant: variant.split(":")[0]
|
|
9564
|
-
});
|
|
9565
|
-
}
|
|
9566
|
-
}
|
|
9567
|
-
}
|
|
9524
|
+
if (!file.classes?.includes(normalizedClass)) continue;
|
|
9525
|
+
components.push({
|
|
9526
|
+
file: file.file,
|
|
9527
|
+
line: 1,
|
|
9528
|
+
column: 1,
|
|
9529
|
+
usageType: "direct"
|
|
9530
|
+
});
|
|
9568
9531
|
}
|
|
9569
9532
|
return components;
|
|
9570
9533
|
}
|
|
9571
|
-
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9576
|
-
|
|
9577
|
-
|
|
9578
|
-
|
|
9579
|
-
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
|
|
9585
|
-
|
|
9586
|
-
return "medium";
|
|
9534
|
+
/**
|
|
9535
|
+
* Cek apakah sebuah class dianggap "critical" (tidak boleh dihapus).
|
|
9536
|
+
*
|
|
9537
|
+
* Native: Rust `is_critical_class()` — O(n) pattern match di CRITICAL_PATTERNS.
|
|
9538
|
+
* Lebih cepat dari regex JS untuk daftar panjang karena no backtracking.
|
|
9539
|
+
*
|
|
9540
|
+
* @example
|
|
9541
|
+
* tracker.isCriticalClass("sr-only") // true
|
|
9542
|
+
* tracker.isCriticalClass("hidden") // true
|
|
9543
|
+
* tracker.isCriticalClass("bg-red-500") // false
|
|
9544
|
+
*/
|
|
9545
|
+
isCriticalClass(className) {
|
|
9546
|
+
const native = getNativeEngineBinding();
|
|
9547
|
+
if (native?.isCriticalClass) {
|
|
9548
|
+
return native.isCriticalClass(className);
|
|
9587
9549
|
}
|
|
9588
|
-
return
|
|
9550
|
+
return false;
|
|
9589
9551
|
}
|
|
9590
|
-
|
|
9591
|
-
|
|
9592
|
-
|
|
9593
|
-
|
|
9594
|
-
|
|
9595
|
-
|
|
9596
|
-
|
|
9597
|
-
|
|
9598
|
-
|
|
9599
|
-
|
|
9600
|
-
|
|
9601
|
-
|
|
9602
|
-
`This class is used in ${impact.totalComponents} components. Consider creating a utility component instead.`
|
|
9603
|
-
);
|
|
9604
|
-
}
|
|
9605
|
-
if (this.isCriticalClass(normalizedClass)) {
|
|
9606
|
-
suggestions.push(
|
|
9607
|
-
"This is a critical positioning/display class. Review all usages before removal."
|
|
9608
|
-
);
|
|
9609
|
-
}
|
|
9610
|
-
suggestions.push("Manual code review recommended before removing this class.");
|
|
9611
|
-
} else if (impact.riskLevel === "medium") {
|
|
9612
|
-
suggestions.push(
|
|
9613
|
-
`This class is used in ${impact.totalComponents} components. Test each component after removal.`
|
|
9614
|
-
);
|
|
9615
|
-
if (impact.indirectUsage > 0) {
|
|
9616
|
-
suggestions.push("Check for indirect usages via variants before removing.");
|
|
9617
|
-
}
|
|
9618
|
-
} else {
|
|
9619
|
-
if (impact.totalComponents > 0) {
|
|
9620
|
-
suggestions.push("Low risk: class is used in fewer than 5 components.");
|
|
9621
|
-
} else {
|
|
9622
|
-
suggestions.push("This class appears to be unused. Consider removing it.");
|
|
9623
|
-
}
|
|
9624
|
-
}
|
|
9625
|
-
if (impact.estimatedSavings > 0) {
|
|
9626
|
-
suggestions.push(`Estimated bundle size savings: ~${impact.estimatedSavings} bytes.`);
|
|
9627
|
-
}
|
|
9628
|
-
if (impact.bundleSizeBytes > 100) {
|
|
9629
|
-
suggestions.push(
|
|
9630
|
-
"This class has significant CSS bundle contribution. Removal will improve load times."
|
|
9631
|
-
);
|
|
9552
|
+
/**
|
|
9553
|
+
* Generate human-readable suggestions berdasarkan impact analysis.
|
|
9554
|
+
*
|
|
9555
|
+
* Native: `generate_suggestions()` di Rust — pattern matching di CRITICAL_PATTERNS
|
|
9556
|
+
* + threshold-based risk categories.
|
|
9557
|
+
*
|
|
9558
|
+
* Biasanya dipanggil setelah `calculateImpact` yang sudah set riskLevel.
|
|
9559
|
+
*/
|
|
9560
|
+
generateSuggestions(className, report) {
|
|
9561
|
+
const native = getNativeEngineBinding();
|
|
9562
|
+
if (native?.generateSuggestions) {
|
|
9563
|
+
return native.generateSuggestions(className, JSON.stringify(report));
|
|
9632
9564
|
}
|
|
9633
|
-
return
|
|
9634
|
-
}
|
|
9635
|
-
isCriticalClass(className) {
|
|
9636
|
-
const normalized = className.startsWith(".") ? className.slice(1) : className;
|
|
9637
|
-
return this.criticalPatterns.some(
|
|
9638
|
-
(pattern) => normalized === pattern || normalized.startsWith(`${pattern}:`)
|
|
9639
|
-
);
|
|
9640
|
-
}
|
|
9641
|
-
calculateSavings(bundleSize, componentCount) {
|
|
9642
|
-
const baseSavings = bundleSize;
|
|
9643
|
-
const componentOverhead = componentCount * 50;
|
|
9644
|
-
return Math.max(0, baseSavings - componentOverhead);
|
|
9565
|
+
return [];
|
|
9645
9566
|
}
|
|
9646
9567
|
createEmptyReport(className) {
|
|
9647
|
-
const normalizedClass = className?.startsWith(".") ? className.slice(1) : className || "";
|
|
9648
9568
|
return {
|
|
9649
|
-
className:
|
|
9569
|
+
className: className?.startsWith(".") ? className.slice(1) : className || "",
|
|
9650
9570
|
totalComponents: 0,
|
|
9651
9571
|
directUsage: 0,
|
|
9652
9572
|
indirectUsage: 0,
|
|
@@ -9668,6 +9588,15 @@ var RuleId = class {
|
|
|
9668
9588
|
return `R${this.value}`;
|
|
9669
9589
|
}
|
|
9670
9590
|
};
|
|
9591
|
+
var SelectorId = class {
|
|
9592
|
+
constructor(value) {
|
|
9593
|
+
this.value = value;
|
|
9594
|
+
}
|
|
9595
|
+
value;
|
|
9596
|
+
toString() {
|
|
9597
|
+
return `S${this.value}`;
|
|
9598
|
+
}
|
|
9599
|
+
};
|
|
9671
9600
|
var VariantChainId = class {
|
|
9672
9601
|
constructor(value) {
|
|
9673
9602
|
this.value = value;
|
|
@@ -9725,322 +9654,308 @@ var ConditionId = class {
|
|
|
9725
9654
|
return `C${this.value}`;
|
|
9726
9655
|
}
|
|
9727
9656
|
};
|
|
9728
|
-
var
|
|
9729
|
-
|
|
9657
|
+
var CascadeResolutionId = class {
|
|
9658
|
+
constructor(value) {
|
|
9659
|
+
this.value = value;
|
|
9660
|
+
}
|
|
9661
|
+
value;
|
|
9662
|
+
toString() {
|
|
9663
|
+
return `R${this.value}`;
|
|
9664
|
+
}
|
|
9665
|
+
};
|
|
9666
|
+
var _propertyNamesFallback = /* @__PURE__ */ new Map();
|
|
9667
|
+
var _valueNamesFallback = /* @__PURE__ */ new Map();
|
|
9668
|
+
function registerPropertyName(id, name) {
|
|
9669
|
+
const native = getNativeEngineBinding();
|
|
9670
|
+
if (native?.registerPropertyName) {
|
|
9671
|
+
native.registerPropertyName(id.value, name);
|
|
9672
|
+
return;
|
|
9673
|
+
}
|
|
9674
|
+
_propertyNamesFallback.set(id.value, name);
|
|
9675
|
+
}
|
|
9676
|
+
function registerValueName(id, name) {
|
|
9677
|
+
const native = getNativeEngineBinding();
|
|
9678
|
+
if (native?.registerValueName) {
|
|
9679
|
+
native.registerValueName(id.value, name);
|
|
9680
|
+
return;
|
|
9681
|
+
}
|
|
9682
|
+
_valueNamesFallback.set(id.value, name);
|
|
9683
|
+
}
|
|
9730
9684
|
function propertyIdToString(id) {
|
|
9731
|
-
|
|
9685
|
+
const native = getNativeEngineBinding();
|
|
9686
|
+
if (native?.propertyIdToString) {
|
|
9687
|
+
return native.propertyIdToString(id.value);
|
|
9688
|
+
}
|
|
9689
|
+
return _propertyNamesFallback.get(id.value) ?? `P${id.value}`;
|
|
9732
9690
|
}
|
|
9733
9691
|
function valueIdToString(id) {
|
|
9734
|
-
|
|
9735
|
-
|
|
9736
|
-
|
|
9692
|
+
const native = getNativeEngineBinding();
|
|
9693
|
+
if (native?.valueIdToString) {
|
|
9694
|
+
return native.valueIdToString(id.value);
|
|
9695
|
+
}
|
|
9696
|
+
return _valueNamesFallback.get(id.value) ?? `V${id.value}`;
|
|
9697
|
+
}
|
|
9698
|
+
var CascadeStage = /* @__PURE__ */ ((CascadeStage2) => {
|
|
9699
|
+
CascadeStage2[CascadeStage2["Origin"] = 0] = "Origin";
|
|
9700
|
+
CascadeStage2[CascadeStage2["Layer"] = 1] = "Layer";
|
|
9701
|
+
CascadeStage2[CascadeStage2["Importance"] = 2] = "Importance";
|
|
9702
|
+
CascadeStage2[CascadeStage2["Specificity"] = 3] = "Specificity";
|
|
9703
|
+
CascadeStage2[CascadeStage2["Order"] = 4] = "Order";
|
|
9704
|
+
return CascadeStage2;
|
|
9705
|
+
})(CascadeStage || {});
|
|
9706
|
+
function createFingerprintFallback(parts) {
|
|
9737
9707
|
const hash = parts.reduce(
|
|
9738
9708
|
(acc, part) => part.split("").reduce((h, char) => (h << 5) - h + char.charCodeAt(0) & h, acc),
|
|
9739
9709
|
0
|
|
9740
9710
|
);
|
|
9741
9711
|
return Math.abs(hash).toString(36);
|
|
9742
9712
|
}
|
|
9713
|
+
function createFingerprint(parts) {
|
|
9714
|
+
const native = getNativeEngineBinding();
|
|
9715
|
+
if (native?.createFingerprint) {
|
|
9716
|
+
return native.createFingerprint(parts);
|
|
9717
|
+
}
|
|
9718
|
+
return createFingerprintFallback(parts);
|
|
9719
|
+
}
|
|
9743
9720
|
|
|
9744
9721
|
// packages/domain/engine/src/reverseLookup.ts
|
|
9745
|
-
|
|
9746
|
-
|
|
9747
|
-
|
|
9748
|
-
|
|
9749
|
-
|
|
9750
|
-
|
|
9751
|
-
// 10MB
|
|
9752
|
-
parseCSS(css) {
|
|
9753
|
-
const cached = this.parsedCache.get(css);
|
|
9754
|
-
if (cached) {
|
|
9755
|
-
return cached;
|
|
9756
|
-
}
|
|
9757
|
-
try {
|
|
9758
|
-
const native = (() => {
|
|
9759
|
-
try {
|
|
9760
|
-
return getNativeEngineBinding();
|
|
9761
|
-
} catch {
|
|
9762
|
-
return null;
|
|
9763
|
-
}
|
|
9764
|
-
})();
|
|
9765
|
-
if (native?.parseCssRulesNative) {
|
|
9766
|
-
const raw = native.parseCssRulesNative(css);
|
|
9767
|
-
const rules2 = (raw ?? []).map((r) => ({
|
|
9768
|
-
className: r.className,
|
|
9769
|
-
property: r.property,
|
|
9770
|
-
value: r.value,
|
|
9771
|
-
specificity: r.specificity,
|
|
9772
|
-
source: { file: "", line: 0, column: 0 },
|
|
9773
|
-
isImportant: r.isImportant,
|
|
9774
|
-
variants: r.variants,
|
|
9775
|
-
isOverride: false
|
|
9776
|
-
}));
|
|
9777
|
-
this.pruneCache();
|
|
9778
|
-
this.parsedCache.set(css, rules2);
|
|
9779
|
-
return rules2;
|
|
9780
|
-
}
|
|
9781
|
-
} catch {
|
|
9782
|
-
}
|
|
9783
|
-
const rules = [];
|
|
9784
|
-
const classMap = /* @__PURE__ */ new Map();
|
|
9785
|
-
const selectorRegex = /\.([a-zA-Z_][a-zA-Z0-9_-]*)/g;
|
|
9786
|
-
const propertyRegex = /([a-zA-Z-]+)\s*:\s*([^;]+)/g;
|
|
9787
|
-
const importantRegex = /!important\s*;?\s*$/;
|
|
9788
|
-
const lines = css.split("\n");
|
|
9789
|
-
const columnState = { offset: 0 };
|
|
9790
|
-
for (const [i, line] of lines.entries()) {
|
|
9791
|
-
const lineEnd = columnState.offset + line.length + 1;
|
|
9792
|
-
for (const match of line.matchAll(selectorRegex)) {
|
|
9793
|
-
const className = match[1];
|
|
9794
|
-
const selectorStart = match.index;
|
|
9795
|
-
const lineColumn = selectorStart + 1;
|
|
9796
|
-
if (!classMap.has(className)) {
|
|
9797
|
-
classMap.set(className, /* @__PURE__ */ new Map());
|
|
9798
|
-
}
|
|
9799
|
-
const braceMatch = css.indexOf("{", lineEnd - 1);
|
|
9800
|
-
if (braceMatch !== -1) {
|
|
9801
|
-
const closingBraceMatch = this.findClosingBrace(css, braceMatch);
|
|
9802
|
-
const ruleContent = css.substring(braceMatch + 1, closingBraceMatch);
|
|
9803
|
-
const variants = [];
|
|
9804
|
-
const variantMatch = className.match(/^(.+?)(?::([a-zA-Z0-9_-]+))?$/);
|
|
9805
|
-
if (variantMatch?.[2]) {
|
|
9806
|
-
variants.push(variantMatch[2]);
|
|
9807
|
-
}
|
|
9808
|
-
const specificity = this.calculateSpecificity(className);
|
|
9809
|
-
const source = {
|
|
9810
|
-
file: "inline",
|
|
9811
|
-
line: i + 1,
|
|
9812
|
-
column: lineColumn
|
|
9813
|
-
};
|
|
9814
|
-
for (const propMatch of ruleContent.matchAll(propertyRegex)) {
|
|
9815
|
-
const property = propMatch[1].trim();
|
|
9816
|
-
const rawValue = propMatch[2].trim();
|
|
9817
|
-
const isImportant = importantRegex.test(rawValue);
|
|
9818
|
-
const value = isImportant ? rawValue.replace(importantRegex, "").trim() : rawValue;
|
|
9819
|
-
const rule = {
|
|
9820
|
-
className,
|
|
9821
|
-
property,
|
|
9822
|
-
value,
|
|
9823
|
-
specificity,
|
|
9824
|
-
source,
|
|
9825
|
-
isImportant,
|
|
9826
|
-
variants,
|
|
9827
|
-
isOverride: false
|
|
9828
|
-
};
|
|
9829
|
-
rules.push(rule);
|
|
9830
|
-
const classRules = classMap.get(className);
|
|
9831
|
-
const existingProp = classRules.get(property);
|
|
9832
|
-
if (existingProp) {
|
|
9833
|
-
rule.isOverride = true;
|
|
9834
|
-
}
|
|
9835
|
-
classRules.set(property, rule);
|
|
9836
|
-
}
|
|
9837
|
-
}
|
|
9838
|
-
}
|
|
9839
|
-
columnState.offset = lineEnd;
|
|
9840
|
-
}
|
|
9841
|
-
this.pruneCache();
|
|
9842
|
-
this.parsedCache.set(css, rules);
|
|
9843
|
-
return rules;
|
|
9722
|
+
function getNative() {
|
|
9723
|
+
const native = getNativeEngineBinding();
|
|
9724
|
+
if (!native?.reverseLookupFromCss || !native?.reverseLookupByProperty || !native?.reverseLookupFindDependents) {
|
|
9725
|
+
throw new Error(
|
|
9726
|
+
"FATAL: Native bindings 'reverseLookupFromCss', 'reverseLookupByProperty', 'reverseLookupFindDependents' are required but not available.\nBuild the native Rust module: npm run build:rust"
|
|
9727
|
+
);
|
|
9844
9728
|
}
|
|
9845
|
-
|
|
9846
|
-
|
|
9847
|
-
|
|
9848
|
-
|
|
9849
|
-
|
|
9850
|
-
|
|
9851
|
-
|
|
9852
|
-
|
|
9853
|
-
}
|
|
9854
|
-
|
|
9855
|
-
|
|
9729
|
+
return native;
|
|
9730
|
+
}
|
|
9731
|
+
function normaliseNativeResults(raw) {
|
|
9732
|
+
return raw.map((r) => ({
|
|
9733
|
+
property: r.property,
|
|
9734
|
+
value: r.value,
|
|
9735
|
+
usedInClasses: r.usedInClasses.map((u) => ({
|
|
9736
|
+
className: u.className,
|
|
9737
|
+
source: { file: "", line: 0, column: 0 },
|
|
9738
|
+
specificity: u.specificity,
|
|
9739
|
+
isOverride: u.isOverride,
|
|
9740
|
+
variants: u.variants
|
|
9741
|
+
}))
|
|
9742
|
+
}));
|
|
9743
|
+
}
|
|
9744
|
+
var ReverseLookup = class {
|
|
9745
|
+
fromCSS(cssProperty, cssValue, css) {
|
|
9746
|
+
if (!css || !cssProperty) return [];
|
|
9747
|
+
return normaliseNativeResults(getNative().reverseLookupFromCss(css, cssProperty, cssValue));
|
|
9856
9748
|
}
|
|
9857
|
-
|
|
9858
|
-
|
|
9859
|
-
|
|
9860
|
-
const pseudoElements = className.match(/::[a-zA-Z-]+/g) || [];
|
|
9861
|
-
return 1 + pseudoClasses.length * 10 + attributes.length * 10 + pseudoElements.length * 100;
|
|
9749
|
+
findByProperty(property, css) {
|
|
9750
|
+
if (!css || !property) return [];
|
|
9751
|
+
return normaliseNativeResults(getNative().reverseLookupByProperty(css, property));
|
|
9862
9752
|
}
|
|
9863
|
-
|
|
9864
|
-
if (!css || !
|
|
9865
|
-
|
|
9866
|
-
}
|
|
9867
|
-
const rules = this.parseCSS(css);
|
|
9868
|
-
const normalizedProperty = cssProperty.toLowerCase();
|
|
9869
|
-
const normalizedValue = cssValue.toLowerCase().trim();
|
|
9870
|
-
const usages = [];
|
|
9871
|
-
for (const rule of rules) {
|
|
9872
|
-
if (rule.property.toLowerCase() !== normalizedProperty) {
|
|
9873
|
-
continue;
|
|
9874
|
-
}
|
|
9875
|
-
const ruleValueLower = rule.value.toLowerCase().trim();
|
|
9876
|
-
if (ruleValueLower !== normalizedValue && !ruleValueLower.includes(normalizedValue)) {
|
|
9877
|
-
continue;
|
|
9878
|
-
}
|
|
9879
|
-
usages.push({
|
|
9880
|
-
className: rule.className,
|
|
9881
|
-
source: rule.source,
|
|
9882
|
-
specificity: rule.specificity,
|
|
9883
|
-
isOverride: rule.isOverride || false,
|
|
9884
|
-
variants: rule.variants
|
|
9885
|
-
});
|
|
9886
|
-
}
|
|
9887
|
-
if (usages.length === 0) {
|
|
9888
|
-
return [];
|
|
9889
|
-
}
|
|
9890
|
-
return [{ property: normalizedProperty, value: cssValue, usedInClasses: usages }];
|
|
9753
|
+
findDependents(className, css) {
|
|
9754
|
+
if (!css || !className) return [];
|
|
9755
|
+
return getNative().reverseLookupFindDependents(css, className);
|
|
9891
9756
|
}
|
|
9892
9757
|
fromBundle(className, css) {
|
|
9893
|
-
if (!css || !className)
|
|
9894
|
-
|
|
9758
|
+
if (!css || !className) return [];
|
|
9759
|
+
const native = getNativeEngineBinding();
|
|
9760
|
+
if (!native?.parseCssRules) {
|
|
9761
|
+
throw new Error("FATAL: Native binding 'parseCssRules' is required but not available.");
|
|
9895
9762
|
}
|
|
9896
|
-
const
|
|
9763
|
+
const raw = native.parseCssRules(css);
|
|
9897
9764
|
const results = [];
|
|
9898
|
-
for (const rule of
|
|
9899
|
-
if (rule.className
|
|
9900
|
-
|
|
9901
|
-
|
|
9902
|
-
|
|
9903
|
-
|
|
9904
|
-
|
|
9905
|
-
|
|
9906
|
-
|
|
9907
|
-
|
|
9908
|
-
|
|
9909
|
-
|
|
9910
|
-
|
|
9911
|
-
|
|
9912
|
-
|
|
9913
|
-
|
|
9914
|
-
|
|
9915
|
-
|
|
9916
|
-
|
|
9917
|
-
results.push(ruleIR);
|
|
9918
|
-
}
|
|
9765
|
+
for (const rule of raw ?? []) {
|
|
9766
|
+
if (rule.className !== className && !rule.className.startsWith(`${className}:`)) continue;
|
|
9767
|
+
results.push({
|
|
9768
|
+
id: { value: results.length },
|
|
9769
|
+
selector: { value: 0 },
|
|
9770
|
+
variantChain: { value: 0 },
|
|
9771
|
+
property: { value: 0 },
|
|
9772
|
+
value: { value: 0 },
|
|
9773
|
+
origin: 2,
|
|
9774
|
+
importance: rule.isImportant ? 1 : 0,
|
|
9775
|
+
layer: null,
|
|
9776
|
+
layerOrder: 0,
|
|
9777
|
+
specificity: rule.specificity,
|
|
9778
|
+
condition: null,
|
|
9779
|
+
conditionResult: 0,
|
|
9780
|
+
insertionOrder: results.length,
|
|
9781
|
+
fingerprint: "",
|
|
9782
|
+
source: { file: "", line: 0, column: 0 }
|
|
9783
|
+
});
|
|
9919
9784
|
}
|
|
9920
9785
|
return results;
|
|
9921
9786
|
}
|
|
9922
|
-
|
|
9923
|
-
|
|
9924
|
-
return [];
|
|
9925
|
-
}
|
|
9926
|
-
const rules = this.parseCSS(css);
|
|
9927
|
-
const dependents = /* @__PURE__ */ new Set();
|
|
9928
|
-
const classParts = className.split(":");
|
|
9929
|
-
const baseClass = classParts[0];
|
|
9930
|
-
for (const rule of rules) {
|
|
9931
|
-
const ruleBaseClass = rule.className.split(":")[0];
|
|
9932
|
-
if (ruleBaseClass === baseClass && rule.className !== className) {
|
|
9933
|
-
dependents.add(rule.className);
|
|
9934
|
-
}
|
|
9935
|
-
if (rule.className.includes(baseClass) && rule.className !== className) {
|
|
9936
|
-
const isVariant = rule.className.includes(":");
|
|
9937
|
-
if (isVariant && !rule.className.startsWith(`${className}:`)) {
|
|
9938
|
-
dependents.add(rule.className);
|
|
9939
|
-
}
|
|
9940
|
-
}
|
|
9941
|
-
}
|
|
9942
|
-
return Array.from(dependents);
|
|
9787
|
+
clearCache() {
|
|
9788
|
+
getNativeEngineBinding()?.reverseLookupClearCache?.();
|
|
9943
9789
|
}
|
|
9944
|
-
|
|
9945
|
-
|
|
9946
|
-
|
|
9947
|
-
|
|
9948
|
-
|
|
9949
|
-
|
|
9950
|
-
|
|
9951
|
-
|
|
9952
|
-
|
|
9953
|
-
|
|
9954
|
-
|
|
9955
|
-
|
|
9956
|
-
|
|
9957
|
-
|
|
9958
|
-
|
|
9959
|
-
|
|
9960
|
-
|
|
9961
|
-
|
|
9962
|
-
|
|
9963
|
-
|
|
9964
|
-
|
|
9965
|
-
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9790
|
+
get cacheSize() {
|
|
9791
|
+
return getNativeEngineBinding()?.reverseLookupCacheSize?.() ?? 0;
|
|
9792
|
+
}
|
|
9793
|
+
};
|
|
9794
|
+
|
|
9795
|
+
// packages/domain/engine/src/resolver.ts
|
|
9796
|
+
function toNativeInput(rule) {
|
|
9797
|
+
return {
|
|
9798
|
+
id: rule.id.value,
|
|
9799
|
+
property: rule.property.value,
|
|
9800
|
+
origin: rule.origin,
|
|
9801
|
+
importance: rule.importance,
|
|
9802
|
+
layerOrder: rule.layerOrder,
|
|
9803
|
+
specificity: rule.specificity,
|
|
9804
|
+
conditionResult: rule.conditionResult,
|
|
9805
|
+
insertionOrder: rule.insertionOrder
|
|
9806
|
+
};
|
|
9807
|
+
}
|
|
9808
|
+
function callResolveCascade(rules) {
|
|
9809
|
+
const native = getNativeEngineBinding();
|
|
9810
|
+
if (!native.resolveCascade) {
|
|
9811
|
+
throw new Error(
|
|
9812
|
+
"FATAL: Native binding 'resolveCascade' is required but not available.\nThis function requires native Rust bindings.\n\nResolution steps:\n1. Build the native Rust module: npm run build:rust"
|
|
9813
|
+
);
|
|
9814
|
+
}
|
|
9815
|
+
const json = JSON.stringify(rules.map(toNativeInput));
|
|
9816
|
+
return JSON.parse(native.resolveCascade(json));
|
|
9817
|
+
}
|
|
9818
|
+
function buildResolutionsMap(nativeResult, rules, styleGraph) {
|
|
9819
|
+
const propertyIdMap = /* @__PURE__ */ new Map();
|
|
9820
|
+
for (const rule of rules) {
|
|
9821
|
+
if (!propertyIdMap.has(rule.property.value)) {
|
|
9822
|
+
propertyIdMap.set(rule.property.value, rule.property);
|
|
9823
|
+
}
|
|
9824
|
+
}
|
|
9825
|
+
const resolvedProperties = /* @__PURE__ */ new Map();
|
|
9826
|
+
for (const res of nativeResult.resolutions) {
|
|
9827
|
+
const propertyId = propertyIdMap.get(res.propertyId);
|
|
9828
|
+
if (!propertyId) continue;
|
|
9829
|
+
const winner = { value: res.winnerId };
|
|
9830
|
+
const losers = res.loserIds.map((v) => ({ value: v }));
|
|
9831
|
+
const existing = styleGraph.ruleConflicts.get(winner) ?? [];
|
|
9832
|
+
styleGraph.ruleConflicts.set(winner, [...existing, ...losers.filter((l) => !existing.some((e) => e.value === l.value))]);
|
|
9833
|
+
resolvedProperties.set(propertyId, {
|
|
9834
|
+
id: new CascadeResolutionId(res.id),
|
|
9835
|
+
property: propertyId,
|
|
9836
|
+
winner,
|
|
9837
|
+
losers,
|
|
9838
|
+
reason: { causes: res.causes, finalDecision: res.finalDecision },
|
|
9839
|
+
stage: res.stage
|
|
9840
|
+
});
|
|
9841
|
+
}
|
|
9842
|
+
return resolvedProperties;
|
|
9843
|
+
}
|
|
9844
|
+
var CascadeResolver = class {
|
|
9845
|
+
rules = /* @__PURE__ */ new Map();
|
|
9846
|
+
classRules = /* @__PURE__ */ new Map();
|
|
9847
|
+
styleGraph = { ruleConflicts: /* @__PURE__ */ new Map() };
|
|
9848
|
+
addRule(rule) {
|
|
9849
|
+
this.rules.set(rule.id, rule);
|
|
9850
|
+
}
|
|
9851
|
+
addRules(rules) {
|
|
9852
|
+
for (const rule of rules) this.addRule(rule);
|
|
9853
|
+
}
|
|
9854
|
+
registerClass(className, ruleIds) {
|
|
9855
|
+
this.classRules.set(className, ruleIds);
|
|
9856
|
+
}
|
|
9857
|
+
getRule(ruleId) {
|
|
9858
|
+
return this.rules.get(ruleId);
|
|
9859
|
+
}
|
|
9860
|
+
getClassRules(className) {
|
|
9861
|
+
return this.classRules.get(className);
|
|
9862
|
+
}
|
|
9863
|
+
getStyleGraph() {
|
|
9864
|
+
return this.styleGraph;
|
|
9974
9865
|
}
|
|
9975
9866
|
/**
|
|
9976
|
-
*
|
|
9977
|
-
*
|
|
9867
|
+
* Resolve cascade for a specific class.
|
|
9868
|
+
* Delegates sort + winner selection to Rust.
|
|
9978
9869
|
*/
|
|
9979
|
-
|
|
9980
|
-
this.
|
|
9981
|
-
|
|
9870
|
+
resolveByClassName(className) {
|
|
9871
|
+
const ruleIds = this.classRules.get(className);
|
|
9872
|
+
if (!ruleIds || ruleIds.length === 0) return null;
|
|
9873
|
+
const classRules = ruleIds.map((id) => this.rules.get(id)).filter((r) => r !== void 0);
|
|
9874
|
+
if (classRules.length === 0) return null;
|
|
9875
|
+
const nativeResult = callResolveCascade(classRules);
|
|
9876
|
+
return { resolvedProperties: buildResolutionsMap(nativeResult, classRules, this.styleGraph) };
|
|
9982
9877
|
}
|
|
9983
9878
|
/**
|
|
9984
|
-
*
|
|
9985
|
-
*
|
|
9879
|
+
* Resolve cascade for all rules.
|
|
9880
|
+
* Delegates sort + winner selection to Rust.
|
|
9986
9881
|
*/
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
|
|
9990
|
-
|
|
9991
|
-
|
|
9992
|
-
this.parsedCache.delete(firstKey);
|
|
9993
|
-
this.cacheSizeBytes -= firstKey.length + (removed?.length ?? 0) * 100;
|
|
9994
|
-
if (this.cacheSizeBytes < 0) this.cacheSizeBytes = 0;
|
|
9995
|
-
}
|
|
9882
|
+
resolveAllProperties() {
|
|
9883
|
+
const allRules = Array.from(this.rules.values());
|
|
9884
|
+
if (allRules.length === 0) return /* @__PURE__ */ new Map();
|
|
9885
|
+
const nativeResult = callResolveCascade(allRules);
|
|
9886
|
+
return buildResolutionsMap(nativeResult, allRules, this.styleGraph);
|
|
9996
9887
|
}
|
|
9997
|
-
/**
|
|
9998
|
-
|
|
9999
|
-
|
|
9888
|
+
/**
|
|
9889
|
+
* Resolve cascade for a specific set of rule IDs.
|
|
9890
|
+
*/
|
|
9891
|
+
resolveForClass(classRuleIds) {
|
|
9892
|
+
const classRules = classRuleIds.map((id) => this.rules.get(id)).filter((r) => r !== void 0);
|
|
9893
|
+
if (classRules.length === 0) return /* @__PURE__ */ new Map();
|
|
9894
|
+
const nativeResult = callResolveCascade(classRules);
|
|
9895
|
+
return buildResolutionsMap(nativeResult, classRules, this.styleGraph);
|
|
9896
|
+
}
|
|
9897
|
+
/**
|
|
9898
|
+
* Resolve cascade for a single property bucket.
|
|
9899
|
+
*/
|
|
9900
|
+
resolveProperty(property) {
|
|
9901
|
+
const bucketRuleIds = Array.from(this.rules.values()).filter((r) => r.property.value === property.value);
|
|
9902
|
+
if (bucketRuleIds.length === 0) return null;
|
|
9903
|
+
const nativeResult = callResolveCascade(bucketRuleIds);
|
|
9904
|
+
const resolved = buildResolutionsMap(nativeResult, bucketRuleIds, this.styleGraph);
|
|
9905
|
+
return resolved.get(property) ?? null;
|
|
9906
|
+
}
|
|
9907
|
+
getResolution(_id) {
|
|
9908
|
+
return void 0;
|
|
10000
9909
|
}
|
|
10001
9910
|
};
|
|
10002
9911
|
|
|
10003
|
-
// packages/
|
|
10004
|
-
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
conditionId: 0,
|
|
10014
|
-
insertionOrder: 0
|
|
10015
|
-
};
|
|
10016
|
-
const generateRuleId = () => new RuleId(_counters.ruleId++);
|
|
10017
|
-
const generateSelectorId = () => new RuleId(_counters.selectorId++);
|
|
10018
|
-
const generatePropertyId = (propertyName) => new PropertyId(_counters.propertyId++, propertyName);
|
|
10019
|
-
const generateValueId = (valueName) => new ValueId(_counters.valueId++, valueName);
|
|
10020
|
-
const generateLayerId = () => new LayerId(_counters.layerId++);
|
|
10021
|
-
const generateConditionId = () => new ConditionId(_counters.conditionId++);
|
|
10022
|
-
const getNextInsertionOrder = () => _counters.insertionOrder++;
|
|
10023
|
-
const reset = () => {
|
|
10024
|
-
_counters.ruleId = 0;
|
|
10025
|
-
_counters.selectorId = 0;
|
|
10026
|
-
_counters.propertyId = 0;
|
|
10027
|
-
_counters.valueId = 0;
|
|
10028
|
-
_counters.layerId = 0;
|
|
10029
|
-
_counters.conditionId = 0;
|
|
10030
|
-
_counters.insertionOrder = 0;
|
|
9912
|
+
// packages/domain/engine/src/cssToIr.ts
|
|
9913
|
+
function createIdGenerator() {
|
|
9914
|
+
const state = {
|
|
9915
|
+
ruleIdCounter: 0,
|
|
9916
|
+
selectorIdCounter: 0,
|
|
9917
|
+
propertyIdCounter: 0,
|
|
9918
|
+
valueIdCounter: 0,
|
|
9919
|
+
layerIdCounter: 0,
|
|
9920
|
+
conditionIdCounter: 0,
|
|
9921
|
+
insertionOrderCounter: 0
|
|
10031
9922
|
};
|
|
10032
9923
|
return {
|
|
10033
|
-
generateRuleId,
|
|
10034
|
-
generateSelectorId,
|
|
10035
|
-
generatePropertyId
|
|
10036
|
-
|
|
10037
|
-
|
|
10038
|
-
|
|
10039
|
-
|
|
10040
|
-
|
|
9924
|
+
generateRuleId: () => new RuleId(state.ruleIdCounter++),
|
|
9925
|
+
generateSelectorId: () => new SelectorId(state.selectorIdCounter++),
|
|
9926
|
+
generatePropertyId: (name) => {
|
|
9927
|
+
const id = new PropertyId(state.propertyIdCounter++);
|
|
9928
|
+
registerPropertyName(id, name);
|
|
9929
|
+
return id;
|
|
9930
|
+
},
|
|
9931
|
+
generateValueId: (name) => {
|
|
9932
|
+
const id = new ValueId(state.valueIdCounter++);
|
|
9933
|
+
registerValueName(id, name);
|
|
9934
|
+
return id;
|
|
9935
|
+
},
|
|
9936
|
+
generateLayerId: () => new LayerId(state.layerIdCounter++),
|
|
9937
|
+
generateConditionId: () => new ConditionId(state.conditionIdCounter++),
|
|
9938
|
+
getNextInsertionOrder: () => state.insertionOrderCounter++,
|
|
9939
|
+
reset: () => {
|
|
9940
|
+
state.ruleIdCounter = 0;
|
|
9941
|
+
state.selectorIdCounter = 0;
|
|
9942
|
+
state.propertyIdCounter = 0;
|
|
9943
|
+
state.valueIdCounter = 0;
|
|
9944
|
+
state.layerIdCounter = 0;
|
|
9945
|
+
state.conditionIdCounter = 0;
|
|
9946
|
+
state.insertionOrderCounter = 0;
|
|
9947
|
+
}
|
|
10041
9948
|
};
|
|
10042
|
-
}
|
|
10043
|
-
var
|
|
9949
|
+
}
|
|
9950
|
+
var _defaultIdGen = createIdGenerator();
|
|
9951
|
+
var generateRuleId = () => _defaultIdGen.generateRuleId();
|
|
9952
|
+
var generateSelectorId = () => _defaultIdGen.generateSelectorId();
|
|
9953
|
+
var generatePropertyId = (name) => _defaultIdGen.generatePropertyId(name);
|
|
9954
|
+
var generateValueId = (name) => _defaultIdGen.generateValueId(name);
|
|
9955
|
+
var generateLayerId = () => _defaultIdGen.generateLayerId();
|
|
9956
|
+
var generateConditionId = () => _defaultIdGen.generateConditionId();
|
|
9957
|
+
var getNextInsertionOrder = () => _defaultIdGen.getNextInsertionOrder();
|
|
9958
|
+
var resetIdGenerator = () => _defaultIdGen.reset();
|
|
10044
9959
|
var layerMap = /* @__PURE__ */ new Map();
|
|
10045
9960
|
var layerOrderMap = /* @__PURE__ */ new Map();
|
|
10046
9961
|
var LAYER_ORDER = {
|
|
@@ -10052,109 +9967,41 @@ var LAYER_ORDER = {
|
|
|
10052
9967
|
function getOrCreateLayerId(layerName) {
|
|
10053
9968
|
const existing = layerMap.get(layerName);
|
|
10054
9969
|
if (existing) return existing;
|
|
10055
|
-
const
|
|
10056
|
-
const layerId = idGenerator.generateLayerId();
|
|
9970
|
+
const layerId = generateLayerId();
|
|
10057
9971
|
layerMap.set(layerName, layerId);
|
|
10058
|
-
layerOrderMap.set(layerName,
|
|
9972
|
+
layerOrderMap.set(layerName, LAYER_ORDER[layerName] ?? 4);
|
|
10059
9973
|
return layerId;
|
|
10060
9974
|
}
|
|
10061
|
-
function
|
|
10062
|
-
|
|
10063
|
-
const pseudoCount = selector.pseudoClasses.length * 10;
|
|
10064
|
-
const mediaCount = selector.mediaQuery ? 1e3 : 0;
|
|
10065
|
-
return classCount + pseudoCount + mediaCount;
|
|
10066
|
-
}
|
|
10067
|
-
function parseSelector(selectorText) {
|
|
10068
|
-
const mediaMatch = selectorText.match(/^@media[^{]+\{(.+)$/);
|
|
10069
|
-
const mediaQuery = mediaMatch ? mediaMatch[0] : null;
|
|
10070
|
-
const baseClass = (mediaMatch ? mediaMatch[1].trim() : selectorText).startsWith(".") ? (mediaMatch ? mediaMatch[1].trim() : selectorText).slice(1) : mediaMatch ? mediaMatch[1].trim() : selectorText;
|
|
10071
|
-
const escapedColon = /\\:/g;
|
|
10072
|
-
const baseClassClean = baseClass.startsWith(".") ? baseClass.slice(1) : baseClass;
|
|
10073
|
-
const baseClassFinal = baseClassClean.replace(escapedColon, "\u200B").split(":")[0].replace(/\u200B/g, ":");
|
|
10074
|
-
const variantRegex = /^(hover|focus|active|visited|checked|disabled|required|optional|first|last|odd|even|before|after|placeholder|file|selection|backdrop|group|peer)/i;
|
|
10075
|
-
const pseudoRegex = /^:([a-zA-Z-]+)$/;
|
|
10076
|
-
const parts = baseClassFinal.split(":").slice(1);
|
|
10077
|
-
const { variants, pseudoClasses } = parts.reduce(
|
|
10078
|
-
(acc, part) => {
|
|
10079
|
-
const normalized = `:${part}`;
|
|
10080
|
-
if (variantRegex.test(part)) {
|
|
10081
|
-
acc.variants.push(part);
|
|
10082
|
-
} else if (pseudoRegex.test(normalized)) {
|
|
10083
|
-
acc.pseudoClasses.push(normalized);
|
|
10084
|
-
} else {
|
|
10085
|
-
acc.variants.push(part);
|
|
10086
|
-
}
|
|
10087
|
-
return acc;
|
|
10088
|
-
},
|
|
10089
|
-
{ variants: [], pseudoClasses: [] }
|
|
10090
|
-
);
|
|
10091
|
-
return {
|
|
10092
|
-
className: baseClassFinal,
|
|
10093
|
-
variants,
|
|
10094
|
-
pseudoClasses,
|
|
10095
|
-
mediaQuery
|
|
10096
|
-
};
|
|
10097
|
-
}
|
|
10098
|
-
function parseDeclaration(block) {
|
|
10099
|
-
const declarations = [];
|
|
10100
|
-
for (const match of block.matchAll(/([a-zA-Z-]+)\s*:\s*([^;!]+)(!important)?/g)) {
|
|
10101
|
-
const property = match[1].trim();
|
|
10102
|
-
const value = match[2].trim();
|
|
10103
|
-
const important = match[3] !== void 0;
|
|
10104
|
-
declarations.push({ property, value, important });
|
|
10105
|
-
}
|
|
10106
|
-
return declarations;
|
|
10107
|
-
}
|
|
10108
|
-
function parseRules(css) {
|
|
10109
|
-
const rules = [];
|
|
10110
|
-
for (const match of css.matchAll(/([^{}]+)\s*\{([^{}]*)\}/g)) {
|
|
10111
|
-
const selectorText = match[1].trim();
|
|
10112
|
-
const declarationBlock = match[2].trim();
|
|
10113
|
-
if (selectorText.startsWith("@")) {
|
|
10114
|
-
continue;
|
|
10115
|
-
}
|
|
10116
|
-
const parsedSelector = parseSelector(selectorText);
|
|
10117
|
-
const declarations = parseDeclaration(declarationBlock);
|
|
10118
|
-
for (const decl of declarations) {
|
|
10119
|
-
rules.push({
|
|
10120
|
-
selector: parsedSelector,
|
|
10121
|
-
property: decl.property,
|
|
10122
|
-
value: decl.value,
|
|
10123
|
-
important: decl.important
|
|
10124
|
-
});
|
|
10125
|
-
}
|
|
10126
|
-
}
|
|
10127
|
-
return rules;
|
|
10128
|
-
}
|
|
10129
|
-
function detectLayerFromSelector(className) {
|
|
10130
|
-
const layerPrefixes = ["tw-", "tailwind-"];
|
|
10131
|
-
for (const prefix of layerPrefixes) {
|
|
10132
|
-
if (className.startsWith(prefix)) {
|
|
10133
|
-
return "tailwind";
|
|
10134
|
-
}
|
|
10135
|
-
}
|
|
9975
|
+
function detectLayerFromClassName(className) {
|
|
9976
|
+
if (className.startsWith("tw-") || className.startsWith("tailwind-")) return "tailwind";
|
|
10136
9977
|
return null;
|
|
10137
9978
|
}
|
|
10138
|
-
function parseCssToIr(css,
|
|
10139
|
-
|
|
9979
|
+
function parseCssToIr(css, options = {}) {
|
|
9980
|
+
resetIdGenerator();
|
|
10140
9981
|
layerMap.clear();
|
|
10141
9982
|
layerOrderMap.clear();
|
|
9983
|
+
const native = getNativeEngineBinding();
|
|
9984
|
+
if (!native?.parseCssRules) {
|
|
9985
|
+
throw new Error("FATAL: Native binding 'parseCssRules' is required but not available.");
|
|
9986
|
+
}
|
|
9987
|
+
const prefix = options.prefix ?? "";
|
|
10142
9988
|
const rules = [];
|
|
10143
9989
|
const classToRuleIds = /* @__PURE__ */ new Map();
|
|
10144
|
-
const
|
|
10145
|
-
for (const
|
|
10146
|
-
const className = prefix +
|
|
10147
|
-
|
|
10148
|
-
const layerName =
|
|
9990
|
+
const parsed = native.parseCssRules(css);
|
|
9991
|
+
for (const r of parsed) {
|
|
9992
|
+
const className = prefix + r.className;
|
|
9993
|
+
r.variants.length > 0;
|
|
9994
|
+
const layerName = detectLayerFromClassName(className);
|
|
10149
9995
|
const layer = layerName ? getOrCreateLayerId(layerName) : null;
|
|
10150
9996
|
const layerOrder = layerName ? layerOrderMap.get(layerName) ?? 4 : 4;
|
|
10151
|
-
const selectorId =
|
|
10152
|
-
const propertyId =
|
|
10153
|
-
const valueId =
|
|
10154
|
-
const
|
|
10155
|
-
const
|
|
10156
|
-
const
|
|
10157
|
-
const ruleId =
|
|
9997
|
+
const selectorId = generateSelectorId();
|
|
9998
|
+
const propertyId = generatePropertyId(r.property);
|
|
9999
|
+
const valueId = generateValueId(r.value);
|
|
10000
|
+
const hasMedia = r.variants.some((v) => v.startsWith("@") || v === "dark" || v === "print");
|
|
10001
|
+
const conditionId = hasMedia ? generateConditionId() : null;
|
|
10002
|
+
const conditionResult = hasMedia ? 2 /* Unknown */ : 2 /* Unknown */;
|
|
10003
|
+
const ruleId = generateRuleId();
|
|
10004
|
+
const fingerprint = createFingerprint([className, r.property, r.value]);
|
|
10158
10005
|
const rule = {
|
|
10159
10006
|
id: ruleId,
|
|
10160
10007
|
selector: selectorId,
|
|
@@ -10162,117 +10009,58 @@ function parseCssToIr(css, prefix = "") {
|
|
|
10162
10009
|
property: propertyId,
|
|
10163
10010
|
value: valueId,
|
|
10164
10011
|
origin: 2 /* AuthorNormal */,
|
|
10165
|
-
importance:
|
|
10012
|
+
importance: r.isImportant ? 1 /* Important */ : 0 /* Normal */,
|
|
10166
10013
|
layer,
|
|
10167
10014
|
layerOrder,
|
|
10168
|
-
specificity,
|
|
10015
|
+
specificity: r.specificity,
|
|
10016
|
+
// from native — no JS recalculation
|
|
10169
10017
|
condition: conditionId,
|
|
10170
10018
|
conditionResult,
|
|
10171
|
-
insertionOrder:
|
|
10019
|
+
insertionOrder: getNextInsertionOrder(),
|
|
10172
10020
|
fingerprint,
|
|
10173
|
-
source: {
|
|
10174
|
-
file: "",
|
|
10175
|
-
line: 1,
|
|
10176
|
-
column: 1
|
|
10177
|
-
}
|
|
10021
|
+
source: { file: "", line: 1, column: 1 }
|
|
10178
10022
|
};
|
|
10179
10023
|
rules.push(rule);
|
|
10180
|
-
const
|
|
10181
|
-
|
|
10182
|
-
classToRuleIds.set(className,
|
|
10024
|
+
const existing = classToRuleIds.get(className) ?? [];
|
|
10025
|
+
existing.push(ruleId);
|
|
10026
|
+
classToRuleIds.set(className, existing);
|
|
10183
10027
|
}
|
|
10184
10028
|
return { rules, classToRuleIds };
|
|
10185
10029
|
}
|
|
10186
|
-
|
|
10187
|
-
|
|
10188
|
-
|
|
10189
|
-
|
|
10190
|
-
|
|
10191
|
-
this.rules.set(rule.id, rule);
|
|
10192
|
-
const property = rule.property;
|
|
10193
|
-
const existingBucket = this.propertyBuckets.get(property);
|
|
10194
|
-
if (!existingBucket) {
|
|
10195
|
-
this.propertyBuckets.set(property, {
|
|
10196
|
-
property,
|
|
10197
|
-
rules: [rule.id]
|
|
10198
|
-
});
|
|
10199
|
-
} else {
|
|
10200
|
-
this.propertyBuckets.set(property, {
|
|
10201
|
-
...existingBucket,
|
|
10202
|
-
rules: [...existingBucket.rules, rule.id]
|
|
10203
|
-
});
|
|
10204
|
-
}
|
|
10205
|
-
}
|
|
10206
|
-
addRules(rules) {
|
|
10207
|
-
for (const rule of rules) {
|
|
10208
|
-
this.addRule(rule);
|
|
10209
|
-
}
|
|
10210
|
-
}
|
|
10211
|
-
getRule(ruleId) {
|
|
10212
|
-
return this.rules.get(ruleId);
|
|
10213
|
-
}
|
|
10214
|
-
registerClass(className, ruleIds) {
|
|
10215
|
-
this.classRules.set(className, ruleIds);
|
|
10216
|
-
}
|
|
10217
|
-
getClassRules(className) {
|
|
10218
|
-
return this.classRules.get(className);
|
|
10219
|
-
}
|
|
10220
|
-
resolveByClassName(className) {
|
|
10221
|
-
const ruleIds = this.classRules.get(className);
|
|
10222
|
-
if (!ruleIds) {
|
|
10223
|
-
return null;
|
|
10224
|
-
}
|
|
10225
|
-
const classRules = [];
|
|
10226
|
-
for (const ruleId of ruleIds) {
|
|
10227
|
-
const rule = this.rules.get(ruleId);
|
|
10228
|
-
if (rule) {
|
|
10229
|
-
classRules.push(rule);
|
|
10230
|
-
}
|
|
10231
|
-
}
|
|
10232
|
-
const propertyMap = /* @__PURE__ */ new Map();
|
|
10233
|
-
for (const rule of classRules) {
|
|
10234
|
-
const existing = propertyMap.get(rule.property) || [];
|
|
10235
|
-
existing.push(rule);
|
|
10236
|
-
propertyMap.set(rule.property, existing);
|
|
10237
|
-
}
|
|
10238
|
-
const resolved = /* @__PURE__ */ new Map();
|
|
10239
|
-
for (const [property, rules] of propertyMap) {
|
|
10240
|
-
if (rules.length > 0) {
|
|
10241
|
-
const activeRules = rules.filter((r) => r.conditionResult !== 1 /* Inactive */);
|
|
10242
|
-
if (activeRules.length > 0) {
|
|
10243
|
-
activeRules.sort((a, b) => {
|
|
10244
|
-
const originDiff = b.origin - a.origin;
|
|
10245
|
-
if (originDiff !== 0) return originDiff;
|
|
10246
|
-
const layerDiff = b.layerOrder - a.layerOrder;
|
|
10247
|
-
if (layerDiff !== 0) return layerDiff;
|
|
10248
|
-
const importanceDiff = b.importance - a.importance;
|
|
10249
|
-
if (importanceDiff !== 0) return importanceDiff;
|
|
10250
|
-
const specificityDiff = b.specificity - a.specificity;
|
|
10251
|
-
if (specificityDiff !== 0) return specificityDiff;
|
|
10252
|
-
return b.insertionOrder - a.insertionOrder;
|
|
10253
|
-
});
|
|
10254
|
-
const winner = activeRules[0];
|
|
10255
|
-
resolved.set(property, { winner: winner.id });
|
|
10256
|
-
}
|
|
10257
|
-
}
|
|
10258
|
-
}
|
|
10259
|
-
return { resolvedProperties: resolved };
|
|
10260
|
-
}
|
|
10261
|
-
};
|
|
10262
|
-
function trace(className, resolver) {
|
|
10263
|
-
const provenance = {
|
|
10030
|
+
|
|
10031
|
+
// packages/domain/engine/src/trace.ts
|
|
10032
|
+
function buildProvenanceChain(className) {
|
|
10033
|
+
return {
|
|
10034
|
+
className,
|
|
10264
10035
|
source: { file: "", line: 0, column: 0 },
|
|
10265
10036
|
variants: /* @__PURE__ */ new Map(),
|
|
10266
10037
|
rules: /* @__PURE__ */ new Map()
|
|
10267
10038
|
};
|
|
10039
|
+
}
|
|
10040
|
+
function formatCause(c) {
|
|
10041
|
+
switch (c.type) {
|
|
10042
|
+
case "LowerOrigin":
|
|
10043
|
+
return "lower origin";
|
|
10044
|
+
case "LowerLayer":
|
|
10045
|
+
return "lower layer";
|
|
10046
|
+
case "LowerImportance":
|
|
10047
|
+
return "lower importance";
|
|
10048
|
+
case "LowerSpecificity":
|
|
10049
|
+
return `specificity ${c.delta}`;
|
|
10050
|
+
case "EarlierOrder":
|
|
10051
|
+
return `earlier order ${c.delta}`;
|
|
10052
|
+
case "InactiveCondition":
|
|
10053
|
+
return "inactive condition";
|
|
10054
|
+
}
|
|
10055
|
+
}
|
|
10056
|
+
function trace(className, resolver) {
|
|
10057
|
+
const provenance = buildProvenanceChain(className);
|
|
10268
10058
|
const classRuleIds = resolver.getClassRules(className);
|
|
10269
10059
|
const allRules = [];
|
|
10270
10060
|
if (classRuleIds) {
|
|
10271
10061
|
for (const ruleId of classRuleIds) {
|
|
10272
10062
|
const rule = resolver.getRule(ruleId);
|
|
10273
|
-
if (rule)
|
|
10274
|
-
allRules.push(rule);
|
|
10275
|
-
}
|
|
10063
|
+
if (rule) allRules.push(rule);
|
|
10276
10064
|
}
|
|
10277
10065
|
}
|
|
10278
10066
|
for (const rules of provenance.rules.values()) {
|
|
@@ -10281,57 +10069,49 @@ function trace(className, resolver) {
|
|
|
10281
10069
|
const rulesByProperty = /* @__PURE__ */ new Map();
|
|
10282
10070
|
for (const rule of allRules) {
|
|
10283
10071
|
const propKey = rule.property.toString();
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
rulesByProperty.get(propKey).push(rule);
|
|
10072
|
+
const bucket = rulesByProperty.get(propKey) ?? [];
|
|
10073
|
+
bucket.push(rule);
|
|
10074
|
+
rulesByProperty.set(propKey, bucket);
|
|
10288
10075
|
}
|
|
10076
|
+
const resolved = resolver.resolveByClassName(className);
|
|
10289
10077
|
const ruleTraces = [];
|
|
10290
10078
|
const conflictTraces = [];
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
|
|
10300
|
-
|
|
10301
|
-
|
|
10302
|
-
|
|
10303
|
-
|
|
10304
|
-
|
|
10305
|
-
|
|
10306
|
-
|
|
10307
|
-
|
|
10308
|
-
|
|
10309
|
-
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
}
|
|
10325
|
-
conflictTraces.push({
|
|
10326
|
-
property,
|
|
10327
|
-
winner: winnerRule.value.toString(),
|
|
10328
|
-
loser: loserRule.value.toString(),
|
|
10329
|
-
stage: "Specificity",
|
|
10330
|
-
causes: ["lower specificity"]
|
|
10331
|
-
});
|
|
10079
|
+
if (resolved) {
|
|
10080
|
+
for (const [propId, resolution] of resolved.resolvedProperties) {
|
|
10081
|
+
const property = propId.toString();
|
|
10082
|
+
const rules = rulesByProperty.get(property) ?? [];
|
|
10083
|
+
const winnerRule = rules.find((r) => r.id.value === resolution.winner.value);
|
|
10084
|
+
if (winnerRule) {
|
|
10085
|
+
ruleTraces.push({
|
|
10086
|
+
property,
|
|
10087
|
+
value: winnerRule.value.toString(),
|
|
10088
|
+
applied: true,
|
|
10089
|
+
reason: null,
|
|
10090
|
+
source: winnerRule.source,
|
|
10091
|
+
specificity: winnerRule.specificity
|
|
10092
|
+
});
|
|
10093
|
+
}
|
|
10094
|
+
for (const loserId of resolution.losers) {
|
|
10095
|
+
const loserRule = rules.find((r) => r.id.value === loserId.value);
|
|
10096
|
+
if (!loserRule) continue;
|
|
10097
|
+
ruleTraces.push({
|
|
10098
|
+
property,
|
|
10099
|
+
value: loserRule.value.toString(),
|
|
10100
|
+
applied: false,
|
|
10101
|
+
reason: resolution.reason.finalDecision,
|
|
10102
|
+
source: loserRule.source,
|
|
10103
|
+
specificity: loserRule.specificity
|
|
10104
|
+
});
|
|
10105
|
+
conflictTraces.push({
|
|
10106
|
+
property,
|
|
10107
|
+
winner: winnerRule?.value.toString() ?? "",
|
|
10108
|
+
loser: loserRule.value.toString(),
|
|
10109
|
+
stage: CascadeStage[resolution.stage],
|
|
10110
|
+
causes: resolution.reason.causes.map(formatCause)
|
|
10111
|
+
});
|
|
10112
|
+
}
|
|
10332
10113
|
}
|
|
10333
10114
|
}
|
|
10334
|
-
const resolved = resolver.resolveByClassName(className);
|
|
10335
10115
|
const finalStyle = [];
|
|
10336
10116
|
if (resolved) {
|
|
10337
10117
|
for (const [propId, resolution] of resolved.resolvedProperties) {
|
|
@@ -10351,6 +10131,30 @@ function trace(className, resolver) {
|
|
|
10351
10131
|
finalStyle
|
|
10352
10132
|
};
|
|
10353
10133
|
}
|
|
10134
|
+
|
|
10135
|
+
// packages/infrastructure/cli/src/utils/traceService.ts
|
|
10136
|
+
init_src2();
|
|
10137
|
+
init_src();
|
|
10138
|
+
function safeToString(value) {
|
|
10139
|
+
if (value === null || value === void 0) return "";
|
|
10140
|
+
if (typeof value === "string") return value;
|
|
10141
|
+
if (typeof value === "number") return String(value);
|
|
10142
|
+
if (typeof value === "object") {
|
|
10143
|
+
const obj = value;
|
|
10144
|
+
if (typeof obj.name === "string" && obj.name.length > 0) return obj.name;
|
|
10145
|
+
if (obj.value !== void 0) return String(obj.value);
|
|
10146
|
+
const toStr = obj.toString;
|
|
10147
|
+
if (typeof toStr === "function") {
|
|
10148
|
+
try {
|
|
10149
|
+
const result = toStr.call(value);
|
|
10150
|
+
if (typeof result === "string" && result !== "[object Object]") return result;
|
|
10151
|
+
} catch {
|
|
10152
|
+
}
|
|
10153
|
+
}
|
|
10154
|
+
return "?";
|
|
10155
|
+
}
|
|
10156
|
+
return String(value);
|
|
10157
|
+
}
|
|
10354
10158
|
async function traceClass(className, options) {
|
|
10355
10159
|
const root = options?.root ?? process.cwd();
|
|
10356
10160
|
const scanResult = await scanWorkspace(root, {
|
|
@@ -10384,53 +10188,16 @@ async function traceClass(className, options) {
|
|
|
10384
10188
|
const { rules, classToRuleIds } = parseCssToIr(cssResult.code);
|
|
10385
10189
|
const ruleIds = classToRuleIds.get(className);
|
|
10386
10190
|
if (!ruleIds || ruleIds.length === 0) {
|
|
10387
|
-
throw TwError.fromCompile(
|
|
10191
|
+
throw TwError.fromCompile(
|
|
10192
|
+
"TRACE_NO_RULES_FOUND",
|
|
10193
|
+
`No rules found for class "${className}" after parsing CSS.`
|
|
10194
|
+
);
|
|
10388
10195
|
}
|
|
10389
10196
|
const resolver = new CascadeResolver();
|
|
10390
10197
|
resolver.addRules(rules);
|
|
10391
10198
|
resolver.registerClass(className, ruleIds);
|
|
10392
|
-
const
|
|
10393
|
-
|
|
10394
|
-
}
|
|
10395
|
-
function safeToString(value) {
|
|
10396
|
-
if (value === null || value === void 0) return "";
|
|
10397
|
-
if (typeof value === "string") return String(value);
|
|
10398
|
-
if (typeof value === "number") return String(value);
|
|
10399
|
-
if (typeof value === "boolean") return String(value);
|
|
10400
|
-
if (typeof value === "object" && value !== null) {
|
|
10401
|
-
const obj = value;
|
|
10402
|
-
const name = obj.name;
|
|
10403
|
-
if (typeof name === "string" && name.length > 0) {
|
|
10404
|
-
return name;
|
|
10405
|
-
}
|
|
10406
|
-
const objValue = obj.value;
|
|
10407
|
-
if (objValue !== void 0) {
|
|
10408
|
-
return String(objValue);
|
|
10409
|
-
}
|
|
10410
|
-
const objValueOf = obj.valueOf;
|
|
10411
|
-
if (typeof objValueOf === "function") {
|
|
10412
|
-
try {
|
|
10413
|
-
const vo = objValueOf.call(value);
|
|
10414
|
-
if (vo !== value) return String(vo);
|
|
10415
|
-
} catch {
|
|
10416
|
-
}
|
|
10417
|
-
}
|
|
10418
|
-
const toStr = obj.toString;
|
|
10419
|
-
if (typeof toStr === "function") {
|
|
10420
|
-
try {
|
|
10421
|
-
const result = toStr.call(value);
|
|
10422
|
-
if (typeof result === "string" && result !== "[object Object]") {
|
|
10423
|
-
return result;
|
|
10424
|
-
}
|
|
10425
|
-
} catch {
|
|
10426
|
-
}
|
|
10427
|
-
}
|
|
10428
|
-
return "?";
|
|
10429
|
-
}
|
|
10430
|
-
return String(value);
|
|
10431
|
-
}
|
|
10432
|
-
function convertTraceResult(engineResult) {
|
|
10433
|
-
return {
|
|
10199
|
+
const engineResult = trace(className, resolver);
|
|
10200
|
+
const result = {
|
|
10434
10201
|
class: safeToString(engineResult.class),
|
|
10435
10202
|
definedAt: {
|
|
10436
10203
|
file: safeToString(engineResult.definedAt.file),
|
|
@@ -10442,7 +10209,8 @@ function convertTraceResult(engineResult) {
|
|
|
10442
10209
|
value: safeToString(v.value),
|
|
10443
10210
|
source: {
|
|
10444
10211
|
file: safeToString(v.source?.file ?? ""),
|
|
10445
|
-
line: Number(v.source?.line ?? 0)
|
|
10212
|
+
line: Number(v.source?.line ?? 0),
|
|
10213
|
+
column: Number(v.source?.column ?? 0)
|
|
10446
10214
|
}
|
|
10447
10215
|
})),
|
|
10448
10216
|
rules: engineResult.rules.map((r) => ({
|
|
@@ -10452,7 +10220,8 @@ function convertTraceResult(engineResult) {
|
|
|
10452
10220
|
reason: r.reason ? safeToString(r.reason) : null,
|
|
10453
10221
|
source: {
|
|
10454
10222
|
file: safeToString(r.source?.file ?? ""),
|
|
10455
|
-
line: Number(r.source?.line ?? 0)
|
|
10223
|
+
line: Number(r.source?.line ?? 0),
|
|
10224
|
+
column: Number(r.source?.column ?? 0)
|
|
10456
10225
|
},
|
|
10457
10226
|
specificity: Number(r.specificity ?? 0)
|
|
10458
10227
|
})),
|
|
@@ -10461,17 +10230,18 @@ function convertTraceResult(engineResult) {
|
|
|
10461
10230
|
winner: safeToString(c.winner),
|
|
10462
10231
|
loser: safeToString(c.loser),
|
|
10463
10232
|
stage: safeToString(c.stage),
|
|
10464
|
-
causes: c.causes
|
|
10233
|
+
causes: (c.causes ?? []).map(safeToString)
|
|
10465
10234
|
})),
|
|
10466
10235
|
finalStyle: engineResult.finalStyle.map((f) => ({
|
|
10467
10236
|
property: safeToString(f.property),
|
|
10468
10237
|
value: safeToString(f.value)
|
|
10469
10238
|
}))
|
|
10470
10239
|
};
|
|
10240
|
+
return result;
|
|
10471
10241
|
}
|
|
10472
10242
|
init_src2();
|
|
10473
10243
|
function toRelativePath(root, value) {
|
|
10474
|
-
const relative =
|
|
10244
|
+
const relative = path6__namespace.default.relative(root, value);
|
|
10475
10245
|
return relative.length > 0 ? relative : ".";
|
|
10476
10246
|
}
|
|
10477
10247
|
function uniqueSorted(values) {
|
|
@@ -10540,7 +10310,7 @@ function tryCompileClasses(classes) {
|
|
|
10540
10310
|
}
|
|
10541
10311
|
}
|
|
10542
10312
|
function traceSingleFile(filePath, root) {
|
|
10543
|
-
const source =
|
|
10313
|
+
const source = fs11__namespace.default.readFileSync(filePath, "utf8");
|
|
10544
10314
|
const classes = uniqueSorted(scanSource(source));
|
|
10545
10315
|
const imports = extractImports(source);
|
|
10546
10316
|
const compiled = tryCompileClasses(classes);
|
|
@@ -10571,7 +10341,7 @@ function traceDirectory(targetDir, root) {
|
|
|
10571
10341
|
const imports = [];
|
|
10572
10342
|
const importKeys = /* @__PURE__ */ new Set();
|
|
10573
10343
|
const files = scanResult.files.filter((entry) => isScannableFile(entry.file, DEFAULT_EXTENSIONS)).map((entry) => {
|
|
10574
|
-
const source =
|
|
10344
|
+
const source = fs11__namespace.default.readFileSync(entry.file, "utf8");
|
|
10575
10345
|
const fileImports = extractImports(source);
|
|
10576
10346
|
for (const fileImport of fileImports) {
|
|
10577
10347
|
const key = `${fileImport.kind}:${fileImport.source}`;
|
|
@@ -10602,12 +10372,12 @@ function traceDirectory(targetDir, root) {
|
|
|
10602
10372
|
};
|
|
10603
10373
|
}
|
|
10604
10374
|
async function traceTarget(target, options = {}) {
|
|
10605
|
-
const root =
|
|
10606
|
-
const resolvedTarget =
|
|
10607
|
-
if (!
|
|
10375
|
+
const root = path6__namespace.default.resolve(options.root ?? process.cwd());
|
|
10376
|
+
const resolvedTarget = path6__namespace.default.resolve(root, target);
|
|
10377
|
+
if (!fs11__namespace.default.existsSync(resolvedTarget)) {
|
|
10608
10378
|
throw new Error(`Trace target not found: ${resolvedTarget}`);
|
|
10609
10379
|
}
|
|
10610
|
-
const stat =
|
|
10380
|
+
const stat = fs11__namespace.default.statSync(resolvedTarget);
|
|
10611
10381
|
if (stat.isDirectory()) {
|
|
10612
10382
|
return traceDirectory(resolvedTarget, root);
|
|
10613
10383
|
}
|
|
@@ -10776,7 +10546,7 @@ async function runGenerateTypesCli(rawArgs) {
|
|
|
10776
10546
|
const logger = createCliLogger({ output });
|
|
10777
10547
|
const cwd2 = process.cwd();
|
|
10778
10548
|
const outFile = rawArgs.find((a) => a.startsWith("--out="))?.slice(6) ?? "src/types/tailwind-styled.d.ts";
|
|
10779
|
-
const outPath =
|
|
10549
|
+
const outPath = path6__namespace.default.resolve(cwd2, outFile);
|
|
10780
10550
|
output.writeText("");
|
|
10781
10551
|
output.writeText(import_picocolors6.default.bold(import_picocolors6.default.cyan(" \u25C6 tw generate-types")));
|
|
10782
10552
|
output.writeText(import_picocolors6.default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
@@ -10790,12 +10560,11 @@ async function runGenerateTypesCli(rawArgs) {
|
|
|
10790
10560
|
throw new Error("Native binding 'generateSubComponentTypes' tidak tersedia \u2014 pastikan build:rust sudah dijalankan");
|
|
10791
10561
|
}
|
|
10792
10562
|
result = binding.generateSubComponentTypes(cwd2, outPath);
|
|
10563
|
+
if (!result) throw new Error("generateSubComponentTypes mengembalikan null");
|
|
10793
10564
|
spinner.stop(`Scanned ${result.filesScanned} files`);
|
|
10794
10565
|
} catch (err) {
|
|
10795
10566
|
spinner.error("Scan gagal");
|
|
10796
|
-
|
|
10797
|
-
output.writeText(import_picocolors6.default.dim(" \u2192 fallback ke JS scanner..."));
|
|
10798
|
-
result = await fallbackJsScan(cwd2);
|
|
10567
|
+
throw err instanceof Error ? err : new Error(String(err));
|
|
10799
10568
|
}
|
|
10800
10569
|
if (!result) {
|
|
10801
10570
|
logger.warn("Tidak ada hasil scan");
|
|
@@ -10813,12 +10582,12 @@ async function runGenerateTypesCli(rawArgs) {
|
|
|
10813
10582
|
}
|
|
10814
10583
|
output.writeText("");
|
|
10815
10584
|
output.writeText(import_picocolors6.default.bold(" [2/2]") + import_picocolors6.default.cyan(" generate .d.ts"));
|
|
10816
|
-
const outDir =
|
|
10817
|
-
if (!
|
|
10818
|
-
|
|
10585
|
+
const outDir = path6__namespace.default.dirname(outPath);
|
|
10586
|
+
if (!fs11__namespace.default.existsSync(outDir)) {
|
|
10587
|
+
fs11__namespace.default.mkdirSync(outDir, { recursive: true });
|
|
10819
10588
|
}
|
|
10820
|
-
|
|
10821
|
-
logger.ok(
|
|
10589
|
+
fs11__namespace.default.writeFileSync(outPath, result.dtsContent, "utf-8");
|
|
10590
|
+
logger.ok(path6__namespace.default.relative(cwd2, outPath));
|
|
10822
10591
|
output.writeText("");
|
|
10823
10592
|
output.writeText(import_picocolors6.default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
10824
10593
|
output.writeText(import_picocolors6.default.bold(import_picocolors6.default.green(" \u2713 types generated")));
|
|
@@ -10829,11 +10598,11 @@ async function runGenerateTypesCli(rawArgs) {
|
|
|
10829
10598
|
}
|
|
10830
10599
|
async function loadNativeBinding2(cwd2) {
|
|
10831
10600
|
const candidates = [
|
|
10832
|
-
|
|
10833
|
-
|
|
10601
|
+
path6__namespace.default.join(cwd2, "native", "tailwind-styled-native.node"),
|
|
10602
|
+
path6__namespace.default.join(cwd2, "node_modules", "tailwind-styled-v4", "native", "tailwind-styled-native.node")
|
|
10834
10603
|
];
|
|
10835
10604
|
for (const candidate of candidates) {
|
|
10836
|
-
if (
|
|
10605
|
+
if (fs11__namespace.default.existsSync(candidate)) {
|
|
10837
10606
|
try {
|
|
10838
10607
|
return __require(candidate);
|
|
10839
10608
|
} catch {
|
|
@@ -10842,42 +10611,6 @@ async function loadNativeBinding2(cwd2) {
|
|
|
10842
10611
|
}
|
|
10843
10612
|
return null;
|
|
10844
10613
|
}
|
|
10845
|
-
async function fallbackJsScan(cwd2, outPath) {
|
|
10846
|
-
const { execSync } = await import('child_process');
|
|
10847
|
-
const registerRe = /registerSubComponent\s*\(\s*\{[^}]*name\s*:\s*["']([a-zA-Z][a-zA-Z0-9_-]*)["']/g;
|
|
10848
|
-
const withSubRe = /\.withSub\s*<\s*([^>]+)\s*>/g;
|
|
10849
|
-
const literalRe = /["']([a-zA-Z][a-zA-Z0-9_-]*)["']/g;
|
|
10850
|
-
const names = /* @__PURE__ */ new Set();
|
|
10851
|
-
let filesScanned = 0;
|
|
10852
|
-
try {
|
|
10853
|
-
const files = execSync(
|
|
10854
|
-
`find . -name "*.tsx" -o -name "*.ts" -o -name "*.jsx" -o -name "*.js" | grep -v node_modules | grep -v .next | grep -v dist`,
|
|
10855
|
-
{ cwd: cwd2, encoding: "utf-8" }
|
|
10856
|
-
).trim().split("\n").filter(Boolean);
|
|
10857
|
-
for (const file of files) {
|
|
10858
|
-
try {
|
|
10859
|
-
const source = fs8__default.default.readFileSync(path3__default.default.join(cwd2, file), "utf-8");
|
|
10860
|
-
filesScanned++;
|
|
10861
|
-
for (const m of source.matchAll(registerRe)) names.add(m[1]);
|
|
10862
|
-
for (const m of source.matchAll(withSubRe)) {
|
|
10863
|
-
for (const lit of m[1].matchAll(literalRe)) names.add(lit[1]);
|
|
10864
|
-
}
|
|
10865
|
-
} catch {
|
|
10866
|
-
}
|
|
10867
|
-
}
|
|
10868
|
-
} catch {
|
|
10869
|
-
}
|
|
10870
|
-
const sorted = [...names].sort();
|
|
10871
|
-
const union = sorted.map((n) => `"${n}"`).join(" | ") || "never";
|
|
10872
|
-
const dtsContent = `// AUTO-GENERATED by tailwind-styled-v4 (JS fallback)
|
|
10873
|
-
// DO NOT EDIT \u2014 Run: npx tw generate-types to regenerate
|
|
10874
|
-
|
|
10875
|
-
declare module "tailwind-styled-v4" {
|
|
10876
|
-
export type DetectedSubComponents = ${union}
|
|
10877
|
-
}
|
|
10878
|
-
`;
|
|
10879
|
-
return { names: sorted, dtsContent, filesScanned };
|
|
10880
|
-
}
|
|
10881
10614
|
|
|
10882
10615
|
// packages/infrastructure/cli/src/commands/why.ts
|
|
10883
10616
|
init_errors();
|
|
@@ -10928,7 +10661,7 @@ async function whyClass(className, options) {
|
|
|
10928
10661
|
for (const file of scanResult.files) {
|
|
10929
10662
|
const source = (() => {
|
|
10930
10663
|
try {
|
|
10931
|
-
return
|
|
10664
|
+
return fs11__namespace.default.readFileSync(file.file, "utf8");
|
|
10932
10665
|
} catch {
|
|
10933
10666
|
return "";
|
|
10934
10667
|
}
|
|
@@ -10942,7 +10675,7 @@ async function whyClass(className, options) {
|
|
|
10942
10675
|
className
|
|
10943
10676
|
]);
|
|
10944
10677
|
usedIn.push({
|
|
10945
|
-
file:
|
|
10678
|
+
file: path6__namespace.default.relative(root, file.file) || path6__namespace.default.basename(file.file),
|
|
10946
10679
|
line: location.line,
|
|
10947
10680
|
column: location.column,
|
|
10948
10681
|
usage: normalizeScannedClass(fileClass)
|
|
@@ -11108,7 +10841,7 @@ function buildMainProgram(context) {
|
|
|
11108
10841
|
new Map(miscCommands.map((command) => [command.name, command]));
|
|
11109
10842
|
const scriptByName = new Map(scriptCommands.map((command) => [command.name, command]));
|
|
11110
10843
|
const program2 = new Command("tw");
|
|
11111
|
-
program2.name("tw").description("tailwind-styled-v4 CLI").option("--json", "Output strict JSON envelope").option("--debug", "Include stack traces for errors").option("--verbose", "Verbose runtime logs");
|
|
10844
|
+
program2.name("tw").description("tailwind-styled-v4 CLI").version("5.0.4", "--version", "Output the current version").option("--json", "Output strict JSON envelope").option("--debug", "Include stack traces for errors").option("--verbose", "Verbose runtime logs");
|
|
11112
10845
|
program2.command("setup").description("Auto-setup project").option("--yes", "Skip prompts").option("--next", "Force Next.js").option("--vite", "Force Vite").option("--rspack", "Force Rspack").option("--react", "Force React").option("--dry-run", "Preview changes").option("--skip-install", "Skip package install").action(async (...actionArgs) => {
|
|
11113
10846
|
const options = actionCommand(actionArgs).opts();
|
|
11114
10847
|
const args = [];
|
|
@@ -11397,12 +11130,23 @@ function buildMainProgram(context) {
|
|
|
11397
11130
|
|
|
11398
11131
|
// packages/infrastructure/cli/src/index.ts
|
|
11399
11132
|
init_runtime();
|
|
11133
|
+
init_args();
|
|
11134
|
+
init_args();
|
|
11135
|
+
init_output();
|
|
11400
11136
|
async function main2() {
|
|
11401
11137
|
await runCliMain({
|
|
11402
11138
|
importMetaUrl: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)),
|
|
11403
11139
|
buildProgram: buildMainProgram
|
|
11404
11140
|
});
|
|
11405
11141
|
}
|
|
11406
|
-
|
|
11142
|
+
var __filename2 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.js', document.baseURI).href)));
|
|
11143
|
+
if (process.argv[1] === __filename2) {
|
|
11144
|
+
main2();
|
|
11145
|
+
}
|
|
11146
|
+
|
|
11147
|
+
exports.createCliOutput = createCliOutput;
|
|
11148
|
+
exports.ensureFlag = ensureFlag;
|
|
11149
|
+
exports.parseCliArgs = parseCliInput;
|
|
11150
|
+
exports.runScanCli = runScanCli;
|
|
11407
11151
|
//# sourceMappingURL=cli.js.map
|
|
11408
11152
|
//# sourceMappingURL=cli.js.map
|