@mintlify/common 1.0.1259 → 1.0.1260
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/mdx/plugins/rehype/rehypeDynamicTailwindCss.js +560 -92
- package/dist/mdx/plugins/remark/remarkMdxInjectSnippets.d.ts +1 -0
- package/dist/mdx/plugins/remark/remarkMdxInjectSnippets.js +1 -1
- package/dist/mdx/server-only/getMdx/getReferencedSnippetPaths.d.ts +1 -0
- package/dist/mdx/server-only/getMdx/getReferencedSnippetPaths.js +29 -0
- package/dist/mdx/server-only/getMdx/snippets.d.ts +1 -0
- package/dist/mdx/server-only/getMdx/snippets.js +49 -0
- package/dist/mdx/server-only/getMdx.js +9 -2
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -3,17 +3,76 @@ import { visit } from 'unist-util-visit';
|
|
|
3
3
|
import { segment } from './segment.js';
|
|
4
4
|
export const MINTLIFY_TAILWIND_PREFIX = 'mint-';
|
|
5
5
|
const CLASS_HELPERS = new Set(['cn', 'clsx', 'classNames', 'classnames', 'twMerge', 'twJoin']);
|
|
6
|
+
const NON_MUTATING_METHODS = new Set([
|
|
7
|
+
'at',
|
|
8
|
+
'charAt',
|
|
9
|
+
'concat',
|
|
10
|
+
'endsWith',
|
|
11
|
+
'includes',
|
|
12
|
+
'indexOf',
|
|
13
|
+
'join',
|
|
14
|
+
'lastIndexOf',
|
|
15
|
+
'padEnd',
|
|
16
|
+
'padStart',
|
|
17
|
+
'repeat',
|
|
18
|
+
'slice',
|
|
19
|
+
'split',
|
|
20
|
+
'startsWith',
|
|
21
|
+
'toLowerCase',
|
|
22
|
+
'toString',
|
|
23
|
+
'toUpperCase',
|
|
24
|
+
'trim',
|
|
25
|
+
'trimEnd',
|
|
26
|
+
'trimStart',
|
|
27
|
+
]);
|
|
28
|
+
const IMMUTABLE_GLOBALS = new Set(['undefined', 'NaN', 'Infinity']);
|
|
29
|
+
const MAX_INLINE_DEPTH = 32;
|
|
30
|
+
const MAX_NODES_PER_INLINE = 1000;
|
|
31
|
+
const MAX_INLINED_NODES_PER_PAGE = 20000;
|
|
6
32
|
export const rehypeDynamicTailwindCss = (tailwindSelectors) => (tree) => {
|
|
7
33
|
const normalizedTailwindSelectors = tailwindSelectors === null || tailwindSelectors === void 0 ? void 0 : tailwindSelectors.map(normalizeSelector);
|
|
8
34
|
if (!(normalizedTailwindSelectors === null || normalizedTailwindSelectors === void 0 ? void 0 : normalizedTailwindSelectors.length))
|
|
9
35
|
return;
|
|
10
36
|
const moduleScope = new Map();
|
|
11
37
|
const moduleScopes = [moduleScope];
|
|
38
|
+
const scopeByNode = new Map();
|
|
39
|
+
const aliases = [];
|
|
12
40
|
visit(tree, (node) => {
|
|
13
41
|
if (node.type === 'mdxjsEsm' && node.data && node.data.estree) {
|
|
14
42
|
collectDeclarations(node.data.estree.body, moduleScope, moduleScopes);
|
|
43
|
+
collectVarNames(node.data.estree).forEach((name) => moduleScope.set(name, createBinding(moduleScopes)));
|
|
15
44
|
}
|
|
16
45
|
});
|
|
46
|
+
const estrees = [];
|
|
47
|
+
visit(tree, (node) => {
|
|
48
|
+
var _a;
|
|
49
|
+
if (node.type === 'mdxjsEsm' ||
|
|
50
|
+
node.type === 'mdxFlowExpression' ||
|
|
51
|
+
node.type === 'mdxTextExpression') {
|
|
52
|
+
if ((_a = node.data) === null || _a === void 0 ? void 0 : _a.estree)
|
|
53
|
+
estrees.push(node.data.estree);
|
|
54
|
+
}
|
|
55
|
+
else if (node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') {
|
|
56
|
+
node.attributes.forEach((attr) => {
|
|
57
|
+
var _a, _b;
|
|
58
|
+
const estree = attr.type === 'mdxJsxExpressionAttribute'
|
|
59
|
+
? (_a = attr.data) === null || _a === void 0 ? void 0 : _a.estree
|
|
60
|
+
: attr.value && typeof attr.value !== 'string'
|
|
61
|
+
? (_b = attr.value.data) === null || _b === void 0 ? void 0 : _b.estree
|
|
62
|
+
: undefined;
|
|
63
|
+
if (estree)
|
|
64
|
+
estrees.push(estree);
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
estrees.forEach((estree) => analyzeProgram(estree, moduleScopes, scopeByNode, aliases));
|
|
69
|
+
propagateMutations(aliases);
|
|
70
|
+
const context = {
|
|
71
|
+
tailwindSelectors: normalizedTailwindSelectors,
|
|
72
|
+
changes: { count: 0 },
|
|
73
|
+
pageBudget: { remaining: MAX_INLINED_NODES_PER_PAGE },
|
|
74
|
+
inlineDepth: 0,
|
|
75
|
+
};
|
|
17
76
|
visit(tree, (node) => {
|
|
18
77
|
var _a;
|
|
19
78
|
if ((node.type === 'mdxJsxFlowElement' || node.type === 'mdxJsxTextElement') &&
|
|
@@ -29,45 +88,77 @@ export const rehypeDynamicTailwindCss = (tailwindSelectors) => (tree) => {
|
|
|
29
88
|
// example: <div className={isActive ? "bg-red-500" : "bg-blue-500"}>
|
|
30
89
|
const [statement] = value.data.estree.body;
|
|
31
90
|
if (statement && statement.type === 'ExpressionStatement') {
|
|
32
|
-
statement.expression = transformExpressionClassNames(statement.expression, moduleScopes,
|
|
91
|
+
statement.expression = transformExpressionClassNames(statement.expression, moduleScopes, context);
|
|
33
92
|
}
|
|
34
93
|
}
|
|
35
94
|
}
|
|
36
95
|
if (node.type === 'mdxjsEsm' && node.data && node.data.estree) {
|
|
37
|
-
transformMdxJsEsmNode(node.data.estree, moduleScopes,
|
|
96
|
+
transformMdxJsEsmNode(node.data.estree, moduleScopes, scopeByNode, context);
|
|
38
97
|
}
|
|
39
98
|
});
|
|
40
99
|
};
|
|
100
|
+
const createBinding = (scopes, init) => ({
|
|
101
|
+
init,
|
|
102
|
+
scopes,
|
|
103
|
+
reassigned: false,
|
|
104
|
+
mutated: false,
|
|
105
|
+
aliasOf: [],
|
|
106
|
+
});
|
|
41
107
|
const collectDeclarations = (statements, scope, scopes) => {
|
|
42
108
|
for (const statement of statements) {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
109
|
+
if (statement.type === 'ImportDeclaration') {
|
|
110
|
+
statement.specifiers.forEach((specifier) => scope.set(specifier.local.name, createBinding(scopes)));
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const declaration = statement.type === 'ExportNamedDeclaration' || statement.type === 'ExportDefaultDeclaration'
|
|
114
|
+
? statement.declaration
|
|
115
|
+
: statement;
|
|
116
|
+
if (!declaration)
|
|
117
|
+
continue;
|
|
118
|
+
if ((declaration.type === 'FunctionDeclaration' || declaration.type === 'ClassDeclaration') &&
|
|
119
|
+
declaration.id) {
|
|
120
|
+
scope.set(declaration.id.name, createBinding(scopes));
|
|
46
121
|
}
|
|
47
|
-
if (
|
|
122
|
+
if (declaration.type !== 'VariableDeclaration' || declaration.kind === 'var')
|
|
48
123
|
continue;
|
|
49
124
|
for (const declarator of declaration.declarations) {
|
|
50
125
|
if (declaration.kind === 'const' && declarator.id.type === 'Identifier' && declarator.init) {
|
|
51
|
-
scope.set(declarator.id.name,
|
|
126
|
+
scope.set(declarator.id.name, createBinding(scopes, declarator.init));
|
|
52
127
|
}
|
|
53
128
|
else {
|
|
54
|
-
getPatternNames(declarator.id).forEach((name) => scope.set(name,
|
|
129
|
+
getPatternNames(declarator.id).forEach((name) => scope.set(name, createBinding(scopes)));
|
|
55
130
|
}
|
|
56
131
|
}
|
|
57
132
|
}
|
|
58
133
|
};
|
|
59
|
-
const
|
|
134
|
+
const collectVarNames = (root) => {
|
|
135
|
+
const names = [];
|
|
136
|
+
walk(root, {
|
|
137
|
+
enter(node) {
|
|
138
|
+
if (node !== root && isFunctionNode(node)) {
|
|
139
|
+
this.skip();
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
if (node.type === 'VariableDeclaration' && node.kind === 'var') {
|
|
143
|
+
node.declarations.forEach((declarator) => names.push(...getPatternNames(declarator.id)));
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
});
|
|
147
|
+
return names;
|
|
148
|
+
};
|
|
149
|
+
const getPatternNames = (pattern) => getPatternIdentifiers(pattern).map((identifier) => identifier.name);
|
|
150
|
+
const getPatternIdentifiers = (pattern) => {
|
|
60
151
|
switch (pattern.type) {
|
|
61
152
|
case 'Identifier':
|
|
62
|
-
return [pattern
|
|
153
|
+
return [pattern];
|
|
63
154
|
case 'AssignmentPattern':
|
|
64
|
-
return
|
|
155
|
+
return getPatternIdentifiers(pattern.left);
|
|
65
156
|
case 'RestElement':
|
|
66
|
-
return
|
|
157
|
+
return getPatternIdentifiers(pattern.argument);
|
|
67
158
|
case 'ArrayPattern':
|
|
68
|
-
return pattern.elements.flatMap((element) => (element ?
|
|
159
|
+
return pattern.elements.flatMap((element) => (element ? getPatternIdentifiers(element) : []));
|
|
69
160
|
case 'ObjectPattern':
|
|
70
|
-
return pattern.properties.flatMap((property) =>
|
|
161
|
+
return pattern.properties.flatMap((property) => getPatternIdentifiers(property.type === 'Property' ? property.value : property));
|
|
71
162
|
default:
|
|
72
163
|
return [];
|
|
73
164
|
}
|
|
@@ -84,64 +175,304 @@ const resolveBinding = (name, scopes) => {
|
|
|
84
175
|
const isFunctionNode = (node) => node.type === 'FunctionDeclaration' ||
|
|
85
176
|
node.type === 'FunctionExpression' ||
|
|
86
177
|
node.type === 'ArrowFunctionExpression';
|
|
87
|
-
const
|
|
178
|
+
const isClassAttribute = (node) => node.name.type === 'JSXIdentifier' &&
|
|
179
|
+
(node.name.name === 'className' || node.name.name === 'class');
|
|
180
|
+
const createScope = (node, scopes) => {
|
|
181
|
+
var _a;
|
|
182
|
+
const scope = new Map();
|
|
183
|
+
const chain = [...scopes, scope];
|
|
184
|
+
const declare = (name) => scope.set(name, createBinding(chain));
|
|
185
|
+
if (isFunctionNode(node)) {
|
|
186
|
+
if (node.type === 'FunctionExpression' && node.id)
|
|
187
|
+
declare(node.id.name);
|
|
188
|
+
node.params.flatMap(getPatternNames).forEach(declare);
|
|
189
|
+
collectVarNames(node.body).forEach(declare);
|
|
190
|
+
return scope;
|
|
191
|
+
}
|
|
192
|
+
switch (node.type) {
|
|
193
|
+
case 'BlockStatement':
|
|
194
|
+
case 'StaticBlock':
|
|
195
|
+
collectDeclarations(node.body, scope, chain);
|
|
196
|
+
return scope;
|
|
197
|
+
case 'SwitchStatement':
|
|
198
|
+
collectDeclarations(node.cases.flatMap((switchCase) => switchCase.consequent), scope, chain);
|
|
199
|
+
return scope;
|
|
200
|
+
case 'ForStatement':
|
|
201
|
+
if (((_a = node.init) === null || _a === void 0 ? void 0 : _a.type) === 'VariableDeclaration' && node.init.kind !== 'var') {
|
|
202
|
+
node.init.declarations.forEach((declarator) => getPatternNames(declarator.id).forEach(declare));
|
|
203
|
+
}
|
|
204
|
+
return scope;
|
|
205
|
+
case 'ForInStatement':
|
|
206
|
+
case 'ForOfStatement':
|
|
207
|
+
if (node.left.type === 'VariableDeclaration' && node.left.kind !== 'var') {
|
|
208
|
+
node.left.declarations.forEach((declarator) => getPatternNames(declarator.id).forEach(declare));
|
|
209
|
+
}
|
|
210
|
+
return scope;
|
|
211
|
+
case 'CatchClause':
|
|
212
|
+
if (node.param)
|
|
213
|
+
getPatternNames(node.param).forEach(declare);
|
|
214
|
+
return scope;
|
|
215
|
+
case 'ClassExpression':
|
|
216
|
+
if (node.id)
|
|
217
|
+
declare(node.id.name);
|
|
218
|
+
return scope;
|
|
219
|
+
default:
|
|
220
|
+
return undefined;
|
|
221
|
+
}
|
|
222
|
+
};
|
|
223
|
+
const propagateMutations = (aliases) => {
|
|
224
|
+
var _a;
|
|
225
|
+
const links = new Map();
|
|
226
|
+
const link = (from, to) => {
|
|
227
|
+
const targets = links.get(from);
|
|
228
|
+
if (targets)
|
|
229
|
+
targets.push(to);
|
|
230
|
+
else
|
|
231
|
+
links.set(from, [to]);
|
|
232
|
+
};
|
|
233
|
+
aliases.forEach((alias) => alias.aliasOf.forEach((source) => {
|
|
234
|
+
link(alias, source);
|
|
235
|
+
link(source, alias);
|
|
236
|
+
}));
|
|
237
|
+
const pending = [...links.keys()].filter((binding) => binding.mutated);
|
|
238
|
+
for (let current = pending.pop(); current; current = pending.pop()) {
|
|
239
|
+
for (const next of (_a = links.get(current)) !== null && _a !== void 0 ? _a : []) {
|
|
240
|
+
if (next.mutated)
|
|
241
|
+
continue;
|
|
242
|
+
next.mutated = true;
|
|
243
|
+
pending.push(next);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
const analyzeProgram = (program, baseScopes, scopeByNode, aliases) => {
|
|
248
|
+
const scopes = [...baseScopes];
|
|
249
|
+
const ancestors = [];
|
|
250
|
+
const declaredIdentifiers = new Set();
|
|
251
|
+
const writtenIdentifiers = new Set();
|
|
252
|
+
const declare = (pattern) => pattern && getPatternIdentifiers(pattern).forEach((id) => declaredIdentifiers.add(id));
|
|
253
|
+
const write = (pattern) => getPatternIdentifiers(pattern).forEach((id) => writtenIdentifiers.add(id));
|
|
254
|
+
walk(program, {
|
|
255
|
+
enter(node, parent, key) {
|
|
256
|
+
const scope = createScope(node, scopes);
|
|
257
|
+
if (scope) {
|
|
258
|
+
scopes.push(scope);
|
|
259
|
+
scopeByNode.set(node, scope);
|
|
260
|
+
}
|
|
261
|
+
if (isFunctionNode(node)) {
|
|
262
|
+
if (node.type !== 'ArrowFunctionExpression')
|
|
263
|
+
declare(node.id);
|
|
264
|
+
node.params.forEach(declare);
|
|
265
|
+
}
|
|
266
|
+
else if (node.type === 'VariableDeclarator') {
|
|
267
|
+
declare(node.id);
|
|
268
|
+
if ((parent === null || parent === void 0 ? void 0 : parent.type) === 'VariableDeclaration' && parent.kind === 'var') {
|
|
269
|
+
getPatternNames(node.id).forEach((name) => {
|
|
270
|
+
const binding = resolveBinding(name, scopes);
|
|
271
|
+
if (binding)
|
|
272
|
+
binding.reassigned = true;
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
else if (node.type === 'CatchClause') {
|
|
277
|
+
declare(node.param);
|
|
278
|
+
}
|
|
279
|
+
else if ((node.type === 'ClassDeclaration' || node.type === 'ClassExpression') && node.id) {
|
|
280
|
+
declare(node.id);
|
|
281
|
+
}
|
|
282
|
+
else if (node.type === 'ImportDeclaration') {
|
|
283
|
+
node.specifiers.forEach((specifier) => declare(specifier.local));
|
|
284
|
+
}
|
|
285
|
+
else if (node.type === 'AssignmentExpression') {
|
|
286
|
+
write(node.left);
|
|
287
|
+
}
|
|
288
|
+
else if (node.type === 'UpdateExpression' && node.argument.type === 'Identifier') {
|
|
289
|
+
writtenIdentifiers.add(node.argument);
|
|
290
|
+
}
|
|
291
|
+
else if ((node.type === 'ForInStatement' || node.type === 'ForOfStatement') &&
|
|
292
|
+
node.left.type !== 'VariableDeclaration') {
|
|
293
|
+
write(node.left);
|
|
294
|
+
}
|
|
295
|
+
if (node.type === 'Identifier' && !declaredIdentifiers.has(node)) {
|
|
296
|
+
const binding = resolveBinding(node.name, scopes);
|
|
297
|
+
if (writtenIdentifiers.has(node)) {
|
|
298
|
+
if (binding)
|
|
299
|
+
binding.reassigned = true;
|
|
300
|
+
}
|
|
301
|
+
else if (parent && isReferencePosition(parent, key)) {
|
|
302
|
+
const usage = classifyReference(node, ancestors, scopes);
|
|
303
|
+
if (usage === 'mutates') {
|
|
304
|
+
if (binding)
|
|
305
|
+
binding.mutated = true;
|
|
306
|
+
}
|
|
307
|
+
else if (usage !== 'reads' && binding) {
|
|
308
|
+
usage.aliasOf.push(binding);
|
|
309
|
+
aliases.push(usage);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
ancestors.push(node);
|
|
314
|
+
},
|
|
315
|
+
leave(node) {
|
|
316
|
+
ancestors.pop();
|
|
317
|
+
if (scopeByNode.has(node) && scopes[scopes.length - 1] === scopeByNode.get(node)) {
|
|
318
|
+
scopes.pop();
|
|
319
|
+
}
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
const isReferencePosition = (parent, key) => {
|
|
324
|
+
switch (parent.type) {
|
|
325
|
+
case 'MemberExpression':
|
|
326
|
+
return key !== 'property' || parent.computed;
|
|
327
|
+
case 'Property':
|
|
328
|
+
case 'MethodDefinition':
|
|
329
|
+
case 'PropertyDefinition':
|
|
330
|
+
return key !== 'key' || parent.computed;
|
|
331
|
+
case 'LabeledStatement':
|
|
332
|
+
case 'BreakStatement':
|
|
333
|
+
case 'ContinueStatement':
|
|
334
|
+
case 'MetaProperty':
|
|
335
|
+
return false;
|
|
336
|
+
case 'ExportSpecifier':
|
|
337
|
+
return key === 'local';
|
|
338
|
+
case 'ImportSpecifier':
|
|
339
|
+
return false;
|
|
340
|
+
default:
|
|
341
|
+
return true;
|
|
342
|
+
}
|
|
343
|
+
};
|
|
344
|
+
const classifyReference = (node, ancestors, scopes) => {
|
|
345
|
+
var _a;
|
|
346
|
+
let child = node;
|
|
347
|
+
for (let i = ancestors.length - 1; i >= 0; i--) {
|
|
348
|
+
const parent = ancestors[i];
|
|
349
|
+
if (!parent)
|
|
350
|
+
break;
|
|
351
|
+
switch (parent.type) {
|
|
352
|
+
case 'MemberExpression':
|
|
353
|
+
if (parent.object !== child)
|
|
354
|
+
return 'reads';
|
|
355
|
+
child = parent;
|
|
356
|
+
continue;
|
|
357
|
+
case 'ChainExpression':
|
|
358
|
+
case 'AwaitExpression':
|
|
359
|
+
case 'LogicalExpression':
|
|
360
|
+
child = parent;
|
|
361
|
+
continue;
|
|
362
|
+
case 'ConditionalExpression':
|
|
363
|
+
if (parent.test === child)
|
|
364
|
+
return 'reads';
|
|
365
|
+
child = parent;
|
|
366
|
+
continue;
|
|
367
|
+
case 'SequenceExpression':
|
|
368
|
+
if (parent.expressions[parent.expressions.length - 1] !== child)
|
|
369
|
+
return 'reads';
|
|
370
|
+
child = parent;
|
|
371
|
+
continue;
|
|
372
|
+
case 'CallExpression':
|
|
373
|
+
case 'NewExpression':
|
|
374
|
+
if (parent.callee === child) {
|
|
375
|
+
if (child.type !== 'MemberExpression')
|
|
376
|
+
return 'reads';
|
|
377
|
+
return !child.computed &&
|
|
378
|
+
child.property.type === 'Identifier' &&
|
|
379
|
+
NON_MUTATING_METHODS.has(child.property.name)
|
|
380
|
+
? 'reads'
|
|
381
|
+
: 'mutates';
|
|
382
|
+
}
|
|
383
|
+
return parent.type === 'CallExpression' &&
|
|
384
|
+
parent.callee.type === 'Identifier' &&
|
|
385
|
+
CLASS_HELPERS.has(parent.callee.name)
|
|
386
|
+
? 'reads'
|
|
387
|
+
: 'mutates';
|
|
388
|
+
case 'SpreadElement':
|
|
389
|
+
case 'ArrayExpression':
|
|
390
|
+
case 'ObjectExpression':
|
|
391
|
+
child = parent;
|
|
392
|
+
continue;
|
|
393
|
+
case 'Property':
|
|
394
|
+
if (parent.value !== child)
|
|
395
|
+
return 'reads';
|
|
396
|
+
child = parent;
|
|
397
|
+
continue;
|
|
398
|
+
case 'TemplateLiteral':
|
|
399
|
+
case 'BinaryExpression':
|
|
400
|
+
case 'TaggedTemplateExpression':
|
|
401
|
+
case 'IfStatement':
|
|
402
|
+
case 'WhileStatement':
|
|
403
|
+
case 'DoWhileStatement':
|
|
404
|
+
case 'SwitchStatement':
|
|
405
|
+
case 'SwitchCase':
|
|
406
|
+
return 'reads';
|
|
407
|
+
case 'UnaryExpression':
|
|
408
|
+
return parent.operator === 'delete' ? 'mutates' : 'reads';
|
|
409
|
+
case 'ExpressionStatement':
|
|
410
|
+
case 'JSXExpressionContainer':
|
|
411
|
+
case 'JSXSpreadAttribute':
|
|
412
|
+
return 'reads';
|
|
413
|
+
case 'VariableDeclarator': {
|
|
414
|
+
const declaration = ancestors[i - 1];
|
|
415
|
+
if (parent.init === child &&
|
|
416
|
+
parent.id.type === 'Identifier' &&
|
|
417
|
+
(declaration === null || declaration === void 0 ? void 0 : declaration.type) === 'VariableDeclaration' &&
|
|
418
|
+
declaration.kind === 'const') {
|
|
419
|
+
return (_a = resolveBinding(parent.id.name, scopes)) !== null && _a !== void 0 ? _a : 'mutates';
|
|
420
|
+
}
|
|
421
|
+
return 'mutates';
|
|
422
|
+
}
|
|
423
|
+
default:
|
|
424
|
+
return 'mutates';
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
return 'reads';
|
|
428
|
+
};
|
|
429
|
+
const transformMdxJsEsmNode = (estreeNode, moduleScopes, scopeByNode, context) => {
|
|
88
430
|
const scopes = [...moduleScopes];
|
|
89
431
|
walk(estreeNode, {
|
|
90
432
|
enter(node) {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
const chain = [...scopes, scope];
|
|
94
|
-
node.params.flatMap(getPatternNames).forEach((name) => scope.set(name, { scopes: chain }));
|
|
95
|
-
scopes.push(scope);
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
if (node.type === 'BlockStatement') {
|
|
99
|
-
const scope = new Map();
|
|
100
|
-
collectDeclarations(node.body, scope, [...scopes, scope]);
|
|
433
|
+
const scope = scopeByNode.get(node);
|
|
434
|
+
if (scope)
|
|
101
435
|
scopes.push(scope);
|
|
102
|
-
|
|
103
|
-
}
|
|
104
|
-
if (node.type === 'JSXAttribute' &&
|
|
105
|
-
node.name.type === 'JSXIdentifier' &&
|
|
106
|
-
(node.name.name === 'className' || node.name.name === 'class')) {
|
|
436
|
+
if (node.type === 'JSXAttribute' && isClassAttribute(node)) {
|
|
107
437
|
// example: className="bg-green-500"
|
|
108
438
|
if (node.value && node.value.type === 'Literal') {
|
|
109
|
-
transformLiteral(node.value,
|
|
439
|
+
transformLiteral(node.value, context);
|
|
110
440
|
}
|
|
111
441
|
if (node.value &&
|
|
112
442
|
node.value.type === 'JSXExpressionContainer' &&
|
|
113
443
|
node.value.expression.type !== 'JSXEmptyExpression') {
|
|
114
|
-
node.value.expression = transformExpressionClassNames(node.value.expression, scopes,
|
|
444
|
+
node.value.expression = transformExpressionClassNames(node.value.expression, scopes, context);
|
|
115
445
|
}
|
|
116
446
|
}
|
|
117
447
|
},
|
|
118
448
|
leave(node) {
|
|
119
|
-
if (
|
|
449
|
+
if (scopeByNode.has(node))
|
|
120
450
|
scopes.pop();
|
|
121
|
-
}
|
|
122
451
|
},
|
|
123
452
|
});
|
|
124
453
|
};
|
|
125
|
-
const transformExpressionClassNames = (expr, scopes,
|
|
126
|
-
const transform = (child) => transformExpressionClassNames(child, scopes,
|
|
454
|
+
const transformExpressionClassNames = (expr, scopes, context, inlining = new Set(), structural = false) => {
|
|
455
|
+
const transform = (child) => transformExpressionClassNames(child, scopes, context, inlining);
|
|
456
|
+
const transformStructural = (child) => transformExpressionClassNames(child, scopes, context, inlining, true);
|
|
127
457
|
const transformElement = (element) => {
|
|
128
458
|
if (element.type !== 'SpreadElement')
|
|
129
459
|
return transform(element);
|
|
130
|
-
element.argument =
|
|
460
|
+
element.argument = transformStructural(element.argument);
|
|
131
461
|
return element;
|
|
132
462
|
};
|
|
133
463
|
switch (expr.type) {
|
|
134
464
|
case 'Literal':
|
|
135
|
-
transformLiteral(expr,
|
|
465
|
+
transformLiteral(expr, context);
|
|
136
466
|
return expr;
|
|
137
467
|
case 'TemplateLiteral':
|
|
138
468
|
// example: className={`bg-green-500`}
|
|
139
469
|
expr.quasis.forEach((quasi) => {
|
|
140
470
|
if (quasi.value.cooked) {
|
|
141
|
-
const transformedValue = transformClassNames(quasi.value.cooked, tailwindSelectors);
|
|
471
|
+
const transformedValue = transformClassNames(quasi.value.cooked, context.tailwindSelectors);
|
|
142
472
|
if (quasi.value.cooked !== transformedValue) {
|
|
143
473
|
quasi.value.cooked = transformedValue;
|
|
144
474
|
quasi.value.raw = transformedValue;
|
|
475
|
+
context.changes.count++;
|
|
145
476
|
}
|
|
146
477
|
}
|
|
147
478
|
});
|
|
@@ -150,13 +481,13 @@ const transformExpressionClassNames = (expr, scopes, tailwindSelectors, inlining
|
|
|
150
481
|
return expr;
|
|
151
482
|
case 'ConditionalExpression':
|
|
152
483
|
// example: ${isActive ? "bg-red-500" : "bg-blue-500"}
|
|
153
|
-
expr.consequent = transform(expr.consequent);
|
|
154
|
-
expr.alternate = transform(expr.alternate);
|
|
484
|
+
expr.consequent = (structural ? transformStructural : transform)(expr.consequent);
|
|
485
|
+
expr.alternate = (structural ? transformStructural : transform)(expr.alternate);
|
|
155
486
|
return expr;
|
|
156
487
|
case 'LogicalExpression':
|
|
157
488
|
// example: ${isActive && "bg-red-500"}
|
|
158
|
-
expr.left = transform(expr.left);
|
|
159
|
-
expr.right = transform(expr.right);
|
|
489
|
+
expr.left = (structural ? transformStructural : transform)(expr.left);
|
|
490
|
+
expr.right = (structural ? transformStructural : transform)(expr.right);
|
|
160
491
|
return expr;
|
|
161
492
|
case 'BinaryExpression':
|
|
162
493
|
if (expr.operator === '+') {
|
|
@@ -174,60 +505,74 @@ const transformExpressionClassNames = (expr, scopes, tailwindSelectors, inlining
|
|
|
174
505
|
return expr;
|
|
175
506
|
// example: ["bg-red-500", "bg-blue-500"].join(" ")
|
|
176
507
|
if (expr.callee.type === 'MemberExpression' && expr.callee.object.type !== 'Super') {
|
|
177
|
-
expr.callee.object =
|
|
508
|
+
expr.callee.object = transformStructural(expr.callee.object);
|
|
509
|
+
expr.arguments = expr.arguments.map(transformElement);
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
expr.arguments = expr.arguments.map((argument) => argument.type === 'SpreadElement'
|
|
513
|
+
? transformElement(argument)
|
|
514
|
+
: transformStructural(argument));
|
|
178
515
|
}
|
|
179
|
-
expr.arguments = expr.arguments.map(transformElement);
|
|
180
516
|
return expr;
|
|
181
517
|
case 'ObjectExpression':
|
|
182
518
|
// example: cn({ "bg-blue-500": isActive })
|
|
183
|
-
transformObjectKeys(expr, transform,
|
|
519
|
+
transformObjectKeys(expr, transform, transformStructural, context);
|
|
184
520
|
return expr;
|
|
185
521
|
case 'MemberExpression':
|
|
186
522
|
// example: const styles = { active: "bg-red-500" }; className={styles.active}
|
|
187
|
-
return transformMemberExpression(expr, scopes, transform);
|
|
523
|
+
return transformMemberExpression(expr, scopes, transform, context);
|
|
188
524
|
case 'Identifier': {
|
|
189
525
|
// example: const classes = "bg-red-500"; className={classes}
|
|
190
526
|
const binding = resolveBinding(expr.name, scopes);
|
|
191
|
-
if (!
|
|
527
|
+
if (!binding || inlining.has(binding))
|
|
192
528
|
return expr;
|
|
193
|
-
const inlined = cloneForUse(
|
|
194
|
-
if (!inlined)
|
|
529
|
+
const inlined = cloneForUse(expr, scopes, scopes, createCloneState(context), structural);
|
|
530
|
+
if (!inlined || inlined.type === 'Identifier')
|
|
195
531
|
return expr;
|
|
196
|
-
const
|
|
197
|
-
|
|
198
|
-
return serialize(transformed) === before ? expr : transformed;
|
|
532
|
+
const nextInlining = new Set([...inlining, binding]);
|
|
533
|
+
return applyIfChanged(expr, inlined, (child) => transformExpressionClassNames(child, scopes, context, nextInlining), context);
|
|
199
534
|
}
|
|
200
535
|
default:
|
|
201
536
|
return expr;
|
|
202
537
|
}
|
|
203
538
|
};
|
|
204
|
-
const
|
|
539
|
+
const createCloneState = (context) => ({
|
|
540
|
+
inlining: new Set(),
|
|
541
|
+
local: { remaining: MAX_NODES_PER_INLINE },
|
|
542
|
+
page: context.pageBudget,
|
|
543
|
+
});
|
|
544
|
+
const applyIfChanged = (original, replacement, transform, context) => {
|
|
545
|
+
if (context.inlineDepth >= MAX_INLINE_DEPTH)
|
|
546
|
+
return original;
|
|
547
|
+
context.inlineDepth++;
|
|
548
|
+
const before = context.changes.count;
|
|
549
|
+
const transformed = transform(replacement);
|
|
550
|
+
context.inlineDepth--;
|
|
551
|
+
return context.changes.count === before ? original : transformed;
|
|
552
|
+
};
|
|
553
|
+
const transformMemberExpression = (expr, scopes, transform, context) => {
|
|
205
554
|
if (getStaticKey(expr) !== undefined) {
|
|
206
555
|
const resolved = resolveStaticValue(expr, scopes);
|
|
207
|
-
const inlined = resolved && cloneForUse(resolved.expr, resolved.scopes, scopes,
|
|
208
|
-
|
|
209
|
-
return expr;
|
|
210
|
-
const before = serialize(inlined);
|
|
211
|
-
const transformed = transform(inlined);
|
|
212
|
-
return serialize(transformed) === before ? expr : transformed;
|
|
556
|
+
const inlined = resolved && cloneForUse(resolved.expr, resolved.scopes, scopes, createCloneState(context));
|
|
557
|
+
return inlined ? applyIfChanged(expr, inlined, transform, context) : expr;
|
|
213
558
|
}
|
|
214
|
-
const object = resolveObject(expr.object, scopes);
|
|
559
|
+
const object = resolveObject(expr.object, scopes, context);
|
|
215
560
|
if (!object)
|
|
216
561
|
return expr;
|
|
217
|
-
const before =
|
|
562
|
+
const before = context.changes.count;
|
|
218
563
|
object.properties.forEach((property) => {
|
|
219
564
|
const value = property.type === 'Property' ? asExpression(property.value) : undefined;
|
|
220
565
|
if (property.type === 'Property' && value)
|
|
221
566
|
property.value = transform(value);
|
|
222
567
|
});
|
|
223
|
-
if (
|
|
568
|
+
if (context.changes.count !== before)
|
|
224
569
|
expr.object = object;
|
|
225
570
|
return expr;
|
|
226
571
|
};
|
|
227
|
-
const transformObjectKeys = (expr, transform,
|
|
572
|
+
const transformObjectKeys = (expr, transform, transformStructural, context) => {
|
|
228
573
|
expr.properties.forEach((property) => {
|
|
229
574
|
if (property.type === 'SpreadElement') {
|
|
230
|
-
property.argument =
|
|
575
|
+
property.argument = transformStructural(property.argument);
|
|
231
576
|
return;
|
|
232
577
|
}
|
|
233
578
|
if (property.computed) {
|
|
@@ -238,51 +583,149 @@ const transformObjectKeys = (expr, transform, tailwindSelectors) => {
|
|
|
238
583
|
const keyName = getPropertyKeyName(property);
|
|
239
584
|
if (keyName === undefined)
|
|
240
585
|
return;
|
|
241
|
-
const transformedValue = transformClassNames(keyName, tailwindSelectors);
|
|
586
|
+
const transformedValue = transformClassNames(keyName, context.tailwindSelectors);
|
|
242
587
|
if (keyName !== transformedValue) {
|
|
243
588
|
property.key = toLiteral(transformedValue);
|
|
244
589
|
property.shorthand = false;
|
|
590
|
+
context.changes.count++;
|
|
245
591
|
}
|
|
246
592
|
});
|
|
247
593
|
};
|
|
248
|
-
const resolveObject = (node, scopes) => {
|
|
594
|
+
const resolveObject = (node, scopes, context) => {
|
|
249
595
|
if (node.type === 'ObjectExpression')
|
|
250
596
|
return node;
|
|
251
597
|
const resolved = resolveStaticValue(node, scopes);
|
|
252
598
|
if ((resolved === null || resolved === void 0 ? void 0 : resolved.expr.type) !== 'ObjectExpression')
|
|
253
599
|
return undefined;
|
|
254
|
-
const cloned = cloneForUse(resolved.expr, resolved.scopes, scopes,
|
|
600
|
+
const cloned = cloneForUse(resolved.expr, resolved.scopes, scopes, createCloneState(context));
|
|
255
601
|
return (cloned === null || cloned === void 0 ? void 0 : cloned.type) === 'ObjectExpression' ? cloned : undefined;
|
|
256
602
|
};
|
|
257
|
-
const resolveStaticValue = (node, scopes, resolving = new Set()) => {
|
|
258
|
-
if (node.type === 'Super')
|
|
603
|
+
const resolveStaticValue = (node, scopes, resolving = new Set(), depth = 0) => {
|
|
604
|
+
if (node.type === 'Super' || depth >= MAX_INLINE_DEPTH)
|
|
259
605
|
return undefined;
|
|
260
606
|
if (node.type === 'Identifier') {
|
|
261
607
|
const binding = resolveBinding(node.name, scopes);
|
|
262
608
|
if (!(binding === null || binding === void 0 ? void 0 : binding.init))
|
|
263
609
|
return { expr: node, scopes };
|
|
264
|
-
if (resolving.has(binding))
|
|
610
|
+
if (resolving.has(binding) || binding.mutated)
|
|
265
611
|
return undefined;
|
|
266
|
-
return resolveStaticValue(binding.init, binding.scopes, new Set([...resolving, binding]));
|
|
612
|
+
return resolveStaticValue(binding.init, binding.scopes, new Set([...resolving, binding]), depth + 1);
|
|
267
613
|
}
|
|
268
614
|
if (node.type === 'MemberExpression') {
|
|
269
615
|
const key = getStaticKey(node);
|
|
270
616
|
if (key === undefined)
|
|
271
617
|
return { expr: node, scopes };
|
|
272
|
-
const object = resolveStaticValue(node.object, scopes, resolving);
|
|
618
|
+
const object = resolveStaticValue(node.object, scopes, resolving, depth + 1);
|
|
273
619
|
if ((object === null || object === void 0 ? void 0 : object.expr.type) !== 'ObjectExpression')
|
|
274
620
|
return undefined;
|
|
275
621
|
const value = findPropertyValue(object.expr, key);
|
|
276
|
-
return value && resolveStaticValue(value, object.scopes, resolving);
|
|
622
|
+
return value && resolveStaticValue(value, object.scopes, resolving, depth + 1);
|
|
277
623
|
}
|
|
278
624
|
return { expr: node, scopes };
|
|
279
625
|
};
|
|
280
|
-
const
|
|
281
|
-
|
|
626
|
+
const createsObjectCache = new WeakMap();
|
|
627
|
+
const isStringCache = new WeakMap();
|
|
628
|
+
const createsObject = (expr, scopes, visiting = new Set(), depth = 0) => {
|
|
629
|
+
const cached = createsObjectCache.get(expr);
|
|
630
|
+
if (cached !== undefined)
|
|
631
|
+
return cached;
|
|
632
|
+
if (depth >= MAX_INLINE_DEPTH)
|
|
633
|
+
return true;
|
|
634
|
+
const result = computeCreatesObject(expr, scopes, visiting, depth);
|
|
635
|
+
createsObjectCache.set(expr, result);
|
|
636
|
+
return result;
|
|
637
|
+
};
|
|
638
|
+
const computeCreatesObject = (expr, scopes, visiting, depth) => {
|
|
639
|
+
const check = (child) => createsObject(child, scopes, visiting, depth);
|
|
640
|
+
switch (expr.type) {
|
|
641
|
+
case 'Literal':
|
|
642
|
+
return 'regex' in expr;
|
|
643
|
+
case 'TemplateLiteral':
|
|
644
|
+
case 'BinaryExpression':
|
|
645
|
+
case 'UnaryExpression':
|
|
646
|
+
return false;
|
|
647
|
+
case 'ConditionalExpression':
|
|
648
|
+
return check(expr.consequent) || check(expr.alternate);
|
|
649
|
+
case 'LogicalExpression':
|
|
650
|
+
return check(expr.left) || check(expr.right);
|
|
651
|
+
case 'CallExpression':
|
|
652
|
+
if (!isClassCall(expr) || expr.callee.type === 'Super')
|
|
653
|
+
return true;
|
|
654
|
+
if (expr.callee.type === 'Identifier')
|
|
655
|
+
return false;
|
|
656
|
+
if (expr.callee.type !== 'MemberExpression' || expr.callee.object.type === 'Super')
|
|
657
|
+
return true;
|
|
658
|
+
return (expr.callee.property.type === 'Identifier' &&
|
|
659
|
+
expr.callee.property.name === 'concat' &&
|
|
660
|
+
!isString(expr.callee.object, scopes, visiting, depth));
|
|
661
|
+
case 'Identifier': {
|
|
662
|
+
const binding = resolveBinding(expr.name, scopes);
|
|
663
|
+
if (!(binding === null || binding === void 0 ? void 0 : binding.init) || visiting.has(binding))
|
|
664
|
+
return false;
|
|
665
|
+
return createsObject(binding.init, binding.scopes, new Set([...visiting, binding]), depth + 1);
|
|
666
|
+
}
|
|
667
|
+
case 'MemberExpression': {
|
|
668
|
+
const resolved = resolveStaticValue(expr, scopes);
|
|
669
|
+
if (resolved && resolved.expr !== expr) {
|
|
670
|
+
return createsObject(resolved.expr, resolved.scopes, visiting, depth + 1);
|
|
671
|
+
}
|
|
672
|
+
return (expr.object.type !== 'Super' && createsObject(expr.object, scopes, visiting, depth + 1));
|
|
673
|
+
}
|
|
674
|
+
default:
|
|
675
|
+
return true;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
const isString = (expr, scopes, visiting, depth) => {
|
|
679
|
+
const cached = isStringCache.get(expr);
|
|
680
|
+
if (cached !== undefined)
|
|
681
|
+
return cached;
|
|
682
|
+
if (depth >= MAX_INLINE_DEPTH)
|
|
683
|
+
return false;
|
|
684
|
+
const result = computeIsString(expr, scopes, visiting, depth);
|
|
685
|
+
isStringCache.set(expr, result);
|
|
686
|
+
return result;
|
|
687
|
+
};
|
|
688
|
+
const computeIsString = (expr, scopes, visiting, depth) => {
|
|
689
|
+
switch (expr.type) {
|
|
690
|
+
case 'Literal':
|
|
691
|
+
return typeof expr.value === 'string';
|
|
692
|
+
case 'TemplateLiteral':
|
|
693
|
+
return true;
|
|
694
|
+
case 'BinaryExpression':
|
|
695
|
+
return (expr.operator === '+' &&
|
|
696
|
+
(isString(expr.left, scopes, visiting, depth) ||
|
|
697
|
+
isString(expr.right, scopes, visiting, depth)));
|
|
698
|
+
case 'CallExpression':
|
|
699
|
+
return isClassCall(expr) && !createsObject(expr, scopes, visiting, depth);
|
|
700
|
+
case 'Identifier': {
|
|
701
|
+
const binding = resolveBinding(expr.name, scopes);
|
|
702
|
+
if (!(binding === null || binding === void 0 ? void 0 : binding.init) || visiting.has(binding))
|
|
703
|
+
return false;
|
|
704
|
+
return isString(binding.init, binding.scopes, new Set([...visiting, binding]), depth + 1);
|
|
705
|
+
}
|
|
706
|
+
default:
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
};
|
|
710
|
+
const getRootIdentifier = (expr) => {
|
|
711
|
+
if (expr.type === 'Identifier')
|
|
712
|
+
return expr;
|
|
713
|
+
if (expr.type === 'MemberExpression')
|
|
714
|
+
return getRootIdentifier(expr.object);
|
|
715
|
+
return undefined;
|
|
716
|
+
};
|
|
717
|
+
const cloneForUse = (expr, declarationScopes, useScopes, state, structural = false) => {
|
|
718
|
+
var _a;
|
|
719
|
+
state.local.remaining--;
|
|
720
|
+
state.page.remaining--;
|
|
721
|
+
if (state.local.remaining < 0 || state.page.remaining < 0)
|
|
722
|
+
return undefined;
|
|
723
|
+
const clone = (child) => cloneForUse(child, declarationScopes, useScopes, state);
|
|
724
|
+
const cloneStructural = (child) => cloneForUse(child, declarationScopes, useScopes, state, true);
|
|
282
725
|
const cloneElement = (element) => {
|
|
283
726
|
if (element.type !== 'SpreadElement')
|
|
284
727
|
return clone(element);
|
|
285
|
-
const argument =
|
|
728
|
+
const argument = cloneStructural(element.argument);
|
|
286
729
|
return argument && Object.assign(Object.assign({}, element), { argument });
|
|
287
730
|
};
|
|
288
731
|
const cloneAll = (items, cloneItem) => {
|
|
@@ -312,24 +755,26 @@ const cloneForUse = (expr, declarationScopes, useScopes, inlining) => {
|
|
|
312
755
|
return left && right && Object.assign(Object.assign({}, expr), { left, right });
|
|
313
756
|
}
|
|
314
757
|
case 'LogicalExpression': {
|
|
315
|
-
const left = clone(expr.left);
|
|
316
|
-
const right = clone(expr.right);
|
|
758
|
+
const left = (structural ? cloneStructural : clone)(expr.left);
|
|
759
|
+
const right = (structural ? cloneStructural : clone)(expr.right);
|
|
317
760
|
return left && right && Object.assign(Object.assign({}, expr), { left, right });
|
|
318
761
|
}
|
|
319
762
|
case 'ConditionalExpression': {
|
|
320
763
|
const test = clone(expr.test);
|
|
321
|
-
const consequent = clone(expr.consequent);
|
|
322
|
-
const alternate = clone(expr.alternate);
|
|
764
|
+
const consequent = (structural ? cloneStructural : clone)(expr.consequent);
|
|
765
|
+
const alternate = (structural ? cloneStructural : clone)(expr.alternate);
|
|
323
766
|
return test && consequent && alternate && Object.assign(Object.assign({}, expr), { test, consequent, alternate });
|
|
324
767
|
}
|
|
325
768
|
case 'UnaryExpression': {
|
|
769
|
+
if (expr.operator === 'delete')
|
|
770
|
+
return undefined;
|
|
326
771
|
const argument = clone(expr.argument);
|
|
327
772
|
return argument && Object.assign(Object.assign({}, expr), { argument });
|
|
328
773
|
}
|
|
329
774
|
case 'ObjectExpression': {
|
|
330
775
|
const properties = cloneAll(expr.properties, (property) => {
|
|
331
776
|
if (property.type === 'SpreadElement') {
|
|
332
|
-
const argument =
|
|
777
|
+
const argument = cloneStructural(property.argument);
|
|
333
778
|
return argument && Object.assign(Object.assign({}, property), { argument });
|
|
334
779
|
}
|
|
335
780
|
if (property.kind !== 'init' || property.method)
|
|
@@ -352,7 +797,10 @@ const cloneForUse = (expr, declarationScopes, useScopes, inlining) => {
|
|
|
352
797
|
if (expr.object.type === 'Super' || expr.property.type === 'PrivateIdentifier') {
|
|
353
798
|
return undefined;
|
|
354
799
|
}
|
|
355
|
-
const
|
|
800
|
+
const root = getRootIdentifier(expr.object);
|
|
801
|
+
if (root && ((_a = resolveBinding(root.name, declarationScopes)) === null || _a === void 0 ? void 0 : _a.mutated))
|
|
802
|
+
return undefined;
|
|
803
|
+
const object = cloneStructural(expr.object);
|
|
356
804
|
const property = expr.computed ? clone(expr.property) : structuredClone(expr.property);
|
|
357
805
|
return object && property && Object.assign(Object.assign({}, expr), { object, property });
|
|
358
806
|
}
|
|
@@ -360,17 +808,28 @@ const cloneForUse = (expr, declarationScopes, useScopes, inlining) => {
|
|
|
360
808
|
if (!isClassCall(expr) || expr.callee.type === 'Super')
|
|
361
809
|
return undefined;
|
|
362
810
|
const callee = clone(expr.callee);
|
|
363
|
-
const args = cloneAll(expr.arguments,
|
|
811
|
+
const args = cloneAll(expr.arguments, (argument) => expr.callee.type === 'Identifier' && argument.type !== 'SpreadElement'
|
|
812
|
+
? cloneStructural(argument)
|
|
813
|
+
: cloneElement(argument));
|
|
364
814
|
return callee && args && Object.assign(Object.assign({}, expr), { callee, arguments: args });
|
|
365
815
|
}
|
|
366
816
|
case 'Identifier': {
|
|
367
817
|
const binding = resolveBinding(expr.name, declarationScopes);
|
|
368
|
-
if ((binding === null || binding === void 0 ? void 0 : binding.init) &&
|
|
369
|
-
|
|
818
|
+
if ((binding === null || binding === void 0 ? void 0 : binding.init) &&
|
|
819
|
+
!state.inlining.has(binding) &&
|
|
820
|
+
state.inlining.size < MAX_INLINE_DEPTH &&
|
|
821
|
+
(!createsObject(binding.init, binding.scopes) || (structural && !binding.mutated))) {
|
|
822
|
+
state.inlining.add(binding);
|
|
823
|
+
const inlined = cloneForUse(binding.init, binding.scopes, useScopes, state, structural);
|
|
824
|
+
state.inlining.delete(binding);
|
|
370
825
|
if (inlined)
|
|
371
826
|
return inlined;
|
|
372
827
|
}
|
|
373
|
-
|
|
828
|
+
const useBinding = resolveBinding(expr.name, useScopes);
|
|
829
|
+
const isStable = binding
|
|
830
|
+
? !binding.reassigned && !binding.mutated && binding === useBinding
|
|
831
|
+
: !useBinding && IMMUTABLE_GLOBALS.has(expr.name);
|
|
832
|
+
return isStable ? structuredClone(expr) : undefined;
|
|
374
833
|
}
|
|
375
834
|
default:
|
|
376
835
|
return undefined;
|
|
@@ -406,8 +865,17 @@ const findPropertyValue = (object, key) => {
|
|
|
406
865
|
const property = object.properties[i];
|
|
407
866
|
if (!property || property.type === 'SpreadElement')
|
|
408
867
|
return undefined;
|
|
409
|
-
|
|
410
|
-
|
|
868
|
+
const name = getPropertyKeyName(property);
|
|
869
|
+
if (name === undefined) {
|
|
870
|
+
if (property.computed)
|
|
871
|
+
return undefined;
|
|
872
|
+
continue;
|
|
873
|
+
}
|
|
874
|
+
if (name !== key)
|
|
875
|
+
continue;
|
|
876
|
+
if (property.kind !== 'init' || property.method)
|
|
877
|
+
return undefined;
|
|
878
|
+
return asExpression(property.value);
|
|
411
879
|
}
|
|
412
880
|
return undefined;
|
|
413
881
|
};
|
|
@@ -417,15 +885,16 @@ const asExpression = (node) => node.type === 'ObjectPattern' ||
|
|
|
417
885
|
node.type === 'AssignmentPattern'
|
|
418
886
|
? undefined
|
|
419
887
|
: node;
|
|
420
|
-
const transformLiteral = (expr,
|
|
888
|
+
const transformLiteral = (expr, context) => {
|
|
421
889
|
if (typeof expr.value !== 'string')
|
|
422
890
|
return;
|
|
423
|
-
const transformedValue = transformClassNames(expr.value, tailwindSelectors);
|
|
891
|
+
const transformedValue = transformClassNames(expr.value, context.tailwindSelectors);
|
|
424
892
|
if (expr.value !== transformedValue) {
|
|
425
893
|
expr.value = transformedValue;
|
|
426
894
|
if (typeof expr.raw === 'string') {
|
|
427
895
|
expr.raw = JSON.stringify(transformedValue);
|
|
428
896
|
}
|
|
897
|
+
context.changes.count++;
|
|
429
898
|
}
|
|
430
899
|
};
|
|
431
900
|
const toLiteral = (value) => ({
|
|
@@ -433,7 +902,6 @@ const toLiteral = (value) => ({
|
|
|
433
902
|
value,
|
|
434
903
|
raw: JSON.stringify(value),
|
|
435
904
|
});
|
|
436
|
-
const serialize = (node) => JSON.stringify(node, (_key, value) => typeof value === 'bigint' ? value.toString() : value);
|
|
437
905
|
const transformClassNames = (value, tailwindSelectors) => {
|
|
438
906
|
var _a, _b, _c, _d;
|
|
439
907
|
if (!tailwindSelectors || !tailwindSelectors.length)
|