voluptasvelit
Version:
JavaScript obfuscator
103 lines (86 loc) • 3.07 kB
text/typescript
import * as espree from 'espree';
import * as ESTree from 'estree';
import chalk, { Chalk } from 'chalk';
/**
* Facade over `espree`
*/
export class EspreeFacade {
/**
* @type {Chalk}
*/
private static readonly colorError: Chalk = chalk.red;
/**
* @type {number}
*/
private static readonly nearestSymbolsCount: number = 15;
/**
* @type {SourceType[]}
*/
private static readonly sourceTypes: espree.SourceType[] = [
'script',
'module'
];
/**
* @param {string} input
* @param {Options} config
* @returns {Program}
*/
public static parse (input: string, config: espree.ParseOptions): ESTree.Program | never {
const sourceTypeLength: number = EspreeFacade.sourceTypes.length;
for (let i: number = 0; i < sourceTypeLength; i++) {
try {
return EspreeFacade.parseType(input, config, EspreeFacade.sourceTypes[i]);
} catch (error) {
if (i < sourceTypeLength - 1) {
continue;
}
throw new Error(EspreeFacade.processParsingError(
input,
error.message,
{
line: error.lineNumber,
column: error.column,
}
));
}
}
throw new Error(`Espree parsing error`);
}
/**
* @param {string} input
* @param {ParseOptions} inputConfig
* @param {SourceType} sourceType
* @returns {Program}
*/
private static parseType (
input: string,
inputConfig: espree.ParseOptions,
sourceType: espree.SourceType
): ESTree.Program {
const config: espree.ParseOptions = { ...inputConfig, sourceType };
return espree.parse(input, config);
}
/**
* @param {string} sourceCode
* @param {string} errorMessage
* @param {Position} position
* @returns {never}
*/
private static processParsingError (sourceCode: string, errorMessage: string, position: ESTree.Position | null): never {
if (!position || !position.line || !position.column) {
throw new Error(errorMessage);
}
const sourceCodeLines: string[] = sourceCode.split(/\r?\n/);
const errorLine: string | undefined = sourceCodeLines[position.line - 1];
if (!errorLine) {
throw new Error(errorMessage);
}
const startErrorIndex: number = Math.max(0, position.column - EspreeFacade.nearestSymbolsCount);
const endErrorIndex: number = Math.min(errorLine.length, position.column + EspreeFacade.nearestSymbolsCount);
const formattedPointer: string = EspreeFacade.colorError('>');
const formattedCodeSlice: string = `...${
errorLine.substring(startErrorIndex, endErrorIndex).replace(/^\s+/, '')
}...`;
throw new Error(`Line ${position.line}: ${errorMessage}\n${formattedPointer} ${formattedCodeSlice}`);
}
}