@styleframe/scanner 3.1.0 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.cjs ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("node:fs/promises"),v=require("fast-glob"),c=require("./watcher-C8V8DPY6.cjs");function x(l){const i=c.createCache(),h=l.cwd??process.cwd(),u=l.extractors,d=l.utilities?.pattern,f=l.utilities?.parse??c.parseUtilityClass;async function m(){return v(l.content,{cwd:h,absolute:!0,ignore:c.DEFAULT_IGNORE_PATTERNS})}async function p(t){const s=await g.readFile(t,"utf-8"),a=c.hashContent(s),n=i.getIfValid(t,a);if(n)return n;const r=c.extractClasses(s,t,u,d),e=r.map(f).filter(F=>F!==null),o={path:t,classes:new Set(r),parsed:e,lastScanned:Date.now()};return i.set(t,o,a),o}function y(t,s="inline"){return c.extractClasses(t,s,u,d).map(f).filter(n=>n!==null)}async function w(){const t=await m(),s=new Map,a=new Set,n=[],r=await Promise.all(t.map(async e=>{try{return await p(e)}catch(o){return console.warn(`[styleframe/scanner] Failed to scan ${e}:`,o),null}}));for(const e of r)if(e){s.set(e.path,e);for(const o of e.classes)a.add(o);n.push(...e.parsed)}return{files:s,allClasses:a,allParsed:n}}function C(t,s){return c.matchUtilities(t,s)}function S(t){const{onChange:s,flush:a}=c.createChangeHandler(async n=>{for(const e of n)i.invalidate(e);const r=await w();t(r)});return()=>{a()}}function N(t){t?i.invalidate(t):i.clear()}return{scan:w,scanFile:p,scanContent:y,match:C,watch:S,invalidate:N}}exports.createScanner=x;
package/dist/node.d.ts ADDED
@@ -0,0 +1,138 @@
1
+ import { ModifierFactory } from '@styleframe/core';
2
+ import { Root } from '@styleframe/core';
3
+ import { UtilityFactory } from '@styleframe/core';
4
+ import { UtilitySelectorFn } from '@styleframe/core';
5
+
6
+ /**
7
+ * Create a scanner instance for detecting utility classes in content files.
8
+ *
9
+ * @param config Scanner configuration
10
+ * @returns Scanner instance
11
+ *
12
+ * @example
13
+ * ```ts
14
+ * const scanner = createScanner({
15
+ * content: ['./src/components/*.tsx', './src/pages/*.vue'],
16
+ * });
17
+ *
18
+ * const result = await scanner.scan();
19
+ * const matches = scanner.match(result.allParsed, root);
20
+ * ```
21
+ */
22
+ export declare function createScanner(config: ScannerConfig): Scanner;
23
+
24
+ /**
25
+ * Custom extractor function type
26
+ */
27
+ declare type Extractor = (content: string, filePath: string) => string[];
28
+
29
+ /**
30
+ * Scan result for a single file
31
+ */
32
+ declare interface FileScanResult {
33
+ /** Absolute file path */
34
+ path: string;
35
+ /** Set of raw class names found */
36
+ classes: Set<string>;
37
+ /** Parsed utility classes */
38
+ parsed: ParsedUtility[];
39
+ /** Timestamp of last scan */
40
+ lastScanned: number;
41
+ }
42
+
43
+ /**
44
+ * Parsed utility class structure
45
+ */
46
+ declare interface ParsedUtility {
47
+ /** Original class name as found in content (e.g., "_margin:sm") */
48
+ raw: string;
49
+ /** Utility name (e.g., "margin", "background") */
50
+ name: string;
51
+ /** Value key (e.g., "sm", "primary", "[16px]") */
52
+ value: string;
53
+ /** Applied modifiers in order (e.g., ["hover", "dark"]) */
54
+ modifiers: string[];
55
+ /** Whether this uses arbitrary value syntax [value] */
56
+ isArbitrary: boolean;
57
+ /** The arbitrary value if isArbitrary is true (e.g., "16px") */
58
+ arbitraryValue?: string;
59
+ }
60
+
61
+ /**
62
+ * Scanner instance interface
63
+ */
64
+ declare interface Scanner {
65
+ /** Scan all content files */
66
+ scan(): Promise<ScanResult>;
67
+ /** Scan a single file */
68
+ scanFile(filePath: string): Promise<FileScanResult>;
69
+ /** Scan content string directly */
70
+ scanContent(content: string, filePath?: string): ParsedUtility[];
71
+ /** Match parsed utilities against a root instance */
72
+ match(parsed: ParsedUtility[], root: Root): UtilityMatch[];
73
+ /** Start watching content files for changes */
74
+ watch(callback: (result: ScanResult) => void): () => void;
75
+ /** Invalidate cache for a file or all files */
76
+ invalidate(filePath?: string): void;
77
+ }
78
+
79
+ /**
80
+ * Configuration for the content scanner
81
+ */
82
+ declare interface ScannerConfig {
83
+ /** Glob patterns for files to scan */
84
+ content: string[];
85
+ /** Custom extraction functions */
86
+ extractors?: Extractor[];
87
+ /** Base directory for glob resolution (defaults to process.cwd()) */
88
+ cwd?: string;
89
+ /** Custom utility class syntax configuration */
90
+ utilities?: ScannerUtilitiesConfig;
91
+ }
92
+
93
+ /**
94
+ * Configuration for custom utility class syntax.
95
+ * All fields are optional — defaults match the `_modifier:property:value` format.
96
+ */
97
+ declare interface ScannerUtilitiesConfig {
98
+ /** Regex pattern to extract utility class candidates from content strings. Must use the global (`g`) flag. */
99
+ pattern?: RegExp;
100
+ /** Parse a matched class name into its components (name, value, modifiers) */
101
+ parse?: UtilityClassParseFn;
102
+ /** Generate a raw class name from components (inverse of parse) */
103
+ selector?: UtilitySelectorFn;
104
+ }
105
+
106
+ /**
107
+ * Complete scan result across all files
108
+ */
109
+ declare interface ScanResult {
110
+ /** Map of file path to scan result */
111
+ files: Map<string, FileScanResult>;
112
+ /** All unique class names found */
113
+ allClasses: Set<string>;
114
+ /** All parsed utilities */
115
+ allParsed: ParsedUtility[];
116
+ }
117
+
118
+ /**
119
+ * Function that parses a class name string into its structured components.
120
+ * Returns null if the string is not a valid utility class.
121
+ */
122
+ declare type UtilityClassParseFn = (className: string) => ParsedUtility | null;
123
+
124
+ /**
125
+ * Match result between a parsed class and a utility factory
126
+ */
127
+ declare interface UtilityMatch {
128
+ /** The parsed utility class */
129
+ parsed: ParsedUtility;
130
+ /** The matched utility factory, or null if not found */
131
+ factory: UtilityFactory | null;
132
+ /** Matched modifier factories */
133
+ modifierFactories: ModifierFactory[];
134
+ /** Whether the utility value exists in the factory */
135
+ exists: boolean;
136
+ }
137
+
138
+ export { }
package/dist/node.js ADDED
@@ -0,0 +1,92 @@
1
+ import { readFile as S } from "node:fs/promises";
2
+ import v from "fast-glob";
3
+ import { p as E, v as T, x as U, m as g, e as d, u as A, z as D } from "./watcher-Bn_8hGt2.js";
4
+ function R(o) {
5
+ const l = T(), w = o.cwd ?? process.cwd(), i = o.extractors, u = o.utilities?.pattern, f = o.utilities?.parse ?? E;
6
+ async function h() {
7
+ return v(o.content, {
8
+ cwd: w,
9
+ absolute: !0,
10
+ ignore: D
11
+ });
12
+ }
13
+ async function m(t) {
14
+ const a = await S(t, "utf-8"), e = A(a), n = l.getIfValid(t, e);
15
+ if (n)
16
+ return n;
17
+ const c = d(
18
+ a,
19
+ t,
20
+ i,
21
+ u
22
+ ), s = c.map(f).filter((F) => F !== null), r = {
23
+ path: t,
24
+ classes: new Set(c),
25
+ parsed: s,
26
+ lastScanned: Date.now()
27
+ };
28
+ return l.set(t, r, e), r;
29
+ }
30
+ function y(t, a = "inline") {
31
+ return d(
32
+ t,
33
+ a,
34
+ i,
35
+ u
36
+ ).map(f).filter((n) => n !== null);
37
+ }
38
+ async function p() {
39
+ const t = await h(), a = /* @__PURE__ */ new Map(), e = /* @__PURE__ */ new Set(), n = [], c = await Promise.all(
40
+ t.map(async (s) => {
41
+ try {
42
+ return await m(s);
43
+ } catch (r) {
44
+ return console.warn(
45
+ `[styleframe/scanner] Failed to scan ${s}:`,
46
+ r
47
+ ), null;
48
+ }
49
+ })
50
+ );
51
+ for (const s of c)
52
+ if (s) {
53
+ a.set(s.path, s);
54
+ for (const r of s.classes)
55
+ e.add(r);
56
+ n.push(...s.parsed);
57
+ }
58
+ return {
59
+ files: a,
60
+ allClasses: e,
61
+ allParsed: n
62
+ };
63
+ }
64
+ function C(t, a) {
65
+ return g(t, a);
66
+ }
67
+ function N(t) {
68
+ const { onChange: a, flush: e } = U(async (n) => {
69
+ for (const s of n)
70
+ l.invalidate(s);
71
+ const c = await p();
72
+ t(c);
73
+ });
74
+ return () => {
75
+ e();
76
+ };
77
+ }
78
+ function x(t) {
79
+ t ? l.invalidate(t) : l.clear();
80
+ }
81
+ return {
82
+ scan: p,
83
+ scanFile: m,
84
+ scanContent: y,
85
+ match: C,
86
+ watch: N,
87
+ invalidate: x
88
+ };
89
+ }
90
+ export {
91
+ R as createScanner
92
+ };
@@ -0,0 +1,387 @@
1
+ import { classNameToCssSelector as b, defaultUtilitySelectorFn as I } from "@styleframe/core";
2
+ const M = /_[a-zA-Z][a-zA-Z0-9-]*(?::[a-zA-Z0-9._-]+|:\[[^\]]+\])*/g, L = /^\[(.+)\]$/, Q = [
3
+ "html",
4
+ "htm",
5
+ "vue",
6
+ "svelte",
7
+ "jsx",
8
+ "tsx",
9
+ "js",
10
+ "ts",
11
+ "astro",
12
+ "mdx",
13
+ "php",
14
+ "erb",
15
+ "twig",
16
+ "blade.php"
17
+ ], K = [
18
+ "**/node_modules/**",
19
+ "**/.git/**",
20
+ "**/dist/**",
21
+ "**/build/**",
22
+ "**/.next/**",
23
+ "**/.nuxt/**",
24
+ "**/coverage/**"
25
+ ];
26
+ function Z(s) {
27
+ if (!s.startsWith("_"))
28
+ return null;
29
+ const e = s.slice(1);
30
+ if (!e)
31
+ return null;
32
+ const t = U(e);
33
+ if (t.length === 0)
34
+ return null;
35
+ let n, r, a = [];
36
+ t.length === 1 ? (n = t[0], r = "default") : (r = t[t.length - 1], n = t[t.length - 2], a = t.slice(0, -2));
37
+ let l = !1, c;
38
+ const u = r.match(L);
39
+ return u && (l = !0, c = u[1]), {
40
+ raw: s,
41
+ name: n,
42
+ value: r,
43
+ modifiers: a,
44
+ isArbitrary: l,
45
+ arbitraryValue: c
46
+ };
47
+ }
48
+ function U(s) {
49
+ const e = [];
50
+ let t = "", n = 0;
51
+ for (const r of s)
52
+ r === "[" ? (n++, t += r) : r === "]" ? (n--, t += r) : r === ":" && n === 0 ? (t && e.push(t), t = "") : t += r;
53
+ return n !== 0 ? [] : (t && e.push(t), e);
54
+ }
55
+ function h(s, e) {
56
+ const t = s.match(e ?? M);
57
+ return t ? [...new Set(t)] : [];
58
+ }
59
+ function H(s, e, t = []) {
60
+ const n = [...t, s];
61
+ return e !== "default" && n.push(e), `_${n.join(":")}`;
62
+ }
63
+ const x = /\bclassName\s*=\s*\{/g, T = /\bclass\s*=\s*\{/g, S = /\bclass\s*=\s*["']([^"']+)["']/gi, A = /\bclassName\s*=\s*["']([^"']+)["']/gi, E = /\bclass:([^\s={>]+)/g, w = /'([^'\\]*(?:\\.[^'\\]*)*)'/g, C = /"([^"\\]*(?:\\.[^"\\]*)*)"/g, y = /`([^`\\]*(?:\\.[^`\\]*)*)`/g;
64
+ function _(s) {
65
+ let e = 1, t = 0;
66
+ for (; t < s.length && e > 0; ) {
67
+ const n = s[t];
68
+ n === "{" ? e++ : n === "}" && e--, t++;
69
+ }
70
+ return e !== 0 ? null : s.slice(0, t - 1);
71
+ }
72
+ function P(s) {
73
+ const e = [];
74
+ x.lastIndex = 0;
75
+ let t;
76
+ for (; (t = x.exec(s)) !== null; ) {
77
+ const n = t.index + t[0].length, r = s.slice(n), a = _(r);
78
+ a !== null && e.push(a);
79
+ }
80
+ return e;
81
+ }
82
+ function v(s) {
83
+ const e = [];
84
+ T.lastIndex = 0;
85
+ let t;
86
+ for (; (t = T.exec(s)) !== null; ) {
87
+ const n = t.index + t[0].length, r = s.slice(n), a = _(r);
88
+ a !== null && e.push(a);
89
+ }
90
+ return e;
91
+ }
92
+ function i(s, e) {
93
+ const t = [];
94
+ S.lastIndex = 0;
95
+ let n;
96
+ for (; (n = S.exec(s)) !== null; )
97
+ n[1] && t.push(...h(n[1], e));
98
+ return t;
99
+ }
100
+ function p(s, e) {
101
+ const t = [];
102
+ A.lastIndex = 0;
103
+ let n;
104
+ for (; (n = A.exec(s)) !== null; )
105
+ n[1] && t.push(...h(n[1], e));
106
+ const r = P(s);
107
+ for (const a of r)
108
+ t.push(...o(a, e));
109
+ return [...new Set(t)];
110
+ }
111
+ function F(s, e) {
112
+ const t = [], n = s.match(/<template[^>]*>([\s\S]*)<\/template>/i);
113
+ n?.[1] && (t.push(...i(n[1], e)), t.push(...o(n[1], e)));
114
+ const r = s.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
115
+ return r?.[1] && t.push(...o(r[1], e)), [...new Set(t)];
116
+ }
117
+ function O(s, e) {
118
+ const t = [];
119
+ t.push(...i(s, e));
120
+ const n = v(s);
121
+ for (const l of n)
122
+ t.push(...o(l, e));
123
+ E.lastIndex = 0;
124
+ let r;
125
+ for (; (r = E.exec(s)) !== null; )
126
+ r[1] && t.push(r[1]);
127
+ const a = s.match(/<script[^>]*>([\s\S]*?)<\/script>/i);
128
+ return a?.[1] && t.push(...o(a[1], e)), [...new Set(t)];
129
+ }
130
+ function V(s, e) {
131
+ const t = [];
132
+ t.push(...i(s, e)), t.push(...p(s, e));
133
+ const n = s.match(/^---\n([\s\S]*?)\n---/);
134
+ return n?.[1] && t.push(...o(n[1], e)), [...new Set(t)];
135
+ }
136
+ function o(s, e) {
137
+ const t = [];
138
+ let n;
139
+ for (w.lastIndex = 0; (n = w.exec(s)) !== null; )
140
+ n[1] && t.push(...h(n[1], e));
141
+ for (C.lastIndex = 0; (n = C.exec(s)) !== null; )
142
+ n[1] && t.push(...h(n[1], e));
143
+ for (y.lastIndex = 0; (n = y.exec(s)) !== null; )
144
+ n[1] && t.push(...h(n[1], e));
145
+ return t;
146
+ }
147
+ function $(s, e) {
148
+ const t = [];
149
+ return t.push(...i(s, e)), t.push(...p(s, e)), [...new Set(t)];
150
+ }
151
+ const j = {
152
+ html: i,
153
+ htm: i,
154
+ vue: F,
155
+ svelte: O,
156
+ jsx: p,
157
+ tsx: p,
158
+ js: o,
159
+ ts: o,
160
+ astro: V,
161
+ mdx: $,
162
+ php: i,
163
+ erb: i,
164
+ twig: i,
165
+ "blade.php": i
166
+ };
167
+ function z(s) {
168
+ if (s.endsWith(".blade.php"))
169
+ return "blade.php";
170
+ const e = s.split(".");
171
+ return e[e.length - 1]?.toLowerCase() ?? "";
172
+ }
173
+ function W(s, e, t, n) {
174
+ const r = [], a = z(e);
175
+ if (t)
176
+ for (const c of t)
177
+ r.push(...c(s, e));
178
+ const l = j[a];
179
+ return l ? r.push(...l(s, n)) : r.push(...o(s, n)), [...new Set(r)];
180
+ }
181
+ function R(s, e) {
182
+ if (e.length === 0)
183
+ return s;
184
+ const t = [...e].sort().join(",");
185
+ return `${s}|${t}`;
186
+ }
187
+ function Y(s, e) {
188
+ const t = /* @__PURE__ */ new Map(), n = /* @__PURE__ */ new Map(), r = /* @__PURE__ */ new Map();
189
+ for (const l of e.utilities) {
190
+ t.set(l.name, l);
191
+ const c = /* @__PURE__ */ new Set();
192
+ for (const u of l.values)
193
+ c.add(R(u.key, u.modifiers));
194
+ r.set(l, c);
195
+ }
196
+ for (const l of e.modifiers)
197
+ for (const c of l.key)
198
+ n.set(c, l);
199
+ const a = [];
200
+ for (const l of s) {
201
+ const c = t.get(l.name) ?? null, u = [];
202
+ for (const d of l.modifiers) {
203
+ const m = n.get(d);
204
+ m && u.push(m);
205
+ }
206
+ let g = !1;
207
+ if (c) {
208
+ const d = R(
209
+ l.value,
210
+ l.modifiers
211
+ );
212
+ g = r.get(c)?.has(d) ?? !1;
213
+ }
214
+ a.push({
215
+ parsed: l,
216
+ factory: c,
217
+ modifierFactories: u,
218
+ exists: g
219
+ });
220
+ }
221
+ return a;
222
+ }
223
+ function q(s, e) {
224
+ const t = N(s, e);
225
+ return b(t);
226
+ }
227
+ function N(s, e) {
228
+ return (e ?? I)(s);
229
+ }
230
+ function D(s, e) {
231
+ return (t) => {
232
+ const n = N(
233
+ {
234
+ name: t.name,
235
+ value: t.value,
236
+ modifiers: t.modifiers
237
+ },
238
+ e
239
+ );
240
+ return s.has(n);
241
+ };
242
+ }
243
+ function J(s, e, t) {
244
+ const n = D(e, t);
245
+ return s.children.filter((r) => r.type !== "utility" ? !0 : n(r));
246
+ }
247
+ function ee(s) {
248
+ const e = /* @__PURE__ */ new Set();
249
+ for (const t of s)
250
+ e.add(t.parsed.raw);
251
+ return e;
252
+ }
253
+ function te(s) {
254
+ return s.filter((e) => e.factory !== null);
255
+ }
256
+ function se(s) {
257
+ return s.filter((e) => e.exists);
258
+ }
259
+ function ne(s) {
260
+ return s.filter((e) => e.parsed.isArbitrary);
261
+ }
262
+ function re(s) {
263
+ let e = 0;
264
+ for (let t = 0; t < s.length; t++) {
265
+ const n = s.charCodeAt(t);
266
+ e = (e << 5) - e + n, e = e & e;
267
+ }
268
+ return `${e.toString(16)}-${s.length}`;
269
+ }
270
+ function ae() {
271
+ const s = /* @__PURE__ */ new Map();
272
+ return {
273
+ get(e) {
274
+ return s.get(e)?.result ?? null;
275
+ },
276
+ set(e, t, n) {
277
+ s.set(e, {
278
+ hash: n,
279
+ result: t,
280
+ timestamp: Date.now()
281
+ });
282
+ },
283
+ isValid(e, t) {
284
+ const n = s.get(e);
285
+ return n !== void 0 && n.hash === t;
286
+ },
287
+ getIfValid(e, t) {
288
+ const n = s.get(e);
289
+ return n && n.hash === t ? n.result : null;
290
+ },
291
+ invalidate(e) {
292
+ s.delete(e);
293
+ },
294
+ clear() {
295
+ s.clear();
296
+ }
297
+ };
298
+ }
299
+ const f = /* @__PURE__ */ new Map();
300
+ function k(s) {
301
+ const e = s.replace(/\\/g, "/");
302
+ if (f.has(e))
303
+ return f.get(e);
304
+ if (!e.includes("**") && !e.includes("*") && !e.includes("?"))
305
+ return f.set(e, null), null;
306
+ try {
307
+ const t = G(e), n = new RegExp(`^${t}$`);
308
+ return f.set(e, n), n;
309
+ } catch {
310
+ return f.set(e, null), null;
311
+ }
312
+ }
313
+ function le(s, e) {
314
+ let t = null;
315
+ return (...n) => {
316
+ t && clearTimeout(t), t = setTimeout(() => {
317
+ s(...n), t = null;
318
+ }, e);
319
+ };
320
+ }
321
+ function ce(s, e = {}) {
322
+ const { debounce: t = 100 } = e, n = /* @__PURE__ */ new Set();
323
+ let r = null;
324
+ const a = () => {
325
+ if (n.size > 0) {
326
+ const c = [...n];
327
+ n.clear(), s(c);
328
+ }
329
+ };
330
+ return { onChange: (c) => {
331
+ n.add(c), r && clearTimeout(r), r = setTimeout(() => {
332
+ a(), r = null;
333
+ }, t);
334
+ }, flush: a };
335
+ }
336
+ function B(s) {
337
+ return s.replace(/[.+^${}()|[\]\\]/g, "\\$&");
338
+ }
339
+ function G(s) {
340
+ return s.replace(/\*\*/g, "<<<GLOBSTAR>>>").replace(/\*/g, "<<<STAR>>>").replace(/\?/g, "<<<QUESTION>>>").split("<<<GLOBSTAR>>>").map(B).join(".*").replace(/<<<STAR>>>/g, "[^/]*").replace(/<<<QUESTION>>>/g, ".");
341
+ }
342
+ function ie(s, e) {
343
+ const t = s.replace(/\\/g, "/");
344
+ for (const n of e) {
345
+ const r = k(n);
346
+ if (r !== null) {
347
+ if (r.test(t))
348
+ return !0;
349
+ } else {
350
+ const a = n.replace(/\\/g, "/");
351
+ if (t === a)
352
+ return !0;
353
+ }
354
+ }
355
+ return !1;
356
+ }
357
+ export {
358
+ L as A,
359
+ Q as D,
360
+ M as U,
361
+ h as a,
362
+ i as b,
363
+ p as c,
364
+ F as d,
365
+ W as e,
366
+ O as f,
367
+ H as g,
368
+ V as h,
369
+ $ as i,
370
+ o as j,
371
+ q as k,
372
+ N as l,
373
+ Y as m,
374
+ D as n,
375
+ J as o,
376
+ Z as p,
377
+ ee as q,
378
+ te as r,
379
+ se as s,
380
+ ne as t,
381
+ re as u,
382
+ ae as v,
383
+ le as w,
384
+ ce as x,
385
+ ie as y,
386
+ K as z
387
+ };
@@ -0,0 +1 @@
1
+ "use strict";const w=require("@styleframe/core"),U=/_[a-zA-Z][a-zA-Z0-9-]*(?::[a-zA-Z0-9._-]+|:\[[^\]]+\])*/g,I=/^\[(.+)\]$/,O=["html","htm","vue","svelte","jsx","tsx","js","ts","astro","mdx","php","erb","twig","blade.php"],V=["**/node_modules/**","**/.git/**","**/dist/**","**/build/**","**/.next/**","**/.nuxt/**","**/coverage/**"];function D(s){if(!s.startsWith("_"))return null;const e=s.slice(1);if(!e)return null;const t=$(e);if(t.length===0)return null;let n,r,i=[];t.length===1?(n=t[0],r="default"):(r=t[t.length-1],n=t[t.length-2],i=t.slice(0,-2));let c=!1,l;const u=r.match(I);return u&&(c=!0,l=u[1]),{raw:s,name:n,value:r,modifiers:i,isArbitrary:c,arbitraryValue:l}}function $(s){const e=[];let t="",n=0;for(const r of s)r==="["?(n++,t+=r):r==="]"?(n--,t+=r):r===":"&&n===0?(t&&e.push(t),t=""):t+=r;return n!==0?[]:(t&&e.push(t),e)}function f(s,e){const t=s.match(e??U);return t?[...new Set(t)]:[]}function X(s,e,t=[]){const n=[...t,s];return e!=="default"&&n.push(e),`_${n.join(":")}`}const T=/\bclassName\s*=\s*\{/g,S=/\bclass\s*=\s*\{/g,A=/\bclass\s*=\s*["']([^"']+)["']/gi,E=/\bclassName\s*=\s*["']([^"']+)["']/gi,C=/\bclass:([^\s={>]+)/g,N=/'([^'\\]*(?:\\.[^'\\]*)*)'/g,R=/"([^"\\]*(?:\\.[^"\\]*)*)"/g,_=/`([^`\\]*(?:\\.[^`\\]*)*)`/g;function L(s){let e=1,t=0;for(;t<s.length&&e>0;){const n=s[t];n==="{"?e++:n==="}"&&e--,t++}return e!==0?null:s.slice(0,t-1)}function j(s){const e=[];T.lastIndex=0;let t;for(;(t=T.exec(s))!==null;){const n=t.index+t[0].length,r=s.slice(n),i=L(r);i!==null&&e.push(i)}return e}function z(s){const e=[];S.lastIndex=0;let t;for(;(t=S.exec(s))!==null;){const n=t.index+t[0].length,r=s.slice(n),i=L(r);i!==null&&e.push(i)}return e}function a(s,e){const t=[];A.lastIndex=0;let n;for(;(n=A.exec(s))!==null;)n[1]&&t.push(...f(n[1],e));return t}function m(s,e){const t=[];E.lastIndex=0;let n;for(;(n=E.exec(s))!==null;)n[1]&&t.push(...f(n[1],e));const r=j(s);for(const i of r)t.push(...o(i,e));return[...new Set(t)]}function M(s,e){const t=[],n=s.match(/<template[^>]*>([\s\S]*)<\/template>/i);n?.[1]&&(t.push(...a(n[1],e)),t.push(...o(n[1],e)));const r=s.match(/<script[^>]*>([\s\S]*?)<\/script>/i);return r?.[1]&&t.push(...o(r[1],e)),[...new Set(t)]}function b(s,e){const t=[];t.push(...a(s,e));const n=z(s);for(const c of n)t.push(...o(c,e));C.lastIndex=0;let r;for(;(r=C.exec(s))!==null;)r[1]&&t.push(r[1]);const i=s.match(/<script[^>]*>([\s\S]*?)<\/script>/i);return i?.[1]&&t.push(...o(i[1],e)),[...new Set(t)]}function F(s,e){const t=[];t.push(...a(s,e)),t.push(...m(s,e));const n=s.match(/^---\n([\s\S]*?)\n---/);return n?.[1]&&t.push(...o(n[1],e)),[...new Set(t)]}function o(s,e){const t=[];let n;for(N.lastIndex=0;(n=N.exec(s))!==null;)n[1]&&t.push(...f(n[1],e));for(R.lastIndex=0;(n=R.exec(s))!==null;)n[1]&&t.push(...f(n[1],e));for(_.lastIndex=0;(n=_.exec(s))!==null;)n[1]&&t.push(...f(n[1],e));return t}function P(s,e){const t=[];return t.push(...a(s,e)),t.push(...m(s,e)),[...new Set(t)]}const B={html:a,htm:a,vue:M,svelte:b,jsx:m,tsx:m,js:o,ts:o,astro:F,mdx:P,php:a,erb:a,twig:a,"blade.php":a};function G(s){if(s.endsWith(".blade.php"))return"blade.php";const e=s.split(".");return e[e.length-1]?.toLowerCase()??""}function k(s,e,t,n){const r=[],i=G(e);if(t)for(const l of t)r.push(...l(s,e));const c=B[i];return c?r.push(...c(s,n)):r.push(...o(s,n)),[...new Set(r)]}function y(s,e){if(e.length===0)return s;const t=[...e].sort().join(",");return`${s}|${t}`}function H(s,e){const t=new Map,n=new Map,r=new Map;for(const c of e.utilities){t.set(c.name,c);const l=new Set;for(const u of c.values)l.add(y(u.key,u.modifiers));r.set(c,l)}for(const c of e.modifiers)for(const l of c.key)n.set(l,c);const i=[];for(const c of s){const l=t.get(c.name)??null,u=[];for(const p of c.modifiers){const d=n.get(p);d&&u.push(d)}let x=!1;if(l){const p=y(c.value,c.modifiers);x=r.get(l)?.has(p)??!1}i.push({parsed:c,factory:l,modifierFactories:u,exists:x})}return i}function Q(s,e){const t=g(s,e);return w.classNameToCssSelector(t)}function g(s,e){return(e??w.defaultUtilitySelectorFn)(s)}function v(s,e){return t=>{const n=g({name:t.name,value:t.value,modifiers:t.modifiers},e);return s.has(n)}}function Y(s,e,t){const n=v(e,t);return s.children.filter(r=>r.type!=="utility"?!0:n(r))}function K(s){const e=new Set;for(const t of s)e.add(t.parsed.raw);return e}function Z(s){return s.filter(e=>e.factory!==null)}function J(s){return s.filter(e=>e.exists)}function W(s){return s.filter(e=>e.parsed.isArbitrary)}function q(s){let e=0;for(let t=0;t<s.length;t++){const n=s.charCodeAt(t);e=(e<<5)-e+n,e=e&e}return`${e.toString(16)}-${s.length}`}function ee(){const s=new Map;return{get(e){return s.get(e)?.result??null},set(e,t,n){s.set(e,{hash:n,result:t,timestamp:Date.now()})},isValid(e,t){const n=s.get(e);return n!==void 0&&n.hash===t},getIfValid(e,t){const n=s.get(e);return n&&n.hash===t?n.result:null},invalidate(e){s.delete(e)},clear(){s.clear()}}}const h=new Map;function te(s){const e=s.replace(/\\/g,"/");if(h.has(e))return h.get(e);if(!e.includes("**")&&!e.includes("*")&&!e.includes("?"))return h.set(e,null),null;try{const t=ie(e),n=new RegExp(`^${t}$`);return h.set(e,n),n}catch{return h.set(e,null),null}}function se(s,e){let t=null;return(...n)=>{t&&clearTimeout(t),t=setTimeout(()=>{s(...n),t=null},e)}}function ne(s,e={}){const{debounce:t=100}=e,n=new Set;let r=null;const i=()=>{if(n.size>0){const l=[...n];n.clear(),s(l)}};return{onChange:l=>{n.add(l),r&&clearTimeout(r),r=setTimeout(()=>{i(),r=null},t)},flush:i}}function re(s){return s.replace(/[.+^${}()|[\]\\]/g,"\\$&")}function ie(s){return s.replace(/\*\*/g,"<<<GLOBSTAR>>>").replace(/\*/g,"<<<STAR>>>").replace(/\?/g,"<<<QUESTION>>>").split("<<<GLOBSTAR>>>").map(re).join(".*").replace(/<<<STAR>>>/g,"[^/]*").replace(/<<<QUESTION>>>/g,".")}function ce(s,e){const t=s.replace(/\\/g,"/");for(const n of e){const r=te(n);if(r!==null){if(r.test(t))return!0}else{const i=n.replace(/\\/g,"/");if(t===i)return!0}}return!1}exports.ARBITRARY_VALUE_PATTERN=I;exports.DEFAULT_EXTENSIONS=O;exports.DEFAULT_IGNORE_PATTERNS=V;exports.UTILITY_CLASS_PATTERN=U;exports.classNameFromUtilityOptions=g;exports.createCache=ee;exports.createChangeHandler=ne;exports.createUtilityFilter=v;exports.debounce=se;exports.extractClasses=k;exports.extractFromAstro=F;exports.extractFromHTML=a;exports.extractFromJSX=m;exports.extractFromMDX=P;exports.extractFromStringLiterals=o;exports.extractFromSvelte=b;exports.extractFromVue=M;exports.extractUtilityClasses=f;exports.filterUtilities=Y;exports.generateUtilityClassName=X;exports.generateUtilitySelector=Q;exports.getArbitraryMatches=W;exports.getExistingMatches=J;exports.getUsedClassNames=K;exports.getValidMatches=Z;exports.hashContent=q;exports.matchUtilities=H;exports.matchesPatterns=ce;exports.parseUtilityClass=D;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@styleframe/scanner",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "module": "./dist/index.js",
@@ -10,6 +10,11 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.js",
12
12
  "require": "./dist/index.cjs"
13
+ },
14
+ "./node": {
15
+ "types": "./dist/node.d.ts",
16
+ "import": "./dist/node.js",
17
+ "require": "./dist/node.cjs"
13
18
  }
14
19
  },
15
20
  "files": [
@@ -22,19 +27,18 @@
22
27
  "fast-glob": "^3.3.2"
23
28
  },
24
29
  "peerDependencies": {
25
- "@styleframe/core": "^3.1.0",
30
+ "@styleframe/core": "^3.5.0",
26
31
  "@styleframe/license": "^2.0.2"
27
32
  },
28
33
  "devDependencies": {
29
34
  "@styleframe/config-typescript": "^3.0.0",
30
35
  "@styleframe/config-vite": "^3.0.0",
31
- "@styleframe/core": "^3.1.0",
36
+ "@styleframe/core": "^3.5.0",
32
37
  "@styleframe/license": "^2.0.2",
33
38
  "@vitest/coverage-v8": "^3.2.4",
34
39
  "typescript": "^5.8.3",
35
40
  "vite": "^7.0.6",
36
41
  "vite-plugin-dts": "^4.5.4",
37
- "vite-plugin-node": "^7.0.0",
38
42
  "vitest": "^3.2.4"
39
43
  },
40
44
  "homepage": "https://github.com/styleframe-dev/styleframe#readme",