UNPKG

javascript-obfuscator

Version:
149 lines (124 loc) 6.73 kB
import { inject, injectable } from 'inversify'; import { ServiceIdentifiers } from '../../../container/ServiceIdentifiers'; import * as ESTree from 'estree'; import { TNodeWithStatements } from '../../../types/node/TNodeWithStatements'; import { TObjectExpressionKeysTransformerCustomNodeFactory } from '../../../types/container/custom-nodes/TObjectExpressionKeysTransformerCustomNodeFactory'; import { IObjectExpressionExtractorResult } from '../../../interfaces/node-transformers/converting-transformers/object-expression-extractors/IObjectExpressionExtractorResult'; import { TStatement } from '../../../types/node/TStatement'; import { ICustomNode } from '../../../interfaces/custom-nodes/ICustomNode'; import { TInitialData } from '../../../types/TInitialData'; import { IObjectExpressionExtractor } from '../../../interfaces/node-transformers/converting-transformers/object-expression-extractors/IObjectExpressionExtractor'; import { ObjectExpressionKeysTransformerCustomNode } from '../../../enums/custom-nodes/ObjectExpressionKeysTransformerCustomNode'; import { ObjectExpressionVariableDeclarationHostNode } from '../../../custom-nodes/object-expression-keys-transformer-nodes/ObjectExpressionVariableDeclarationHostNode'; import { NodeAppender } from '../../../node/NodeAppender'; import { NodeGuards } from '../../../node/NodeGuards'; import { NodeStatementUtils } from '../../../node/NodeStatementUtils'; import { NodeUtils } from '../../../node/NodeUtils'; @injectable() export class ObjectExpressionToVariableDeclarationExtractor implements IObjectExpressionExtractor { /** * @type {TObjectExpressionKeysTransformerCustomNodeFactory} */ private readonly objectExpressionKeysTransformerCustomNodeFactory: TObjectExpressionKeysTransformerCustomNodeFactory; /** * @param {TObjectExpressionKeysTransformerCustomNodeFactory} objectExpressionKeysTransformerCustomNodeFactory */ public constructor ( @inject(ServiceIdentifiers.Factory__IObjectExpressionKeysTransformerCustomNode) objectExpressionKeysTransformerCustomNodeFactory: TObjectExpressionKeysTransformerCustomNodeFactory, ) { this.objectExpressionKeysTransformerCustomNodeFactory = objectExpressionKeysTransformerCustomNodeFactory; } /** * extracts object expression: * var object = { * foo: 1, * bar: 2 * }; * * to: * var _0xabc123 = { * foo: 1, * bar: 2 * }; * var object = _0xabc123; * * @param {ObjectExpression} objectExpressionNode * @param {Statement} hostStatement * @returns {IObjectExpressionExtractorResult} */ public extract ( objectExpressionNode: ESTree.ObjectExpression, hostStatement: ESTree.Statement ): IObjectExpressionExtractorResult { return this.transformObjectExpressionToVariableDeclaration( objectExpressionNode, hostStatement ); } /** * @param {ObjectExpression} objectExpressionNode * @param {Statement} hostStatement * @returns {Node} */ private transformObjectExpressionToVariableDeclaration ( objectExpressionNode: ESTree.ObjectExpression, hostStatement: ESTree.Statement ): IObjectExpressionExtractorResult { const properties: ESTree.Property[] = objectExpressionNode.properties; const newObjectExpressionHostStatement: ESTree.VariableDeclaration = this.getObjectExpressionHostNode(properties); const newObjectExpressionIdentifier: ESTree.Identifier = this.getObjectExpressionIdentifierNode(newObjectExpressionHostStatement); const newObjectExpressionNode: ESTree.ObjectExpression = this.getObjectExpressionNode(newObjectExpressionHostStatement); const statementsToInsert: TStatement[] = [newObjectExpressionHostStatement]; const hostNodeWithStatements: TNodeWithStatements = NodeStatementUtils.getScopeOfNode(hostStatement); NodeAppender.insertBefore(hostNodeWithStatements, statementsToInsert, hostStatement); NodeUtils.parentizeAst(newObjectExpressionHostStatement); NodeUtils.parentizeNode(newObjectExpressionHostStatement, hostNodeWithStatements); return { nodeToReplace: newObjectExpressionIdentifier, objectExpressionHostStatement: newObjectExpressionHostStatement, objectExpressionNode: newObjectExpressionNode }; } /** * @param {Property[]} properties * @returns {VariableDeclaration} */ private getObjectExpressionHostNode (properties: ESTree.Property[]): ESTree.VariableDeclaration { const variableDeclarationHostNodeCustomNode: ICustomNode<TInitialData<ObjectExpressionVariableDeclarationHostNode>> = this.objectExpressionKeysTransformerCustomNodeFactory( ObjectExpressionKeysTransformerCustomNode.ObjectExpressionVariableDeclarationHostNode ); variableDeclarationHostNodeCustomNode.initialize(properties); const statementNode: TStatement = variableDeclarationHostNodeCustomNode.getNode()[0]; if ( !statementNode || !NodeGuards.isVariableDeclarationNode(statementNode) ) { throw new Error('`objectExpressionHostCustomNode.getNode()[0]` should returns array with `VariableDeclaration` node'); } return statementNode; } /** * @param {VariableDeclaration} objectExpressionHostNode * @returns {Identifier} */ private getObjectExpressionIdentifierNode (objectExpressionHostNode: ESTree.VariableDeclaration): ESTree.Identifier { const newObjectExpressionIdentifierNode: ESTree.Pattern = objectExpressionHostNode.declarations[0].id; if (!NodeGuards.isIdentifierNode(newObjectExpressionIdentifierNode)) { throw new Error('`objectExpressionHostNode` should contain `VariableDeclarator` node with `Identifier` id property'); } return newObjectExpressionIdentifierNode; } /** * @param {VariableDeclaration} objectExpressionHostNode * @returns {Identifier} */ private getObjectExpressionNode (objectExpressionHostNode: ESTree.VariableDeclaration): ESTree.ObjectExpression { const newObjectExpressionNode: ESTree.Expression | null = objectExpressionHostNode.declarations[0].init ?? null; if (!newObjectExpressionNode || !NodeGuards.isObjectExpressionNode(newObjectExpressionNode)) { throw new Error('`objectExpressionHostNode` should contain `VariableDeclarator` node with `ObjectExpression` init property'); } return newObjectExpressionNode; } }