@tailwindcss-mangle/shared 1.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +23 -0
- package/dist/index.cjs +202 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.mjs +186 -0
- package/package.json +52 -0
package/README.md
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# @tailwindcss-mangle/shared
|
|
2
|
+
|
|
3
|
+
The shared utils of tailwindcss-mangle
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
<npm|yarn|pnpm> i @tailwindcss-mangle/shared
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### ClassGenerator
|
|
14
|
+
|
|
15
|
+
the class generator of tailwindcss-mangle
|
|
16
|
+
|
|
17
|
+
### escapeStringRegexp
|
|
18
|
+
|
|
19
|
+
### makeRegex
|
|
20
|
+
|
|
21
|
+
### splitCode
|
|
22
|
+
|
|
23
|
+
### defaultMangleClassFilter
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const preserveClassNames = [
|
|
4
|
+
// https://tailwindcss.com/docs/transition-timing-function start
|
|
5
|
+
// https://github.com/sonofmagic/tailwindcss-mangle/issues/21
|
|
6
|
+
"ease-out",
|
|
7
|
+
"ease-linear",
|
|
8
|
+
"ease-in",
|
|
9
|
+
"ease-in-out"
|
|
10
|
+
// https://tailwindcss.com/docs/transition-timing-function end
|
|
11
|
+
];
|
|
12
|
+
const preserveClassNamesMap = preserveClassNames.reduce((acc, cur) => {
|
|
13
|
+
acc[cur] = true;
|
|
14
|
+
return acc;
|
|
15
|
+
}, {});
|
|
16
|
+
const defaultMangleClassFilter = (className) => {
|
|
17
|
+
if (preserveClassNamesMap[className]) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
return /[:-]/.test(className);
|
|
21
|
+
};
|
|
22
|
+
function groupBy(arr, cb) {
|
|
23
|
+
if (!Array.isArray(arr)) {
|
|
24
|
+
throw new TypeError("expected an array for first argument");
|
|
25
|
+
}
|
|
26
|
+
if (typeof cb !== "function") {
|
|
27
|
+
throw new TypeError("expected a function for second argument");
|
|
28
|
+
}
|
|
29
|
+
const result = {};
|
|
30
|
+
for (const item of arr) {
|
|
31
|
+
const bucketCategory = cb(item);
|
|
32
|
+
const bucket = result[bucketCategory];
|
|
33
|
+
if (Array.isArray(bucket)) {
|
|
34
|
+
result[bucketCategory].push(item);
|
|
35
|
+
} else {
|
|
36
|
+
result[bucketCategory] = [item];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
const acceptChars = [..."abcdefghijklmnopqrstuvwxyz"];
|
|
42
|
+
function stripEscapeSequence(words) {
|
|
43
|
+
return words.replaceAll("\\", "");
|
|
44
|
+
}
|
|
45
|
+
const validate = (opts, classGenerator) => {
|
|
46
|
+
if (!opts.log)
|
|
47
|
+
return;
|
|
48
|
+
for (const className in classGenerator.newClassMap) {
|
|
49
|
+
const c = classGenerator.newClassMap[className];
|
|
50
|
+
if (c.usedBy.length > 0) {
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (/.+\.css:*$/.test(c.usedBy[0])) {
|
|
54
|
+
console.log(`The class name '${className}' is not used: defined at ${c.usedBy[0]}.`);
|
|
55
|
+
} else {
|
|
56
|
+
console.log(`The class name '${className}' is not defined: used at ${c.usedBy[0]}.`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
function isRegexp(value) {
|
|
61
|
+
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
62
|
+
}
|
|
63
|
+
function isMap(value) {
|
|
64
|
+
return Object.prototype.toString.call(value) === "[object Map]";
|
|
65
|
+
}
|
|
66
|
+
function regExpTest(arr = [], str) {
|
|
67
|
+
if (Array.isArray(arr)) {
|
|
68
|
+
for (const item of arr) {
|
|
69
|
+
if (typeof item === "string") {
|
|
70
|
+
if (item === str) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
} else if (isRegexp(item)) {
|
|
74
|
+
item.lastIndex = 0;
|
|
75
|
+
if (item.test(str)) {
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
throw new TypeError("paramater 'arr' should be a Array of Regexp | String !");
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
class ClassGenerator {
|
|
86
|
+
constructor(opts = {}) {
|
|
87
|
+
this.newClassMap = {};
|
|
88
|
+
this.newClassSize = 0;
|
|
89
|
+
this.context = {};
|
|
90
|
+
this.opts = opts;
|
|
91
|
+
this.classPrefix = opts.classPrefix ?? "tw-";
|
|
92
|
+
}
|
|
93
|
+
defaultClassGenerate() {
|
|
94
|
+
const chars = [];
|
|
95
|
+
let rest = (this.newClassSize - this.newClassSize % acceptChars.length) / acceptChars.length;
|
|
96
|
+
if (rest > 0) {
|
|
97
|
+
while (true) {
|
|
98
|
+
rest -= 1;
|
|
99
|
+
const m = rest % acceptChars.length;
|
|
100
|
+
const c = acceptChars[m];
|
|
101
|
+
chars.push(c);
|
|
102
|
+
rest -= m;
|
|
103
|
+
if (rest === 0) {
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
rest /= acceptChars.length;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const prefixIndex = this.newClassSize % acceptChars.length;
|
|
110
|
+
const newClassName = `${this.classPrefix}${acceptChars[prefixIndex]}${chars.join("")}`;
|
|
111
|
+
return newClassName;
|
|
112
|
+
}
|
|
113
|
+
ignoreClassName(className) {
|
|
114
|
+
return regExpTest(this.opts.ignoreClass, className);
|
|
115
|
+
}
|
|
116
|
+
includeFilePath(filePath) {
|
|
117
|
+
const { include } = this.opts;
|
|
118
|
+
return Array.isArray(include) ? regExpTest(include, filePath) : true;
|
|
119
|
+
}
|
|
120
|
+
excludeFilePath(filePath) {
|
|
121
|
+
const { exclude } = this.opts;
|
|
122
|
+
return Array.isArray(exclude) ? regExpTest(exclude, filePath) : false;
|
|
123
|
+
}
|
|
124
|
+
isFileIncluded(filePath) {
|
|
125
|
+
return this.includeFilePath(filePath) && !this.excludeFilePath(filePath);
|
|
126
|
+
}
|
|
127
|
+
transformCssClass(className) {
|
|
128
|
+
const key = stripEscapeSequence(className);
|
|
129
|
+
const cn = this.newClassMap[key];
|
|
130
|
+
if (cn)
|
|
131
|
+
return cn.name;
|
|
132
|
+
return className;
|
|
133
|
+
}
|
|
134
|
+
generateClassName(original) {
|
|
135
|
+
const opts = this.opts;
|
|
136
|
+
original = stripEscapeSequence(original);
|
|
137
|
+
const cn = this.newClassMap[original];
|
|
138
|
+
if (cn)
|
|
139
|
+
return cn;
|
|
140
|
+
let newClassName;
|
|
141
|
+
if (opts.customGenerate && typeof opts.customGenerate === "function") {
|
|
142
|
+
newClassName = opts.customGenerate(original, opts, this.context);
|
|
143
|
+
}
|
|
144
|
+
if (!newClassName) {
|
|
145
|
+
newClassName = this.defaultClassGenerate();
|
|
146
|
+
}
|
|
147
|
+
if (opts.reserveClassName && regExpTest(opts.reserveClassName, newClassName)) {
|
|
148
|
+
if (opts.log) {
|
|
149
|
+
console.log(`The class name has been reserved. ${newClassName}`);
|
|
150
|
+
}
|
|
151
|
+
this.newClassSize++;
|
|
152
|
+
return this.generateClassName(original);
|
|
153
|
+
}
|
|
154
|
+
if (opts.log) {
|
|
155
|
+
console.log(`Minify class name from ${original} to ${newClassName}`);
|
|
156
|
+
}
|
|
157
|
+
const newClass = {
|
|
158
|
+
name: newClassName,
|
|
159
|
+
usedBy: []
|
|
160
|
+
};
|
|
161
|
+
this.newClassMap[original] = newClass;
|
|
162
|
+
this.newClassSize++;
|
|
163
|
+
return newClass;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function escapeStringRegexp(str) {
|
|
168
|
+
if (typeof str !== "string") {
|
|
169
|
+
throw new TypeError("Expected a string");
|
|
170
|
+
}
|
|
171
|
+
return str.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&").replaceAll("-", "\\x2d");
|
|
172
|
+
}
|
|
173
|
+
function makeRegex(str, options = {
|
|
174
|
+
exact: true
|
|
175
|
+
}) {
|
|
176
|
+
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str) + (options.exact ? '(?=$|[\\s"])' : ""), "g");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const validateFilterRE = /[\w%-?\u00A0-\uFFFF-]/;
|
|
180
|
+
function isValidSelector(selector = "") {
|
|
181
|
+
return validateFilterRE.test(selector);
|
|
182
|
+
}
|
|
183
|
+
const splitCode = (code, options = { splitQuote: true }) => {
|
|
184
|
+
const regex = options.splitQuote ? /[\s"]+/ : /\s+/;
|
|
185
|
+
return code.split(regex).filter((x) => isValidSelector(x));
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
exports.ClassGenerator = ClassGenerator;
|
|
189
|
+
exports.acceptChars = acceptChars;
|
|
190
|
+
exports.defaultMangleClassFilter = defaultMangleClassFilter;
|
|
191
|
+
exports.escapeStringRegexp = escapeStringRegexp;
|
|
192
|
+
exports.groupBy = groupBy;
|
|
193
|
+
exports.isMap = isMap;
|
|
194
|
+
exports.isRegexp = isRegexp;
|
|
195
|
+
exports.isValidSelector = isValidSelector;
|
|
196
|
+
exports.makeRegex = makeRegex;
|
|
197
|
+
exports.preserveClassNames = preserveClassNames;
|
|
198
|
+
exports.regExpTest = regExpTest;
|
|
199
|
+
exports.splitCode = splitCode;
|
|
200
|
+
exports.stripEscapeSequence = stripEscapeSequence;
|
|
201
|
+
exports.validate = validate;
|
|
202
|
+
exports.validateFilterRE = validateFilterRE;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
interface IClassGeneratorContextItem {
|
|
2
|
+
name: string;
|
|
3
|
+
usedBy: any[];
|
|
4
|
+
}
|
|
5
|
+
interface IClassGeneratorOptions {
|
|
6
|
+
reserveClassName?: (string | RegExp)[];
|
|
7
|
+
customGenerate?: (original: string, opts: IClassGeneratorOptions, context: Record<string, any>) => string | undefined;
|
|
8
|
+
log?: boolean;
|
|
9
|
+
exclude?: (string | RegExp)[];
|
|
10
|
+
include?: (string | RegExp)[];
|
|
11
|
+
ignoreClass?: (string | RegExp)[];
|
|
12
|
+
classPrefix?: string;
|
|
13
|
+
}
|
|
14
|
+
interface IClassGenerator {
|
|
15
|
+
newClassMap: Record<string, IClassGeneratorContextItem>;
|
|
16
|
+
newClassSize: number;
|
|
17
|
+
context: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare class ClassGenerator implements IClassGenerator {
|
|
21
|
+
newClassMap: Record<string, IClassGeneratorContextItem>;
|
|
22
|
+
newClassSize: number;
|
|
23
|
+
context: Record<string, any>;
|
|
24
|
+
opts: IClassGeneratorOptions;
|
|
25
|
+
classPrefix: string;
|
|
26
|
+
constructor(opts?: IClassGeneratorOptions);
|
|
27
|
+
defaultClassGenerate(): string;
|
|
28
|
+
ignoreClassName(className: string): boolean;
|
|
29
|
+
includeFilePath(filePath: string): boolean;
|
|
30
|
+
excludeFilePath(filePath: string): boolean;
|
|
31
|
+
isFileIncluded(filePath: string): boolean;
|
|
32
|
+
transformCssClass(className: string): string;
|
|
33
|
+
generateClassName(original: string): IClassGeneratorContextItem;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
declare function escapeStringRegexp(str: string): string;
|
|
37
|
+
declare function makeRegex(str: string, options?: {
|
|
38
|
+
exact: boolean;
|
|
39
|
+
}): RegExp;
|
|
40
|
+
|
|
41
|
+
declare const validateFilterRE: RegExp;
|
|
42
|
+
declare function isValidSelector(selector?: string): selector is string;
|
|
43
|
+
declare const splitCode: (code: string, options?: {
|
|
44
|
+
splitQuote?: boolean;
|
|
45
|
+
}) => string[];
|
|
46
|
+
|
|
47
|
+
declare const preserveClassNames: string[];
|
|
48
|
+
declare const defaultMangleClassFilter: (className: string) => boolean;
|
|
49
|
+
declare function groupBy<T>(arr: T[], cb: (arg: T) => string): Record<string, T[]>;
|
|
50
|
+
declare const acceptChars: string[];
|
|
51
|
+
declare function stripEscapeSequence(words: string): string;
|
|
52
|
+
declare const validate: (opts: IClassGeneratorOptions, classGenerator: IClassGenerator) => void;
|
|
53
|
+
declare function isRegexp(value: unknown): boolean;
|
|
54
|
+
declare function isMap(value: unknown): boolean;
|
|
55
|
+
declare function regExpTest(arr: (string | RegExp)[] | undefined, str: string): boolean;
|
|
56
|
+
|
|
57
|
+
export { ClassGenerator, IClassGenerator, IClassGeneratorContextItem, IClassGeneratorOptions, acceptChars, defaultMangleClassFilter, escapeStringRegexp, groupBy, isMap, isRegexp, isValidSelector, makeRegex, preserveClassNames, regExpTest, splitCode, stripEscapeSequence, validate, validateFilterRE };
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
const preserveClassNames = [
|
|
2
|
+
// https://tailwindcss.com/docs/transition-timing-function start
|
|
3
|
+
// https://github.com/sonofmagic/tailwindcss-mangle/issues/21
|
|
4
|
+
"ease-out",
|
|
5
|
+
"ease-linear",
|
|
6
|
+
"ease-in",
|
|
7
|
+
"ease-in-out"
|
|
8
|
+
// https://tailwindcss.com/docs/transition-timing-function end
|
|
9
|
+
];
|
|
10
|
+
const preserveClassNamesMap = preserveClassNames.reduce((acc, cur) => {
|
|
11
|
+
acc[cur] = true;
|
|
12
|
+
return acc;
|
|
13
|
+
}, {});
|
|
14
|
+
const defaultMangleClassFilter = (className) => {
|
|
15
|
+
if (preserveClassNamesMap[className]) {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
return /[:-]/.test(className);
|
|
19
|
+
};
|
|
20
|
+
function groupBy(arr, cb) {
|
|
21
|
+
if (!Array.isArray(arr)) {
|
|
22
|
+
throw new TypeError("expected an array for first argument");
|
|
23
|
+
}
|
|
24
|
+
if (typeof cb !== "function") {
|
|
25
|
+
throw new TypeError("expected a function for second argument");
|
|
26
|
+
}
|
|
27
|
+
const result = {};
|
|
28
|
+
for (const item of arr) {
|
|
29
|
+
const bucketCategory = cb(item);
|
|
30
|
+
const bucket = result[bucketCategory];
|
|
31
|
+
if (Array.isArray(bucket)) {
|
|
32
|
+
result[bucketCategory].push(item);
|
|
33
|
+
} else {
|
|
34
|
+
result[bucketCategory] = [item];
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
const acceptChars = [..."abcdefghijklmnopqrstuvwxyz"];
|
|
40
|
+
function stripEscapeSequence(words) {
|
|
41
|
+
return words.replaceAll("\\", "");
|
|
42
|
+
}
|
|
43
|
+
const validate = (opts, classGenerator) => {
|
|
44
|
+
if (!opts.log)
|
|
45
|
+
return;
|
|
46
|
+
for (const className in classGenerator.newClassMap) {
|
|
47
|
+
const c = classGenerator.newClassMap[className];
|
|
48
|
+
if (c.usedBy.length > 0) {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (/.+\.css:*$/.test(c.usedBy[0])) {
|
|
52
|
+
console.log(`The class name '${className}' is not used: defined at ${c.usedBy[0]}.`);
|
|
53
|
+
} else {
|
|
54
|
+
console.log(`The class name '${className}' is not defined: used at ${c.usedBy[0]}.`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
function isRegexp(value) {
|
|
59
|
+
return Object.prototype.toString.call(value) === "[object RegExp]";
|
|
60
|
+
}
|
|
61
|
+
function isMap(value) {
|
|
62
|
+
return Object.prototype.toString.call(value) === "[object Map]";
|
|
63
|
+
}
|
|
64
|
+
function regExpTest(arr = [], str) {
|
|
65
|
+
if (Array.isArray(arr)) {
|
|
66
|
+
for (const item of arr) {
|
|
67
|
+
if (typeof item === "string") {
|
|
68
|
+
if (item === str) {
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
} else if (isRegexp(item)) {
|
|
72
|
+
item.lastIndex = 0;
|
|
73
|
+
if (item.test(str)) {
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
throw new TypeError("paramater 'arr' should be a Array of Regexp | String !");
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
class ClassGenerator {
|
|
84
|
+
constructor(opts = {}) {
|
|
85
|
+
this.newClassMap = {};
|
|
86
|
+
this.newClassSize = 0;
|
|
87
|
+
this.context = {};
|
|
88
|
+
this.opts = opts;
|
|
89
|
+
this.classPrefix = opts.classPrefix ?? "tw-";
|
|
90
|
+
}
|
|
91
|
+
defaultClassGenerate() {
|
|
92
|
+
const chars = [];
|
|
93
|
+
let rest = (this.newClassSize - this.newClassSize % acceptChars.length) / acceptChars.length;
|
|
94
|
+
if (rest > 0) {
|
|
95
|
+
while (true) {
|
|
96
|
+
rest -= 1;
|
|
97
|
+
const m = rest % acceptChars.length;
|
|
98
|
+
const c = acceptChars[m];
|
|
99
|
+
chars.push(c);
|
|
100
|
+
rest -= m;
|
|
101
|
+
if (rest === 0) {
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
rest /= acceptChars.length;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
const prefixIndex = this.newClassSize % acceptChars.length;
|
|
108
|
+
const newClassName = `${this.classPrefix}${acceptChars[prefixIndex]}${chars.join("")}`;
|
|
109
|
+
return newClassName;
|
|
110
|
+
}
|
|
111
|
+
ignoreClassName(className) {
|
|
112
|
+
return regExpTest(this.opts.ignoreClass, className);
|
|
113
|
+
}
|
|
114
|
+
includeFilePath(filePath) {
|
|
115
|
+
const { include } = this.opts;
|
|
116
|
+
return Array.isArray(include) ? regExpTest(include, filePath) : true;
|
|
117
|
+
}
|
|
118
|
+
excludeFilePath(filePath) {
|
|
119
|
+
const { exclude } = this.opts;
|
|
120
|
+
return Array.isArray(exclude) ? regExpTest(exclude, filePath) : false;
|
|
121
|
+
}
|
|
122
|
+
isFileIncluded(filePath) {
|
|
123
|
+
return this.includeFilePath(filePath) && !this.excludeFilePath(filePath);
|
|
124
|
+
}
|
|
125
|
+
transformCssClass(className) {
|
|
126
|
+
const key = stripEscapeSequence(className);
|
|
127
|
+
const cn = this.newClassMap[key];
|
|
128
|
+
if (cn)
|
|
129
|
+
return cn.name;
|
|
130
|
+
return className;
|
|
131
|
+
}
|
|
132
|
+
generateClassName(original) {
|
|
133
|
+
const opts = this.opts;
|
|
134
|
+
original = stripEscapeSequence(original);
|
|
135
|
+
const cn = this.newClassMap[original];
|
|
136
|
+
if (cn)
|
|
137
|
+
return cn;
|
|
138
|
+
let newClassName;
|
|
139
|
+
if (opts.customGenerate && typeof opts.customGenerate === "function") {
|
|
140
|
+
newClassName = opts.customGenerate(original, opts, this.context);
|
|
141
|
+
}
|
|
142
|
+
if (!newClassName) {
|
|
143
|
+
newClassName = this.defaultClassGenerate();
|
|
144
|
+
}
|
|
145
|
+
if (opts.reserveClassName && regExpTest(opts.reserveClassName, newClassName)) {
|
|
146
|
+
if (opts.log) {
|
|
147
|
+
console.log(`The class name has been reserved. ${newClassName}`);
|
|
148
|
+
}
|
|
149
|
+
this.newClassSize++;
|
|
150
|
+
return this.generateClassName(original);
|
|
151
|
+
}
|
|
152
|
+
if (opts.log) {
|
|
153
|
+
console.log(`Minify class name from ${original} to ${newClassName}`);
|
|
154
|
+
}
|
|
155
|
+
const newClass = {
|
|
156
|
+
name: newClassName,
|
|
157
|
+
usedBy: []
|
|
158
|
+
};
|
|
159
|
+
this.newClassMap[original] = newClass;
|
|
160
|
+
this.newClassSize++;
|
|
161
|
+
return newClass;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function escapeStringRegexp(str) {
|
|
166
|
+
if (typeof str !== "string") {
|
|
167
|
+
throw new TypeError("Expected a string");
|
|
168
|
+
}
|
|
169
|
+
return str.replaceAll(/[$()*+.?[\\\]^{|}]/g, "\\$&").replaceAll("-", "\\x2d");
|
|
170
|
+
}
|
|
171
|
+
function makeRegex(str, options = {
|
|
172
|
+
exact: true
|
|
173
|
+
}) {
|
|
174
|
+
return new RegExp('(?<=^|[\\s"])' + escapeStringRegexp(str) + (options.exact ? '(?=$|[\\s"])' : ""), "g");
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const validateFilterRE = /[\w%-?\u00A0-\uFFFF-]/;
|
|
178
|
+
function isValidSelector(selector = "") {
|
|
179
|
+
return validateFilterRE.test(selector);
|
|
180
|
+
}
|
|
181
|
+
const splitCode = (code, options = { splitQuote: true }) => {
|
|
182
|
+
const regex = options.splitQuote ? /[\s"]+/ : /\s+/;
|
|
183
|
+
return code.split(regex).filter((x) => isValidSelector(x));
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export { ClassGenerator, acceptChars, defaultMangleClassFilter, escapeStringRegexp, groupBy, isMap, isRegexp, isValidSelector, makeRegex, preserveClassNames, regExpTest, splitCode, stripEscapeSequence, validate, validateFilterRE };
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tailwindcss-mangle/shared",
|
|
3
|
+
"version": "1.2.7",
|
|
4
|
+
"description": "The shared utils of tailwindcss-mangle",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"import": "./dist/index.mjs",
|
|
9
|
+
"require": "./dist/index.cjs"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"typesVersions": {
|
|
13
|
+
"*": {
|
|
14
|
+
"*": [
|
|
15
|
+
"./dist/*",
|
|
16
|
+
"./dist/index.d.ts"
|
|
17
|
+
]
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/index.cjs",
|
|
21
|
+
"module": "./dist/index.mjs",
|
|
22
|
+
"types": "./dist/index.d.ts",
|
|
23
|
+
"files": [
|
|
24
|
+
"dist"
|
|
25
|
+
],
|
|
26
|
+
"keywords": [
|
|
27
|
+
"tailwindcss",
|
|
28
|
+
"patch",
|
|
29
|
+
"core",
|
|
30
|
+
"mangle",
|
|
31
|
+
"shared",
|
|
32
|
+
"utils"
|
|
33
|
+
],
|
|
34
|
+
"author": "SonOfMagic <qq1324318532@gmail.com>",
|
|
35
|
+
"license": "MIT",
|
|
36
|
+
"publishConfig": {
|
|
37
|
+
"access": "public",
|
|
38
|
+
"registry": "https://registry.npmjs.org/"
|
|
39
|
+
},
|
|
40
|
+
"dependencies": {},
|
|
41
|
+
"devDependencies": {},
|
|
42
|
+
"homepage": "https://github.com/sonofmagic/tailwindcss-mangle",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/sonofmagic/tailwindcss-mangle.git"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "unbuild",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:dev": "vitest"
|
|
51
|
+
}
|
|
52
|
+
}
|