UNPKG

@oaklean/cli

Version:

A command-line interface that provides utilities for parsing, inspecting, and converting the .oak file format, as well as interfaces used in the @oaklean suite.

228 lines 21.1 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const fs = __importStar(require("fs")); const glob_1 = require("glob"); const profiler_core_1 = require("@oaklean/profiler-core"); const commander_1 = require("commander"); class CodeParsingCommands { constructor() { const parseCommand = commander_1.program .command('parse') .description('commands to parse javascript or typescript files'); parseCommand .command('toPST') .description('Converts a given javascript/typescript file and extracts the ProgramStructureTree from it and stores it into a file') .argument('<input>', 'input file path') .argument('<output>', 'output file path') .action(this.convertToProgramStructureTree.bind(this)); parseCommand .command('verify-identifiers') .alias('vi') .description('Parses all source files (.js, .ts, .jsx, .tsx) within a given path and verifies that all identifiers are valid and unique') .argument('<input>', 'input file path') .option('--t262', 'Specifies whether files should be ignored that contain a "$DONOTEVALUATE();", this is useful for test262 source files') .action(this.verifySourceFilesIdentifiers.bind(this)); const externalResourceCommand = commander_1.program .command('external-resource') .alias('er') .description('commands to interact with external resource files ' + `(${profiler_core_1.EXTERNAL_RESOURCE_HELPER_FILE_EXTENSION})`); externalResourceCommand .command('verify-identifiers') .alias('vi') .description('Parses all source files in all resource files within a given path and verifies that all identifiers are valid and unique') .argument('<input>', `File path to the directory containing the ${profiler_core_1.EXTERNAL_RESOURCE_HELPER_FILE_EXTENSION} files`) .action(this.verifyIdentifiers.bind(this)); externalResourceCommand .command('extract') .alias('e') .description('Extract a file from a resource file and stores it into a separate file') .argument('<input>', `File path to the ${profiler_core_1.EXTERNAL_RESOURCE_HELPER_FILE_EXTENSION} file`) .argument('<file>', 'File to extract from the resource file (scriptID or file path)') .option('-o, --output <output>', 'Path to store the file (default: execute directory + code.ts)', undefined) .action(this.extractFile.bind(this)); } static init() { return new CodeParsingCommands(); } convertToProgramStructureTree(input, output) { return __awaiter(this, void 0, void 0, function* () { let inputPath = new profiler_core_1.UnifiedPath(input); if (inputPath.isRelative()) { inputPath = new profiler_core_1.UnifiedPath(process.cwd()).join(inputPath); } let outputPath = new profiler_core_1.UnifiedPath(output); if (outputPath.isRelative()) { outputPath = new profiler_core_1.UnifiedPath(process.cwd()).join(outputPath); } const programStructureTree = profiler_core_1.TypescriptParser.parseFile(inputPath); programStructureTree.storeToFile(outputPath); }); } verifyCode(code, addToDebug) { if (code === null) { return; } const tmpName = (addToDebug.scriptID !== undefined ? addToDebug.scriptID : addToDebug.filePath) || 'tmp.ts'; profiler_core_1.TypescriptParser.parseSource(new profiler_core_1.UnifiedPath(tmpName), code, 'TSX', (filePath, node, identifier, loc, duplicateLoc) => { profiler_core_1.LoggerHelper.warn('Duplicated identifier found:', Object.assign(Object.assign({}, addToDebug), { identifier, original: loc, duplicate: duplicateLoc })); }); } verifySourceFilesIdentifiers(input, options) { return __awaiter(this, void 0, void 0, function* () { let inputPath = new profiler_core_1.UnifiedPath(input); if (inputPath.isRelative()) { inputPath = new profiler_core_1.UnifiedPath(process.cwd()).join(inputPath); } const globPattern = inputPath .join('**', '*.{js,ts,jsx,tsx}') .toPlatformString(); if (fs.existsSync(inputPath.toPlatformString())) { const filePaths = (0, glob_1.sync)(globPattern.toString(), { dot: true }); filePaths.map((filePath) => new profiler_core_1.UnifiedPath(filePath)); for (const filePath of filePaths) { if (fs.statSync(filePath).isDirectory()) { continue; } if (filePath.endsWith('.d.ts')) { continue; // Skip declaration files } const sourceFilePath = new profiler_core_1.UnifiedPath(filePath); let code = fs.readFileSync(sourceFilePath.toPlatformString(), 'utf-8'); if (options.t262 !== undefined && code.includes('$DONOTEVALUATE();')) { code = code.split('$DONOTEVALUATE();')[0]; } try { this.verifyCode(code, { resourceFile: inputPath.toPlatformString(), filePath: sourceFilePath.toString() }); } catch (error) { profiler_core_1.LoggerHelper.error(`Error parsing file ${sourceFilePath.toPlatformString()}:`, error); continue; } } } else { profiler_core_1.LoggerHelper.error(`Input path does not exist: ${inputPath.toPlatformString()}`); return; } }); } verifyIdentifiers(input) { return __awaiter(this, void 0, void 0, function* () { let inputPath = new profiler_core_1.UnifiedPath(input); if (inputPath.isRelative()) { inputPath = new profiler_core_1.UnifiedPath(process.cwd()).join(inputPath); } const exportAssetHelper = new profiler_core_1.ExportAssetHelper(inputPath); const cwdPath = new profiler_core_1.UnifiedPath(process.cwd()); const externalResourcePaths = exportAssetHelper.allExternalResourcePathsInOutputDir(); for (const externalResourcePath of externalResourcePaths) { const relativePath = cwdPath.pathTo(externalResourcePath); const resourceFile = profiler_core_1.ExternalResourceHelper.loadFromFile(new profiler_core_1.UnifiedPath(process.cwd()), externalResourcePath); if (resourceFile === undefined) { profiler_core_1.LoggerHelper.error(`Could not load resource file: ${relativePath.toPlatformString()}`); continue; } const scriptIDs = resourceFile.scriptIDs; const filePaths = resourceFile.loadedFilePaths; for (const scriptID of scriptIDs) { const code = yield resourceFile.sourceCodeFromScriptID(scriptID); this.verifyCode(code, { resourceFile: relativePath.toPlatformString(), scriptID }); } for (const filePath of filePaths) { const code = yield resourceFile.sourceCodeFromPath(filePath, filePath); this.verifyCode(code, { resourceFile: relativePath.toPlatformString(), filePath }); } } }); } extractFile(input, file, options) { return __awaiter(this, void 0, void 0, function* () { let inputPath = new profiler_core_1.UnifiedPath(input); if (inputPath.isRelative()) { inputPath = new profiler_core_1.UnifiedPath(process.cwd()).join(inputPath); } let outputPath = new profiler_core_1.UnifiedPath(options.output !== undefined ? options.output : 'code.ts'); if (outputPath.isRelative()) { outputPath = new profiler_core_1.UnifiedPath(process.cwd()).join(outputPath); } const cwdPath = new profiler_core_1.UnifiedPath(process.cwd()); const relativeInputPath = cwdPath.pathTo(inputPath); const resourceFile = profiler_core_1.ExternalResourceHelper.loadFromFile(new profiler_core_1.UnifiedPath(process.cwd()), inputPath); if (resourceFile === undefined) { profiler_core_1.LoggerHelper.error(`Could not load resource file: ${relativeInputPath.toPlatformString()}`); return; } let code = ''; if (resourceFile.scriptIDs.includes(file)) { code = yield resourceFile.sourceCodeFromScriptID(file); } else if (resourceFile.loadedFilePaths.includes(file)) { code = yield resourceFile.sourceCodeFromPath(file, file); } else { profiler_core_1.LoggerHelper.error(`File ${file} not found in resource file: ${relativeInputPath.toPlatformString()}`); } if (code === null) { profiler_core_1.LoggerHelper.error(`File '${file}' is marked as missing (was not present during profiling)`); return; } profiler_core_1.PermissionHelper.writeFileWithUserPermission(outputPath, code); }); } } exports.default = CodeParsingCommands; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQ29kZVBhcnNpbmdDb21tYW5kcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jb21tYW5kcy9Db2RlUGFyc2luZ0NvbW1hbmRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUEsdUNBQXdCO0FBRXhCLCtCQUEyQjtBQUMzQiwwREFVK0I7QUFDL0IseUNBQW1DO0FBRW5DLE1BQXFCLG1CQUFtQjtJQUN2QztRQUNDLE1BQU0sWUFBWSxHQUFHLG1CQUFPO2FBQzFCLE9BQU8sQ0FBQyxPQUFPLENBQUM7YUFDaEIsV0FBVyxDQUFDLGtEQUFrRCxDQUFDLENBQUE7UUFFakUsWUFBWTthQUNWLE9BQU8sQ0FBQyxPQUFPLENBQUM7YUFDaEIsV0FBVyxDQUNYLHFIQUFxSCxDQUNySDthQUNBLFFBQVEsQ0FBQyxTQUFTLEVBQUUsaUJBQWlCLENBQUM7YUFDdEMsUUFBUSxDQUFDLFVBQVUsRUFBRSxrQkFBa0IsQ0FBQzthQUN4QyxNQUFNLENBQUMsSUFBSSxDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFBO1FBRXZELFlBQVk7YUFDVixPQUFPLENBQUMsb0JBQW9CLENBQUM7YUFDN0IsS0FBSyxDQUFDLElBQUksQ0FBQzthQUNYLFdBQVcsQ0FDWCwySEFBMkgsQ0FDM0g7YUFDQSxRQUFRLENBQUMsU0FBUyxFQUFFLGlCQUFpQixDQUFDO2FBQ3RDLE1BQU0sQ0FDTixRQUFRLEVBQ1IsdUhBQXVILENBQ3ZIO2FBQ0EsTUFBTSxDQUFDLElBQUksQ0FBQyw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQTtRQUV0RCxNQUFNLHVCQUF1QixHQUFHLG1CQUFPO2FBQ3JDLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQzthQUM1QixLQUFLLENBQUMsSUFBSSxDQUFDO2FBQ1gsV0FBVyxDQUNYLG9EQUFvRDtZQUNuRCxJ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