esbuild-javascript-obfuscator 1.0.1 → 1.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -3
- package/dist/plugin/plugin.d.ts.map +1 -1
- package/dist/plugin/plugin.js +34 -28
- package/dist/tests/plugin.test.js +15 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
# esbuild-javascript-obfuscator
|
|
2
2
|
|
|
3
|
-
This project obfuscates your code using the javascript-obfuscator NPM package.
|
|
3
|
+
This project obfuscates your code using the [javascript-obfuscator](https://github.com/javascript-obfuscator/javascript-obfuscator) NPM package.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Highlights
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- Currently the **only maintained** esbuild plugin for the **javascript-obfuscator** package.
|
|
8
|
+
- **The only** esbuild plugin that supports **VM Obfuscation** _(API key required)._
|
|
9
|
+
|
|
10
|
+
## Acknowledgments
|
|
11
|
+
|
|
12
|
+
Thanks to [sanex3339](https://github.com/javascript-obfuscator/javascript-obfuscator/commits?author=sanex3339), the creator of **javascript-obfuscator**.
|
|
13
|
+
|
|
14
|
+
## Important
|
|
15
|
+
|
|
16
|
+
Licensed under the MIT License.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAMnC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/plugin/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,SAAS,CAAC;AAMnC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAkDxE,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAwEtD,OAAO,CAAC,MAAM,CACtB"}
|
package/dist/plugin/plugin.js
CHANGED
|
@@ -4,13 +4,14 @@ import fs from 'fs';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { ValidateOptions } from './optionValidator';
|
|
6
6
|
import { CreateLogger } from '../logging';
|
|
7
|
-
async function ObfuscateFile(pluginOptions,
|
|
7
|
+
async function ObfuscateFile(pluginOptions, file) {
|
|
8
8
|
const logger = CreateLogger(pluginOptions);
|
|
9
|
+
const originalCode = new TextDecoder().decode(file.contents);
|
|
9
10
|
if (!file.path.endsWith('.js')) {
|
|
10
11
|
logger('file does not end with .js, skipping obfuscation: ', file.path);
|
|
11
|
-
return
|
|
12
|
+
return originalCode;
|
|
12
13
|
}
|
|
13
|
-
if (pluginOptions.VMProtection
|
|
14
|
+
if (pluginOptions.VMProtection?.Enabled) {
|
|
14
15
|
const { ApiKey, Version } = pluginOptions.VMProtection;
|
|
15
16
|
logger('obfuscating with VM Protection ... ');
|
|
16
17
|
const proApiOptions = {
|
|
@@ -19,21 +20,17 @@ async function ObfuscateFile(pluginOptions, finalized, file) {
|
|
|
19
20
|
if (Version) {
|
|
20
21
|
Reflect.set(proApiOptions, 'version', Version);
|
|
21
22
|
}
|
|
22
|
-
const obfuscateResult = await JsObf.obfuscatePro(
|
|
23
|
-
finalized.push({ fileName: file.path, outputCode: obfuscateResult.getObfuscatedCode().toString() });
|
|
23
|
+
const obfuscateResult = await JsObf.obfuscatePro(originalCode, pluginOptions.ObfuscatorOptions, proApiOptions, logger);
|
|
24
24
|
logger('obfuscation with VM Protection completed for file: ', file.path);
|
|
25
|
-
return
|
|
25
|
+
return obfuscateResult.getObfuscatedCode().toString();
|
|
26
26
|
}
|
|
27
|
-
logger('
|
|
28
|
-
const obfuscateResult = JsObf.obfuscate(
|
|
29
|
-
finalized.push({ fileName: file.path, outputCode: obfuscateResult.getObfuscatedCode().toString() });
|
|
30
|
-
console.log(finalized);
|
|
27
|
+
logger('obfuscating with no VM protection...');
|
|
28
|
+
const obfuscateResult = JsObf.obfuscate(originalCode, pluginOptions.ObfuscatorOptions);
|
|
31
29
|
logger('obfuscation completed for file: ', file.path);
|
|
32
|
-
return
|
|
30
|
+
return obfuscateResult.getObfuscatedCode().toString();
|
|
33
31
|
}
|
|
34
32
|
export function JSObfuscatorPlugin(options) {
|
|
35
33
|
const log = CreateLogger(options);
|
|
36
|
-
const finalized = [];
|
|
37
34
|
log('JSObfuscatorPlugin initialized with options:', options);
|
|
38
35
|
const [isValid, errorMsg] = ValidateOptions(options);
|
|
39
36
|
log('isValid: ', isValid, ' errorMsg: ', errorMsg);
|
|
@@ -41,11 +38,10 @@ export function JSObfuscatorPlugin(options) {
|
|
|
41
38
|
throw new Error(`Invalid JSObfuscatorPlugin options: ${errorMsg || 'no error message provided'}`);
|
|
42
39
|
}
|
|
43
40
|
log('creating plugin');
|
|
44
|
-
const obfuscateFile = ObfuscateFile.bind(null, options, finalized);
|
|
45
41
|
return {
|
|
46
42
|
name: 'esbuild-javascript-obfuscator',
|
|
47
43
|
setup(build) {
|
|
48
|
-
if (build.initialOptions.write) {
|
|
44
|
+
if (build.initialOptions.write || build.initialOptions.write === undefined) {
|
|
49
45
|
throw new Error('esbuild-javascript-obfuscator plugin requires write: false in build options');
|
|
50
46
|
}
|
|
51
47
|
build.onEnd(async ({ errors, outputFiles }) => {
|
|
@@ -57,22 +53,32 @@ export function JSObfuscatorPlugin(options) {
|
|
|
57
53
|
log('No output files found, skipping obfuscation');
|
|
58
54
|
return;
|
|
59
55
|
}
|
|
60
|
-
if
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
56
|
+
/* keep this here: on `watch` modes, this can cause a memory leak if not placed in this certain way.*/
|
|
57
|
+
const finalized = [];
|
|
58
|
+
for (const file of outputFiles) {
|
|
59
|
+
const fileName = path.basename(file.path);
|
|
60
|
+
const shouldObfuscate = options.ObfuscateAllFiles || (options.ObfuscateFilesWhitelist?.includes(fileName) ?? false);
|
|
61
|
+
if (shouldObfuscate && file.path.endsWith('.js')) {
|
|
62
|
+
try {
|
|
63
|
+
const outputCode = await ObfuscateFile(options, file);
|
|
64
|
+
/* write obfuscated output */
|
|
65
|
+
finalized.push({ fileName: file.path, outputCode });
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
log('failed to obfuscate file: ', file.path, err);
|
|
69
|
+
/* it failed, so just write the original file to the output */
|
|
70
|
+
finalized.push({
|
|
71
|
+
fileName: file.path,
|
|
72
|
+
outputCode: new TextDecoder().decode(file.contents),
|
|
73
|
+
});
|
|
68
74
|
}
|
|
69
75
|
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
else {
|
|
77
|
+
/* should not obfuscate, write orig file. */
|
|
78
|
+
finalized.push({
|
|
79
|
+
fileName: file.path,
|
|
80
|
+
outputCode: new TextDecoder().decode(file.contents),
|
|
81
|
+
});
|
|
76
82
|
}
|
|
77
83
|
}
|
|
78
84
|
/* write pass */
|
|
@@ -15,13 +15,15 @@ const ObfuscationOptions = {
|
|
|
15
15
|
ObfuscateAllFiles: false,
|
|
16
16
|
};
|
|
17
17
|
function CreateDummyFiles() {
|
|
18
|
+
function cleanup() {
|
|
19
|
+
fs.rmSync(path.join(__dirname, 'temp'), { recursive: true, force: true });
|
|
20
|
+
}
|
|
21
|
+
cleanup(); /* needs to be called incase other tests failed and left the temp folder behind */
|
|
18
22
|
fs.mkdirSync(path.join(__dirname, 'temp'));
|
|
19
23
|
fs.writeFileSync(path.join(__dirname, 'temp', 'index.ts'), `
|
|
20
24
|
console.log("Hello World")
|
|
21
25
|
`);
|
|
22
|
-
return
|
|
23
|
-
fs.rmSync(path.join(__dirname, 'temp'), { recursive: true, force: true });
|
|
24
|
-
};
|
|
26
|
+
return cleanup;
|
|
25
27
|
}
|
|
26
28
|
test('plugin should throw error when write: true', async () => {
|
|
27
29
|
const cleanup = CreateDummyFiles();
|
|
@@ -34,6 +36,16 @@ test('plugin should throw error when write: true', async () => {
|
|
|
34
36
|
})).rejects.toThrow(`esbuild-javascript-obfuscator plugin requires write: false in build options`);
|
|
35
37
|
cleanup();
|
|
36
38
|
});
|
|
39
|
+
test('plugin should throw error when write option is not provided', async () => {
|
|
40
|
+
const cleanup = CreateDummyFiles();
|
|
41
|
+
expect(esbuild.build({
|
|
42
|
+
entryPoints: [path.join(__dirname, 'temp', 'index.ts')],
|
|
43
|
+
bundle: true,
|
|
44
|
+
minify: true,
|
|
45
|
+
plugins: [JSObfuscatorPlugin(ObfuscationOptions)],
|
|
46
|
+
})).rejects.toThrow(`esbuild-javascript-obfuscator plugin requires write: false in build options`);
|
|
47
|
+
cleanup();
|
|
48
|
+
});
|
|
37
49
|
test('plugin should successfully obfuscate a single file', async () => {
|
|
38
50
|
const cleanup = CreateDummyFiles();
|
|
39
51
|
await esbuild.build({
|