obscura-js 2.0.1 → 2.0.3

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obscura-js",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "JavaScript code protection tool — obfuscation & anti-debugging inspired by Google reCAPTCHA",
5
5
  "type": "commonjs",
6
6
  "main": "dist/src/index.js",
@@ -65,13 +65,13 @@
65
65
  "commander": "^12.0.0"
66
66
  },
67
67
  "devDependencies": {
68
- "@types/jest": "^29.5.12",
69
- "@types/node": "^20.12.0",
68
+ "@types/jest": "^30.0.0",
69
+ "@types/node": "^24.0.0",
70
70
  "@typescript-eslint/eslint-plugin": "^8.59.4",
71
71
  "@typescript-eslint/parser": "^8.59.4",
72
- "eslint": "^8.57.0",
72
+ "eslint": "^10.0.0",
73
73
  "eslint-config-prettier": "^10.1.8",
74
- "jest": "^29.7.0",
74
+ "jest": "^30.0.0",
75
75
  "prettier": "^3.8.3",
76
76
  "ts-jest": "^29.1.2",
77
77
  "ts-node": "^10.9.2",
@@ -1 +1 @@
1
- {"version":3,"file":"functionTable.d.ts","sourceRoot":"","sources":["../../../src/obfuscation/functionTable.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGrD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,oBAAyB,GAAG,IAAI,CAyH5F"}
1
+ {"version":3,"file":"functionTable.d.ts","sourceRoot":"","sources":["../../../src/obfuscation/functionTable.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAGrD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,GAAE,oBAAyB,GAAG,IAAI,CAsH5F"}
@@ -31,10 +31,9 @@ function applyFunctionTable(ast, options = {}) {
31
31
  if (path.node.source)
32
32
  return; // re-export from another file — no local binding // eslint-disable-line @typescript-eslint/no-explicit-any
33
33
  for (const spec of path.node.specifiers ?? []) {
34
- // eslint-disable-line @typescript-eslint/no-explicit-any
35
34
  if (swc_utils_1.t.isExportSpecifier(spec)) {
36
35
  // SWC ExportSpecifier uses .orig (not .local)
37
- const orig = spec.orig; // eslint-disable-line @typescript-eslint/no-explicit-any
36
+ const orig = spec.orig;
38
37
  if (orig && orig.type === "Identifier") {
39
38
  leakedNames.add(orig.value);
40
39
  }
@@ -44,7 +43,7 @@ function applyFunctionTable(ast, options = {}) {
44
43
  // ESM: export default foo (identifier, not an inline declaration)
45
44
  ExportDefaultExpression(path) {
46
45
  // SWC uses ExportDefaultExpression.expression for identifier exports
47
- const expr = path.node.expression ?? path.node.decl; // eslint-disable-line @typescript-eslint/no-explicit-any
46
+ const expr = path.node.expression ?? path.node.decl;
48
47
  if (expr && expr.type === "Identifier") {
49
48
  leakedNames.add(expr.value);
50
49
  }
@@ -56,32 +55,28 @@ function applyFunctionTable(ast, options = {}) {
56
55
  if (!isExportsTarget(left))
57
56
  return;
58
57
  if (swc_utils_1.t.isIdentifier(right)) {
59
- leakedNames.add(right.value); // eslint-disable-line @typescript-eslint/no-explicit-any
58
+ leakedNames.add(right.value);
60
59
  }
61
60
  else if (swc_utils_1.t.isObjectExpression(right)) {
62
61
  for (const prop of right.properties ?? []) {
63
- // eslint-disable-line @typescript-eslint/no-explicit-any
64
62
  // SWC shorthand { foo } → Identifier node directly in properties[]
65
63
  if (swc_utils_1.t.isIdentifier(prop)) {
66
- leakedNames.add(prop.value); // eslint-disable-line @typescript-eslint/no-explicit-any
64
+ leakedNames.add(prop.value);
67
65
  }
68
66
  else if (swc_utils_1.t.isObjectProperty(prop) && swc_utils_1.t.isIdentifier(prop.value)) {
69
- // eslint-disable-line @typescript-eslint/no-explicit-any
70
- leakedNames.add(prop.value.value); // eslint-disable-line @typescript-eslint/no-explicit-any
67
+ leakedNames.add(prop.value.value);
71
68
  }
72
69
  }
73
70
  }
74
71
  },
75
72
  });
76
73
  // Collect top-level named function declarations first, then remove only if threshold is met
77
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
74
  const functions = [];
79
75
  const nameToIndex = new Map();
80
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
81
76
  const functionPaths = [];
82
77
  (0, swc_utils_1.traverse)(ast, {
83
78
  FunctionDeclaration(path) {
84
- const node = path.node; // eslint-disable-line @typescript-eslint/no-explicit-any
79
+ const node = path.node;
85
80
  // SWC FunctionDeclaration uses .identifier (not .id)
86
81
  if (!node.identifier)
87
82
  return;
@@ -96,7 +91,7 @@ function applyFunctionTable(ast, options = {}) {
96
91
  return;
97
92
  // Build the index map before touching the AST
98
93
  for (let i = 0; i < functionPaths.length; i++) {
99
- nameToIndex.set(functionPaths[i].node.identifier.value, i); // eslint-disable-line @typescript-eslint/no-explicit-any
94
+ nameToIndex.set(functionPaths[i].node.identifier.value, i);
100
95
  }
101
96
  // Replace call sites FIRST (while function bodies are still in the AST)
102
97
  // so calls inside one function to another are also rewritten.
@@ -104,7 +99,7 @@ function applyFunctionTable(ast, options = {}) {
104
99
  CallExpression(path) {
105
100
  if (!swc_utils_1.t.isIdentifier(path.node.callee))
106
101
  return;
107
- const idx = nameToIndex.get(path.node.callee.value); // eslint-disable-line @typescript-eslint/no-explicit-any
102
+ const idx = nameToIndex.get(path.node.callee.value);
108
103
  if (idx === undefined)
109
104
  return;
110
105
  path.node.callee = swc_utils_1.t.memberExpression(swc_utils_1.t.identifier(tableId), swc_utils_1.t.numericLiteral(idx), true // computed
@@ -114,7 +109,7 @@ function applyFunctionTable(ast, options = {}) {
114
109
  // Now extract function expressions and remove declarations from the AST
115
110
  // Extract in original order first, then remove in reverse order to preserve indices
116
111
  for (const path of functionPaths) {
117
- const node = path.node; // eslint-disable-line @typescript-eslint/no-explicit-any
112
+ const node = path.node;
118
113
  functions.push({
119
114
  id: node.identifier.value,
120
115
  fn: swc_utils_1.t.functionExpression(null, node.params, // already Parameter[] in SWC
@@ -129,22 +124,21 @@ function applyFunctionTable(ast, options = {}) {
129
124
  const tableDeclaration = swc_utils_1.t.variableDeclaration("const", [
130
125
  swc_utils_1.t.variableDeclarator(swc_utils_1.t.identifier(tableId), swc_utils_1.t.arrayExpression(functions.map((f) => f.fn))),
131
126
  ]);
132
- ast.body.unshift(tableDeclaration); // eslint-disable-line @typescript-eslint/no-explicit-any
127
+ ast.body.unshift(tableDeclaration);
133
128
  }
134
129
  /**
135
130
  * Returns true if `node` is an assignment target that exposes a value as a
136
131
  * CJS export: `exports`, `module.exports`, or any member of `module.exports`.
137
132
  */
138
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
139
133
  function isExportsTarget(node) {
140
134
  // bare `exports`
141
135
  if (swc_utils_1.t.isIdentifier(node) && node.value === "exports")
142
- return true; // eslint-disable-line @typescript-eslint/no-explicit-any
136
+ return true;
143
137
  // must be a MemberExpression and not computed
144
138
  if (!swc_utils_1.t.isMemberExpression(node) || node.property?.type === "Computed")
145
- return false; // eslint-disable-line @typescript-eslint/no-explicit-any
146
- const obj = node.object; // eslint-disable-line @typescript-eslint/no-explicit-any
147
- const prop = node.property; // eslint-disable-line @typescript-eslint/no-explicit-any
139
+ return false;
140
+ const obj = node.object;
141
+ const prop = node.property;
148
142
  // `exports.foo`
149
143
  if (swc_utils_1.t.isIdentifier(obj) && obj.value === "exports")
150
144
  return true;
@@ -156,12 +150,11 @@ function isExportsTarget(node) {
156
150
  return true;
157
151
  // `module.exports.foo`
158
152
  if (swc_utils_1.t.isMemberExpression(obj) &&
159
- obj.property?.type !== "Computed" && // eslint-disable-line @typescript-eslint/no-explicit-any
160
- swc_utils_1.t.isIdentifier(obj.object) && // eslint-disable-line @typescript-eslint/no-explicit-any
161
- obj.object.value === "module" && // eslint-disable-line @typescript-eslint/no-explicit-any
162
- swc_utils_1.t.isIdentifier(obj.property) && // eslint-disable-line @typescript-eslint/no-explicit-any
163
- obj.property.value === "exports" // eslint-disable-line @typescript-eslint/no-explicit-any
164
- )
153
+ obj.property?.type !== "Computed" &&
154
+ swc_utils_1.t.isIdentifier(obj.object) &&
155
+ obj.object.value === "module" &&
156
+ swc_utils_1.t.isIdentifier(obj.property) &&
157
+ obj.property.value === "exports")
165
158
  return true;
166
159
  return false;
167
160
  }
@@ -1 +1 @@
1
- {"version":3,"file":"functionTable.js","sourceRoot":"","sources":["../../../src/obfuscation/functionTable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"functionTable.js","sourceRoot":"","sources":["../../../src/obfuscation/functionTable.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sequenceExpression.d.ts","sourceRoot":"","sources":["../../../src/obfuscation/sequenceExpression.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,yBAA8B,GACtC,IAAI,CA2CN"}
1
+ {"version":3,"file":"sequenceExpression.d.ts","sourceRoot":"","sources":["../../../src/obfuscation/sequenceExpression.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,UAAU,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,UAAU,EACf,OAAO,GAAE,yBAA8B,GACtC,IAAI,CA6EN"}
@@ -34,22 +34,50 @@ function applySequenceExpression(ast, options = {}) {
34
34
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
35
35
  const toSeq = (block) => {
36
36
  const exprs = block.stmts.map((s) => s.expression); // eslint-disable-line @typescript-eslint/no-explicit-any
37
+ // Always wrap in ParenthesisExpression so the comma-operator sequence
38
+ // and single assignment expressions are always syntactically valid
39
+ // regardless of the enclosing context (ternary branch or && right-hand
40
+ // side). Without parens, `cond && x = v` is parsed as `(cond && x) = v`
41
+ // which is a SyntaxError because the LHS is not assignable.
37
42
  if (exprs.length === 1)
38
- return exprs[0];
39
- // Wrap in ParenthesisExpression so the comma-operator sequence is
40
- // always syntactically valid regardless of the enclosing context
41
- // (ternary branch or && right-hand side).
43
+ return swc_utils_1.t.parenthesisExpression(exprs[0]);
42
44
  return swc_utils_1.t.parenthesisExpression(swc_utils_1.t.sequenceExpression(exprs));
43
45
  };
46
+ // SWC's printer does NOT automatically parenthesise lower-precedence
47
+ // operators on the left-hand side of && or as the condition of ?:.
48
+ // We must do it explicitly when the test node has lower precedence
49
+ // than the operator we are generating.
50
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
51
+ const wrapTest = (node, context) => {
52
+ const type = node?.type;
53
+ const op = node?.operator;
54
+ if (context === "&&") {
55
+ // Lower precedence than &&: || ?? ?: = , (sequence)
56
+ if ((type === "BinaryExpression" && (op === "||" || op === "??")) ||
57
+ type === "ConditionalExpression" ||
58
+ type === "AssignmentExpression" ||
59
+ type === "SequenceExpression") {
60
+ return swc_utils_1.t.parenthesisExpression(node);
61
+ }
62
+ }
63
+ else {
64
+ // Lower precedence than ?:: = , (sequence)
65
+ // (|| / ?? / && all bind tighter than ?: so they never need wrapping here)
66
+ if (type === "AssignmentExpression" || type === "SequenceExpression") {
67
+ return swc_utils_1.t.parenthesisExpression(node);
68
+ }
69
+ }
70
+ return node;
71
+ };
44
72
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
45
73
  let replacement;
46
74
  if (alternate === null || alternate === undefined) {
47
75
  // if (cond) { ... } → cond && (...)
48
- replacement = swc_utils_1.t.logicalExpression("&&", test, toSeq(consequent));
76
+ replacement = swc_utils_1.t.logicalExpression("&&", wrapTest(test, "&&"), toSeq(consequent));
49
77
  }
50
78
  else {
51
79
  // if (cond) { ... } else { ... } → cond ? (...) : (...)
52
- replacement = swc_utils_1.t.conditionalExpression(test, toSeq(consequent), toSeq(alternate));
80
+ replacement = swc_utils_1.t.conditionalExpression(wrapTest(test, "?:"), toSeq(consequent), toSeq(alternate));
53
81
  }
54
82
  path.replaceWith(swc_utils_1.t.expressionStatement(replacement));
55
83
  },
@@ -1 +1 @@
1
- {"version":3,"file":"sequenceExpression.js","sourceRoot":"","sources":["../../../src/obfuscation/sequenceExpression.ts"],"names":[],"mappings":";;AAgBA,0DA8CC;AA9DD,4CAA2C;AAI3C;;;;;;;;;;;GAWG;AACH,SAAgB,uBAAuB,CACrC,GAAe,EACf,UAAqC,EAAE;IAEvC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,GAAG,CAAC;IAE/C,IAAA,oBAAQ,EAAC,GAAG,EAAE;QACZ,WAAW,CAAC,IAAI;YACd,IAAI,IAAI,CAAC,MAAM,EAAE,GAAG,WAAW;gBAAE,OAAO;YAExC,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC;YAElD,8DAA8D;YAC9D,iDAAiD;YACjD,8DAA8D;YAC9D,MAAM,UAAU,GAAG,CAAC,IAAS,EAAW,EAAE,CACxC,aAAC,CAAC,gBAAgB,CAAC,IAAI,CAAC;gBACxB,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;gBACrB,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,aAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,yDAAyD;YAErH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;gBAAE,OAAO;YACpC,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;gBAAE,OAAO;YAEpF,8DAA8D;YAC9D,MAAM,KAAK,GAAG,CAAC,KAAU,EAAO,EAAE;gBAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,yDAAyD;gBAClH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;gBACxC,kEAAkE;gBAClE,iEAAiE;gBACjE,0CAA0C;gBAC1C,OAAO,aAAC,CAAC,qBAAqB,CAAC,aAAC,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC9D,CAAC,CAAC;YAEF,8DAA8D;YAC9D,IAAI,WAAgB,CAAC;YACrB,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAClD,sCAAsC;gBACtC,WAAW,GAAG,aAAC,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,0DAA0D;gBAC1D,WAAW,GAAG,aAAC,CAAC,qBAAqB,CAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC;YACnF,CAAC;YAED,IAAI,CAAC,WAAW,CAAC,aAAC,CAAC,mBAAmB,CAAC,WAAW,CAAC,CAAC,CAAC;QACvD,CAAC;KACF,CAAC,CAAC;AACL,CAAC"}
1
+ {"version":3,"file":"sequenceExpression.js","sourceRoot":"","sources":["../../../src/obfuscation/sequenceExpression.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "obscura-js",
3
- "version": "2.0.1",
3
+ "version": "2.0.3",
4
4
  "description": "JavaScript code protection tool — obfuscation & anti-debugging inspired by Google reCAPTCHA",
5
5
  "type": "commonjs",
6
6
  "main": "dist/src/index.js",
@@ -65,13 +65,13 @@
65
65
  "commander": "^12.0.0"
66
66
  },
67
67
  "devDependencies": {
68
- "@types/jest": "^29.5.12",
69
- "@types/node": "^20.12.0",
68
+ "@types/jest": "^30.0.0",
69
+ "@types/node": "^24.0.0",
70
70
  "@typescript-eslint/eslint-plugin": "^8.59.4",
71
71
  "@typescript-eslint/parser": "^8.59.4",
72
- "eslint": "^8.57.0",
72
+ "eslint": "^10.0.0",
73
73
  "eslint-config-prettier": "^10.1.8",
74
- "jest": "^29.7.0",
74
+ "jest": "^30.0.0",
75
75
  "prettier": "^3.8.3",
76
76
  "ts-jest": "^29.1.2",
77
77
  "ts-node": "^10.9.2",