Skip to content

Commit 0dd46b3

Browse files
committed
fix(js-ast): added support to TemplateLiteral & TemplateElement #45
1 parent 8c95ba0 commit 0dd46b3

File tree

3 files changed

+77
-7
lines changed

3 files changed

+77
-7
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "next-css-obfuscator",
3-
"version": "2.2.17",
3+
"version": "2.2.18",
44
"description": "A package deeply inspired by PostCSS-Obfuscator but for Next.js.",
55
"main": "dist/index.js",
66
"type": "commonjs",

src/handlers/js-ast.test.ts

+29
Original file line numberDiff line numberDiff line change
@@ -1358,6 +1358,35 @@ describe("searchStringLiterals", () => {
13581358
expect(stripCode(generator(ast, {}, code).code)).toEqual(stripCode(expectedCode));
13591359
});
13601360

1361+
//? *******************************
1362+
//? Template Literals & Template Elements
1363+
//? *******************************
1364+
1365+
it("should handle template literals correctly", () => {
1366+
const code = `
1367+
function startPoint() {
1368+
const value = "value";
1369+
return \`hello \${value}\`;
1370+
}
1371+
`
1372+
const expectedCode = `
1373+
function startPoint() {
1374+
const value = "{{found}}";
1375+
return \`{{found}} \${value}\`;
1376+
}
1377+
`
1378+
1379+
const ast = parser.parse(code);
1380+
let result: string[] = [];
1381+
searchStringLiterals(findStartPointNode(ast)!, (str) => {
1382+
result.push(str);
1383+
return "{{found}}"
1384+
})
1385+
1386+
expect(result).toEqual(["hello "/* Raw */, "hello " /* Cooked */, "value"]);
1387+
expect(stripCode(generator(ast, {}, code).code)).toEqual(stripCode(expectedCode));
1388+
});
1389+
13611390
});
13621391

13631392
//! ================================

src/handlers/js-ast.ts

+47-6
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ function obfuscateJsWithAst(
3737
return "{{obfuscated}}";
3838
}
3939

40-
// strip unnecessary space, e.g. " a b c " => "a b c"
41-
str = stripUnnecessarySpace ? str.replace(/\s+/g, " ").trim() : str;
40+
// strip unnecessary space, e.g. " a b c " => "a b c "
41+
str = stripUnnecessarySpace ? str.replace(/\s+/g, " ").trimStart() //? avoid trimming the end to keep the space between classes
42+
: str;
4243

4344
const { obfuscatedContent, usedKeys: obfuscateUsedKeys } = obfuscateKeys(selectorConversion, str);
4445
if (obfuscatedContent !== str) {
@@ -118,7 +119,7 @@ function searchStringLiterals(path: NodePath<t.Node>,
118119
searchStringLiterals(arg, callback, scannedNodes);
119120
});
120121
}
121-
}
122+
}
122123
}
123124
/* binary expression (e.g. const a = "hello" + "world") */
124125
else if (t.isBinaryExpression(path.node)) {
@@ -294,7 +295,7 @@ function searchStringLiterals(path: NodePath<t.Node>,
294295
searchStringLiterals(handlerBody, callback, scannedNodes);
295296
}
296297
}
297-
}
298+
}
298299
/* member expression (e.g. "scroll-top".replace("-", "_")); "scroll-top ".concat("visible"); */
299300
else if (t.isMemberExpression(path.node)) {
300301
const object = path.get("object");
@@ -313,7 +314,47 @@ function searchStringLiterals(path: NodePath<t.Node>,
313314
searchStringLiterals(arg, callback, scannedNodes);
314315
});
315316
}
316-
} else {
317+
}
318+
/* template literal (e.g. `hello ${name}`) */
319+
else if (t.isTemplateLiteral(path.node)) {
320+
const quasis = path.get("quasis");
321+
const expressions = path.get("expressions");
322+
if (Array.isArray(quasis)) {
323+
quasis.forEach(quasi => {
324+
searchStringLiterals(quasi, callback, scannedNodes);
325+
});
326+
}
327+
if (Array.isArray(expressions)) {
328+
expressions.forEach(expression => {
329+
searchStringLiterals(expression, callback, scannedNodes);
330+
});
331+
}
332+
}
333+
/* template element (e.g. `hello ${name}`) */
334+
else if (t.isTemplateElement(path.node)) {
335+
const node = path.node as t.TemplateElement;
336+
337+
if (node.value) {
338+
const { raw, cooked } = node.value;
339+
340+
// Replace the "raw" and "cooked" values of the template element
341+
if (raw) {
342+
// If the raw is not empty
343+
const rawReplacement = callback(raw);
344+
if (rawReplacement !== undefined) {
345+
node.value.raw = rawReplacement;
346+
}
347+
}
348+
if (cooked) {
349+
// If the cooked is not empty and undefined
350+
const cookedReplacement = callback(cooked);
351+
if (cookedReplacement !== undefined) {
352+
node.value.cooked = cookedReplacement;
353+
}
354+
}
355+
}
356+
}
357+
else {
317358
path.traverse({
318359
Identifier(innerPath) {
319360
searchStringLiterals(innerPath, callback, scannedNodes);
@@ -329,4 +370,4 @@ function searchStringLiterals(path: NodePath<t.Node>,
329370
export {
330371
searchStringLiterals,
331372
obfuscateJsWithAst,
332-
}
373+
}

0 commit comments

Comments
 (0)