distinctiomagnam
Version:
JavaScript Obfuscation Tool.
913 lines (849 loc) • 27 kB
text/typescript
import { ok } from "assert";
import presets from "./presets";
import { ProbabilityMap } from "./probability";
export interface ObfuscateOptions {
/**
* ### `preset`
*
* JS-Confuser comes with three presets built into the obfuscator.
*
* | Preset | Transforms | Performance Reduction | Sample |
* | --- | --- | --- | --- |
* | High | 21/22 | 98% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/high.js) |
* | Medium | 15/22 | 52% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/medium.js) |
* | Low | 10/22 | 30% | [Sample](https://github.com/MichaelXF/js-confuser/blob/master/samples/low.js) |
*
* You can extend each preset or all go without them entirely. (`"high"/"medium"/"low"`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
preset?: "high" | "medium" | "low" | false;
/**
* ### `target`
*
* The execution context for your output. _Required_.
*
* 1. `"node"`
* 2. `"browser"`
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
target: "node" | "browser";
/**
* ### `indent`
*
* Controls the indentation of the output.
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
indent?: 2 | 4 | "tabs";
/**
* ### `compact`
*
* Remove's whitespace from the final output. (`true/false`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
compact?: boolean;
/**
* ### `minify`
*
* Minifies redundant code. (`true/false`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
minify?: boolean;
/**
* ### `es5`
*
* Converts output to ES5-compatible code. (`true/false`)
*
* Does not cover all cases such as Promises or Generator functions. Use [Babel](https://babel.dev/).
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
es5?: boolean;
/**
* ### `renameVariables`
*
* Determines if variables should be renamed. (`true/false`)
* - Potency High
* - Resilience High
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
renameVariables?: ProbabilityMap<boolean>;
/**
* ### `renameGlobals`
*
* Renames top-level variables, turn this off for web-related scripts. Enabled by default. (`true/false`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
renameGlobals?: ProbabilityMap<boolean>;
/**
* ### `identifierGenerator`
*
* Determines how variables are renamed.
*
* | Mode | Description | Example |
* | --- | --- | --- |
* | `"hexadecimal"` | Random hex strings | \_0xa8db5 |
* | `"randomized"` | Random characters | w$Tsu4G |
* | `"zeroWidth"` | Invisible characters | U+200D |
* | `"mangled"` | Alphabet sequence | a, b, c |
* | `"number"` | Numbered sequence | var_1, var_2 |
* | `<function>` | Write a custom name generator | See Below |
*
* ```js
* // Custom implementation
* JsConfuser.obfuscate(code, {
* target: "node",
* renameVariables: true,
* identifierGenerator: function () {
* return "$" + Math.random().toString(36).substring(7);
* },
* });
*
* // Numbered variables
* var counter = 0;
* JsConfuser.obfuscate(code, {
* target: "node",
* renameVariables: true,
* identifierGenerator: function () {
* return "var_" + (counter++);
* },
* });
* ```
*
* JSConfuser tries to reuse names when possible, creating very potent code.
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
identifierGenerator?: ProbabilityMap<
"hexadecimal" | "randomized" | "zeroWidth" | "mangled" | "number"
>;
/**
* ### `nameRecycling`
*
* Attempts to reuse released names.
*
* - Potency Medium
* - Resilience High
* - Cost Low
*
* ```js
* // Input
* function percentage(x) {
* var multiplied = x * 100;
* var floored = Math.floor(multiplied);
* var output = floored + "%"
* return output;
* }
*
* // Output
* function percentage(x) {
* var multiplied = x * 100;
* var floored = Math.floor(multiplied);
* multiplied = floored + "%";
* return multiplied;
* }
* ```
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
nameRecycling?: ProbabilityMap<boolean>;
/**
* ### `controlFlowFlattening`
*
* ⚠️ Significantly impacts performance, use sparingly!
*
* [Control-flow Flattening](https://docs.jscrambler.com/code-integrity/documentation/transformations/control-flow-flattening) hinders program comprehension by creating convoluted switch statements. (`true/false/0-1`)
*
* Use a number to control the percentage from 0 to 1.
*
* - Potency High
* - Resilience High
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
controlFlowFlattening?: ProbabilityMap<boolean>;
/**
* ### `hideInitializingCode`
*
* Hides initializing code with complex ternary expressions. (`true/false`)
*
* - Potency High
* - Resilience High
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
hideInitializingCode?: ProbabilityMap<boolean>;
/**
* ### `globalConcealing`
*
* Global Concealing hides global variables being accessed. (`true/false`)
*
* - Potency Medium
* - Resilience High
* - Cost Low
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
globalConcealing?: ProbabilityMap<boolean>;
/**
* ### `stringCompression`
*
* String Compression uses LZW's compression algorithm to compress strings. (`true/false/0-1`)
*
* `"console"` -> `inflate('replaĕ!ğğuģģ<~@')`
*
* - Potency High
* - Resilience Medium
* - Cost Medium
*/
stringCompression?: ProbabilityMap<boolean>;
/**
* ### `stringConcealing`
*
* [String Concealing](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-concealing) involves encoding strings to conceal plain-text values. (`true/false/0-1`)
*
* `"console"` -> `decrypt('<~@rH7+Dert~>')`
*
* - Potency High
* - Resilience Medium
* - Cost Medium
*/
stringConcealing?: ProbabilityMap<boolean>;
/**
* ### `stringEncoding`
*
* [String Encoding](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-encoding) transforms a string into an encoded representation. (`true/false/0-1`)
*
* `"console"` -> `'\x63\x6f\x6e\x73\x6f\x6c\x65'`
*
* - Potency Low
* - Resilience Low
* - Cost Low
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
stringEncoding?: ProbabilityMap<boolean>;
/**
* ### `stringSplitting`
*
* [String Splitting](https://docs.jscrambler.com/code-integrity/documentation/transformations/string-splitting) splits your strings into multiple expressions. (`true/false/0-1`)
*
* `"console"` -> `String.fromCharCode(99) + 'ons' + 'ole'`
*
* - Potency Medium
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
stringSplitting?: ProbabilityMap<boolean>;
/**
* ### `duplicateLiteralsRemoval`
*
* [Duplicate Literals Removal](https://docs.jscrambler.com/code-integrity/documentation/transformations/duplicate-literals-removal) replaces duplicate literals with a single variable name. (`true/false`)
*
* - Potency Medium
* - Resilience Low
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
duplicateLiteralsRemoval?: ProbabilityMap<boolean>;
/**
* ### `dispatcher`
*
* Creates a middleman function to process function calls. (`true/false/0-1`)
*
* - Potency Medium
* - Resilience Medium
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
dispatcher?: ProbabilityMap<boolean>;
/**
* ### `eval`
*
* #### **`Security Warning`**
*
* From [MDN](<(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)**>): Executing JavaScript from a string is an enormous security risk. It is far too easy
* for a bad actor to run arbitrary code when you use eval(). Never use eval()!
*
* Wraps defined functions within eval statements.
*
* - **`false`** - Avoids using the `eval` function. _Default_.
* - **`true`** - Wraps function's code into an `eval` statement.
*
* ```js
* // Output.js
* var Q4r1__ = {
* Oo$Oz8t: eval(
* "(function(YjVpAp){var gniSBq6=kHmsJrhOO;switch(gniSBq6){case'RW11Hj5x':return console;}});"
* ),
* };
* Q4r1__.Oo$Oz8t("RW11Hj5x");
* ```
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
eval?: ProbabilityMap<boolean>;
/**
* ### `rgf`
*
* RGF (Runtime-Generated-Functions) uses the [`new Function(code...)`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/Function) syntax to construct executable code from strings. (`"all"/true/false`)
*
* - **This can break your code. This is also as dangerous as `eval`.**
* - **Due to the security concerns of arbitrary code execution, you must enable this yourself.**
* - The arbitrary code is also obfuscated.
*
* | Mode | Description |
* | --- | --- |
* | `"all"` | Recursively applies to every scope (slow) |
* | `true` | Applies to the top level only |
* | `false` | Feature disabled |
*
* ```js
* // Input
* function log(x){
* console.log(x)
* }
*
* log("Hello World")
*
* // Output
* var C6z0jyO=[new Function('a2Fjjl',"function OqNW8x(OqNW8x){console['log'](OqNW8x)}return OqNW8x(...Array.prototype.slice.call(arguments,1))")];(function(){return C6z0jyO[0](C6z0jyO,...arguments)}('Hello World'))
* ```
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
rgf?: ProbabilityMap<boolean | "all">;
/**
* ### `stack`
*
* Local variables are consolidated into a rotating array.
*
* [Similar to Jscrambler's Variable Masking](https://docs.jscrambler.com/code-integrity/documentation/transformations/variable-masking)
*
* - Potency Medium
* - Resilience Medium
* - Cost Low
*
* ```js
* // Input
* function add3(x, y, z){
* return x + y + z;
* }
*
* // Output
* function iVQoGQD(...iVQoGQD){
* ~(iVQoGQD.length = 3, iVQoGQD[215] = iVQoGQD[2], iVQoGQD[75] = 227, iVQoGQD[iVQoGQD[75] - (iVQoGQD[75] - 75)] = iVQoGQD[75] - (iVQoGQD[75] - 239), iVQoGQD[iVQoGQD[iVQoGQD[75] - 164] - 127] = iVQoGQD[iVQoGQD[75] - 238], iVQoGQD[iVQoGQD[75] - 104] = iVQoGQD[75] - 482, iVQoGQD[iVQoGQD[135] + 378] = iVQoGQD[iVQoGQD[135] + 318] - 335, iVQoGQD[21] = iVQoGQD[iVQoGQD[135] + 96], iVQoGQD[iVQoGQD[iVQoGQD[75] - 104] - (iVQoGQD[75] - 502)] = iVQoGQD[iVQoGQD[75] - 164] - 440);
* return iVQoGQD[75] > iVQoGQD[75] + 90 ? iVQoGQD[iVQoGQD[135] - (iVQoGQD[135] + 54)] : iVQoGQD[iVQoGQD[135] + 117] + iVQoGQD[iVQoGQD[iVQoGQD[75] - (iVQoGQD[75] - (iVQoGQD[75] - 104))] - (iVQoGQD[135] - 112)] + iVQoGQD[215];
* };
* ```
*/
stack?: ProbabilityMap<boolean>;
/**
* ### `objectExtraction`
*
* Extracts object properties into separate variables. (`true/false`)
*
* - Potency Medium
* - Resilience Medium
* - Cost Low
*
* ```js
* // Input
* var utils = {
* isString: x=>typeof x === "string",
* isBoolean: x=>typeof x === "boolean"
* }
* if ( utils.isString("Hello") ) {
* // ...
* }
*
* // Output
* var utils_isString = x=>typeof x === "string";
* var utils_isBoolean = x=>typeof x === "boolean"
* if ( utils_isString("Hello") ) {
* // ...
* }
* ```
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
objectExtraction?: ProbabilityMap<boolean>;
/**
* ### `flatten`
*
* Brings independent declarations to the highest scope. (`true/false`)
*
* - Potency Medium
* - Resilience Medium
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
flatten?: ProbabilityMap<boolean>;
/**
* ### `deadCode`
*
* Randomly injects dead code. (`true/false/0-1`)
*
* Use a number to control the percentage from 0 to 1.
*
* - Potency Medium
* - Resilience Medium
* - Cost Low
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
deadCode?: ProbabilityMap<boolean>;
/**
* ### `calculator`
*
* Creates a calculator function to handle arithmetic and logical expressions. (`true/false/0-1`)
*
* - Potency Medium
* - Resilience Medium
* - Cost Low
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
calculator?: ProbabilityMap<boolean>;
lock?: {
/**
* ### `lock.selfDefending`
*
* Prevents the use of code beautifiers or formatters against your code.
*
* [Identical to Obfuscator.io's Self Defending](https://github.com/javascript-obfuscator/javascript-obfuscator#selfdefending)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
selfDefending?: boolean;
/**
* ### `lock.antiDebug`
*
* Adds `debugger` statements throughout the code. Additionally adds a background function for DevTools detection. (`true/false/0-1`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
antiDebug?: ProbabilityMap<boolean>;
/**
* ### `lock.context`
*
* Properties that must be present on the `window` object (or `global` for NodeJS). (`string[]`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
context?: string[];
/**
* ### `lock.nativeFunctions`
*
* Set of global functions that are native. Such as `require`, `fetch`. If these variables are modified the program crashes.
* Set to `true` to use the default set of native functions. (`string[]/true/false`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
nativeFunctions?: string[] | Set<string> | boolean;
/**
* ### `lock.startDate`
*
* When the program is first able to be used. (`number` or `Date`)
*
* Number should be in milliseconds.
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
startDate?: number | Date | false;
/**
* ### `lock.endDate`
*
* When the program is no longer able to be used. (`number` or `Date`)
*
* Number should be in milliseconds.
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
endDate?: number | Date | false;
/**
* ### `lock.domainLock`
* Array of regex strings that the `window.location.href` must follow. (`Regex[]` or `string[]`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
domainLock?: RegExp[] | string[] | false;
/**
* ### `lock.osLock`
* Array of operating-systems where the script is allowed to run. (`string[]`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* Allowed values: `"linux"`, `"windows"`, `"osx"`, `"android"`, `"ios"`
*
* Example: `["linux", "windows"]`
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
osLock?: ("linux" | "windows" | "osx" | "android" | "ios")[] | false;
/**
* ### `lock.browserLock`
* Array of browsers where the script is allowed to run. (`string[]`)
*
* - Potency Low
* - Resilience Medium
* - Cost Medium
*
* Allowed values: `"firefox"`, `"chrome"`, `"iexplorer"`, `"edge"`, `"safari"`, `"opera"`
*
* Example: `["firefox", "chrome"]`
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
browserLock?:
| ("firefox" | "chrome" | "iexplorer" | "edge" | "safari" | "opera")[]
| false;
/**
* ### `lock.integrity`
*
* Integrity ensures the source code is unchanged. (`true/false/0-1`)
*
* [Learn more here](https://github.com/MichaelXF/js-confuser/blob/master/Integrity.md).
*
* - Potency Medium
* - Resilience High
* - Cost High
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
integrity?: ProbabilityMap<boolean>;
/**
* ### `lock.countermeasures`
*
* A custom callback function to invoke when a lock is triggered. (`string/false`)
*
* This could be due to an invalid domain, incorrect time, or code's integrity changed.
*
* [Learn more about the rules of your countermeasures function](https://github.com/MichaelXF/js-confuser/blob/master/Countermeasures.md).
*
* Otherwise, the obfuscator falls back to crashing the process.
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
countermeasures?: string | boolean;
};
/**
* ### `movedDeclarations`
*
* Moves variable declarations to the top of the context. (`true/false`)
*
* - Potency Medium
* - Resilience Medium
* - Cost Low
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
movedDeclarations?: ProbabilityMap<boolean>;
/**
* ### `opaquePredicates`
*
* An [Opaque Predicate](https://en.wikipedia.org/wiki/Opaque_predicate) is a predicate(true/false) that is evaluated at runtime, this can confuse reverse engineers
* understanding your code. (`true/false`)
*
* - Potency Medium
* - Resilience Medium
* - Cost Low
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
opaquePredicates?: ProbabilityMap<boolean>;
/**
* ### `shuffle`
*
* Shuffles the initial order of arrays. The order is brought back to the original during runtime. (`"hash"/true/false/0-1`)
*
* - Potency Medium
* - Resilience Low
* - Cost Low
*
* | Mode | Description |
* | --- | --- |
* | `"hash"`| Array is shifted based on hash of the elements |
* | `true`| Arrays are shifted *n* elements, unshifted at runtime |
* | `false` | Feature disabled |
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
shuffle?: ProbabilityMap<boolean | "hash">;
/**
* ### `verbose`
*
* Enable logs to view the obfuscator's state. (`true/false`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
verbose?: boolean;
/**
* ### `globalVariables`
*
* Set of global variables. *Optional*. (`Set<string>`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
globalVariables?: Set<string>;
/**
* ### `debugComments`
*
* Enable debug comments. (`true/false`)
*
* [See all settings here](https://github.com/MichaelXF/js-confuser/blob/master/README.md#options)
*/
debugComments?: boolean;
}
const validProperties = new Set([
"preset",
"target",
"indent",
"compact",
"minify",
"es5",
"renameVariables",
"renameGlobals",
"identifierGenerator",
"nameRecycling",
"controlFlowFlattening",
"hideInitializingCode",
"globalConcealing",
"stringCompression",
"stringConcealing",
"stringEncoding",
"stringSplitting",
"duplicateLiteralsRemoval",
"dispatcher",
"eval",
"rgf",
"objectExtraction",
"flatten",
"deadCode",
"calculator",
"lock",
"movedDeclarations",
"opaquePredicates",
"shuffle",
"stack",
"verbose",
"globalVariables",
"debugComments",
]);
const validOses = new Set(["windows", "linux", "osx", "ios", "android"]);
const validBrowsers = new Set([
"firefox",
"chrome",
"iexplorer",
"edge",
"safari",
"opera",
]);
export function validateOptions(options: ObfuscateOptions) {
if (Object.keys(options).length <= 1) {
/**
* Give a welcoming introduction to those who skipped the documentation.
*/
var line = `You provided zero obfuscation options. By default everything is disabled.\nYou can use a preset with:\n\n> {target: '${
options.target || "node"
}', preset: 'high' | 'medium' | 'low'}.\n\n\nView all settings here:\nhttps://github.com/MichaelXF/js-confuser#options`;
throw new Error(
`\n\n` +
line
.split("\n")
.map((x) => `\t${x}`)
.join("\n") +
`\n\n`
);
}
ok(options, "options cannot be null");
ok(
options.target,
"Missing options.target option (required, must one the following: 'browser' or 'node')"
);
ok(
["browser", "node"].includes(options.target),
`'${options.target}' is not a valid target mode`
);
Object.keys(options).forEach((key) => {
if (!validProperties.has(key)) {
throw new TypeError("Invalid option: '" + key + "'");
}
});
if (
options.target === "node" &&
options.lock &&
options.lock.browserLock &&
options.lock.browserLock.length
) {
throw new TypeError('browserLock can only be used when target="browser"');
}
if (options.lock) {
// Validate browser-lock option
if (typeof options.lock.browserLock !== "undefined") {
ok(
Array.isArray(options.lock.browserLock),
"browserLock must be an array"
);
ok(
!options.lock.browserLock.find(
(browserName) => !validBrowsers.has(browserName)
),
'Invalid browser name. Allowed: "firefox", "chrome", "iexplorer", "edge", "safari", "opera"'
);
}
// Validate os-lock option
if (typeof options.lock.osLock !== "undefined") {
ok(Array.isArray(options.lock.osLock), "osLock must be an array");
ok(
!options.lock.osLock.find((osName) => !validOses.has(osName)),
'Invalid OS name. Allowed: "windows", "linux", "osx", "ios", "android"'
);
}
// Validate domain-lock option
if (typeof options.lock.domainLock !== "undefined") {
ok(Array.isArray(options.lock.domainLock), "domainLock must be an array");
}
// Validate context option
if (typeof options.lock.context !== "undefined") {
ok(Array.isArray(options.lock.context), "context must be an array");
}
// Validate start-date option
if (
typeof options.lock.startDate !== "undefined" &&
options.lock.startDate
) {
ok(
typeof options.lock.startDate === "number" ||
options.lock.startDate instanceof Date,
"startDate must be Date object or number"
);
}
// Validate end-date option
if (typeof options.lock.endDate !== "undefined" && options.lock.endDate) {
ok(
typeof options.lock.endDate === "number" ||
options.lock.endDate instanceof Date,
"endDate must be Date object or number"
);
}
}
if (options.preset) {
if (!presets[options.preset]) {
throw new TypeError("Unknown preset of '" + options.preset + "'");
}
}
}
/**
* Corrects the user's options. Sets the default values and validates the configuration.
* @param options
* @returns
*/
export async function correctOptions(
options: ObfuscateOptions
): Promise<ObfuscateOptions> {
if (options.preset) {
// Clone and allow overriding
options = Object.assign({}, presets[options.preset], options);
}
if (!options.hasOwnProperty("debugComments")) {
options.debugComments = false; // debugComments is off by default
}
if (!options.hasOwnProperty("compact")) {
options.compact = true; // Compact is on by default
}
if (!options.hasOwnProperty("renameGlobals")) {
options.renameGlobals = true; // RenameGlobals is on by default
}
if (options.globalVariables && !(options.globalVariables instanceof Set)) {
options.globalVariables = new Set(Object.keys(options.globalVariables));
}
if (options.lock && options.lock.selfDefending) {
options.compact = true; // self defending forcibly enables this
}
// options.globalVariables was never used.
// GlobalConcealing implicitly determines a global to be a variable referenced but never defined or modified.
if (!options.hasOwnProperty("globalVariables")) {
options.globalVariables = new Set([]);
if (options.target == "browser") {
// browser
[
"window",
"document",
"postMessage",
"alert",
"confirm",
"location",
].forEach((x) => options.globalVariables.add(x));
} else {
// node
[
"global",
"Buffer",
"require",
"process",
"__dirname",
"__filename",
].forEach((x) => options.globalVariables.add(x));
}
[
"globalThis",
"console",
"parseInt",
"parseFloat",
"Math",
"Promise",
"String",
"Boolean",
"Function",
"Object",
"Array",
"Proxy",
"Error",
"setTimeout",
"clearTimeout",
"setInterval",
"clearInterval",
"setImmediate",
"clearImmediate",
"queueMicrotask",
"exports",
"module",
"isNaN",
"isFinite",
].forEach((x) => options.globalVariables.add(x));
}
return options;
}