expose-kit 0.9.0 → 0.10.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/README.md +288 -258
- package/dist/index.js +367 -38
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,230 +1,233 @@
|
|
|
1
|
-
# Expose Kit
|
|
2
|
-

|
|
3
|
-
[](https://discord.gg/evex)
|
|
4
|
-
|
|
5
|
-
> A universal toolkit for JavaScript deobfuscation
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## What is this?
|
|
10
|
-
|
|
11
|
-
JavaScript deobfuscation tools are everywhere.
|
|
12
|
-
But many of them are **too aggressive**, rewriting code until it breaks.
|
|
13
|
-
|
|
14
|
-
Expose Kit takes a **different approach**.
|
|
15
|
-
|
|
16
|
-
- No brute force
|
|
17
|
-
- Step-by-step, verifiable transforms
|
|
18
|
-
- Designed to *not* break your code silently
|
|
19
|
-
|
|
20
|
-
Each transformation is meant to be **checked and validated**, so you always know *when* something goes wrong.
|
|
21
|
-
|
|
22
|
-
Alongside deobfuscation, Expose Kit also provides a set of **practical utilities** for working with obfuscated JavaScript.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Installation
|
|
27
|
-
|
|
28
|
-
Just one step:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm i -g expose-kit
|
|
32
|
-
# or
|
|
33
|
-
bun i -g expose-kit
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
```bash
|
|
37
|
-
expose --help
|
|
38
|
-
expose parsable sample.js
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
---
|
|
42
|
-
|
|
43
|
-
## Usage Notes
|
|
44
|
-
|
|
45
|
-
### Default arguments
|
|
46
|
-
|
|
47
|
-
- The first argument is the input file
|
|
48
|
-
(`--file` / `--input` can also be used)
|
|
49
|
-
- If required options are missing, Expose Kit will **prompt you**
|
|
50
|
-
- A timeout is enabled by default to avoid hangs
|
|
51
|
-
Use `--unlimited` for long-running execution
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Recommended Workflow
|
|
56
|
-
|
|
57
|
-
First, an important premise:
|
|
58
|
-
|
|
59
|
-
> It is **impossible** to create a static deobfuscation tool that *never* breaks.
|
|
60
|
-
|
|
61
|
-
Reasons include:
|
|
62
|
-
- Unpredictable execution (`eval`, dynamic code)
|
|
63
|
-
- Bugs or edge cases in AST manipulation
|
|
64
|
-
|
|
65
|
-
Because of this, you should **verify the code at every step**.
|
|
66
|
-
|
|
67
|
-
### 1. Always verify with `parsable`
|
|
68
|
-
|
|
69
|
-
After each transformation, run:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
expose parsable file.js
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
This ensures the syntax is still valid.
|
|
76
|
-
|
|
77
|
-
---
|
|
78
|
-
|
|
79
|
-
### 2. Make scopes safe first
|
|
80
|
-
|
|
81
|
-
One of the most common causes of breakage is **variable name confusion**.
|
|
82
|
-
|
|
83
|
-
If you try to write your own deobfuscation logic (e.g. in Python), you’ll quickly realize how painful it is to track scopes correctly.
|
|
84
|
-
|
|
85
|
-
That’s why you should **always start with**:
|
|
86
|
-
|
|
87
|
-
```bash
|
|
88
|
-
expose safe-scope input.js
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
This renames bindings per scope, producing code like:
|
|
92
|
-
|
|
93
|
-
```js
|
|
94
|
-
Before: var x = 810;((x) => console.log(x))(114514);
|
|
95
|
-
After: var x = 810;((_x) => console.log(_x))(114514);
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
With this alone:
|
|
99
|
-
- The code becomes far more resistant to breakage
|
|
100
|
-
- Writing custom deobfuscation logic becomes much easier
|
|
101
|
-
- You no longer need to worry about scope collisions
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
### 3. Apply transforms step by step
|
|
106
|
-
|
|
107
|
-
After `safe-scope`, combine common techniques like:
|
|
108
|
-
- `expand-array`, `expand-object` and more
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
Expose Kit will also clearly indicate whether a **diff** exists, making inspection easy.
|
|
114
|
-
|
|
115
|
-
Repeat this process, and the original code will gradually reveal itself.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## Commands
|
|
120
|
-
|
|
121
|
-
### `expose parsable`
|
|
122
|
-
|
|
123
|
-
Check whether a file is syntactically valid.
|
|
124
|
-
|
|
125
|
-
```js
|
|
126
|
-
parsable: const x = 810;
|
|
127
|
-
not parsable: const ;x; == 810;
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
expose parsable path/to/file.js
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Args:
|
|
135
|
-
- Default args only
|
|
136
|
-
|
|
137
|
-
---
|
|
138
|
-
|
|
139
|
-
### `expose safe-scope`
|
|
140
|
-
|
|
141
|
-
Rename bindings per scope for safer transformations.
|
|
142
|
-
|
|
143
|
-
```bash
|
|
144
|
-
expose safe-scope path/to/file.js --output path/to/file.safe-scope.js
|
|
145
|
-
```
|
|
146
|
-
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/safe-scope/mocks).
|
|
147
|
-
|
|
148
|
-
Args:
|
|
149
|
-
- `--o, --output <file>`
|
|
150
|
-
Output file path
|
|
151
|
-
- No extension → `file.safe-scope.js`
|
|
152
|
-
- With extension → `file.safe-scope.<ext>`
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
### `expose pre-evaluate`
|
|
157
|
-
|
|
158
|
-
Pre-evaluate const numeric/string expressions. (Safe evaluate)
|
|
159
|
-
|
|
160
|
-
```js
|
|
161
|
-
const a = 1 + 2 * 3; // => 7
|
|
162
|
-
const c = "aaaa";
|
|
163
|
-
const b = "a" + c; // => "aaaaa"
|
|
164
|
-
```
|
|
165
|
-
|
|
166
|
-
```bash
|
|
167
|
-
expose pre-evaluate path/to/file.js --output path/to/file.pre-evaluate.js
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Args:
|
|
171
|
-
- `--o, --output <file>`
|
|
172
|
-
Output file path
|
|
173
|
-
- No extension → `file.pre-evaluate.js`
|
|
174
|
-
- With extension → `file.pre-evaluate.<ext>`
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
```
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
1
|
+
# Expose Kit
|
|
2
|
+

|
|
3
|
+
[](https://discord.gg/evex)
|
|
4
|
+
|
|
5
|
+
> A universal toolkit for JavaScript deobfuscation
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## What is this?
|
|
10
|
+
|
|
11
|
+
JavaScript deobfuscation tools are everywhere.
|
|
12
|
+
But many of them are **too aggressive**, rewriting code until it breaks.
|
|
13
|
+
|
|
14
|
+
Expose Kit takes a **different approach**.
|
|
15
|
+
|
|
16
|
+
- No brute force
|
|
17
|
+
- Step-by-step, verifiable transforms
|
|
18
|
+
- Designed to *not* break your code silently
|
|
19
|
+
|
|
20
|
+
Each transformation is meant to be **checked and validated**, so you always know *when* something goes wrong.
|
|
21
|
+
|
|
22
|
+
Alongside deobfuscation, Expose Kit also provides a set of **practical utilities** for working with obfuscated JavaScript.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Just one step:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
npm i -g expose-kit
|
|
32
|
+
# or
|
|
33
|
+
bun i -g expose-kit
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
expose --help
|
|
38
|
+
expose parsable sample.js
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Usage Notes
|
|
44
|
+
|
|
45
|
+
### Default arguments
|
|
46
|
+
|
|
47
|
+
- The first argument is the input file
|
|
48
|
+
(`--file` / `--input` can also be used)
|
|
49
|
+
- If required options are missing, Expose Kit will **prompt you**
|
|
50
|
+
- A timeout is enabled by default to avoid hangs
|
|
51
|
+
Use `--unlimited` for long-running execution
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Recommended Workflow
|
|
56
|
+
|
|
57
|
+
First, an important premise:
|
|
58
|
+
|
|
59
|
+
> It is **impossible** to create a static deobfuscation tool that *never* breaks.
|
|
60
|
+
|
|
61
|
+
Reasons include:
|
|
62
|
+
- Unpredictable execution (`eval`, dynamic code)
|
|
63
|
+
- Bugs or edge cases in AST manipulation
|
|
64
|
+
|
|
65
|
+
Because of this, you should **verify the code at every step**.
|
|
66
|
+
|
|
67
|
+
### 1. Always verify with `parsable`
|
|
68
|
+
|
|
69
|
+
After each transformation, run:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
expose parsable file.js
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
This ensures the syntax is still valid.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### 2. Make scopes safe first
|
|
80
|
+
|
|
81
|
+
One of the most common causes of breakage is **variable name confusion**.
|
|
82
|
+
|
|
83
|
+
If you try to write your own deobfuscation logic (e.g. in Python), you’ll quickly realize how painful it is to track scopes correctly.
|
|
84
|
+
|
|
85
|
+
That’s why you should **always start with**:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
expose safe-scope input.js
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
This renames bindings per scope, producing code like:
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
Before: var x = 810;((x) => console.log(x))(114514);
|
|
95
|
+
After: var x = 810;((_x) => console.log(_x))(114514);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
With this alone:
|
|
99
|
+
- The code becomes far more resistant to breakage
|
|
100
|
+
- Writing custom deobfuscation logic becomes much easier
|
|
101
|
+
- You no longer need to worry about scope collisions
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### 3. Apply transforms step by step
|
|
106
|
+
|
|
107
|
+
After `safe-scope`, combine common techniques like:
|
|
108
|
+
- `expand-array`, `expand-object` and more
|
|
109
|
+
|
|
110
|
+
After **each step**, run `parsable` and `remove-unused` again.
|
|
111
|
+
(even if it's not frequent, we might overlook something broken)
|
|
112
|
+
|
|
113
|
+
Expose Kit will also clearly indicate whether a **diff** exists, making inspection easy.
|
|
114
|
+
|
|
115
|
+
Repeat this process, and the original code will gradually reveal itself.
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Commands
|
|
120
|
+
|
|
121
|
+
### `expose parsable`
|
|
122
|
+
|
|
123
|
+
Check whether a file is syntactically valid.
|
|
124
|
+
|
|
125
|
+
```js
|
|
126
|
+
parsable: const x = 810;
|
|
127
|
+
not parsable: const ;x; == 810;
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
expose parsable path/to/file.js
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
- Default args only
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
### `expose safe-scope`
|
|
140
|
+
|
|
141
|
+
Rename bindings per scope for safer transformations.
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
expose safe-scope path/to/file.js --output path/to/file.safe-scope.js
|
|
145
|
+
```
|
|
146
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/safe-scope/mocks).
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
- `--o, --output <file>`
|
|
150
|
+
Output file path
|
|
151
|
+
- No extension → `file.safe-scope.js`
|
|
152
|
+
- With extension → `file.safe-scope.<ext>`
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
### `expose pre-evaluate`
|
|
157
|
+
|
|
158
|
+
Pre-evaluate const numeric/string expressions. (Safe evaluate)
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
const a = 1 + 2 * 3; // => 7
|
|
162
|
+
const c = "aaaa";
|
|
163
|
+
const b = "a" + c; // => "aaaaa"
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
expose pre-evaluate path/to/file.js --output path/to/file.pre-evaluate.js
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
- `--o, --output <file>`
|
|
172
|
+
Output file path
|
|
173
|
+
- No extension → `file.pre-evaluate.js`
|
|
174
|
+
- With extension → `file.pre-evaluate.<ext>`
|
|
175
|
+
|
|
176
|
+
Notes:
|
|
177
|
+
- Inlines zero-arg functions that return safe array literals by hoisting them to a var.
|
|
178
|
+
|
|
179
|
+
---
|
|
180
|
+
|
|
181
|
+
### `expose expand-array`
|
|
182
|
+
|
|
183
|
+
Expand array index access for primitive values.
|
|
184
|
+
```js
|
|
185
|
+
var a = [1, 1, 4, 5, 1, 4];
|
|
186
|
+
// before
|
|
187
|
+
console.log(a[0], a[2], a[3]);
|
|
188
|
+
// after
|
|
189
|
+
console.log(1, 4, 5);
|
|
190
|
+
```
|
|
191
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-array/mocks).
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
expose expand-array path/to/file.js --target arrayName --output path/to/file.expand-array.js
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
- `--target <name>`
|
|
199
|
+
Target array variable name
|
|
200
|
+
- `--o, --output <file>`
|
|
201
|
+
Output file path
|
|
202
|
+
|
|
203
|
+
Notes:
|
|
204
|
+
- Each replacement is validated by reparsing; unsafe replacements are skipped.
|
|
205
|
+
(This array is intended to be immutable, so caution is required)
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
206
209
|
### `expose expand-object`
|
|
207
|
-
|
|
208
|
-
Expand object property access for primitive values.
|
|
209
|
-
```js
|
|
210
|
-
const obj = { a: 1, b: 2 };
|
|
211
|
-
// before
|
|
212
|
-
console.log(obj.a, obj["b"]);
|
|
213
|
-
// after
|
|
214
|
-
console.log(1, 2);
|
|
215
|
-
```
|
|
216
|
-
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-object/mocks).
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
expose expand-object path/to/file.js --target objectName --output path/to/file.expand-object.js
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
Args:
|
|
223
|
-
- `--target <name>`
|
|
224
|
-
Target object variable name
|
|
225
|
-
- `--o, --output <file>`
|
|
226
|
-
Output file path
|
|
227
|
-
|
|
210
|
+
|
|
211
|
+
Expand object property access for primitive values.
|
|
212
|
+
```js
|
|
213
|
+
const obj = { a: 1, b: 2 };
|
|
214
|
+
// before
|
|
215
|
+
console.log(obj.a, obj["b"]);
|
|
216
|
+
// after
|
|
217
|
+
console.log(1, 2);
|
|
218
|
+
```
|
|
219
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-object/mocks).
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
expose expand-object path/to/file.js --target objectName --output path/to/file.expand-object.js
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
- `--target <name>`
|
|
227
|
+
Target object variable name
|
|
228
|
+
- `--o, --output <file>`
|
|
229
|
+
Output file path
|
|
230
|
+
|
|
228
231
|
Notes:
|
|
229
232
|
- Each replacement is validated by reparsing; unsafe replacements are skipped.
|
|
230
233
|
(This object is intended to be immutable, so caution is required)
|
|
@@ -346,38 +349,65 @@ Notes:
|
|
|
346
349
|
|
|
347
350
|
---
|
|
348
351
|
|
|
352
|
+
### `expose sequence-split`
|
|
353
|
+
|
|
354
|
+
Split sequence expressions into statements.
|
|
355
|
+
```js
|
|
356
|
+
// before
|
|
357
|
+
a, b, c;
|
|
358
|
+
// after
|
|
359
|
+
a;
|
|
360
|
+
b;
|
|
361
|
+
c;
|
|
362
|
+
```
|
|
363
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/sequence-split/mocks).
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
expose sequence-split path/to/file.js --output path/to/file.sequence-split.js
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Args:
|
|
370
|
+
- `--o, --output <file>`
|
|
371
|
+
Output file path
|
|
372
|
+
|
|
373
|
+
Notes:
|
|
374
|
+
- Splits safe sequence expressions into standalone statements.
|
|
375
|
+
- Also normalizes single-statement control flow blocks.
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
349
379
|
### `expose remove-unused`
|
|
350
380
|
|
|
351
381
|
Remove unused variabless.
|
|
352
|
-
```js
|
|
353
|
-
// before
|
|
354
|
-
var a = 0, b = 1;
|
|
355
|
-
console.log(a);
|
|
356
|
-
// after
|
|
357
|
-
var a = 0;
|
|
358
|
-
console.log(a);
|
|
359
|
-
```
|
|
360
|
-
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-unused/mocks).
|
|
361
|
-
|
|
362
|
-
```bash
|
|
363
|
-
expose remove-unused path/to/file.js --output path/to/file.remove-unused.js
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
Args:
|
|
367
|
-
- `--o, --output <file>`
|
|
368
|
-
Output file path
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
## Community & Support
|
|
372
|
-
|
|
373
|
-
- Missing a feature? → [Create an issue](https://github.com/EdamAme-x/expose-kit/issues)
|
|
374
|
-
- Not sure which command to use? → Join our [Discord](https://evex.land)
|
|
375
|
-
|
|
376
|
-
---
|
|
377
|
-
|
|
378
|
-
## Author
|
|
379
|
-
|
|
380
|
-
- [EdamAme-x](https://github.com/EdamAme-x)
|
|
381
|
-
|
|
382
|
-
Built for research, not abuse.
|
|
383
|
-
Want stronger obfuscation? Then build something this tool can’t reverse.
|
|
382
|
+
```js
|
|
383
|
+
// before
|
|
384
|
+
var a = 0, b = 1;
|
|
385
|
+
console.log(a);
|
|
386
|
+
// after
|
|
387
|
+
var a = 0;
|
|
388
|
+
console.log(a);
|
|
389
|
+
```
|
|
390
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-unused/mocks).
|
|
391
|
+
|
|
392
|
+
```bash
|
|
393
|
+
expose remove-unused path/to/file.js --output path/to/file.remove-unused.js
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
Args:
|
|
397
|
+
- `--o, --output <file>`
|
|
398
|
+
Output file path
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
## Community & Support
|
|
402
|
+
|
|
403
|
+
- Missing a feature? → [Create an issue](https://github.com/EdamAme-x/expose-kit/issues)
|
|
404
|
+
- Not sure which command to use? → Join our [Discord](https://evex.land)
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Author
|
|
409
|
+
|
|
410
|
+
- [EdamAme-x](https://github.com/EdamAme-x)
|
|
411
|
+
|
|
412
|
+
Built for research, not abuse.
|
|
413
|
+
Want stronger obfuscation? Then build something this tool can’t reverse.
|
package/dist/index.js
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
// index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { dirname as
|
|
5
|
+
import { dirname as dirname11, join as join11 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import chalk4 from "chalk";
|
|
8
8
|
|
|
9
9
|
// utils/cli/createCommand.ts
|
|
10
10
|
var createCommand = (creator) => {
|
|
11
|
-
return (
|
|
12
|
-
creator(
|
|
11
|
+
return (program3) => {
|
|
12
|
+
creator(program3);
|
|
13
13
|
};
|
|
14
14
|
};
|
|
15
15
|
|
|
@@ -85,8 +85,8 @@ var showError = (message) => {
|
|
|
85
85
|
};
|
|
86
86
|
|
|
87
87
|
// commands/parsable/index.ts
|
|
88
|
-
var parsable_default = createCommand((
|
|
89
|
-
|
|
88
|
+
var parsable_default = createCommand((program3) => {
|
|
89
|
+
program3.command("parsable").description("Check if the file is parsable").argument("[file]", "The file to check").option("--input, --file <file>", "The file to check").option("--unlimited", "Unlimited timeout").action(
|
|
90
90
|
async (fileArgument, options) => {
|
|
91
91
|
await timeout(
|
|
92
92
|
async ({ finish }) => {
|
|
@@ -215,8 +215,8 @@ var renameBindingsByScope = (code, filename) => {
|
|
|
215
215
|
});
|
|
216
216
|
return patchDefault(generate)(ast).code;
|
|
217
217
|
};
|
|
218
|
-
var safe_scope_default = createCommand((
|
|
219
|
-
|
|
218
|
+
var safe_scope_default = createCommand((program3) => {
|
|
219
|
+
program3.command("safe-scope").description("Rename bindings per scope for safer transforms").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
220
220
|
async (fileArgument, options) => {
|
|
221
221
|
await timeout(
|
|
222
222
|
async ({ finish }) => {
|
|
@@ -450,8 +450,8 @@ var expandArrayAccess = async (code, filename, targetName) => {
|
|
|
450
450
|
replacedCount
|
|
451
451
|
};
|
|
452
452
|
};
|
|
453
|
-
var expand_array_default = createCommand((
|
|
454
|
-
|
|
453
|
+
var expand_array_default = createCommand((program3) => {
|
|
454
|
+
program3.command("expand-array").description("Expand array index access for primitive values").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--target <name>", "Target array variable name").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
455
455
|
async (fileArgument, options) => {
|
|
456
456
|
await timeout(
|
|
457
457
|
async ({ finish }) => {
|
|
@@ -721,8 +721,8 @@ var expandObjectAccess = async (code, filename, targetName) => {
|
|
|
721
721
|
replacedCount
|
|
722
722
|
};
|
|
723
723
|
};
|
|
724
|
-
var expand_object_default = createCommand((
|
|
725
|
-
|
|
724
|
+
var expand_object_default = createCommand((program3) => {
|
|
725
|
+
program3.command("expand-object").description("Expand object property access for primitive values").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--target <name>", "Target object variable name").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
726
726
|
async (fileArgument, options) => {
|
|
727
727
|
await timeout(
|
|
728
728
|
async ({ finish }) => {
|
|
@@ -908,8 +908,8 @@ var packObjectProperties = (code, filename) => {
|
|
|
908
908
|
removedStatements
|
|
909
909
|
};
|
|
910
910
|
};
|
|
911
|
-
var object_packer_default = createCommand((
|
|
912
|
-
|
|
911
|
+
var object_packer_default = createCommand((program3) => {
|
|
912
|
+
program3.command("object-packer").description("Pack consecutive object property assignments into literals").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
913
913
|
async (fileArgument, options) => {
|
|
914
914
|
await timeout(
|
|
915
915
|
async ({ finish }) => {
|
|
@@ -1105,6 +1105,108 @@ var shouldSkipReferencedIdentifier = (path) => {
|
|
|
1105
1105
|
}
|
|
1106
1106
|
return false;
|
|
1107
1107
|
};
|
|
1108
|
+
var getArrayReturnExpression = (node) => {
|
|
1109
|
+
if (node.params.length !== 0) return null;
|
|
1110
|
+
if (t4.isBlockStatement(node.body)) {
|
|
1111
|
+
if (node.body.body.length !== 1) return null;
|
|
1112
|
+
const statement = node.body.body[0];
|
|
1113
|
+
if (!t4.isReturnStatement(statement) || !statement.argument) return null;
|
|
1114
|
+
return t4.isArrayExpression(statement.argument) ? statement.argument : null;
|
|
1115
|
+
}
|
|
1116
|
+
return t4.isArrayExpression(node.body) ? node.body : null;
|
|
1117
|
+
};
|
|
1118
|
+
var isSafeArrayElement = (node) => {
|
|
1119
|
+
if (!node) return true;
|
|
1120
|
+
if (t4.isNumericLiteral(node) || t4.isStringLiteral(node) || t4.isBooleanLiteral(node) || t4.isNullLiteral(node)) {
|
|
1121
|
+
return true;
|
|
1122
|
+
}
|
|
1123
|
+
if (t4.isUnaryExpression(node) && (node.operator === "-" || node.operator === "+") && t4.isNumericLiteral(node.argument)) {
|
|
1124
|
+
return true;
|
|
1125
|
+
}
|
|
1126
|
+
if (t4.isArrayExpression(node)) {
|
|
1127
|
+
return node.elements.every((element) => {
|
|
1128
|
+
if (element === null) return true;
|
|
1129
|
+
if (t4.isSpreadElement(element)) return false;
|
|
1130
|
+
return isSafeArrayElement(element);
|
|
1131
|
+
});
|
|
1132
|
+
}
|
|
1133
|
+
return false;
|
|
1134
|
+
};
|
|
1135
|
+
var isSafeArrayExpression = (node) => {
|
|
1136
|
+
return node.elements.every((element) => {
|
|
1137
|
+
if (element === null) return true;
|
|
1138
|
+
if (t4.isSpreadElement(element)) return false;
|
|
1139
|
+
return isSafeArrayElement(element);
|
|
1140
|
+
});
|
|
1141
|
+
};
|
|
1142
|
+
var collectArrayReturnFunctions = (ast) => {
|
|
1143
|
+
const results = [];
|
|
1144
|
+
let counter = 0;
|
|
1145
|
+
patchDefault(traverse5)(ast, {
|
|
1146
|
+
FunctionDeclaration(path) {
|
|
1147
|
+
if (!path.node.id) return;
|
|
1148
|
+
const arrayExpression = getArrayReturnExpression(path.node);
|
|
1149
|
+
if (!arrayExpression || !isSafeArrayExpression(arrayExpression)) return;
|
|
1150
|
+
const binding = path.scope.getBinding(path.node.id.name);
|
|
1151
|
+
if (!binding) return;
|
|
1152
|
+
const programScope = path.scope.getProgramParent();
|
|
1153
|
+
let replacementName = `${path.node.id.name}_${counter}`;
|
|
1154
|
+
counter += 1;
|
|
1155
|
+
while (programScope.hasBinding(replacementName)) {
|
|
1156
|
+
replacementName = `${path.node.id.name}_${counter}`;
|
|
1157
|
+
counter += 1;
|
|
1158
|
+
}
|
|
1159
|
+
results.push({
|
|
1160
|
+
binding,
|
|
1161
|
+
arrayNode: arrayExpression,
|
|
1162
|
+
replacementName,
|
|
1163
|
+
used: false
|
|
1164
|
+
});
|
|
1165
|
+
},
|
|
1166
|
+
VariableDeclarator(path) {
|
|
1167
|
+
if (!t4.isIdentifier(path.node.id)) return;
|
|
1168
|
+
const init = path.node.init;
|
|
1169
|
+
if (!init || !t4.isFunctionExpression(init) && !t4.isArrowFunctionExpression(init)) {
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
|
+
const arrayExpression = getArrayReturnExpression(init);
|
|
1173
|
+
if (!arrayExpression || !isSafeArrayExpression(arrayExpression)) return;
|
|
1174
|
+
const binding = path.scope.getBinding(path.node.id.name);
|
|
1175
|
+
if (!binding || !binding.constant || binding.kind !== "const") return;
|
|
1176
|
+
const programScope = path.scope.getProgramParent();
|
|
1177
|
+
let replacementName = `${path.node.id.name}_${counter}`;
|
|
1178
|
+
counter += 1;
|
|
1179
|
+
while (programScope.hasBinding(replacementName)) {
|
|
1180
|
+
replacementName = `${path.node.id.name}_${counter}`;
|
|
1181
|
+
counter += 1;
|
|
1182
|
+
}
|
|
1183
|
+
results.push({
|
|
1184
|
+
binding,
|
|
1185
|
+
arrayNode: arrayExpression,
|
|
1186
|
+
replacementName,
|
|
1187
|
+
used: false
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
});
|
|
1191
|
+
return results;
|
|
1192
|
+
};
|
|
1193
|
+
var insertArrayReturnDeclarations = (ast, functions) => {
|
|
1194
|
+
const declarations = functions.filter((info) => info.used).map(
|
|
1195
|
+
(info) => t4.variableDeclaration("var", [
|
|
1196
|
+
t4.variableDeclarator(
|
|
1197
|
+
t4.identifier(info.replacementName),
|
|
1198
|
+
t4.cloneNode(info.arrayNode, true)
|
|
1199
|
+
)
|
|
1200
|
+
])
|
|
1201
|
+
);
|
|
1202
|
+
if (declarations.length === 0) return;
|
|
1203
|
+
const body = ast.program.body;
|
|
1204
|
+
let insertIndex = 0;
|
|
1205
|
+
while (insertIndex < body.length && t4.isExpressionStatement(body[insertIndex]) && "directive" in (body[insertIndex] || {})) {
|
|
1206
|
+
insertIndex += 1;
|
|
1207
|
+
}
|
|
1208
|
+
body.splice(insertIndex, 0, ...declarations);
|
|
1209
|
+
};
|
|
1108
1210
|
var preEvaluate = (code, filename) => {
|
|
1109
1211
|
const ast = parse6(code, createParseOptions(filename));
|
|
1110
1212
|
const state = {
|
|
@@ -1112,7 +1214,23 @@ var preEvaluate = (code, filename) => {
|
|
|
1112
1214
|
bindingStack: /* @__PURE__ */ new Set()
|
|
1113
1215
|
};
|
|
1114
1216
|
let replacedCount = 0;
|
|
1217
|
+
const arrayReturnFunctions = collectArrayReturnFunctions(ast);
|
|
1218
|
+
const arrayReturnMap = /* @__PURE__ */ new Map();
|
|
1219
|
+
for (const info of arrayReturnFunctions) {
|
|
1220
|
+
arrayReturnMap.set(info.binding, info);
|
|
1221
|
+
}
|
|
1115
1222
|
patchDefault(traverse5)(ast, {
|
|
1223
|
+
CallExpression(path) {
|
|
1224
|
+
if (!t4.isIdentifier(path.node.callee)) return;
|
|
1225
|
+
if (path.node.arguments.length !== 0) return;
|
|
1226
|
+
const binding = path.scope.getBinding(path.node.callee.name);
|
|
1227
|
+
if (!binding) return;
|
|
1228
|
+
const info = arrayReturnMap.get(binding);
|
|
1229
|
+
if (!info) return;
|
|
1230
|
+
path.replaceWith(t4.identifier(info.replacementName));
|
|
1231
|
+
info.used = true;
|
|
1232
|
+
replacedCount += 1;
|
|
1233
|
+
},
|
|
1116
1234
|
ReferencedIdentifier(path) {
|
|
1117
1235
|
if (shouldSkipReferencedIdentifier(path)) {
|
|
1118
1236
|
return;
|
|
@@ -1163,13 +1281,14 @@ var preEvaluate = (code, filename) => {
|
|
|
1163
1281
|
}
|
|
1164
1282
|
}
|
|
1165
1283
|
});
|
|
1284
|
+
insertArrayReturnDeclarations(ast, arrayReturnFunctions);
|
|
1166
1285
|
return {
|
|
1167
1286
|
code: patchDefault(generate5)(ast).code,
|
|
1168
1287
|
replacedCount
|
|
1169
1288
|
};
|
|
1170
1289
|
};
|
|
1171
|
-
var pre_evaluate_default = createCommand((
|
|
1172
|
-
|
|
1290
|
+
var pre_evaluate_default = createCommand((program3) => {
|
|
1291
|
+
program3.command("pre-evaluate").description("Pre-evaluate const numeric/string expressions").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
1173
1292
|
async (fileArgument, options) => {
|
|
1174
1293
|
await timeout(
|
|
1175
1294
|
async ({ finish }) => {
|
|
@@ -1262,8 +1381,8 @@ var removeUpdaters = (code, filename) => {
|
|
|
1262
1381
|
replacedCount
|
|
1263
1382
|
};
|
|
1264
1383
|
};
|
|
1265
|
-
var remove_updater_default = createCommand((
|
|
1266
|
-
|
|
1384
|
+
var remove_updater_default = createCommand((program3) => {
|
|
1385
|
+
program3.command("remove-updater").description("Replace safe update expressions with += or -=").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
1267
1386
|
async (fileArgument, options) => {
|
|
1268
1387
|
await timeout(
|
|
1269
1388
|
async ({ finish }) => {
|
|
@@ -1505,8 +1624,8 @@ var removeReassign = (code, filename) => {
|
|
|
1505
1624
|
wrapperReplacedCount
|
|
1506
1625
|
};
|
|
1507
1626
|
};
|
|
1508
|
-
var remove_reassign_default = createCommand((
|
|
1509
|
-
|
|
1627
|
+
var remove_reassign_default = createCommand((program3) => {
|
|
1628
|
+
program3.command("remove-reassign").description("Inline safe alias assignments and wrapper calls").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
1510
1629
|
async (fileArgument, options) => {
|
|
1511
1630
|
await timeout(
|
|
1512
1631
|
async ({ finish }) => {
|
|
@@ -1611,8 +1730,8 @@ var removeUnusedVariables = (code, filename) => {
|
|
|
1611
1730
|
changed
|
|
1612
1731
|
};
|
|
1613
1732
|
};
|
|
1614
|
-
var remove_unused_default = createCommand((
|
|
1615
|
-
|
|
1733
|
+
var remove_unused_default = createCommand((program3) => {
|
|
1734
|
+
program3.command("remove-unused").description("Remove unused variables and declarations").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
1616
1735
|
async (fileArgument, options) => {
|
|
1617
1736
|
await timeout(
|
|
1618
1737
|
async ({ finish }) => {
|
|
@@ -1682,11 +1801,15 @@ var isProxyFunctionExpression = (node) => {
|
|
|
1682
1801
|
return t8.isFunction(node) && node.params.every((param) => t8.isIdentifier(param)) && (t8.isBlockStatement(node.body) && node.body.body.length === 1 && t8.isReturnStatement(node.body.body[0]) && (node.body.body[0].argument === void 0 || t8.isExpression(node.body.body[0].argument) && isProxyValue(node.body.body[0].argument)) || t8.isArrowFunctionExpression(node) && t8.isExpression(node.body) && isProxyValue(node.body));
|
|
1683
1802
|
};
|
|
1684
1803
|
var isProxyValue = (node) => {
|
|
1685
|
-
if (t8.isFunction(node) || t8.isBlockStatement(node) || t8.isSequenceExpression(node)) {
|
|
1804
|
+
if (t8.isFunction(node) || t8.isBlockStatement(node) || t8.isSequenceExpression(node) || t8.isAssignmentExpression(node)) {
|
|
1686
1805
|
return false;
|
|
1687
1806
|
}
|
|
1688
1807
|
let isValid = true;
|
|
1689
|
-
|
|
1808
|
+
if (!t8.isExpression(node)) {
|
|
1809
|
+
return false;
|
|
1810
|
+
}
|
|
1811
|
+
const wrapper = t8.file(t8.program([t8.expressionStatement(node)]));
|
|
1812
|
+
walk(wrapper, {
|
|
1690
1813
|
"SequenceExpression|BlockStatement|Function|AssignmentExpression"(path) {
|
|
1691
1814
|
isValid = false;
|
|
1692
1815
|
path.stop();
|
|
@@ -1716,9 +1839,31 @@ var ProxyFunction = class {
|
|
|
1716
1839
|
])
|
|
1717
1840
|
);
|
|
1718
1841
|
const pathsToReplace = [];
|
|
1719
|
-
|
|
1842
|
+
const shouldSkipIdentifier = (path) => {
|
|
1843
|
+
const parent = path.parentPath;
|
|
1844
|
+
if (!parent) return false;
|
|
1845
|
+
if (parent.isMemberExpression() || parent.isOptionalMemberExpression()) {
|
|
1846
|
+
if (path.key === "property" && !parent.node.computed) {
|
|
1847
|
+
return true;
|
|
1848
|
+
}
|
|
1849
|
+
}
|
|
1850
|
+
if (parent.isObjectProperty()) {
|
|
1851
|
+
if (parent.node.shorthand) return true;
|
|
1852
|
+
if (parent.get("key") === path && !parent.node.computed) {
|
|
1853
|
+
return true;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
if (parent.isObjectMethod()) {
|
|
1857
|
+
if (parent.get("key") === path && !parent.node.computed) {
|
|
1858
|
+
return true;
|
|
1859
|
+
}
|
|
1860
|
+
}
|
|
1861
|
+
return false;
|
|
1862
|
+
};
|
|
1863
|
+
const wrapper = t8.file(t8.program([t8.expressionStatement(expression)]));
|
|
1864
|
+
walk(wrapper, {
|
|
1720
1865
|
enter(path) {
|
|
1721
|
-
if (t8.isIdentifier(path.node) && !(path
|
|
1866
|
+
if (t8.isIdentifier(path.node) && !shouldSkipIdentifier(path) && paramMap.has(path.node.name)) {
|
|
1722
1867
|
const replacement = paramMap.get(path.node.name);
|
|
1723
1868
|
pathsToReplace.push([path, replacement]);
|
|
1724
1869
|
}
|
|
@@ -1794,8 +1939,8 @@ var inlineProxyFunctions = (code, filename) => {
|
|
|
1794
1939
|
replacedCount
|
|
1795
1940
|
};
|
|
1796
1941
|
};
|
|
1797
|
-
var fn_inliner_default = createCommand((
|
|
1798
|
-
|
|
1942
|
+
var fn_inliner_default = createCommand((program3) => {
|
|
1943
|
+
program3.command("fn-inliner").description("Inline proxy function calls into expressions").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
1799
1944
|
async (fileArgument, options) => {
|
|
1800
1945
|
await timeout(
|
|
1801
1946
|
async ({ finish }) => {
|
|
@@ -1843,6 +1988,189 @@ var fn_inliner_default = createCommand((program2) => {
|
|
|
1843
1988
|
);
|
|
1844
1989
|
});
|
|
1845
1990
|
|
|
1991
|
+
// commands/sequence-split/index.ts
|
|
1992
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync10 } from "fs";
|
|
1993
|
+
import { basename as basename10, dirname as dirname10, extname as extname10, join as join10 } from "path";
|
|
1994
|
+
import { parse as parse11 } from "@babel/parser";
|
|
1995
|
+
import traverse10 from "@babel/traverse";
|
|
1996
|
+
import generate10 from "@babel/generator";
|
|
1997
|
+
import * as t9 from "@babel/types";
|
|
1998
|
+
import loading11 from "loading-cli";
|
|
1999
|
+
var walk2 = patchDefault(traverse10);
|
|
2000
|
+
var createDefaultOutputPath10 = (inputPath) => {
|
|
2001
|
+
const ext = extname10(inputPath);
|
|
2002
|
+
if (!ext) {
|
|
2003
|
+
return `${inputPath}.sequence-split.js`;
|
|
2004
|
+
}
|
|
2005
|
+
const base = basename10(inputPath, ext);
|
|
2006
|
+
return join10(dirname10(inputPath), `${base}.sequence-split${ext}`);
|
|
2007
|
+
};
|
|
2008
|
+
var isExcluded = (node) => {
|
|
2009
|
+
return t9.isIdentifier(node) && node.name === "eval";
|
|
2010
|
+
};
|
|
2011
|
+
var sequenceSplit = (code, filename) => {
|
|
2012
|
+
const ast = parse11(code, createParseOptions(filename));
|
|
2013
|
+
let changedCount = 0;
|
|
2014
|
+
const markChanged = () => {
|
|
2015
|
+
changedCount += 1;
|
|
2016
|
+
};
|
|
2017
|
+
walk2(ast, {
|
|
2018
|
+
ConditionalExpression(path) {
|
|
2019
|
+
if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
|
|
2020
|
+
const replacement = t9.ifStatement(
|
|
2021
|
+
path.node.test,
|
|
2022
|
+
t9.expressionStatement(path.node.consequent),
|
|
2023
|
+
t9.expressionStatement(path.node.alternate)
|
|
2024
|
+
);
|
|
2025
|
+
if (path.parentPath.parentPath && path.parentPath.parentPath.key === "alternate" && path.parentPath.parentPath.isBlockStatement() && path.parentPath.parentPath.node.body.length === 1) {
|
|
2026
|
+
path.parentPath.parentPath.replaceWith(replacement);
|
|
2027
|
+
} else {
|
|
2028
|
+
path.parentPath.replaceWith(replacement);
|
|
2029
|
+
}
|
|
2030
|
+
path.skip();
|
|
2031
|
+
markChanged();
|
|
2032
|
+
},
|
|
2033
|
+
LogicalExpression(path) {
|
|
2034
|
+
if (!path.parentPath || !path.parentPath.isExpressionStatement()) return;
|
|
2035
|
+
if (path.node.operator !== "&&" && path.node.operator !== "||") return;
|
|
2036
|
+
const test = path.node.operator === "&&" ? path.node.left : t9.unaryExpression("!", path.node.left);
|
|
2037
|
+
const replacement = t9.ifStatement(
|
|
2038
|
+
test,
|
|
2039
|
+
t9.expressionStatement(path.node.right)
|
|
2040
|
+
);
|
|
2041
|
+
if (path.parentPath.parentPath && path.parentPath.parentPath.key === "alternate" && path.parentPath.parentPath.isBlockStatement() && path.parentPath.parentPath.node.body.length === 1) {
|
|
2042
|
+
path.parentPath.parentPath.replaceWith(replacement);
|
|
2043
|
+
} else {
|
|
2044
|
+
path.parentPath.replaceWith(replacement);
|
|
2045
|
+
}
|
|
2046
|
+
path.skip();
|
|
2047
|
+
markChanged();
|
|
2048
|
+
},
|
|
2049
|
+
"ForStatement|WhileStatement|DoWhileStatement"(path) {
|
|
2050
|
+
if (!path.isForStatement() && !path.isWhileStatement() && !path.isDoWhileStatement()) return;
|
|
2051
|
+
if (t9.isBlockStatement(path.node.body)) return;
|
|
2052
|
+
path.node.body = t9.blockStatement([path.node.body]);
|
|
2053
|
+
markChanged();
|
|
2054
|
+
},
|
|
2055
|
+
IfStatement(path) {
|
|
2056
|
+
if (!t9.isBlockStatement(path.node.consequent)) {
|
|
2057
|
+
path.node.consequent = t9.blockStatement([path.node.consequent]);
|
|
2058
|
+
markChanged();
|
|
2059
|
+
}
|
|
2060
|
+
if (path.node.alternate && !t9.isBlockStatement(path.node.alternate) && !t9.isIfStatement(path.node.alternate)) {
|
|
2061
|
+
path.node.alternate = t9.blockStatement([path.node.alternate]);
|
|
2062
|
+
markChanged();
|
|
2063
|
+
}
|
|
2064
|
+
},
|
|
2065
|
+
VariableDeclaration(path) {
|
|
2066
|
+
if (path.node.declarations.length <= 1) return;
|
|
2067
|
+
const replacements = path.node.declarations.map(
|
|
2068
|
+
(declaration) => t9.variableDeclaration(path.node.kind, [declaration])
|
|
2069
|
+
);
|
|
2070
|
+
if (path.parentPath?.isForStatement() && path.parentKey === "init") {
|
|
2071
|
+
const lastDeclaration = replacements.pop();
|
|
2072
|
+
if (lastDeclaration) {
|
|
2073
|
+
path.parentPath.insertBefore(replacements);
|
|
2074
|
+
path.parentPath.node.init = lastDeclaration;
|
|
2075
|
+
}
|
|
2076
|
+
} else {
|
|
2077
|
+
path.replaceWithMultiple(replacements);
|
|
2078
|
+
}
|
|
2079
|
+
markChanged();
|
|
2080
|
+
},
|
|
2081
|
+
SequenceExpression(path) {
|
|
2082
|
+
const expressions = path.node.expressions;
|
|
2083
|
+
if (expressions.length === 1 && expressions[0]) {
|
|
2084
|
+
path.replaceWith(expressions[0]);
|
|
2085
|
+
markChanged();
|
|
2086
|
+
return;
|
|
2087
|
+
}
|
|
2088
|
+
let outerPath = path;
|
|
2089
|
+
while (!t9.isStatement(outerPath.node)) {
|
|
2090
|
+
const parent = outerPath.parentPath;
|
|
2091
|
+
if (!parent) return;
|
|
2092
|
+
if (parent.isConditionalExpression() && (outerPath.key === "consequent" || outerPath.key === "alternate") || parent.isLogicalExpression() && outerPath.key === "right" || parent.isForStatement() && (outerPath.key === "test" || outerPath.key === "update") || parent.isDoWhileStatement() && outerPath.key === "test" || parent.isArrowFunctionExpression() && outerPath.key === "body") {
|
|
2093
|
+
return;
|
|
2094
|
+
}
|
|
2095
|
+
outerPath = parent;
|
|
2096
|
+
}
|
|
2097
|
+
const lastExpression = expressions[expressions.length - 1];
|
|
2098
|
+
if (lastExpression && isExcluded(lastExpression)) {
|
|
2099
|
+
const firstExpressions = expressions.splice(0, expressions.length - 2);
|
|
2100
|
+
if (firstExpressions.length > 0) {
|
|
2101
|
+
const expressionStatements = firstExpressions.map(
|
|
2102
|
+
(expression) => t9.expressionStatement(expression)
|
|
2103
|
+
);
|
|
2104
|
+
outerPath.insertBefore(expressionStatements);
|
|
2105
|
+
markChanged();
|
|
2106
|
+
}
|
|
2107
|
+
} else {
|
|
2108
|
+
const finalExpression = expressions.splice(expressions.length - 1, 1)[0];
|
|
2109
|
+
const expressionStatements = expressions.map(
|
|
2110
|
+
(expression) => t9.expressionStatement(expression)
|
|
2111
|
+
);
|
|
2112
|
+
outerPath.insertBefore(expressionStatements);
|
|
2113
|
+
if (finalExpression) {
|
|
2114
|
+
path.replaceWith(finalExpression);
|
|
2115
|
+
}
|
|
2116
|
+
markChanged();
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
});
|
|
2120
|
+
return {
|
|
2121
|
+
code: patchDefault(generate10)(ast).code,
|
|
2122
|
+
changedCount
|
|
2123
|
+
};
|
|
2124
|
+
};
|
|
2125
|
+
var sequence_split_default = createCommand((program3) => {
|
|
2126
|
+
program3.command("sequence-split").description("Split sequence expressions into statements").argument("[file]", "The file to transform").option("--input, --file <file>", "The file to transform").option("--o, --output <file>", "Output file path").option("--unlimited", "Unlimited timeout").action(
|
|
2127
|
+
async (fileArgument, options) => {
|
|
2128
|
+
await timeout(
|
|
2129
|
+
async ({ finish }) => {
|
|
2130
|
+
const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
|
|
2131
|
+
if (!filename) {
|
|
2132
|
+
showError("No file provided");
|
|
2133
|
+
return finish();
|
|
2134
|
+
}
|
|
2135
|
+
try {
|
|
2136
|
+
const fileContent = readFileSync11(filename, "utf8");
|
|
2137
|
+
const defaultOutputPath = createDefaultOutputPath10(filename);
|
|
2138
|
+
let outputPath = options.output;
|
|
2139
|
+
if (!outputPath) {
|
|
2140
|
+
const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
|
|
2141
|
+
outputPath = promptPath || defaultOutputPath;
|
|
2142
|
+
}
|
|
2143
|
+
const loader = loading11("Splitting sequences...").start();
|
|
2144
|
+
try {
|
|
2145
|
+
const { code: output, changedCount } = sequenceSplit(
|
|
2146
|
+
fileContent,
|
|
2147
|
+
filename
|
|
2148
|
+
);
|
|
2149
|
+
writeFileSync10(outputPath, output, "utf8");
|
|
2150
|
+
loader.succeed(
|
|
2151
|
+
`Saved sequence-split file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${changedCount} transforms)`
|
|
2152
|
+
);
|
|
2153
|
+
return finish();
|
|
2154
|
+
} catch (error) {
|
|
2155
|
+
loader.fail("Failed to apply sequence-split transform");
|
|
2156
|
+
showError(
|
|
2157
|
+
`Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2158
|
+
);
|
|
2159
|
+
return finish();
|
|
2160
|
+
}
|
|
2161
|
+
} catch (error) {
|
|
2162
|
+
showError(
|
|
2163
|
+
`Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
2164
|
+
);
|
|
2165
|
+
return finish();
|
|
2166
|
+
}
|
|
2167
|
+
},
|
|
2168
|
+
options.unlimited ? null : 120 * 1e3
|
|
2169
|
+
);
|
|
2170
|
+
}
|
|
2171
|
+
);
|
|
2172
|
+
});
|
|
2173
|
+
|
|
1846
2174
|
// utils/cli/showCredit.ts
|
|
1847
2175
|
import chalk3 from "chalk";
|
|
1848
2176
|
var beautify = (strings, ...values) => {
|
|
@@ -1867,10 +2195,10 @@ var calmGradienrain = (text) => {
|
|
|
1867
2195
|
const endHue = 300;
|
|
1868
2196
|
const saturation = 0.45;
|
|
1869
2197
|
const value = 0.8;
|
|
1870
|
-
const ease = (
|
|
2198
|
+
const ease = (t10) => t10 * t10 * (3 - 2 * t10);
|
|
1871
2199
|
return text.split("").map((char, i) => {
|
|
1872
|
-
const
|
|
1873
|
-
const hue = startHue + (endHue - startHue) *
|
|
2200
|
+
const t10 = ease(i / Math.max(text.length - 1, 1));
|
|
2201
|
+
const hue = startHue + (endHue - startHue) * t10;
|
|
1874
2202
|
const c = value * saturation;
|
|
1875
2203
|
const h = hue / 60;
|
|
1876
2204
|
const x = c * (1 - Math.abs(h % 2 - 1));
|
|
@@ -1894,14 +2222,14 @@ ${calmGradienrain(`Expose Kit v${VERSION}`)}
|
|
|
1894
2222
|
`;
|
|
1895
2223
|
|
|
1896
2224
|
// index.ts
|
|
1897
|
-
import { readFileSync as
|
|
2225
|
+
import { readFileSync as readFileSync12 } from "fs";
|
|
1898
2226
|
var __filename = fileURLToPath(import.meta.url);
|
|
1899
|
-
var __dirname =
|
|
1900
|
-
var pkg = JSON.parse(
|
|
2227
|
+
var __dirname = dirname11(__filename);
|
|
2228
|
+
var pkg = JSON.parse(readFileSync12(join11(__dirname, "package.json"), "utf8"));
|
|
1901
2229
|
console.log(showCredit(pkg.version));
|
|
1902
2230
|
console.log();
|
|
1903
|
-
var
|
|
1904
|
-
|
|
2231
|
+
var program2 = new Command();
|
|
2232
|
+
program2.name("expose").description("CLI for Deobfuscating").version(
|
|
1905
2233
|
chalk4.bold("It's written above, lol"),
|
|
1906
2234
|
"-v, --version",
|
|
1907
2235
|
"display version number"
|
|
@@ -1916,9 +2244,10 @@ var commands = [
|
|
|
1916
2244
|
remove_updater_default,
|
|
1917
2245
|
remove_reassign_default,
|
|
1918
2246
|
fn_inliner_default,
|
|
1919
|
-
remove_unused_default
|
|
2247
|
+
remove_unused_default,
|
|
2248
|
+
sequence_split_default
|
|
1920
2249
|
];
|
|
1921
2250
|
for (const command of commands) {
|
|
1922
|
-
command(
|
|
2251
|
+
command(program2);
|
|
1923
2252
|
}
|
|
1924
|
-
|
|
2253
|
+
program2.parse();
|
package/dist/package.json
CHANGED