expose-kit 0.3.0 → 0.4.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/README.md +53 -1
- package/dist/index.js +497 -8
- package/dist/package.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -124,7 +124,7 @@ Check whether a file is syntactically valid.
|
|
|
124
124
|
|
|
125
125
|
```js
|
|
126
126
|
parsable: const x = 810;
|
|
127
|
-
not parsable:
|
|
127
|
+
not parsable: const ;x; == 810;
|
|
128
128
|
```
|
|
129
129
|
|
|
130
130
|
```bash
|
|
@@ -143,6 +143,7 @@ Rename bindings per scope for safer transformations.
|
|
|
143
143
|
```bash
|
|
144
144
|
expose safe-scope path/to/file.js --output path/to/file.safe-scope.js
|
|
145
145
|
```
|
|
146
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/safe-scope/mocks).
|
|
146
147
|
|
|
147
148
|
Args:
|
|
148
149
|
- `--o, --output <file>`
|
|
@@ -152,6 +153,57 @@ Args:
|
|
|
152
153
|
|
|
153
154
|
---
|
|
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
|
+
### `expose expand-array`
|
|
179
|
+
|
|
180
|
+
Expand array index access for primitive values.
|
|
181
|
+
```js
|
|
182
|
+
var a = [1, 1, 4, 5, 1, 4];
|
|
183
|
+
// before
|
|
184
|
+
console.log(a[0], a[2], a[3]);
|
|
185
|
+
// after
|
|
186
|
+
console.log(1, 4, 5);
|
|
187
|
+
```
|
|
188
|
+
Example is [here](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-array/mocks).
|
|
189
|
+
|
|
190
|
+
```bash
|
|
191
|
+
expose expand-array path/to/file.js --target arrayName --output path/to/file.expand-array.js
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
- `--target <name>`
|
|
196
|
+
Target array variable name
|
|
197
|
+
- `--o, --output <file>`
|
|
198
|
+
Output file path
|
|
199
|
+
- No extension → `file.expand-array.js`
|
|
200
|
+
- With extension → `file.expand-array.<ext>`
|
|
201
|
+
|
|
202
|
+
Notes:
|
|
203
|
+
- Each replacement is validated by reparsing; invalid replacements (e.g. `++a[0]` or `a[0]++`) are skipped.-
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
155
207
|
## Community & Support
|
|
156
208
|
|
|
157
209
|
- Missing a feature? → [Create an issue](https://github.com/EdamAme-x/expose-kit/issues)
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
-
import { dirname as
|
|
5
|
+
import { dirname as dirname4, join as join4 } from "path";
|
|
6
6
|
import { fileURLToPath } from "url";
|
|
7
7
|
import chalk4 from "chalk";
|
|
8
8
|
|
|
@@ -261,6 +261,495 @@ var safe_scope_default = createCommand((program2) => {
|
|
|
261
261
|
);
|
|
262
262
|
});
|
|
263
263
|
|
|
264
|
+
// commands/expand-array/index.ts
|
|
265
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
266
|
+
import { basename as basename2, dirname as dirname2, extname as extname2, join as join2 } from "path";
|
|
267
|
+
import { parse as parse3 } from "@babel/parser";
|
|
268
|
+
import traverse2 from "@babel/traverse";
|
|
269
|
+
import generate2 from "@babel/generator";
|
|
270
|
+
import * as t from "@babel/types";
|
|
271
|
+
import loading3 from "loading-cli";
|
|
272
|
+
var createDefaultOutputPath2 = (inputPath) => {
|
|
273
|
+
const ext = extname2(inputPath);
|
|
274
|
+
if (!ext) {
|
|
275
|
+
return `${inputPath}.expand-array.js`;
|
|
276
|
+
}
|
|
277
|
+
const base = basename2(inputPath, ext);
|
|
278
|
+
return join2(dirname2(inputPath), `${base}.expand-array${ext}`);
|
|
279
|
+
};
|
|
280
|
+
var isPrimitiveArray = (arrayNode) => {
|
|
281
|
+
return arrayNode.elements.every((element) => {
|
|
282
|
+
if (!element || t.isSpreadElement(element)) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
return true;
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
var getIndexFromProperty = (property) => {
|
|
289
|
+
if (t.isNumericLiteral(property) && Number.isInteger(property.value)) {
|
|
290
|
+
return property.value;
|
|
291
|
+
}
|
|
292
|
+
if (t.isStringLiteral(property)) {
|
|
293
|
+
if (!/^-?\d+$/.test(property.value)) {
|
|
294
|
+
return null;
|
|
295
|
+
}
|
|
296
|
+
return Number.parseInt(property.value, 10);
|
|
297
|
+
}
|
|
298
|
+
if (t.isUnaryExpression(property, { operator: "-" }) && t.isNumericLiteral(property.argument)) {
|
|
299
|
+
return -property.argument.value;
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
};
|
|
303
|
+
var isAssignmentTarget = (path) => {
|
|
304
|
+
const parent = path.parentPath;
|
|
305
|
+
if (!parent) return false;
|
|
306
|
+
if (parent.isUpdateExpression()) return true;
|
|
307
|
+
if (parent.isAssignmentExpression() && parent.get("left") === path) {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
if (parent.isForInStatement() && parent.get("left") === path) {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
if (parent.isForOfStatement() && parent.get("left") === path) {
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
return false;
|
|
317
|
+
};
|
|
318
|
+
var collectMutatedIndexes = (ast, targetName) => {
|
|
319
|
+
const mutatedIndexes = /* @__PURE__ */ new Set();
|
|
320
|
+
let hasUnknownMutations = false;
|
|
321
|
+
patchDefault(traverse2)(ast, {
|
|
322
|
+
MemberExpression(path) {
|
|
323
|
+
if (!path.node.computed) return;
|
|
324
|
+
if (!t.isIdentifier(path.node.object, { name: targetName })) return;
|
|
325
|
+
const parent = path.parentPath;
|
|
326
|
+
if (!parent) return;
|
|
327
|
+
const isMutationTarget = parent.isUpdateExpression() || parent.isAssignmentExpression() && parent.get("left") === path || parent.isForInStatement() && parent.get("left") === path || parent.isForOfStatement() && parent.get("left") === path;
|
|
328
|
+
if (!isMutationTarget) return;
|
|
329
|
+
if (!t.isExpression(path.node.property)) return;
|
|
330
|
+
const index = getIndexFromProperty(path.node.property);
|
|
331
|
+
if (index === null) {
|
|
332
|
+
hasUnknownMutations = true;
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
mutatedIndexes.add(index);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
return { mutatedIndexes, hasUnknownMutations };
|
|
339
|
+
};
|
|
340
|
+
var findTargetArray = (ast, targetName) => {
|
|
341
|
+
let found = null;
|
|
342
|
+
patchDefault(traverse2)(ast, {
|
|
343
|
+
VariableDeclarator(path) {
|
|
344
|
+
if (found) return;
|
|
345
|
+
if (!t.isIdentifier(path.node.id, { name: targetName })) return;
|
|
346
|
+
if (!t.isArrayExpression(path.node.init)) return;
|
|
347
|
+
if (!isPrimitiveArray(path.node.init)) return;
|
|
348
|
+
found = {
|
|
349
|
+
binding: path.scope.getBinding(targetName) ?? null,
|
|
350
|
+
arrayNode: path.node.init
|
|
351
|
+
};
|
|
352
|
+
},
|
|
353
|
+
AssignmentExpression(path) {
|
|
354
|
+
if (found) return;
|
|
355
|
+
if (!t.isIdentifier(path.node.left, { name: targetName })) return;
|
|
356
|
+
if (!t.isArrayExpression(path.node.right)) return;
|
|
357
|
+
if (!isPrimitiveArray(path.node.right)) return;
|
|
358
|
+
found = {
|
|
359
|
+
binding: path.scope.getBinding(targetName) ?? null,
|
|
360
|
+
arrayNode: path.node.right
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
});
|
|
364
|
+
if (!found) return null;
|
|
365
|
+
let hasRiskOfSideEffects = false;
|
|
366
|
+
patchDefault(traverse2)(ast, {
|
|
367
|
+
Identifier(path) {
|
|
368
|
+
if (hasRiskOfSideEffects) return;
|
|
369
|
+
if (!t.isIdentifier(path.node, { name: targetName })) return;
|
|
370
|
+
const parent = path.parentPath;
|
|
371
|
+
if (!parent) return;
|
|
372
|
+
if (parent.isVariableDeclarator() && parent.get("id") === path) return;
|
|
373
|
+
if (parent.isAssignmentExpression() && parent.get("left") === path) return;
|
|
374
|
+
if (parent.isMemberExpression() && parent.get("object") === path) return;
|
|
375
|
+
hasRiskOfSideEffects = true;
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
const result = found;
|
|
379
|
+
result.hasRiskOfSideEffects = hasRiskOfSideEffects;
|
|
380
|
+
return result;
|
|
381
|
+
};
|
|
382
|
+
var expandArrayAccess = async (code, filename, targetName) => {
|
|
383
|
+
const ast = parse3(code, createParseOptions(filename));
|
|
384
|
+
const targetArray = findTargetArray(ast, targetName);
|
|
385
|
+
if (!targetArray) {
|
|
386
|
+
throw new Error(`Target array '${targetName}' is not a primitive array`);
|
|
387
|
+
}
|
|
388
|
+
if (targetArray.hasRiskOfSideEffects) {
|
|
389
|
+
const continueAnswer = await createPrompt("The target array has risk of side effects, do you want to continue? (y/n)");
|
|
390
|
+
if (continueAnswer !== "y") {
|
|
391
|
+
throw new Error("User cancelled");
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const candidates = [];
|
|
395
|
+
const mutatedInfo = collectMutatedIndexes(ast, targetName);
|
|
396
|
+
if (mutatedInfo.hasUnknownMutations) {
|
|
397
|
+
return {
|
|
398
|
+
code: patchDefault(generate2)(ast).code,
|
|
399
|
+
replacedCount: 0
|
|
400
|
+
};
|
|
401
|
+
}
|
|
402
|
+
patchDefault(traverse2)(ast, {
|
|
403
|
+
MemberExpression(path) {
|
|
404
|
+
if (!path.node.computed) return;
|
|
405
|
+
if (isAssignmentTarget(path)) return;
|
|
406
|
+
if (!t.isIdentifier(path.node.object, { name: targetName })) return;
|
|
407
|
+
if (targetArray.binding && path.scope.getBinding(targetName) !== targetArray.binding) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
if (!t.isExpression(path.node.property)) return;
|
|
411
|
+
const index = getIndexFromProperty(path.node.property);
|
|
412
|
+
if (index === null || index < 0) return;
|
|
413
|
+
if (mutatedInfo.mutatedIndexes.has(index)) return;
|
|
414
|
+
const element = targetArray.arrayNode.elements[index];
|
|
415
|
+
if (!element || t.isSpreadElement(element)) return;
|
|
416
|
+
candidates.push({
|
|
417
|
+
path,
|
|
418
|
+
replacement: t.cloneNode(element, true)
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
let replacedCount = 0;
|
|
423
|
+
for (const candidate of candidates) {
|
|
424
|
+
const original = t.cloneNode(candidate.path.node, true);
|
|
425
|
+
candidate.path.replaceWith(t.cloneNode(candidate.replacement, true));
|
|
426
|
+
const nextCode = patchDefault(generate2)(ast).code;
|
|
427
|
+
try {
|
|
428
|
+
parse3(nextCode, createParseOptions(filename));
|
|
429
|
+
replacedCount += 1;
|
|
430
|
+
} catch {
|
|
431
|
+
candidate.path.replaceWith(original);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
code: patchDefault(generate2)(ast).code,
|
|
436
|
+
replacedCount
|
|
437
|
+
};
|
|
438
|
+
};
|
|
439
|
+
var expand_array_default = createCommand((program2) => {
|
|
440
|
+
program2.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(
|
|
441
|
+
async (fileArgument, options) => {
|
|
442
|
+
await timeout(
|
|
443
|
+
async ({ finish }) => {
|
|
444
|
+
const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
|
|
445
|
+
if (!filename) {
|
|
446
|
+
showError("No file provided");
|
|
447
|
+
return finish();
|
|
448
|
+
}
|
|
449
|
+
const targetName = options.target ?? await createPrompt("Enter the target variable name:");
|
|
450
|
+
if (!targetName) {
|
|
451
|
+
showError("No target variable provided");
|
|
452
|
+
return finish();
|
|
453
|
+
}
|
|
454
|
+
try {
|
|
455
|
+
const fileContent = readFileSync3(filename, "utf8");
|
|
456
|
+
const defaultOutputPath = createDefaultOutputPath2(filename);
|
|
457
|
+
let outputPath = options.output;
|
|
458
|
+
if (!outputPath) {
|
|
459
|
+
const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
|
|
460
|
+
outputPath = promptPath || defaultOutputPath;
|
|
461
|
+
}
|
|
462
|
+
const loader = loading3("Expanding array access...").start();
|
|
463
|
+
try {
|
|
464
|
+
const { code: output, replacedCount } = await expandArrayAccess(
|
|
465
|
+
fileContent,
|
|
466
|
+
filename,
|
|
467
|
+
targetName
|
|
468
|
+
);
|
|
469
|
+
writeFileSync2(outputPath, output, "utf8");
|
|
470
|
+
loader.succeed(
|
|
471
|
+
`Saved expand-array file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
|
|
472
|
+
);
|
|
473
|
+
return finish();
|
|
474
|
+
} catch (error) {
|
|
475
|
+
loader.fail("Failed to apply expand-array transform");
|
|
476
|
+
showError(
|
|
477
|
+
`Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
478
|
+
);
|
|
479
|
+
return finish();
|
|
480
|
+
}
|
|
481
|
+
} catch (error) {
|
|
482
|
+
showError(
|
|
483
|
+
`Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
484
|
+
);
|
|
485
|
+
return finish();
|
|
486
|
+
}
|
|
487
|
+
},
|
|
488
|
+
options.unlimited ? null : 120 * 1e3
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
);
|
|
492
|
+
});
|
|
493
|
+
|
|
494
|
+
// commands/pre-evaluate/index.ts
|
|
495
|
+
import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
|
|
496
|
+
import { basename as basename3, dirname as dirname3, extname as extname3, join as join3 } from "path";
|
|
497
|
+
import { parse as parse4 } from "@babel/parser";
|
|
498
|
+
import traverse3 from "@babel/traverse";
|
|
499
|
+
import generate3 from "@babel/generator";
|
|
500
|
+
import * as t2 from "@babel/types";
|
|
501
|
+
import loading4 from "loading-cli";
|
|
502
|
+
var createDefaultOutputPath3 = (inputPath) => {
|
|
503
|
+
const ext = extname3(inputPath);
|
|
504
|
+
if (!ext) {
|
|
505
|
+
return `${inputPath}.pre-evaluate.js`;
|
|
506
|
+
}
|
|
507
|
+
const base = basename3(inputPath, ext);
|
|
508
|
+
return join3(dirname3(inputPath), `${base}.pre-evaluate${ext}`);
|
|
509
|
+
};
|
|
510
|
+
var isSupportedNumberOperator = (operator) => {
|
|
511
|
+
return operator === "-" || operator === "*" || operator === "/" || operator === "%" || operator === "**" || operator === "<<" || operator === ">>" || operator === ">>>" || operator === "|" || operator === "&" || operator === "^";
|
|
512
|
+
};
|
|
513
|
+
var resolveBindingValue = (binding, state) => {
|
|
514
|
+
if (!binding.constant || binding.kind !== "const") {
|
|
515
|
+
return null;
|
|
516
|
+
}
|
|
517
|
+
const cached = state.bindingValues.get(binding);
|
|
518
|
+
if (cached !== void 0) {
|
|
519
|
+
return cached;
|
|
520
|
+
}
|
|
521
|
+
if (state.bindingStack.has(binding)) {
|
|
522
|
+
return null;
|
|
523
|
+
}
|
|
524
|
+
state.bindingStack.add(binding);
|
|
525
|
+
let value = null;
|
|
526
|
+
if (binding.path.isVariableDeclarator()) {
|
|
527
|
+
if (binding.path.node.init) {
|
|
528
|
+
const initPath = binding.path.get("init");
|
|
529
|
+
if (!Array.isArray(initPath) && initPath.isExpression()) {
|
|
530
|
+
value = evaluateExpression(initPath, state);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
state.bindingStack.delete(binding);
|
|
535
|
+
if (value !== null) {
|
|
536
|
+
state.bindingValues.set(binding, value);
|
|
537
|
+
}
|
|
538
|
+
return value;
|
|
539
|
+
};
|
|
540
|
+
var evaluateExpression = (path, state) => {
|
|
541
|
+
if (path.isNumericLiteral()) {
|
|
542
|
+
return path.node.value;
|
|
543
|
+
}
|
|
544
|
+
if (path.isStringLiteral()) {
|
|
545
|
+
return path.node.value;
|
|
546
|
+
}
|
|
547
|
+
if (path.isParenthesizedExpression()) {
|
|
548
|
+
const inner = path.get("expression");
|
|
549
|
+
if (!Array.isArray(inner) && inner.isExpression()) {
|
|
550
|
+
return evaluateExpression(inner, state);
|
|
551
|
+
}
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
554
|
+
if (path.isIdentifier()) {
|
|
555
|
+
const binding = path.scope.getBinding(path.node.name);
|
|
556
|
+
if (!binding) return null;
|
|
557
|
+
return resolveBindingValue(binding, state);
|
|
558
|
+
}
|
|
559
|
+
if (path.isUnaryExpression()) {
|
|
560
|
+
const argumentPath = path.get("argument");
|
|
561
|
+
if (Array.isArray(argumentPath) || !argumentPath.isExpression()) {
|
|
562
|
+
return null;
|
|
563
|
+
}
|
|
564
|
+
const argument = evaluateExpression(argumentPath, state);
|
|
565
|
+
if (argument === null || typeof argument !== "number") {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
if (path.node.operator === "+") return +argument;
|
|
569
|
+
if (path.node.operator === "-") return -argument;
|
|
570
|
+
if (path.node.operator === "~") return ~argument;
|
|
571
|
+
return null;
|
|
572
|
+
}
|
|
573
|
+
if (path.isBinaryExpression()) {
|
|
574
|
+
const leftPath = path.get("left");
|
|
575
|
+
const rightPath = path.get("right");
|
|
576
|
+
if (Array.isArray(leftPath) || Array.isArray(rightPath) || !leftPath.isExpression() || !rightPath.isExpression()) {
|
|
577
|
+
return null;
|
|
578
|
+
}
|
|
579
|
+
const left = evaluateExpression(leftPath, state);
|
|
580
|
+
const right = evaluateExpression(rightPath, state);
|
|
581
|
+
if (left === null || right === null) {
|
|
582
|
+
return null;
|
|
583
|
+
}
|
|
584
|
+
if (path.node.operator === "+") {
|
|
585
|
+
if (typeof left === "string" || typeof right === "string") {
|
|
586
|
+
return `${left}${right}`;
|
|
587
|
+
}
|
|
588
|
+
if (typeof left === "number" && typeof right === "number") {
|
|
589
|
+
return left + right;
|
|
590
|
+
}
|
|
591
|
+
return null;
|
|
592
|
+
}
|
|
593
|
+
if (typeof left !== "number" || typeof right !== "number" || !isSupportedNumberOperator(path.node.operator)) {
|
|
594
|
+
return null;
|
|
595
|
+
}
|
|
596
|
+
switch (path.node.operator) {
|
|
597
|
+
case "-":
|
|
598
|
+
return left - right;
|
|
599
|
+
case "*":
|
|
600
|
+
return left * right;
|
|
601
|
+
case "/":
|
|
602
|
+
return left / right;
|
|
603
|
+
case "%":
|
|
604
|
+
return left % right;
|
|
605
|
+
case "**":
|
|
606
|
+
return left ** right;
|
|
607
|
+
case "<<":
|
|
608
|
+
return left << right;
|
|
609
|
+
case ">>":
|
|
610
|
+
return left >> right;
|
|
611
|
+
case ">>>":
|
|
612
|
+
return left >>> right;
|
|
613
|
+
case "|":
|
|
614
|
+
return left | right;
|
|
615
|
+
case "&":
|
|
616
|
+
return left & right;
|
|
617
|
+
case "^":
|
|
618
|
+
return left ^ right;
|
|
619
|
+
default:
|
|
620
|
+
return null;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return null;
|
|
624
|
+
};
|
|
625
|
+
var shouldSkipReferencedIdentifier = (path) => {
|
|
626
|
+
const parent = path.parentPath;
|
|
627
|
+
if (!parent) return false;
|
|
628
|
+
if (parent.isObjectProperty()) {
|
|
629
|
+
if (parent.node.shorthand) return true;
|
|
630
|
+
if (parent.get("key") === path && !parent.node.computed) {
|
|
631
|
+
return true;
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
if (parent.isObjectMethod()) {
|
|
635
|
+
if (parent.get("key") === path && !parent.node.computed) {
|
|
636
|
+
return true;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
return false;
|
|
640
|
+
};
|
|
641
|
+
var preEvaluate = (code, filename) => {
|
|
642
|
+
const ast = parse4(code, createParseOptions(filename));
|
|
643
|
+
const state = {
|
|
644
|
+
bindingValues: /* @__PURE__ */ new Map(),
|
|
645
|
+
bindingStack: /* @__PURE__ */ new Set()
|
|
646
|
+
};
|
|
647
|
+
let replacedCount = 0;
|
|
648
|
+
patchDefault(traverse3)(ast, {
|
|
649
|
+
ReferencedIdentifier(path) {
|
|
650
|
+
if (shouldSkipReferencedIdentifier(path)) {
|
|
651
|
+
return;
|
|
652
|
+
}
|
|
653
|
+
const value = evaluateExpression(path, state);
|
|
654
|
+
if (value === null) return;
|
|
655
|
+
if (typeof value === "number") {
|
|
656
|
+
path.replaceWith(t2.numericLiteral(value));
|
|
657
|
+
} else {
|
|
658
|
+
path.replaceWith(t2.stringLiteral(value));
|
|
659
|
+
}
|
|
660
|
+
replacedCount += 1;
|
|
661
|
+
},
|
|
662
|
+
UnaryExpression: {
|
|
663
|
+
exit(path) {
|
|
664
|
+
const value = evaluateExpression(path, state);
|
|
665
|
+
if (value === null) return;
|
|
666
|
+
if (typeof value === "number") {
|
|
667
|
+
path.replaceWith(t2.numericLiteral(value));
|
|
668
|
+
} else {
|
|
669
|
+
path.replaceWith(t2.stringLiteral(value));
|
|
670
|
+
}
|
|
671
|
+
replacedCount += 1;
|
|
672
|
+
}
|
|
673
|
+
},
|
|
674
|
+
BinaryExpression: {
|
|
675
|
+
exit(path) {
|
|
676
|
+
const value = evaluateExpression(path, state);
|
|
677
|
+
if (value === null) return;
|
|
678
|
+
if (typeof value === "number") {
|
|
679
|
+
path.replaceWith(t2.numericLiteral(value));
|
|
680
|
+
} else {
|
|
681
|
+
path.replaceWith(t2.stringLiteral(value));
|
|
682
|
+
}
|
|
683
|
+
replacedCount += 1;
|
|
684
|
+
}
|
|
685
|
+
},
|
|
686
|
+
ParenthesizedExpression: {
|
|
687
|
+
exit(path) {
|
|
688
|
+
const value = evaluateExpression(path, state);
|
|
689
|
+
if (value === null) return;
|
|
690
|
+
if (typeof value === "number") {
|
|
691
|
+
path.replaceWith(t2.numericLiteral(value));
|
|
692
|
+
} else {
|
|
693
|
+
path.replaceWith(t2.stringLiteral(value));
|
|
694
|
+
}
|
|
695
|
+
replacedCount += 1;
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
});
|
|
699
|
+
return {
|
|
700
|
+
code: patchDefault(generate3)(ast).code,
|
|
701
|
+
replacedCount
|
|
702
|
+
};
|
|
703
|
+
};
|
|
704
|
+
var pre_evaluate_default = createCommand((program2) => {
|
|
705
|
+
program2.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(
|
|
706
|
+
async (fileArgument, options) => {
|
|
707
|
+
await timeout(
|
|
708
|
+
async ({ finish }) => {
|
|
709
|
+
const filename = fileArgument ?? options.file ?? await createPrompt("Enter the file path:");
|
|
710
|
+
if (!filename) {
|
|
711
|
+
showError("No file provided");
|
|
712
|
+
return finish();
|
|
713
|
+
}
|
|
714
|
+
try {
|
|
715
|
+
const fileContent = readFileSync4(filename, "utf8");
|
|
716
|
+
const defaultOutputPath = createDefaultOutputPath3(filename);
|
|
717
|
+
let outputPath = options.output;
|
|
718
|
+
if (!outputPath) {
|
|
719
|
+
const promptPath = (await createPrompt("Enter the output file path:"))?.trim();
|
|
720
|
+
outputPath = promptPath || defaultOutputPath;
|
|
721
|
+
}
|
|
722
|
+
const loader = loading4("Pre-evaluating constants...").start();
|
|
723
|
+
try {
|
|
724
|
+
const { code: output, replacedCount } = preEvaluate(
|
|
725
|
+
fileContent,
|
|
726
|
+
filename
|
|
727
|
+
);
|
|
728
|
+
writeFileSync3(outputPath, output, "utf8");
|
|
729
|
+
loader.succeed(
|
|
730
|
+
`Saved pre-evaluate file to: ${outputPath} (${diff(fileContent, output).length} lines changed, ${replacedCount} replacements)`
|
|
731
|
+
);
|
|
732
|
+
return finish();
|
|
733
|
+
} catch (error) {
|
|
734
|
+
loader.fail("Failed to apply pre-evaluate transform");
|
|
735
|
+
showError(
|
|
736
|
+
`Error transforming file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
737
|
+
);
|
|
738
|
+
return finish();
|
|
739
|
+
}
|
|
740
|
+
} catch (error) {
|
|
741
|
+
showError(
|
|
742
|
+
`Error reading file '${filename}': ${error instanceof Error ? error.message : "Unknown error"}`
|
|
743
|
+
);
|
|
744
|
+
return finish();
|
|
745
|
+
}
|
|
746
|
+
},
|
|
747
|
+
options.unlimited ? null : 120 * 1e3
|
|
748
|
+
);
|
|
749
|
+
}
|
|
750
|
+
);
|
|
751
|
+
});
|
|
752
|
+
|
|
264
753
|
// utils/cli/showCredit.ts
|
|
265
754
|
import chalk3 from "chalk";
|
|
266
755
|
var beautify = (strings, ...values) => {
|
|
@@ -285,10 +774,10 @@ var calmGradienrain = (text) => {
|
|
|
285
774
|
const endHue = 300;
|
|
286
775
|
const saturation = 0.45;
|
|
287
776
|
const value = 0.8;
|
|
288
|
-
const ease = (
|
|
777
|
+
const ease = (t3) => t3 * t3 * (3 - 2 * t3);
|
|
289
778
|
return text.split("").map((char, i) => {
|
|
290
|
-
const
|
|
291
|
-
const hue = startHue + (endHue - startHue) *
|
|
779
|
+
const t3 = ease(i / Math.max(text.length - 1, 1));
|
|
780
|
+
const hue = startHue + (endHue - startHue) * t3;
|
|
292
781
|
const c = value * saturation;
|
|
293
782
|
const h = hue / 60;
|
|
294
783
|
const x = c * (1 - Math.abs(h % 2 - 1));
|
|
@@ -312,10 +801,10 @@ ${calmGradienrain(`Expose Kit v${VERSION}`)}
|
|
|
312
801
|
`;
|
|
313
802
|
|
|
314
803
|
// index.ts
|
|
315
|
-
import { readFileSync as
|
|
804
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
316
805
|
var __filename = fileURLToPath(import.meta.url);
|
|
317
|
-
var __dirname =
|
|
318
|
-
var pkg = JSON.parse(
|
|
806
|
+
var __dirname = dirname4(__filename);
|
|
807
|
+
var pkg = JSON.parse(readFileSync5(join4(__dirname, "package.json"), "utf8"));
|
|
319
808
|
console.log(showCredit(pkg.version));
|
|
320
809
|
console.log();
|
|
321
810
|
var program = new Command();
|
|
@@ -324,7 +813,7 @@ program.name("expose").description("CLI for Deobfuscating").version(
|
|
|
324
813
|
"-v, --version",
|
|
325
814
|
"display version number"
|
|
326
815
|
);
|
|
327
|
-
var commands = [parsable_default, safe_scope_default];
|
|
816
|
+
var commands = [parsable_default, safe_scope_default, expand_array_default, pre_evaluate_default];
|
|
328
817
|
for (const command of commands) {
|
|
329
818
|
command(program);
|
|
330
819
|
}
|
package/dist/package.json
CHANGED