Explorar o código

Merge pull request #128 from javascript-obfuscator/0.12.3-release

0.12.3 release
Timofey Kachalov %!s(int64=7) %!d(string=hai) anos
pai
achega
05d5b24c0d

+ 5 - 0
CHANGELOG.md

@@ -1,5 +1,10 @@
 Change Log
 Change Log
 ===
 ===
+v0.12.3
+---
+* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/125 (dead code injection and await expression)
+* Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/123
+
 v0.12.2
 v0.12.2
 ---
 ---
 * Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/121
 * Fixed https://github.com/javascript-obfuscator/javascript-obfuscator/issues/121

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
dist/index.js


+ 6 - 5
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "javascript-obfuscator",
   "name": "javascript-obfuscator",
-  "version": "0.12.2",
+  "version": "0.12.3",
   "description": "JavaScript obfuscator",
   "description": "JavaScript obfuscator",
   "keywords": [
   "keywords": [
     "obfuscator",
     "obfuscator",
@@ -37,7 +37,7 @@
     "tslib": "1.8.0"
     "tslib": "1.8.0"
   },
   },
   "devDependencies": {
   "devDependencies": {
-    "@types/chai": "4.0.4",
+    "@types/chai": "4.0.5",
     "@types/chance": "0.7.35",
     "@types/chance": "0.7.35",
     "@types/commander": "2.11.0",
     "@types/commander": "2.11.0",
     "@types/escodegen": "0.0.6",
     "@types/escodegen": "0.0.6",
@@ -47,11 +47,11 @@
     "@types/md5": "2.1.32",
     "@types/md5": "2.1.32",
     "@types/mkdirp": "0.5.1",
     "@types/mkdirp": "0.5.1",
     "@types/mocha": "2.2.44",
     "@types/mocha": "2.2.44",
-    "@types/node": "8.0.50",
-    "@types/sinon": "2.3.7",
+    "@types/node": "8.0.53",
+    "@types/sinon": "4.0.0",
     "@types/string-template": "1.0.2",
     "@types/string-template": "1.0.2",
     "@types/webpack-env": "1.13.2",
     "@types/webpack-env": "1.13.2",
-    "awesome-typescript-loader": "3.3.0",
+    "awesome-typescript-loader": "3.4.0",
     "babel-cli": "6.26.0",
     "babel-cli": "6.26.0",
     "babel-loader": "7.1.2",
     "babel-loader": "7.1.2",
     "babel-plugin-array-includes": "2.0.3",
     "babel-plugin-array-includes": "2.0.3",
@@ -62,6 +62,7 @@
     "mocha": "4.0.1",
     "mocha": "4.0.1",
     "pre-commit": "1.2.2",
     "pre-commit": "1.2.2",
     "sinon": "4.1.2",
     "sinon": "4.1.2",
+    "threads": "^0.8.1",
     "ts-node": "3.3.0",
     "ts-node": "3.3.0",
     "tslint": "5.8.0",
     "tslint": "5.8.0",
     "tslint-eslint-rules": "4.1.1",
     "tslint-eslint-rules": "4.1.1",

+ 2 - 1
src/declarations/escodegen.d.ts

@@ -1,4 +1,5 @@
 import * as escodegen from 'escodegen';
 import * as escodegen from 'escodegen';
+import * as ESTree from 'estree';
 
 
 import { IGeneratorOutput } from '../interfaces/IGeneratorOutput';
 import { IGeneratorOutput } from '../interfaces/IGeneratorOutput';
 
 
@@ -8,5 +9,5 @@ declare module 'escodegen' {
      * @param options
      * @param options
      * @returns IGeneratorOutput
      * @returns IGeneratorOutput
      */
      */
-    export function generate (ast: any, options?: escodegen.GenerateOptions): IGeneratorOutput;
+    export function generate (ast: ESTree.Node, options?: escodegen.GenerateOptions): IGeneratorOutput;
 }
 }

+ 15 - 0
src/declarations/threads.d.ts

@@ -0,0 +1,15 @@
+declare module 'threads' {
+    type PostMessage <U> = (data: U) => void;
+    type SpawnCallback <T, U> = (data: T, postMessage: PostMessage <U>) => void;
+    type ResponseCallback <U> = (response: U) => void;
+
+    class Thread <T, U> {
+        public killed: boolean;
+
+        public send (data: T): Thread <T, U>;
+        public on (eventType: string, responseCallback: ResponseCallback<U>): Thread <T, U>;
+        public kill (): void;
+    }
+
+    export function spawn <T, U> (spawnCallback: SpawnCallback <T, U>): Thread <T, U>;
+}

+ 1 - 0
src/enums/node/NodeType.ts

@@ -3,6 +3,7 @@ export enum NodeType {
     ArrowFunctionExpression = 'ArrowFunctionExpression',
     ArrowFunctionExpression = 'ArrowFunctionExpression',
     AssignmentExpression = 'AssignmentExpression',
     AssignmentExpression = 'AssignmentExpression',
     AssignmentPattern = 'AssignmentPattern',
     AssignmentPattern = 'AssignmentPattern',
+    AwaitExpression = 'AwaitExpression',
     BinaryExpression = 'BinaryExpression',
     BinaryExpression = 'BinaryExpression',
     BlockStatement = 'BlockStatement',
     BlockStatement = 'BlockStatement',
     BreakStatement = 'BreakStatement',
     BreakStatement = 'BreakStatement',

+ 2 - 1
src/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.ts

@@ -174,7 +174,8 @@ export class DeadCodeInjectionTransformer extends AbstractNodeTransformer {
                 if (
                 if (
                     nestedBlockStatementsCount > DeadCodeInjectionTransformer.maxNestedBlockStatementsCount ||
                     nestedBlockStatementsCount > DeadCodeInjectionTransformer.maxNestedBlockStatementsCount ||
                     NodeGuards.isBreakStatementNode(node) ||
                     NodeGuards.isBreakStatementNode(node) ||
-                    NodeGuards.isContinueStatementNode(node)
+                    NodeGuards.isContinueStatementNode(node) ||
+                    NodeGuards.isAwaitExpressionNode(node)
                 ) {
                 ) {
                     isValidBlockStatementNode = false;
                     isValidBlockStatementNode = false;
 
 

+ 8 - 0
src/node/NodeGuards.ts

@@ -21,6 +21,14 @@ export class NodeGuards {
         return node.type === NodeType.AssignmentPattern;
         return node.type === NodeType.AssignmentPattern;
     }
     }
 
 
+    /**
+     * @param {Node} node
+     * @returns {boolean}
+     */
+    public static isAwaitExpressionNode (node: ESTree.Node): node is ESTree.AwaitExpression {
+        return node.type === NodeType.AwaitExpression;
+    }
+
     /**
     /**
      * @param {Node} node
      * @param {Node} node
      * @returns {boolean}
      * @returns {boolean}

+ 3 - 2
src/node/NodeUtils.ts

@@ -4,6 +4,7 @@ import * as estraverse from 'estraverse';
 import * as ESTree from 'estree';
 import * as ESTree from 'estree';
 
 
 import { TNodeWithBlockStatement } from '../types/node/TNodeWithBlockStatement';
 import { TNodeWithBlockStatement } from '../types/node/TNodeWithBlockStatement';
+import { TObject } from '../types/TObject';
 import { TStatement } from '../types/node/TStatement';
 import { TStatement } from '../types/node/TStatement';
 
 
 import { NodeType } from '../enums/node/NodeType';
 import { NodeType } from '../enums/node/NodeType';
@@ -55,13 +56,13 @@ export class NodeUtils {
                 return node;
                 return node;
             }
             }
 
 
-            const copy: {[key: string]: any} = {};
+            const copy: TObject = {};
 
 
             Object
             Object
                 .keys(node)
                 .keys(node)
                 .filter((property: string) => property !== 'parentNode')
                 .filter((property: string) => property !== 'parentNode')
                 .forEach((property: string): void => {
                 .forEach((property: string): void => {
-                    const value: any = (<{[key: string]: any}>node)[property];
+                    const value: any = (<TObject>node)[property];
 
 
                     let clonedValue: any | null;
                     let clonedValue: any | null;
 
 

+ 1 - 1
src/templates/debug-protection-nodes/debug-protection-function-call-node/DebufProtectionFunctionCallTemplate.ts

@@ -5,7 +5,7 @@ export function DebugProtectionFunctionCallTemplate (): string {
     return `
     return `
         (function () {
         (function () {
             var regExp1 = new RegExp('function *\\\\( *\\\\)');
             var regExp1 = new RegExp('function *\\\\( *\\\\)');
-            var regExp2 = new RegExp('\\\\+\\\\+ *_0x([a-f0-9]){4,6}');
+            var regExp2 = new RegExp('\\\\+\\\\+ *\\(?:_0x([a-f0-9]){4,6}|\\\\b[a-zA-Z]{1,2}\\\\b\\)');
             var result = {debugProtectionFunctionName}('init');
             var result = {debugProtectionFunctionName}('init');
             
             
             if (!regExp1.test(result + 'chain') || !regExp2.test(result + 'input')) {
             if (!regExp1.test(result + 'chain') || !regExp2.test(result + 'input')) {

+ 56 - 3
test/functional-tests/node-transformers/dead-code-injection-transformers/DeadCodeInjectionTransformer.spec.ts

@@ -178,7 +178,60 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #5 - chance of `IfStatement` variant', () => {
+        describe('variant #5 - await expression in block statement', () => {
+            const functionRegExp: RegExp = new RegExp(
+                `var *${variableMatch} *= *function *\\(\\) *\\{` +
+                    `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
+                `\\};`,
+                'g'
+            );
+            const awaitExpressionRegExp: RegExp = new RegExp(
+                `await *${variableMatch}\\(\\)`,
+                'g'
+            );
+            const expectedFunctionMatchesLength: number = 4;
+            const expectedAwaitExpressionMatchesLength: number = 1;
+
+            let functionMatchesLength: number = 0,
+                awaitExpressionMatchesLength: number = 0;
+
+            before(() => {
+                const code: string = readFileAsString(__dirname + '/fixtures/await-expression.js');
+                const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                    code,
+                    {
+                        ...NO_CUSTOM_NODES_PRESET,
+                        deadCodeInjection: true,
+                        deadCodeInjectionThreshold: 1,
+                        stringArray: true,
+                        stringArrayThreshold: 1
+                    }
+                );
+                const obfuscatedCode: string = obfuscationResult.getObfuscatedCode();
+                const functionMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(functionRegExp);
+                const awaitExpressionMatches: RegExpMatchArray = <RegExpMatchArray>obfuscatedCode.match(awaitExpressionRegExp);
+
+                console.log(obfuscatedCode);
+
+                if (functionMatches) {
+                    functionMatchesLength = functionMatches.length;
+                }
+
+                if (awaitExpressionMatches) {
+                    awaitExpressionMatchesLength = awaitExpressionMatches.length;
+                }
+            });
+
+            it('match #1: shouldn\'t add dead code', () => {
+                assert.equal(functionMatchesLength, expectedFunctionMatchesLength);
+            });
+
+            it('match #2: shouldn\'t add dead code', () => {
+                assert.equal(awaitExpressionMatchesLength, expectedAwaitExpressionMatchesLength);
+            });
+        });
+
+        describe('variant #6 - chance of `IfStatement` variant', () => {
             const samplesCount: number = 1000;
             const samplesCount: number = 1000;
             const delta: number = 0.1;
             const delta: number = 0.1;
             const expectedDistribution: number = 0.25;
             const expectedDistribution: number = 0.25;
@@ -280,7 +333,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #6 - block scope of block statement is `ProgramNode`', () => {
+        describe('variant #7 - block scope of block statement is `ProgramNode`', () => {
             const regExp: RegExp = new RegExp(
             const regExp: RegExp = new RegExp(
                 `if *\\(!!\\[\\]\\) *{` +
                 `if *\\(!!\\[\\]\\) *{` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
                     `console\\[${variableMatch}\\('${hexMatch}'\\)\\]\\(${variableMatch}\\('${hexMatch}'\\)\\);` +
@@ -310,7 +363,7 @@ describe('DeadCodeInjectionTransformer', () => {
             });
             });
         });
         });
 
 
-        describe('variant #7 - correct obfuscation of dead-code block statements', () => {
+        describe('variant #8 - correct obfuscation of dead-code block statements', () => {
             const variableName: string = 'importantVariableName';
             const variableName: string = 'importantVariableName';
 
 
             let obfuscatedCode: string;
             let obfuscatedCode: string;

+ 25 - 0
test/functional-tests/node-transformers/dead-code-injection-transformers/fixtures/await-expression.js

@@ -0,0 +1,25 @@
+(async function(){
+    if (true) {
+        var foo = function () {
+            console.log('abc');
+        };
+        var bar = function () {
+            console.log('def');
+        };
+        var baz = function () {
+            console.log('ghi');
+        };
+        var bark = function () {
+            console.log('jkl');
+        };
+
+        if (true) {
+            await foo();
+        }
+
+        foo();
+        bar();
+        baz();
+        bark();
+    }
+})();

+ 138 - 0
test/functional-tests/templates/custom-nodes/debug-protection-nodes/DebufProtectionFunctionCallTemplate.spec.ts

@@ -0,0 +1,138 @@
+import { assert } from 'chai';
+import { spawn } from 'threads';
+
+import { IObfuscationResult } from '../../../../../src/interfaces/IObfuscationResult';
+
+import { readFileAsString } from '../../../../helpers/readFileAsString';
+
+import { NO_CUSTOM_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
+
+import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
+
+function spawnThread(inputCallback: Function, threadCallback: Function, timeoutCallback: Function): void {
+    const thread = spawn<string, number>((input: string, postMessage: Function) => {
+        postMessage(eval(input));
+    });
+
+    const timeout = setTimeout(() => {
+        thread.kill();
+        timeoutCallback();
+    }, 500);
+
+    thread
+        .send(inputCallback())
+        .on('message', (response: number) => {
+            clearTimeout(timeout);
+            thread.kill();
+            threadCallback(response);
+        });
+}
+
+describe('DebugProtectionFunctionCallTemplate (): string', () => {
+    describe('variant #1: correctly obfuscated code`', () => {
+        const expectedEvaluationResult: number = 1;
+
+        let obfuscatedCode: string,
+            evaluationResult: number = 0;
+
+        beforeEach((done) => {
+            const code: string = readFileAsString(__dirname + '/fixtures/input.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET,
+                    debugProtection: true
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+
+            spawnThread(
+                () => obfuscatedCode,
+                (response: number) => {
+                    evaluationResult = response;
+                    done();
+                },
+                () => {
+                    done();
+                }
+            );
+        });
+
+        it('should correctly evaluate code with enabled debug protection', () => {
+            assert.equal(evaluationResult, expectedEvaluationResult);
+        });
+    });
+
+    describe('variant #2: correctly obfuscated code with enabled `mangle` option', () => {
+        const expectedEvaluationResult: number = 1;
+
+        let obfuscatedCode: string,
+            evaluationResult: number = 0;
+
+        beforeEach((done) => {
+            const code: string = readFileAsString(__dirname + '/fixtures/input.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET,
+                    debugProtection: true,
+                    mangle: true
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+
+            spawnThread(
+                () => obfuscatedCode,
+                (response: number) => {
+                    evaluationResult = response;
+                    done();
+                },
+                () => {
+                    done();
+                }
+            );
+        });
+
+        it('should correctly evaluate code with enabled debug protection', () => {
+            assert.equal(evaluationResult, expectedEvaluationResult);
+        });
+    });
+
+    describe('variant #3: obfuscated code with removed debug protection function call', () => {
+        const expectedEvaluationResult: number = 0;
+
+        let obfuscatedCode: string,
+            evaluationResult: number = 0;
+
+        beforeEach((done) => {
+            const code: string = readFileAsString(__dirname + '/fixtures/input.js');
+            const obfuscationResult: IObfuscationResult = JavaScriptObfuscator.obfuscate(
+                code,
+                {
+                    ...NO_CUSTOM_NODES_PRESET,
+                    debugProtection: true
+                }
+            );
+
+            obfuscatedCode = obfuscationResult.getObfuscatedCode();
+            obfuscatedCode = obfuscatedCode.replace(/\+\+ *_0x([a-f0-9]){4,6}/, '++abc');
+
+            spawnThread(
+                () => obfuscatedCode,
+                (response: number) => {
+                    evaluationResult = response;
+                    done();
+                },
+                () => {
+                    done();
+                }
+            );
+        });
+
+        it('should enter code in infinity loop', () => {
+            assert.equal(evaluationResult, expectedEvaluationResult);
+        });
+    });
+});

+ 3 - 0
test/functional-tests/templates/custom-nodes/debug-protection-nodes/fixtures/input.js

@@ -0,0 +1,3 @@
+(function () {
+    return 1;
+})();

+ 1 - 0
test/index.spec.ts

@@ -62,6 +62,7 @@ import './functional-tests/node-transformers/obfuscating-transformers/object-exp
 import './functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec';
 import './functional-tests/node-transformers/obfuscating-transformers/variable-declaration-transformer/VariableDeclarationTransformer.spec';
 import './functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
 import './functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/black-list-obfuscating-guard/BlackListObfuscatingGuard.spec';
 import './functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
 import './functional-tests/node-transformers/parentizing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
+import './functional-tests/templates/custom-nodes/debug-protection-nodes/DebufProtectionFunctionCallTemplate.spec';
 import './functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec';
 import './functional-tests/templates/custom-nodes/domain-lock-nodes/DomainLockNodeTemplate.spec';
 import './functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec';
 import './functional-tests/templates/custom-nodes/string-array-nodes/StringArrayCallsWrapperNodeTemplate.spec';
 
 

+ 27 - 16
yarn.lock

@@ -2,9 +2,9 @@
 # yarn lockfile v1
 # yarn lockfile v1
 
 
 
 
-"@types/[email protected].4":
-  version "4.0.4"
-  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.4.tgz#fe86315d9a66827feeb16f73bc954688ec950e18"
+"@types/[email protected].5":
+  version "4.0.5"
+  resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.0.5.tgz#b6e250e281b47e0192e236619e9b1afe62fd345c"
 
 
 "@types/[email protected]":
 "@types/[email protected]":
   version "0.7.35"
   version "0.7.35"
@@ -52,17 +52,13 @@
   version "2.2.44"
   version "2.2.44"
   resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e"
   resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.44.tgz#1d4a798e53f35212fd5ad4d04050620171cd5b5e"
 
 
-"@types/node@*":
-  version "8.0.47"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.47.tgz#968e596f91acd59069054558a00708c445ca30c2"
-
-"@types/[email protected]":
-  version "8.0.50"
-  resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.50.tgz#dc545448e128c88c4eec7cd64025fcc3b7604541"
+"@types/node@*", "@types/[email protected]":
+  version "8.0.53"
+  resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.53.tgz#396b35af826fa66aad472c8cb7b8d5e277f4e6d8"
 
 
-"@types/sinon@2.3.7":
-  version "2.3.7"
-  resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-2.3.7.tgz#e92c2fed3297eae078d78d1da032b26788b4af86"
+"@types/[email protected]":
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-4.0.0.tgz#9a93ffa4ee1329e85166278a5ed99f81dc4c8362"
 
 
 "@types/[email protected]":
 "@types/[email protected]":
   version "1.0.2"
   version "1.0.2"
@@ -256,9 +252,9 @@ atob@^2.0.0:
   version "2.0.3"
   version "2.0.3"
   resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
   resolved "https://registry.yarnpkg.com/atob/-/atob-2.0.3.tgz#19c7a760473774468f20b2d2d03372ad7d4cbf5d"
 
 
-awesome-typescript-loader@3.3.0:
-  version "3.3.0"
-  resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-3.3.0.tgz#24bed5650ca0d6e95457904d9969127ba4ff3575"
+awesome-typescript-loader@3.4.0:
+  version "3.4.0"
+  resolved "https://registry.yarnpkg.com/awesome-typescript-loader/-/awesome-typescript-loader-3.4.0.tgz#aed2c83af614d617d11e3ec368ac3befb55d002f"
   dependencies:
   dependencies:
     colors "^1.1.2"
     colors "^1.1.2"
     enhanced-resolve "3.3.0"
     enhanced-resolve "3.3.0"
@@ -1532,6 +1528,10 @@ event-emitter@~0.3.5:
     d "1"
     d "1"
     es5-ext "~0.10.14"
     es5-ext "~0.10.14"
 
 
+eventemitter3@^2.0.2:
+  version "2.0.3"
+  resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-2.0.3.tgz#b5e1079b59fb5e1ba2771c0a993be060a58c99ba"
+
 events@^1.0.0:
 events@^1.0.0:
   version "1.1.1"
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
   resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924"
@@ -2683,6 +2683,10 @@ nanomatch@^1.2.5:
     snapdragon "^0.8.1"
     snapdragon "^0.8.1"
     to-regex "^3.0.1"
     to-regex "^3.0.1"
 
 
+native-promise-only@^0.8.1:
+  version "0.8.1"
+  resolved "https://registry.yarnpkg.com/native-promise-only/-/native-promise-only-0.8.1.tgz#20a318c30cb45f71fe7adfbf7b21c99c1472ef11"
+
 nise@^1.2.0:
 nise@^1.2.0:
   version "1.2.0"
   version "1.2.0"
   resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
   resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.0.tgz#079d6cadbbcb12ba30e38f1c999f36ad4d6baa53"
@@ -3723,6 +3727,13 @@ text-encoding@^0.6.4:
   version "0.6.4"
   version "0.6.4"
   resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
   resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19"
 
 
+threads@^0.8.1:
+  version "0.8.1"
+  resolved "https://registry.yarnpkg.com/threads/-/threads-0.8.1.tgz#e340115b5947316d2f7ee3123c4c2c5bf9c76d72"
+  dependencies:
+    eventemitter3 "^2.0.2"
+    native-promise-only "^0.8.1"
+
 through@^2.3.6:
 through@^2.3.6:
   version "2.3.8"
   version "2.3.8"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"
   resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio