UNPKG

ts-ast

Version:

Command line interface for cannabis, the TypeScript advanced AST Query library

145 lines (134 loc) 5.99 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { 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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); const shelljs_1 = require("shelljs"); const path_1 = require("path"); const cannabis_1 = require("cannabis"); const misc_utils_of_mine_generic_1 = require("misc-utils-of-mine-generic"); const fs_1 = require("fs"); const glob_1 = require("glob"); function main() { return __awaiter(this, void 0, void 0, function* () { const options = require('yargs-parser')(process.argv.slice(2)); preconditions(options); const query = shelljs_1.test('-f', options.query) ? misc_utils_of_mine_generic_1.tryTo(() => JSON.parse(fs_1.readFileSync(options.query).toString())) : options.query; if (!query) { fail('Unable to read query from ' + options.query); } let result; if (options.project) { let tsConfigFile = options.project; if (shelljs_1.test('-d', options.project)) { tsConfigFile = path_1.join(options.project, 'tsconfig.json'); } if (!shelljs_1.test('-f', tsConfigFile)) { fail(`Project's tsconfig.json file cannot be found, exiting.`); } const p = cannabis_1.loadProject(tsConfigFile); const root = p.getRootDirectory(); result = cannabis_1.queryAst(query, root); } else if (options.files) { const files = shelljs_1.test('-f', options.files) ? [options.files] : glob_1.sync(options.files); const { error } = cannabis_1.queryAst(query, 'var a'); if (error) { result = { error }; } else { result = { result: files.map(f => cannabis_1.queryAst(query, fs_1.readFileSync(f).toString()).result).filter(misc_utils_of_mine_generic_1.notUndefined).flat() }; } } if (result) { if (result.error) { fail(`An error ocurred: \n ${printError(result.error)}`); } let outputText = ''; if (options.outputCount) { outputText = result.result.length + ''; } else { const output = getResultOutput(result.result, options.output); outputText = options.outputCompress ? JSON.stringify(output) : JSON.stringify(output, null, 2); } if (options.outputFile) { fs_1.writeFileSync(options.outputFile, outputText); } else { process.stdout.write(outputText + '\n'); } } }); } exports.main = main; function getResultOutput(result, style = ['nodePath', 'name', 'kind']) { return result.map(node => misc_utils_of_mine_generic_1.arrayToObject(style, s => { if (s === 'nodePath') { return cannabis_1.getASTNodePath(node); } else if (s === 'name') { return cannabis_1.getASTNodeName(node); } else if (s === 'kind') { return cannabis_1.getASTNodeKindName(node); } else if (s === 'text') { return cannabis_1.getASTNodeText(node); } else if (s === 'filePath') { return cannabis_1.getASTNodeFilePath(node); } })); } function printError(e) { return `${e.name}, "${e.message}"\n * ${(e.stack || '').split('\n').join('\n * ')}`; } function preconditions(options) { if (options.output) { options.output = options.output.split(','); } if (options.help) { printHelp(); process.exit(0); } if (!options.query) { fail(`--query argument is mandatory and none was given. Aborting.`); } if (!options.files && !options.project) { fail(`One of --files or --project arguments is mandatory and none was given. Aborting.`); } } function fail(s) { console.error(s); process.exit(1); } function printHelp() { console.log(` Usage: cannabis --query "//ClassDeclaration [@modifiers=~'export']" --files "src/**/foo/**/*.ts*" Options: * '--query': the query to search. It could be a query string or a text file with the query. If a files exists it will be used, otherwise it assumes that is a query string. Examples: '--query "//* [@name == 'foo']"', '--query ./queries/myLongQuery.txt'. * '--files': TypeScript files to search. Valid files are .ts, .tsx, .js, .jsx. The value could be a glob pattern, in that case all files matching the pattern will be the input. Examples: '--files "src/**/are42/**/*.ts?"'. * '--project': TypeScript project in which to search. It could be a folder or a 'tsconfig.json' path. If '--files' also given it will be used as a filter pattern. * '--params': query parameters. It could be a json file containing an object or a literal json text. Examples: '--params blackListWords.json', '--params '{"blackList": ["foo","bar"]}'' * '--output': the output style. Valid values: 'nodePath', 'text', 'name', 'filePath', 'kind' or a combination of any of them, comma separated. * '--help': prints help and exits. * '--outputFile': If given the search result will be written in that file, otherwise will be written in stdout. * '--outputCompress': if given JSON output will be minified. * '--outputCount': Just print the result count. `); } //# sourceMappingURL=main.js.map