@tailwindcss-mangle/core 1.2.7 → 2.0.1

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/index.cjs CHANGED
@@ -4,26 +4,16 @@ const postcss = require('postcss');
4
4
  const parser = require('postcss-selector-parser');
5
5
  const parse5 = require('parse5');
6
6
  const shared = require('@tailwindcss-mangle/shared');
7
- const t = require('@babel/types');
8
- const core = require('@babel/core');
7
+ const babel = require('@babel/core');
8
+ const helperPluginUtils = require('@babel/helper-plugin-utils');
9
+ const MagicString = require('magic-string');
9
10
 
10
11
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
11
12
 
12
- function _interopNamespaceCompat(e) {
13
- if (e && typeof e === 'object' && 'default' in e) return e;
14
- const n = Object.create(null);
15
- if (e) {
16
- for (const k in e) {
17
- n[k] = e[k];
18
- }
19
- }
20
- n.default = e;
21
- return n;
22
- }
23
-
24
13
  const postcss__default = /*#__PURE__*/_interopDefaultCompat(postcss);
25
14
  const parser__default = /*#__PURE__*/_interopDefaultCompat(parser);
26
- const t__namespace = /*#__PURE__*/_interopNamespaceCompat(t);
15
+ const babel__default = /*#__PURE__*/_interopDefaultCompat(babel);
16
+ const MagicString__default = /*#__PURE__*/_interopDefaultCompat(MagicString);
27
17
 
28
18
  function isObject(value) {
29
19
  return value !== null && typeof value === "object";
@@ -80,64 +70,41 @@ function isVueScoped(s) {
80
70
  }
81
71
  return false;
82
72
  }
83
- const postcssMangleTailwindcssPlugin = (options) => {
84
- const { ignoreVueScoped } = defu(options, {
73
+ const transformSelectorPostcssPlugin = function(options) {
74
+ const { ignoreVueScoped, replaceMap } = defu(options, {
85
75
  ignoreVueScoped: true
86
76
  });
87
- if (options?.scene === "loader") {
88
- let set = /* @__PURE__ */ new Set();
89
- if (options && options.runtimeSet) {
90
- set = options.runtimeSet;
91
- }
92
- return {
93
- postcssPlugin,
94
- Rule(rule) {
95
- rule.selector = parser__default((selectors) => {
96
- selectors.walkClasses((s) => {
97
- if (s.value) {
98
- const existed = set.has(s.value);
99
- if (existed) {
100
- if (ignoreVueScoped && isVueScoped(s)) {
101
- return;
102
- }
103
- s.value = options.classGenerator.generateClassName(s.value).name;
104
- }
77
+ return {
78
+ postcssPlugin,
79
+ async Rule(rule) {
80
+ await parser__default((selectors) => {
81
+ selectors.walkClasses((s) => {
82
+ if (s.value && replaceMap && replaceMap.has(s.value)) {
83
+ if (ignoreVueScoped && isVueScoped(s)) {
84
+ return;
105
85
  }
106
- });
107
- }).processSync(rule.selector);
108
- }
109
- };
110
- } else {
111
- let newClassMap = {};
112
- if (options && options.classGenerator) {
113
- newClassMap = options.classGenerator.newClassMap;
114
- }
115
- return {
116
- postcssPlugin,
117
- Rule(rule) {
118
- rule.selector = parser__default((selectors) => {
119
- selectors.walkClasses((s) => {
120
- if (s.value) {
121
- const hit = newClassMap[s.value];
122
- const existed = Boolean(hit);
123
- if (existed) {
124
- if (ignoreVueScoped && isVueScoped(s)) {
125
- return;
126
- }
127
- s.value = hit.name;
128
- }
86
+ const v = replaceMap.get(s.value);
87
+ if (v) {
88
+ s.value = v;
129
89
  }
130
- });
131
- }).processSync(rule.selector);
132
- }
133
- };
134
- }
90
+ }
91
+ });
92
+ }).transform(rule, {
93
+ lossless: false,
94
+ updateSelector: true
95
+ });
96
+ }
97
+ };
135
98
  };
136
- postcssMangleTailwindcssPlugin.postcss = true;
99
+ transformSelectorPostcssPlugin.postcss = true;
137
100
 
138
101
  function cssHandler(rawSource, options) {
139
- const acceptedPlugins = [postcssMangleTailwindcssPlugin(options)];
140
- return postcss__default(acceptedPlugins).process(rawSource).css;
102
+ const acceptedPlugins = [transformSelectorPostcssPlugin(options)];
103
+ const { file } = options;
104
+ return postcss__default(acceptedPlugins).process(rawSource, {
105
+ from: file,
106
+ to: file
107
+ });
141
108
  }
142
109
 
143
110
  ({
@@ -234,7 +201,7 @@ function traverse(node, visitor, parent) {
234
201
  }
235
202
 
236
203
  function htmlHandler(rawSource, options) {
237
- const { runtimeSet, classGenerator } = options;
204
+ const { replaceMap, classGenerator } = options;
238
205
  const fragment = parse5.parse(rawSource);
239
206
  traverse(fragment, {
240
207
  element(node) {
@@ -244,7 +211,7 @@ function htmlHandler(rawSource, options) {
244
211
  splitQuote: false
245
212
  });
246
213
  for (const v of array) {
247
- if (runtimeSet.has(v)) {
214
+ if (replaceMap.has(v)) {
248
215
  attribute.value = attribute.value.replace(shared.makeRegex(v), classGenerator.generateClassName(v).name);
249
216
  }
250
217
  }
@@ -256,14 +223,213 @@ function htmlHandler(rawSource, options) {
256
223
 
257
224
  const isProd = () => process.env.NODE_ENV === "production";
258
225
 
259
- function handleValue(string_, node, options) {
260
- const { runtimeSet: set, classGenerator: clsGen, splitQuote = true } = options;
261
- const array = shared.splitCode(string_, {
226
+ // >>> INTERFACES <<<
227
+ // >>> HELPERS <<<
228
+ var castComparer = function (comparer) { return function (a, b, order) { return comparer(a, b, order) * order; }; };
229
+ var throwInvalidConfigErrorIfTrue = function (condition, context) {
230
+ if (condition)
231
+ throw Error("Invalid sort config: " + context);
232
+ };
233
+ var unpackObjectSorter = function (sortByObj) {
234
+ var _a = sortByObj || {}, asc = _a.asc, desc = _a.desc;
235
+ var order = asc ? 1 : -1;
236
+ var sortBy = (asc || desc);
237
+ // Validate object config
238
+ throwInvalidConfigErrorIfTrue(!sortBy, 'Expected `asc` or `desc` property');
239
+ throwInvalidConfigErrorIfTrue(asc && desc, 'Ambiguous object with `asc` and `desc` config properties');
240
+ var comparer = sortByObj.comparer && castComparer(sortByObj.comparer);
241
+ return { order: order, sortBy: sortBy, comparer: comparer };
242
+ };
243
+ // >>> SORTERS <<<
244
+ var multiPropertySorterProvider = function (defaultComparer) {
245
+ return function multiPropertySorter(sortBy, sortByArr, depth, order, comparer, a, b) {
246
+ var valA;
247
+ var valB;
248
+ if (typeof sortBy === 'string') {
249
+ valA = a[sortBy];
250
+ valB = b[sortBy];
251
+ }
252
+ else if (typeof sortBy === 'function') {
253
+ valA = sortBy(a);
254
+ valB = sortBy(b);
255
+ }
256
+ else {
257
+ var objectSorterConfig = unpackObjectSorter(sortBy);
258
+ return multiPropertySorter(objectSorterConfig.sortBy, sortByArr, depth, objectSorterConfig.order, objectSorterConfig.comparer || defaultComparer, a, b);
259
+ }
260
+ var equality = comparer(valA, valB, order);
261
+ if ((equality === 0 || (valA == null && valB == null)) &&
262
+ sortByArr.length > depth) {
263
+ return multiPropertySorter(sortByArr[depth], sortByArr, depth + 1, order, comparer, a, b);
264
+ }
265
+ return equality;
266
+ };
267
+ };
268
+ function getSortStrategy(sortBy, comparer, order) {
269
+ // Flat array sorter
270
+ if (sortBy === undefined || sortBy === true) {
271
+ return function (a, b) { return comparer(a, b, order); };
272
+ }
273
+ // Sort list of objects by single object key
274
+ if (typeof sortBy === 'string') {
275
+ throwInvalidConfigErrorIfTrue(sortBy.includes('.'), 'String syntax not allowed for nested properties.');
276
+ return function (a, b) { return comparer(a[sortBy], b[sortBy], order); };
277
+ }
278
+ // Sort list of objects by single function sorter
279
+ if (typeof sortBy === 'function') {
280
+ return function (a, b) { return comparer(sortBy(a), sortBy(b), order); };
281
+ }
282
+ // Sort by multiple properties
283
+ if (Array.isArray(sortBy)) {
284
+ var multiPropSorter_1 = multiPropertySorterProvider(comparer);
285
+ return function (a, b) { return multiPropSorter_1(sortBy[0], sortBy, 1, order, comparer, a, b); };
286
+ }
287
+ // Unpack object config to get actual sorter strategy
288
+ var objectSorterConfig = unpackObjectSorter(sortBy);
289
+ return getSortStrategy(objectSorterConfig.sortBy, objectSorterConfig.comparer || comparer, objectSorterConfig.order);
290
+ }
291
+ var sortArray = function (order, ctx, sortBy, comparer) {
292
+ var _a;
293
+ if (!Array.isArray(ctx)) {
294
+ return ctx;
295
+ }
296
+ // Unwrap sortBy if array with only 1 value to get faster sort strategy
297
+ if (Array.isArray(sortBy) && sortBy.length < 2) {
298
+ _a = sortBy, sortBy = _a[0];
299
+ }
300
+ return ctx.sort(getSortStrategy(sortBy, comparer, order));
301
+ };
302
+ function createNewSortInstance(opts) {
303
+ var comparer = castComparer(opts.comparer);
304
+ return function (arrayToSort) {
305
+ var ctx = Array.isArray(arrayToSort) && !opts.inPlaceSorting
306
+ ? arrayToSort.slice()
307
+ : arrayToSort;
308
+ return {
309
+ asc: function (sortBy) {
310
+ return sortArray(1, ctx, sortBy, comparer);
311
+ },
312
+ desc: function (sortBy) {
313
+ return sortArray(-1, ctx, sortBy, comparer);
314
+ },
315
+ by: function (sortBy) {
316
+ return sortArray(1, ctx, sortBy, comparer);
317
+ },
318
+ };
319
+ };
320
+ }
321
+ var defaultComparer = function (a, b, order) {
322
+ if (a == null)
323
+ return order;
324
+ if (b == null)
325
+ return -order;
326
+ if (typeof a !== typeof b) {
327
+ return typeof a < typeof b ? -1 : 1;
328
+ }
329
+ if (a < b)
330
+ return -1;
331
+ if (a > b)
332
+ return 1;
333
+ return 0;
334
+ };
335
+ var sort = createNewSortInstance({
336
+ comparer: defaultComparer,
337
+ });
338
+ createNewSortInstance({
339
+ comparer: defaultComparer,
340
+ inPlaceSorting: true,
341
+ });
342
+
343
+ function handleValue$1(options) {
344
+ const { addToUsedBy, id, magicString, node, raw, replaceMap, offset = 0 } = options;
345
+ let value = raw;
346
+ const arr = sort(shared.splitCode(value)).desc((x) => x.length);
347
+ for (const str of arr) {
348
+ if (replaceMap.has(str)) {
349
+ addToUsedBy(str, id);
350
+ const v = replaceMap.get(str);
351
+ if (v) {
352
+ value = value.replaceAll(str, v);
353
+ }
354
+ }
355
+ }
356
+ if (typeof node.start === "number" && typeof node.end === "number" && value) {
357
+ magicString.update(node.start + offset, node.end - offset, value);
358
+ }
359
+ }
360
+ const plugin = helperPluginUtils.declare((api, options) => {
361
+ api.assertVersion(7);
362
+ const { magicString, replaceMap, id, addToUsedBy } = options;
363
+ return {
364
+ visitor: {
365
+ StringLiteral: {
366
+ enter(p) {
367
+ const node = p.node;
368
+ handleValue$1({
369
+ addToUsedBy,
370
+ id,
371
+ magicString,
372
+ node,
373
+ raw: node.value,
374
+ replaceMap,
375
+ offset: 1
376
+ });
377
+ }
378
+ },
379
+ TemplateElement: {
380
+ enter(p) {
381
+ const node = p.node;
382
+ handleValue$1({
383
+ addToUsedBy,
384
+ id,
385
+ magicString,
386
+ node,
387
+ raw: node.value.raw,
388
+ replaceMap,
389
+ offset: 0
390
+ });
391
+ }
392
+ }
393
+ }
394
+ };
395
+ });
396
+ function preProcessJs(options) {
397
+ const { code, replaceMap, id, addToUsedBy } = options;
398
+ const magicString = new MagicString__default(code);
399
+ babel__default.transformSync(code, {
400
+ presets: [
401
+ // ['@babel/preset-react', {}],
402
+ [
403
+ require("@babel/preset-typescript"),
404
+ {
405
+ allExtensions: true,
406
+ isTSX: true
407
+ }
408
+ ]
409
+ ],
410
+ plugins: [
411
+ [
412
+ plugin,
413
+ {
414
+ magicString,
415
+ replaceMap,
416
+ id,
417
+ addToUsedBy
418
+ }
419
+ ]
420
+ ]
421
+ });
422
+ return magicString.toString();
423
+ }
424
+
425
+ function handleValue(raw, node, options) {
426
+ const { replaceMap, classGenerator: clsGen, splitQuote = true } = options;
427
+ const array = shared.splitCode(raw, {
262
428
  splitQuote
263
429
  });
264
- let rawString = string_;
430
+ let rawString = raw;
265
431
  for (const v of array) {
266
- if (set.has(v)) {
432
+ if (replaceMap.has(v)) {
267
433
  let ignoreFlag = false;
268
434
  if (Array.isArray(node.leadingComments)) {
269
435
  ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("tw-mangle") && x.value.includes("ignore")) > -1;
@@ -276,7 +442,7 @@ function handleValue(string_, node, options) {
276
442
  return rawString;
277
443
  }
278
444
  function jsHandler(rawSource, options) {
279
- const result = core.transformSync(rawSource, {
445
+ const result = babel.transformSync(rawSource, {
280
446
  babelrc: false,
281
447
  ast: true,
282
448
  plugins: [
@@ -297,12 +463,18 @@ function jsHandler(rawSource, options) {
297
463
  },
298
464
  CallExpression: {
299
465
  enter(p) {
300
- const n = p.node;
301
- if (t__namespace.isIdentifier(n.callee) && n.callee.name === "eval" && t__namespace.isStringLiteral(n.arguments[0])) {
302
- const res = jsHandler(n.arguments[0].value, options);
303
- if (res.code) {
304
- n.arguments[0].value = res.code;
305
- }
466
+ const calleePath = p.get("callee");
467
+ if (calleePath.isIdentifier() && calleePath.node.name === "eval") {
468
+ p.traverse({
469
+ StringLiteral: {
470
+ enter(s) {
471
+ const res = jsHandler(s.node.value, options);
472
+ if (res.code) {
473
+ s.node.value = res.code;
474
+ }
475
+ }
476
+ }
477
+ });
306
478
  }
307
479
  }
308
480
  }
@@ -323,3 +495,4 @@ exports.cssHandler = cssHandler;
323
495
  exports.handleValue = handleValue;
324
496
  exports.htmlHandler = htmlHandler;
325
497
  exports.jsHandler = jsHandler;
498
+ exports.preProcessJs = preProcessJs;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import * as postcss_lib_no_work_result from 'postcss/lib/no-work-result';
2
+ import postcss from 'postcss';
1
3
  import { ClassGenerator } from '@tailwindcss-mangle/shared';
2
4
  export { ClassGenerator } from '@tailwindcss-mangle/shared';
3
5
  import { StringLiteral, TemplateElement } from '@babel/types';
@@ -5,7 +7,7 @@ import { BabelFileResult } from '@babel/core';
5
7
 
6
8
  interface IClassGeneratorContextItem {
7
9
  name: string;
8
- usedBy: any[];
10
+ usedBy: string[];
9
11
  }
10
12
  interface IClassGeneratorOptions {
11
13
  reserveClassName?: (string | RegExp)[];
@@ -17,8 +19,8 @@ interface IClassGeneratorOptions {
17
19
  classPrefix?: string;
18
20
  }
19
21
  interface IHandlerOptions {
20
- runtimeSet: Set<string>;
21
22
  classGenerator: ClassGenerator;
23
+ replaceMap: Map<string, string>;
22
24
  }
23
25
  interface IHtmlHandlerOptions extends IHandlerOptions {
24
26
  }
@@ -27,8 +29,8 @@ interface IJsHandlerOptions extends IHandlerOptions {
27
29
  minified?: boolean;
28
30
  }
29
31
  interface ICssHandlerOptions extends IHandlerOptions {
30
- scene?: 'loader' | 'process';
31
32
  ignoreVueScoped?: boolean;
33
+ file?: string;
32
34
  }
33
35
  interface ClassSetOutputOptions {
34
36
  filename: string;
@@ -47,11 +49,18 @@ interface Options {
47
49
  classMapOutput?: boolean | ClassMapOutputOptions;
48
50
  }
49
51
 
50
- declare function cssHandler(rawSource: string, options: ICssHandlerOptions): string;
52
+ declare function cssHandler(rawSource: string, options: ICssHandlerOptions): postcss.LazyResult | postcss_lib_no_work_result.default;
51
53
 
52
54
  declare function htmlHandler(rawSource: string, options: IHtmlHandlerOptions): string;
53
55
 
54
- declare function handleValue(string_: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions): string;
56
+ declare function preProcessJs(options: {
57
+ code: string;
58
+ replaceMap: Map<string, string>;
59
+ id: string;
60
+ addToUsedBy: (key: string, file: string) => void;
61
+ }): string;
62
+
63
+ declare function handleValue(raw: string, node: StringLiteral | TemplateElement, options: IJsHandlerOptions): string;
55
64
  declare function jsHandler(rawSource: string, options: IJsHandlerOptions): BabelFileResult;
56
65
 
57
- export { ClassMapOutputOptions, ClassSetOutputOptions, IClassGeneratorContextItem, IClassGeneratorOptions, ICssHandlerOptions, IHandlerOptions, IHtmlHandlerOptions, IJsHandlerOptions, Options, cssHandler, handleValue, htmlHandler, jsHandler };
66
+ export { ClassMapOutputOptions, ClassSetOutputOptions, IClassGeneratorContextItem, IClassGeneratorOptions, ICssHandlerOptions, IHandlerOptions, IHtmlHandlerOptions, IJsHandlerOptions, Options, cssHandler, handleValue, htmlHandler, jsHandler, preProcessJs };
package/dist/index.mjs CHANGED
@@ -3,9 +3,19 @@ import parser from 'postcss-selector-parser';
3
3
  import { html, defaultTreeAdapter, parse, serialize } from 'parse5';
4
4
  import { splitCode, makeRegex } from '@tailwindcss-mangle/shared';
5
5
  export { ClassGenerator } from '@tailwindcss-mangle/shared';
6
- import * as t from '@babel/types';
7
- import { transformSync } from '@babel/core';
6
+ import babel, { transformSync } from '@babel/core';
7
+ import { declare } from '@babel/helper-plugin-utils';
8
+ import MagicString from 'magic-string';
8
9
 
10
+
11
+
12
+ // -- Unbuild CommonJS Shims --
13
+ import __cjs_url__ from 'url';
14
+ import __cjs_path__ from 'path';
15
+ import __cjs_mod__ from 'module';
16
+ const __filename = __cjs_url__.fileURLToPath(import.meta.url);
17
+ const __dirname = __cjs_path__.dirname(__filename);
18
+ const require = __cjs_mod__.createRequire(import.meta.url);
9
19
  function isObject(value) {
10
20
  return value !== null && typeof value === "object";
11
21
  }
@@ -61,64 +71,41 @@ function isVueScoped(s) {
61
71
  }
62
72
  return false;
63
73
  }
64
- const postcssMangleTailwindcssPlugin = (options) => {
65
- const { ignoreVueScoped } = defu(options, {
74
+ const transformSelectorPostcssPlugin = function(options) {
75
+ const { ignoreVueScoped, replaceMap } = defu(options, {
66
76
  ignoreVueScoped: true
67
77
  });
68
- if (options?.scene === "loader") {
69
- let set = /* @__PURE__ */ new Set();
70
- if (options && options.runtimeSet) {
71
- set = options.runtimeSet;
72
- }
73
- return {
74
- postcssPlugin,
75
- Rule(rule) {
76
- rule.selector = parser((selectors) => {
77
- selectors.walkClasses((s) => {
78
- if (s.value) {
79
- const existed = set.has(s.value);
80
- if (existed) {
81
- if (ignoreVueScoped && isVueScoped(s)) {
82
- return;
83
- }
84
- s.value = options.classGenerator.generateClassName(s.value).name;
85
- }
78
+ return {
79
+ postcssPlugin,
80
+ async Rule(rule) {
81
+ await parser((selectors) => {
82
+ selectors.walkClasses((s) => {
83
+ if (s.value && replaceMap && replaceMap.has(s.value)) {
84
+ if (ignoreVueScoped && isVueScoped(s)) {
85
+ return;
86
86
  }
87
- });
88
- }).processSync(rule.selector);
89
- }
90
- };
91
- } else {
92
- let newClassMap = {};
93
- if (options && options.classGenerator) {
94
- newClassMap = options.classGenerator.newClassMap;
95
- }
96
- return {
97
- postcssPlugin,
98
- Rule(rule) {
99
- rule.selector = parser((selectors) => {
100
- selectors.walkClasses((s) => {
101
- if (s.value) {
102
- const hit = newClassMap[s.value];
103
- const existed = Boolean(hit);
104
- if (existed) {
105
- if (ignoreVueScoped && isVueScoped(s)) {
106
- return;
107
- }
108
- s.value = hit.name;
109
- }
87
+ const v = replaceMap.get(s.value);
88
+ if (v) {
89
+ s.value = v;
110
90
  }
111
- });
112
- }).processSync(rule.selector);
113
- }
114
- };
115
- }
91
+ }
92
+ });
93
+ }).transform(rule, {
94
+ lossless: false,
95
+ updateSelector: true
96
+ });
97
+ }
98
+ };
116
99
  };
117
- postcssMangleTailwindcssPlugin.postcss = true;
100
+ transformSelectorPostcssPlugin.postcss = true;
118
101
 
119
102
  function cssHandler(rawSource, options) {
120
- const acceptedPlugins = [postcssMangleTailwindcssPlugin(options)];
121
- return postcss(acceptedPlugins).process(rawSource).css;
103
+ const acceptedPlugins = [transformSelectorPostcssPlugin(options)];
104
+ const { file } = options;
105
+ return postcss(acceptedPlugins).process(rawSource, {
106
+ from: file,
107
+ to: file
108
+ });
122
109
  }
123
110
 
124
111
  ({
@@ -215,7 +202,7 @@ function traverse(node, visitor, parent) {
215
202
  }
216
203
 
217
204
  function htmlHandler(rawSource, options) {
218
- const { runtimeSet, classGenerator } = options;
205
+ const { replaceMap, classGenerator } = options;
219
206
  const fragment = parse(rawSource);
220
207
  traverse(fragment, {
221
208
  element(node) {
@@ -225,7 +212,7 @@ function htmlHandler(rawSource, options) {
225
212
  splitQuote: false
226
213
  });
227
214
  for (const v of array) {
228
- if (runtimeSet.has(v)) {
215
+ if (replaceMap.has(v)) {
229
216
  attribute.value = attribute.value.replace(makeRegex(v), classGenerator.generateClassName(v).name);
230
217
  }
231
218
  }
@@ -237,14 +224,213 @@ function htmlHandler(rawSource, options) {
237
224
 
238
225
  const isProd = () => process.env.NODE_ENV === "production";
239
226
 
240
- function handleValue(string_, node, options) {
241
- const { runtimeSet: set, classGenerator: clsGen, splitQuote = true } = options;
242
- const array = splitCode(string_, {
227
+ // >>> INTERFACES <<<
228
+ // >>> HELPERS <<<
229
+ var castComparer = function (comparer) { return function (a, b, order) { return comparer(a, b, order) * order; }; };
230
+ var throwInvalidConfigErrorIfTrue = function (condition, context) {
231
+ if (condition)
232
+ throw Error("Invalid sort config: " + context);
233
+ };
234
+ var unpackObjectSorter = function (sortByObj) {
235
+ var _a = sortByObj || {}, asc = _a.asc, desc = _a.desc;
236
+ var order = asc ? 1 : -1;
237
+ var sortBy = (asc || desc);
238
+ // Validate object config
239
+ throwInvalidConfigErrorIfTrue(!sortBy, 'Expected `asc` or `desc` property');
240
+ throwInvalidConfigErrorIfTrue(asc && desc, 'Ambiguous object with `asc` and `desc` config properties');
241
+ var comparer = sortByObj.comparer && castComparer(sortByObj.comparer);
242
+ return { order: order, sortBy: sortBy, comparer: comparer };
243
+ };
244
+ // >>> SORTERS <<<
245
+ var multiPropertySorterProvider = function (defaultComparer) {
246
+ return function multiPropertySorter(sortBy, sortByArr, depth, order, comparer, a, b) {
247
+ var valA;
248
+ var valB;
249
+ if (typeof sortBy === 'string') {
250
+ valA = a[sortBy];
251
+ valB = b[sortBy];
252
+ }
253
+ else if (typeof sortBy === 'function') {
254
+ valA = sortBy(a);
255
+ valB = sortBy(b);
256
+ }
257
+ else {
258
+ var objectSorterConfig = unpackObjectSorter(sortBy);
259
+ return multiPropertySorter(objectSorterConfig.sortBy, sortByArr, depth, objectSorterConfig.order, objectSorterConfig.comparer || defaultComparer, a, b);
260
+ }
261
+ var equality = comparer(valA, valB, order);
262
+ if ((equality === 0 || (valA == null && valB == null)) &&
263
+ sortByArr.length > depth) {
264
+ return multiPropertySorter(sortByArr[depth], sortByArr, depth + 1, order, comparer, a, b);
265
+ }
266
+ return equality;
267
+ };
268
+ };
269
+ function getSortStrategy(sortBy, comparer, order) {
270
+ // Flat array sorter
271
+ if (sortBy === undefined || sortBy === true) {
272
+ return function (a, b) { return comparer(a, b, order); };
273
+ }
274
+ // Sort list of objects by single object key
275
+ if (typeof sortBy === 'string') {
276
+ throwInvalidConfigErrorIfTrue(sortBy.includes('.'), 'String syntax not allowed for nested properties.');
277
+ return function (a, b) { return comparer(a[sortBy], b[sortBy], order); };
278
+ }
279
+ // Sort list of objects by single function sorter
280
+ if (typeof sortBy === 'function') {
281
+ return function (a, b) { return comparer(sortBy(a), sortBy(b), order); };
282
+ }
283
+ // Sort by multiple properties
284
+ if (Array.isArray(sortBy)) {
285
+ var multiPropSorter_1 = multiPropertySorterProvider(comparer);
286
+ return function (a, b) { return multiPropSorter_1(sortBy[0], sortBy, 1, order, comparer, a, b); };
287
+ }
288
+ // Unpack object config to get actual sorter strategy
289
+ var objectSorterConfig = unpackObjectSorter(sortBy);
290
+ return getSortStrategy(objectSorterConfig.sortBy, objectSorterConfig.comparer || comparer, objectSorterConfig.order);
291
+ }
292
+ var sortArray = function (order, ctx, sortBy, comparer) {
293
+ var _a;
294
+ if (!Array.isArray(ctx)) {
295
+ return ctx;
296
+ }
297
+ // Unwrap sortBy if array with only 1 value to get faster sort strategy
298
+ if (Array.isArray(sortBy) && sortBy.length < 2) {
299
+ _a = sortBy, sortBy = _a[0];
300
+ }
301
+ return ctx.sort(getSortStrategy(sortBy, comparer, order));
302
+ };
303
+ function createNewSortInstance(opts) {
304
+ var comparer = castComparer(opts.comparer);
305
+ return function (arrayToSort) {
306
+ var ctx = Array.isArray(arrayToSort) && !opts.inPlaceSorting
307
+ ? arrayToSort.slice()
308
+ : arrayToSort;
309
+ return {
310
+ asc: function (sortBy) {
311
+ return sortArray(1, ctx, sortBy, comparer);
312
+ },
313
+ desc: function (sortBy) {
314
+ return sortArray(-1, ctx, sortBy, comparer);
315
+ },
316
+ by: function (sortBy) {
317
+ return sortArray(1, ctx, sortBy, comparer);
318
+ },
319
+ };
320
+ };
321
+ }
322
+ var defaultComparer = function (a, b, order) {
323
+ if (a == null)
324
+ return order;
325
+ if (b == null)
326
+ return -order;
327
+ if (typeof a !== typeof b) {
328
+ return typeof a < typeof b ? -1 : 1;
329
+ }
330
+ if (a < b)
331
+ return -1;
332
+ if (a > b)
333
+ return 1;
334
+ return 0;
335
+ };
336
+ var sort = createNewSortInstance({
337
+ comparer: defaultComparer,
338
+ });
339
+ createNewSortInstance({
340
+ comparer: defaultComparer,
341
+ inPlaceSorting: true,
342
+ });
343
+
344
+ function handleValue$1(options) {
345
+ const { addToUsedBy, id, magicString, node, raw, replaceMap, offset = 0 } = options;
346
+ let value = raw;
347
+ const arr = sort(splitCode(value)).desc((x) => x.length);
348
+ for (const str of arr) {
349
+ if (replaceMap.has(str)) {
350
+ addToUsedBy(str, id);
351
+ const v = replaceMap.get(str);
352
+ if (v) {
353
+ value = value.replaceAll(str, v);
354
+ }
355
+ }
356
+ }
357
+ if (typeof node.start === "number" && typeof node.end === "number" && value) {
358
+ magicString.update(node.start + offset, node.end - offset, value);
359
+ }
360
+ }
361
+ const plugin = declare((api, options) => {
362
+ api.assertVersion(7);
363
+ const { magicString, replaceMap, id, addToUsedBy } = options;
364
+ return {
365
+ visitor: {
366
+ StringLiteral: {
367
+ enter(p) {
368
+ const node = p.node;
369
+ handleValue$1({
370
+ addToUsedBy,
371
+ id,
372
+ magicString,
373
+ node,
374
+ raw: node.value,
375
+ replaceMap,
376
+ offset: 1
377
+ });
378
+ }
379
+ },
380
+ TemplateElement: {
381
+ enter(p) {
382
+ const node = p.node;
383
+ handleValue$1({
384
+ addToUsedBy,
385
+ id,
386
+ magicString,
387
+ node,
388
+ raw: node.value.raw,
389
+ replaceMap,
390
+ offset: 0
391
+ });
392
+ }
393
+ }
394
+ }
395
+ };
396
+ });
397
+ function preProcessJs(options) {
398
+ const { code, replaceMap, id, addToUsedBy } = options;
399
+ const magicString = new MagicString(code);
400
+ babel.transformSync(code, {
401
+ presets: [
402
+ // ['@babel/preset-react', {}],
403
+ [
404
+ require("@babel/preset-typescript"),
405
+ {
406
+ allExtensions: true,
407
+ isTSX: true
408
+ }
409
+ ]
410
+ ],
411
+ plugins: [
412
+ [
413
+ plugin,
414
+ {
415
+ magicString,
416
+ replaceMap,
417
+ id,
418
+ addToUsedBy
419
+ }
420
+ ]
421
+ ]
422
+ });
423
+ return magicString.toString();
424
+ }
425
+
426
+ function handleValue(raw, node, options) {
427
+ const { replaceMap, classGenerator: clsGen, splitQuote = true } = options;
428
+ const array = splitCode(raw, {
243
429
  splitQuote
244
430
  });
245
- let rawString = string_;
431
+ let rawString = raw;
246
432
  for (const v of array) {
247
- if (set.has(v)) {
433
+ if (replaceMap.has(v)) {
248
434
  let ignoreFlag = false;
249
435
  if (Array.isArray(node.leadingComments)) {
250
436
  ignoreFlag = node.leadingComments.findIndex((x) => x.value.includes("tw-mangle") && x.value.includes("ignore")) > -1;
@@ -278,12 +464,18 @@ function jsHandler(rawSource, options) {
278
464
  },
279
465
  CallExpression: {
280
466
  enter(p) {
281
- const n = p.node;
282
- if (t.isIdentifier(n.callee) && n.callee.name === "eval" && t.isStringLiteral(n.arguments[0])) {
283
- const res = jsHandler(n.arguments[0].value, options);
284
- if (res.code) {
285
- n.arguments[0].value = res.code;
286
- }
467
+ const calleePath = p.get("callee");
468
+ if (calleePath.isIdentifier() && calleePath.node.name === "eval") {
469
+ p.traverse({
470
+ StringLiteral: {
471
+ enter(s) {
472
+ const res = jsHandler(s.node.value, options);
473
+ if (res.code) {
474
+ s.node.value = res.code;
475
+ }
476
+ }
477
+ }
478
+ });
287
479
  }
288
480
  }
289
481
  }
@@ -299,4 +491,4 @@ function jsHandler(rawSource, options) {
299
491
  return result;
300
492
  }
301
493
 
302
- export { cssHandler, handleValue, htmlHandler, jsHandler };
494
+ export { cssHandler, handleValue, htmlHandler, jsHandler, preProcessJs };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tailwindcss-mangle/core",
3
- "version": "1.2.7",
3
+ "version": "2.0.1",
4
4
  "description": "The core of tailwindcss-mangle",
5
5
  "exports": {
6
6
  ".": {
@@ -36,12 +36,15 @@
36
36
  "registry": "https://registry.npmjs.org/"
37
37
  },
38
38
  "dependencies": {
39
+ "@babel/helper-plugin-utils": "^7.22.5",
40
+ "@babel/preset-typescript": "^7.22.5",
39
41
  "@babel/core": "^7.22.10",
40
42
  "@babel/types": "^7.22.10",
41
43
  "parse5": "^7.1.2",
42
44
  "postcss": "^8.4.27",
43
45
  "postcss-selector-parser": "^6.0.13",
44
- "@tailwindcss-mangle/shared": "^1.2.7"
46
+ "magic-string": "^0.30.2",
47
+ "@tailwindcss-mangle/shared": "^2.0.0"
45
48
  },
46
49
  "devDependencies": {
47
50
  "@parse5/tools": "^0.2.0",
@@ -54,7 +57,7 @@
54
57
  },
55
58
  "scripts": {
56
59
  "build": "unbuild",
57
- "test": "vitest run",
60
+ "test": "vitest run --coverage.enabled",
58
61
  "test:dev": "vitest",
59
62
  "coverage": "vitest run --coverage"
60
63
  }