webfuscator 1.2.0 → 1.3.0
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/analysis/constant.js +3 -4
- package/dist/analysis/constant.js.map +1 -1
- package/dist/analysis/inlineability.d.ts.map +1 -1
- package/dist/analysis/inlineability.js +37 -25
- package/dist/analysis/inlineability.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/obfuscator.d.ts +2 -1
- package/dist/obfuscator.d.ts.map +1 -1
- package/dist/obfuscator.js +47 -12
- package/dist/obfuscator.js.map +1 -1
- package/dist/options.d.ts +24 -4
- package/dist/options.d.ts.map +1 -1
- package/dist/preparation/expand-destructuring.d.ts +3 -3
- package/dist/preparation/expand-destructuring.js +6 -6
- package/dist/preparation/expand-destructuring.js.map +1 -1
- package/dist/transforms/arrow-to-function.js +3 -5
- package/dist/transforms/arrow-to-function.js.map +1 -1
- package/dist/transforms/conceal-strings.d.ts +57 -0
- package/dist/transforms/conceal-strings.d.ts.map +1 -0
- package/dist/transforms/conceal-strings.js +361 -0
- package/dist/transforms/conceal-strings.js.map +1 -0
- package/dist/transforms/const-let-to-var.d.ts +3 -3
- package/dist/transforms/const-let-to-var.d.ts.map +1 -1
- package/dist/transforms/const-let-to-var.js +36 -9
- package/dist/transforms/const-let-to-var.js.map +1 -1
- package/dist/transforms/const-to-let.d.ts +2 -3
- package/dist/transforms/const-to-let.d.ts.map +1 -1
- package/dist/transforms/const-to-let.js +3 -5
- package/dist/transforms/const-to-let.js.map +1 -1
- package/dist/transforms/fold-builtin-methods.d.ts.map +1 -1
- package/dist/transforms/fold-builtin-methods.js +48 -10
- package/dist/transforms/fold-builtin-methods.js.map +1 -1
- package/dist/transforms/fold-constants.js +3 -0
- package/dist/transforms/fold-constants.js.map +1 -1
- package/dist/transforms/hoist-variables.d.ts +30 -0
- package/dist/transforms/hoist-variables.d.ts.map +1 -0
- package/dist/transforms/hoist-variables.js +224 -0
- package/dist/transforms/hoist-variables.js.map +1 -0
- package/dist/transforms/inline-functions.js +3 -4
- package/dist/transforms/inline-functions.js.map +1 -1
- package/dist/transforms/mangle-properties.js +7 -4
- package/dist/transforms/mangle-properties.js.map +1 -1
- package/dist/transforms/merge-variable-declarations.d.ts +17 -0
- package/dist/transforms/merge-variable-declarations.d.ts.map +1 -0
- package/dist/transforms/merge-variable-declarations.js +68 -0
- package/dist/transforms/merge-variable-declarations.js.map +1 -0
- package/dist/transforms/numbers-to-strings.d.ts.map +1 -1
- package/dist/transforms/numbers-to-strings.js +1 -8
- package/dist/transforms/numbers-to-strings.js.map +1 -1
- package/dist/transforms/pack-declarations-into-parameters.js +1 -5
- package/dist/transforms/pack-declarations-into-parameters.js.map +1 -1
- package/dist/transforms/pack.d.ts +5 -7
- package/dist/transforms/pack.d.ts.map +1 -1
- package/dist/transforms/pack.js +194 -32
- package/dist/transforms/pack.js.map +1 -1
- package/dist/transforms/remove-unused-code.d.ts.map +1 -1
- package/dist/transforms/remove-unused-code.js +7 -39
- package/dist/transforms/remove-unused-code.js.map +1 -1
- package/dist/transforms/rename-identifiers.d.ts.map +1 -1
- package/dist/transforms/rename-identifiers.js +29 -17
- package/dist/transforms/rename-identifiers.js.map +1 -1
- package/dist/transforms/reorder-function-declarations.d.ts +25 -0
- package/dist/transforms/reorder-function-declarations.d.ts.map +1 -0
- package/dist/transforms/reorder-function-declarations.js +64 -0
- package/dist/transforms/reorder-function-declarations.js.map +1 -0
- package/dist/transforms/specials-to-strings.js +4 -3
- package/dist/transforms/specials-to-strings.js.map +1 -1
- package/dist/transforms/update-to-assignment.js +1 -16
- package/dist/transforms/update-to-assignment.js.map +1 -1
- package/dist/utils/ast.d.ts +1 -2
- package/dist/utils/ast.d.ts.map +1 -1
- package/dist/utils/ast.js +12 -42
- package/dist/utils/ast.js.map +1 -1
- package/dist/utils/literal.d.ts.map +1 -1
- package/dist/utils/literal.js +74 -2
- package/dist/utils/literal.js.map +1 -1
- package/dist/utils/statement-lists.d.ts +9 -0
- package/dist/utils/statement-lists.d.ts.map +1 -0
- package/dist/utils/statement-lists.js +27 -0
- package/dist/utils/statement-lists.js.map +1 -0
- package/package.json +12 -13
- package/src/analysis/constant.ts +3 -6
- package/src/analysis/inlineability.ts +40 -32
- package/src/index.ts +1 -0
- package/src/obfuscator.ts +51 -14
- package/src/options.ts +28 -3
- package/src/preparation/expand-destructuring.ts +6 -6
- package/src/transforms/arrow-to-function.ts +3 -5
- package/src/transforms/conceal-strings.ts +530 -0
- package/src/transforms/const-let-to-var.ts +37 -9
- package/src/transforms/const-to-let.ts +3 -5
- package/src/transforms/fold-builtin-methods.ts +67 -12
- package/src/transforms/fold-constants.ts +3 -0
- package/src/transforms/hoist-variables.ts +272 -0
- package/src/transforms/inline-functions.ts +3 -4
- package/src/transforms/mangle-properties.ts +7 -7
- package/src/transforms/merge-variable-declarations.ts +91 -0
- package/src/transforms/numbers-to-strings.ts +2 -12
- package/src/transforms/pack-declarations-into-parameters.ts +1 -5
- package/src/transforms/pack.ts +202 -35
- package/src/transforms/remove-unused-code.ts +9 -64
- package/src/transforms/rename-identifiers.ts +42 -17
- package/src/transforms/reorder-function-declarations.ts +80 -0
- package/src/transforms/specials-to-strings.ts +4 -3
- package/src/transforms/update-to-assignment.ts +1 -17
- package/src/utils/ast.ts +15 -51
- package/src/utils/literal.ts +91 -2
- package/src/utils/statement-lists.ts +45 -0
- package/DISCLOSURE +0 -9
- package/README.md +0 -62
|
@@ -2,7 +2,7 @@ import type { Binding, NodePath, Visitor } from '@babel/traverse'
|
|
|
2
2
|
import * as t from '@babel/types'
|
|
3
3
|
import type { File } from '@babel/types'
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { isInsideWith } from '../utils/ast'
|
|
6
6
|
import { traverseForChanges } from '../utils/change-tracking'
|
|
7
7
|
import type { ChangeState } from '../utils/change-tracking'
|
|
8
8
|
|
|
@@ -52,10 +52,6 @@ const visitor: Visitor<ChangeState> = {
|
|
|
52
52
|
if (!isNumericBinding(binding)) {
|
|
53
53
|
return
|
|
54
54
|
}
|
|
55
|
-
// Direct eval anywhere in the binding's scope can change its type.
|
|
56
|
-
if (bindingScopeReachesDirectEval(binding!)) {
|
|
57
|
-
return
|
|
58
|
-
}
|
|
59
55
|
const compound = operator === '++' ? '+=' : '-='
|
|
60
56
|
path.replaceWith(t.assignmentExpression(compound, argument, t.numericLiteral(1)))
|
|
61
57
|
state.changed = true
|
|
@@ -95,18 +91,6 @@ function isNumericBinding(binding: Binding | undefined): boolean {
|
|
|
95
91
|
return binding.constantViolations.every((violation) => keepsNumeric(violation.node))
|
|
96
92
|
}
|
|
97
93
|
|
|
98
|
-
// A sibling or nested direct eval can still close over and reassign the binding.
|
|
99
|
-
function bindingScopeReachesDirectEval(binding: Binding): boolean {
|
|
100
|
-
let found = false
|
|
101
|
-
t.traverseFast(binding.scope.block, (node) => {
|
|
102
|
-
if (isDirectEvalCall(node)) {
|
|
103
|
-
found = true
|
|
104
|
-
}
|
|
105
|
-
return found ? t.traverseFast.stop : undefined
|
|
106
|
-
})
|
|
107
|
-
return found
|
|
108
|
-
}
|
|
109
|
-
|
|
110
94
|
function isForInOfLoopVariable(binding: Binding): boolean {
|
|
111
95
|
const declaration = binding.path.parentPath
|
|
112
96
|
if (!declaration || !declaration.isVariableDeclaration()) {
|
package/src/utils/ast.ts
CHANGED
|
@@ -62,75 +62,39 @@ export function isProtoKey(key: t.Node): boolean {
|
|
|
62
62
|
)
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
+
// A non-computed key names a property; it is not a runtime value.
|
|
66
|
+
export function isNonComputedKey(path: NodePath): boolean {
|
|
67
|
+
const parent = path.parent
|
|
68
|
+
return (
|
|
69
|
+
'key' in parent && parent.key === path.node && 'computed' in parent && parent.computed === false
|
|
70
|
+
)
|
|
71
|
+
}
|
|
72
|
+
|
|
65
73
|
// `with` can shadow names outside Babel's scope table.
|
|
66
74
|
export function isInsideWith(path: NodePath): boolean {
|
|
67
|
-
if (!
|
|
75
|
+
if (!programHasWith(path.scope.getProgramParent().block)) {
|
|
68
76
|
return false
|
|
69
77
|
}
|
|
70
78
|
return path.findParent((ancestor) => ancestor.isWithStatement()) !== null
|
|
71
79
|
}
|
|
72
80
|
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
export function enclosingScopeHasDirectEval(path: NodePath): boolean {
|
|
76
|
-
if (!programContains(path.scope.getProgramParent().block, programDirectEval, isDirectEvalCall)) {
|
|
77
|
-
return false
|
|
78
|
-
}
|
|
79
|
-
let current: NodePath | null = path
|
|
80
|
-
while (current) {
|
|
81
|
-
if ((current.isFunction() || current.isProgram()) && ownScopeHasDirectEval(current.node)) {
|
|
82
|
-
return true
|
|
83
|
-
}
|
|
84
|
-
current = current.parentPath
|
|
85
|
-
}
|
|
86
|
-
return false
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Cache program-wide `eval` and `with` checks to avoid a subtree walk per name.
|
|
90
|
-
// No transform creates either construct, so a negative result stays valid.
|
|
91
|
-
const programDirectEval = new WeakMap<t.Node, boolean>()
|
|
81
|
+
// Cache the program-wide scan because `isInsideWith` runs for many identifiers.
|
|
82
|
+
// Transforms never add `with`, so a cached miss remains valid.
|
|
92
83
|
const programWith = new WeakMap<t.Node, boolean>()
|
|
93
84
|
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
-
cache: WeakMap<t.Node, boolean>,
|
|
97
|
-
matches: (node: t.Node) => boolean,
|
|
98
|
-
): boolean {
|
|
99
|
-
const cached = cache.get(programNode)
|
|
85
|
+
function programHasWith(programNode: t.Node): boolean {
|
|
86
|
+
const cached = programWith.get(programNode)
|
|
100
87
|
if (cached !== undefined) {
|
|
101
88
|
return cached
|
|
102
89
|
}
|
|
103
90
|
let found = false
|
|
104
91
|
t.traverseFast(programNode, (node) => {
|
|
105
|
-
if (!
|
|
92
|
+
if (!t.isWithStatement(node)) {
|
|
106
93
|
return
|
|
107
94
|
}
|
|
108
95
|
found = true
|
|
109
96
|
return t.traverseFast.stop
|
|
110
97
|
})
|
|
111
|
-
|
|
98
|
+
programWith.set(programNode, found)
|
|
112
99
|
return found
|
|
113
100
|
}
|
|
114
|
-
|
|
115
|
-
function ownScopeHasDirectEval(owner: t.Node): boolean {
|
|
116
|
-
let found = false
|
|
117
|
-
// This walk stops at the first hit, unlike `walkOwnFunctionScope`.
|
|
118
|
-
t.traverseFast(owner, (node) => {
|
|
119
|
-
if (isDirectEvalCall(node)) {
|
|
120
|
-
found = true
|
|
121
|
-
return t.traverseFast.stop
|
|
122
|
-
}
|
|
123
|
-
return node !== owner && t.isFunction(node) ? t.traverseFast.skip : undefined
|
|
124
|
-
})
|
|
125
|
-
return found
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function isDirectEvalCall(node: t.Node): boolean {
|
|
129
|
-
// `eval?.(...)` is an OptionalCallExpression yet still a direct eval, so both
|
|
130
|
-
// call node shapes count.
|
|
131
|
-
return (
|
|
132
|
-
(t.isCallExpression(node) || t.isOptionalCallExpression(node)) &&
|
|
133
|
-
t.isIdentifier(node.callee) &&
|
|
134
|
-
node.callee.name === 'eval'
|
|
135
|
-
)
|
|
136
|
-
}
|
package/src/utils/literal.ts
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import generate from '@babel/generator'
|
|
1
2
|
import * as t from '@babel/types'
|
|
2
3
|
|
|
4
|
+
const MAX_GENERATED_LITERAL_LENGTH = 8192
|
|
5
|
+
const MAX_LITERAL_DEPTH = 32
|
|
6
|
+
const MAX_LITERAL_NODES = 512
|
|
3
7
|
const MAX_STRING_LITERAL_LENGTH = 4096
|
|
4
8
|
|
|
5
9
|
// RegExp literals allocate mutable objects and are not primitive values.
|
|
@@ -45,19 +49,56 @@ function literalShapeKind(node: t.Node): 'bigint' | 'other' | null {
|
|
|
45
49
|
}
|
|
46
50
|
|
|
47
51
|
export function valueToLiteral(value: unknown): t.Expression | null {
|
|
52
|
+
const literal = buildValueLiteral(value, new Set(), { nodesRemaining: MAX_LITERAL_NODES }, 0)
|
|
53
|
+
if (!literal || generate(literal).code.length > MAX_GENERATED_LITERAL_LENGTH) {
|
|
54
|
+
return null
|
|
55
|
+
}
|
|
56
|
+
return literal
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface LiteralBudget {
|
|
60
|
+
nodesRemaining: number
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function reserveLiteralNodes(budget: LiteralBudget, count: number): boolean {
|
|
64
|
+
if (budget.nodesRemaining < count) {
|
|
65
|
+
return false
|
|
66
|
+
}
|
|
67
|
+
budget.nodesRemaining -= count
|
|
68
|
+
return true
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function buildValueLiteral(
|
|
72
|
+
value: unknown,
|
|
73
|
+
seen: Set<object>,
|
|
74
|
+
budget: LiteralBudget,
|
|
75
|
+
depth: number,
|
|
76
|
+
): t.Expression | null {
|
|
77
|
+
if (depth > MAX_LITERAL_DEPTH) {
|
|
78
|
+
return null
|
|
79
|
+
}
|
|
48
80
|
if (typeof value === 'string') {
|
|
49
|
-
if (value.length > MAX_STRING_LITERAL_LENGTH) {
|
|
81
|
+
if (value.length > MAX_STRING_LITERAL_LENGTH || !reserveLiteralNodes(budget, 1)) {
|
|
50
82
|
return null
|
|
51
83
|
}
|
|
52
84
|
return t.stringLiteral(value)
|
|
53
85
|
}
|
|
54
86
|
if (typeof value === 'boolean') {
|
|
87
|
+
if (!reserveLiteralNodes(budget, 1)) {
|
|
88
|
+
return null
|
|
89
|
+
}
|
|
55
90
|
return t.booleanLiteral(value)
|
|
56
91
|
}
|
|
57
92
|
if (value === null) {
|
|
93
|
+
if (!reserveLiteralNodes(budget, 1)) {
|
|
94
|
+
return null
|
|
95
|
+
}
|
|
58
96
|
return t.nullLiteral()
|
|
59
97
|
}
|
|
60
98
|
if (value === undefined) {
|
|
99
|
+
if (!reserveLiteralNodes(budget, 2)) {
|
|
100
|
+
return null
|
|
101
|
+
}
|
|
61
102
|
// `void 0` cannot be shadowed like the identifier `undefined`.
|
|
62
103
|
return t.unaryExpression('void', t.numericLiteral(0))
|
|
63
104
|
}
|
|
@@ -65,8 +106,14 @@ export function valueToLiteral(value: unknown): t.Expression | null {
|
|
|
65
106
|
// A UnaryExpression lets the generator parenthesize negative BigInt where
|
|
66
107
|
// precedence requires it.
|
|
67
108
|
if (value < 0n) {
|
|
109
|
+
if (!reserveLiteralNodes(budget, 2)) {
|
|
110
|
+
return null
|
|
111
|
+
}
|
|
68
112
|
return t.unaryExpression('-', t.bigIntLiteral(-value))
|
|
69
113
|
}
|
|
114
|
+
if (!reserveLiteralNodes(budget, 1)) {
|
|
115
|
+
return null
|
|
116
|
+
}
|
|
70
117
|
return t.bigIntLiteral(value)
|
|
71
118
|
}
|
|
72
119
|
if (typeof value === 'number') {
|
|
@@ -74,17 +121,30 @@ export function valueToLiteral(value: unknown): t.Expression | null {
|
|
|
74
121
|
return null
|
|
75
122
|
}
|
|
76
123
|
if (Object.is(value, -0)) {
|
|
124
|
+
if (!reserveLiteralNodes(budget, 2)) {
|
|
125
|
+
return null
|
|
126
|
+
}
|
|
77
127
|
return t.unaryExpression('-', t.numericLiteral(0))
|
|
78
128
|
}
|
|
79
129
|
if (value < 0) {
|
|
130
|
+
if (!reserveLiteralNodes(budget, 2)) {
|
|
131
|
+
return null
|
|
132
|
+
}
|
|
80
133
|
return t.unaryExpression('-', t.numericLiteral(-value))
|
|
81
134
|
}
|
|
135
|
+
if (!reserveLiteralNodes(budget, 1)) {
|
|
136
|
+
return null
|
|
137
|
+
}
|
|
82
138
|
return t.numericLiteral(value)
|
|
83
139
|
}
|
|
84
140
|
if (Array.isArray(value)) {
|
|
141
|
+
if (seen.has(value) || !arrayHasLiteralShape(value) || !reserveLiteralNodes(budget, 1)) {
|
|
142
|
+
return null
|
|
143
|
+
}
|
|
144
|
+
seen.add(value)
|
|
85
145
|
const elements: t.Expression[] = []
|
|
86
146
|
for (const item of value) {
|
|
87
|
-
const lit =
|
|
147
|
+
const lit = buildValueLiteral(item, seen, budget, depth + 1)
|
|
88
148
|
if (!lit) {
|
|
89
149
|
return null
|
|
90
150
|
}
|
|
@@ -94,3 +154,32 @@ export function valueToLiteral(value: unknown): t.Expression | null {
|
|
|
94
154
|
}
|
|
95
155
|
return null
|
|
96
156
|
}
|
|
157
|
+
|
|
158
|
+
function arrayHasLiteralShape(value: unknown[]): boolean {
|
|
159
|
+
if (Object.getPrototypeOf(value) !== Array.prototype || !Object.isExtensible(value)) {
|
|
160
|
+
return false
|
|
161
|
+
}
|
|
162
|
+
const names = Object.getOwnPropertyNames(value)
|
|
163
|
+
if (names.length !== value.length + 1 || names.at(-1) !== 'length') {
|
|
164
|
+
return false
|
|
165
|
+
}
|
|
166
|
+
for (let index = 0; index < value.length; index++) {
|
|
167
|
+
if (
|
|
168
|
+
names[index] !== String(index) ||
|
|
169
|
+
!isOrdinaryDataProperty(Object.getOwnPropertyDescriptor(value, String(index)))
|
|
170
|
+
) {
|
|
171
|
+
return false
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return Object.getOwnPropertySymbols(value).length === 0
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function isOrdinaryDataProperty(descriptor: PropertyDescriptor | undefined): boolean {
|
|
178
|
+
return (
|
|
179
|
+
descriptor !== undefined &&
|
|
180
|
+
'value' in descriptor &&
|
|
181
|
+
descriptor.configurable === true &&
|
|
182
|
+
descriptor.enumerable === true &&
|
|
183
|
+
descriptor.writable === true
|
|
184
|
+
)
|
|
185
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { NodePath } from '@babel/traverse'
|
|
2
|
+
import type * as t from '@babel/types'
|
|
3
|
+
import type { File } from '@babel/types'
|
|
4
|
+
|
|
5
|
+
import { traverseForChanges } from './change-tracking'
|
|
6
|
+
import type { ChangeState } from './change-tracking'
|
|
7
|
+
|
|
8
|
+
export type StatementListContainer = t.Program | t.BlockStatement | t.StaticBlock | t.SwitchCase
|
|
9
|
+
|
|
10
|
+
type Rewrite = (
|
|
11
|
+
statements: NodePath<t.Statement>[],
|
|
12
|
+
container: NodePath<StatementListContainer>,
|
|
13
|
+
) => t.Statement[] | null
|
|
14
|
+
|
|
15
|
+
/** Applies a rewrite to every statement-list container in the AST. */
|
|
16
|
+
export function rewriteStatementLists(ast: File, rewrite: Rewrite): boolean {
|
|
17
|
+
return traverseForChanges(ast, {
|
|
18
|
+
Program(path, state) {
|
|
19
|
+
apply(path, 'body', rewrite, state)
|
|
20
|
+
},
|
|
21
|
+
BlockStatement(path, state) {
|
|
22
|
+
apply(path, 'body', rewrite, state)
|
|
23
|
+
},
|
|
24
|
+
StaticBlock(path, state) {
|
|
25
|
+
apply(path, 'body', rewrite, state)
|
|
26
|
+
},
|
|
27
|
+
SwitchCase(path, state) {
|
|
28
|
+
apply(path, 'consequent', rewrite, state)
|
|
29
|
+
},
|
|
30
|
+
})
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function apply(
|
|
34
|
+
container: NodePath<StatementListContainer>,
|
|
35
|
+
key: 'body' | 'consequent',
|
|
36
|
+
rewrite: Rewrite,
|
|
37
|
+
state: ChangeState,
|
|
38
|
+
): void {
|
|
39
|
+
const statements = container.get(key) as NodePath<t.Statement>[]
|
|
40
|
+
const replacement = rewrite(statements, container)
|
|
41
|
+
if (replacement) {
|
|
42
|
+
container.set(key, replacement)
|
|
43
|
+
state.changed = true
|
|
44
|
+
}
|
|
45
|
+
}
|
package/DISCLOSURE
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
webfuscator transforms and obfuscates JavaScript source code. Its features
|
|
2
|
-
include identifier and property-name mangling, constant folding, dead-code
|
|
3
|
-
removal, and control-flow and literal rewrites.
|
|
4
|
-
|
|
5
|
-
These capabilities can make JavaScript harder to inspect and may have both
|
|
6
|
-
legitimate and harmful uses. The intended use is transforming software that
|
|
7
|
-
the user owns or is authorized to modify. This package is not intended to
|
|
8
|
-
create, conceal, distribute, or operate malware, or to interfere with systems
|
|
9
|
-
without authorization.
|
package/README.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
`webfuscator` is a Babel-based JavaScript obfuscator. It parses a JavaScript source string, applies configurable transforms, and returns JavaScript source.
|
|
2
|
-
|
|
3
|
-
[Read the documentation](https://webfuscator.mintlify.app/) for the quickstart, configuration guides, API details, and a reference page for every transform.
|
|
4
|
-
|
|
5
|
-
## Install
|
|
6
|
-
|
|
7
|
-
```sh
|
|
8
|
-
npm install --save-dev webfuscator
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
The package is ESM-only, includes TypeScript declarations, and requires Node.js `^22.18.0 || >=24.11.0`.
|
|
12
|
-
|
|
13
|
-
## Usage
|
|
14
|
-
|
|
15
|
-
```js
|
|
16
|
-
import { obfuscate } from 'webfuscator'
|
|
17
|
-
|
|
18
|
-
const source = `export default function square(value) {
|
|
19
|
-
return value * value
|
|
20
|
-
}`
|
|
21
|
-
|
|
22
|
-
const output = obfuscate(source, {
|
|
23
|
-
minify: true,
|
|
24
|
-
seed: 0,
|
|
25
|
-
transforms: {
|
|
26
|
-
renameIdentifiers: true,
|
|
27
|
-
},
|
|
28
|
-
})
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
`obfuscate(code, options?)` is synchronous. It does not execute the input or write files.
|
|
32
|
-
|
|
33
|
-
Configurable transforms are disabled by default; preparation passes always run.
|
|
34
|
-
|
|
35
|
-
## Documentation
|
|
36
|
-
|
|
37
|
-
- [Quickstart](https://webfuscator.mintlify.app/getting-started/quickstart)
|
|
38
|
-
- [JavaScript API](https://webfuscator.mintlify.app/reference/api)
|
|
39
|
-
- [Configure transforms](https://webfuscator.mintlify.app/guides/configure-transforms)
|
|
40
|
-
- [Obfuscator options](https://webfuscator.mintlify.app/reference/options)
|
|
41
|
-
- [Property mangling](https://webfuscator.mintlify.app/reference/property-mangling-options)
|
|
42
|
-
- [String generator modes](https://webfuscator.mintlify.app/reference/string-generator-modes)
|
|
43
|
-
- [Report a bug](https://webfuscator.mintlify.app/troubleshooting/report-a-bug)
|
|
44
|
-
|
|
45
|
-
## Development
|
|
46
|
-
|
|
47
|
-
```sh
|
|
48
|
-
pnpm install
|
|
49
|
-
pnpm test
|
|
50
|
-
pnpm check
|
|
51
|
-
pnpm docs:check
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Read [AGENTS.md](./AGENTS.md) before changing transforms or analysis code.
|
|
55
|
-
|
|
56
|
-
## Responsible use
|
|
57
|
-
|
|
58
|
-
Use `webfuscator` only on software you own or are authorized to modify. Read [DISCLOSURE](./DISCLOSURE) for the project's dual-use policy.
|
|
59
|
-
|
|
60
|
-
## License
|
|
61
|
-
|
|
62
|
-
[MIT](./LICENSE)
|