Created
July 24, 2018 19:04
-
-
Save paulomenezes/e55fcbdaa62fc70ce7add7ee3787075f to your computer and use it in GitHub Desktop.
Typescript parser for AngularJS project
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as acorn from 'acorn'; | |
| import * as fs from 'fs'; | |
| const sourcePath = './source/'; | |
| function getWordAt(str: string, pos: number) { | |
| // Perform type conversions. | |
| str = String(str); | |
| pos = Number(pos) >>> 0; | |
| // Search for the word's beginning and end. | |
| var left = str.slice(0, pos + 1).search(/\S+$/), | |
| right = str.slice(pos).search(/\s/); | |
| // The last word in the string is a special case. | |
| if (right < 0) { | |
| return str.slice(left); | |
| } | |
| // Return the word, using the located bounds to extract it from the string. | |
| return str.slice(left, right + pos); | |
| } | |
| var walkSync = function(dir: string, filelist: string[]) { | |
| var files = fs.readdirSync(dir); | |
| filelist = filelist || []; | |
| files.forEach(function(file) { | |
| if (fs.statSync(dir + file).isDirectory()) { | |
| filelist = walkSync(dir + file + '/', filelist); | |
| } else { | |
| filelist.push(dir + file); | |
| } | |
| }); | |
| return filelist; | |
| }; | |
| let files: string[] = []; | |
| walkSync(sourcePath, files); | |
| let calls: string[] = []; | |
| files.forEach((file: string) => { | |
| const data = fs.readFileSync(file, 'utf8'); | |
| const lines: string[] = data.split('\n'); | |
| lines.forEach((line: string) => { | |
| let newLine = line.trim(); //.replace(/ /g, ''); | |
| const index = newLine.toLowerCase().indexOf('service.'); | |
| if (index >= 0) { | |
| let word: string = getWordAt(newLine, index); | |
| word = word.replace('.all([', ''); | |
| word = word.replace('(!', ''); | |
| word = word.replace('!', ''); | |
| if (word.indexOf('(') > 0) { | |
| word = word.substring(0, word.indexOf('(')); | |
| } | |
| if (word[word.length - 1] === ';' || word[word.length - 1] === ')') { | |
| word = word.substr(0, word.length - 1); | |
| } | |
| calls.push(word); | |
| } | |
| }); | |
| }); | |
| let services: string[] = []; | |
| calls.forEach(call => { | |
| const service = call.split('.')[0]; | |
| if (service === 'PsiUtilService') { | |
| return; | |
| } | |
| if (service === 'LoginService') { | |
| services.push('LoginServiceUrls'); | |
| } else { | |
| services.push(service); | |
| } | |
| }); | |
| services = Array.from(new Set(services)); | |
| let urlsOut: string[] = []; | |
| files.forEach((file: string) => { | |
| const data = fs.readFileSync(file, 'utf8'); //, (err, data) => { | |
| services.forEach(service => { | |
| if (data.toLowerCase().indexOf(`factory('${service.toLowerCase()}'`) >= 0) { | |
| // console.log(file, service); | |
| const serviceCalls = calls.filter(c => | |
| c.toLowerCase().startsWith(service.toLowerCase()) | |
| ); | |
| const parsed = acorn.parse(data); | |
| parsed.body[0].expression.callee.body.body.forEach((expressionBody: any) => { | |
| if (expressionBody.type === 'ExpressionStatement') { | |
| if ( | |
| expressionBody.expression.arguments[0].value.toLowerCase() === | |
| service.toLowerCase() | |
| ) { | |
| serviceCalls.forEach(serviceCall => { | |
| const key = serviceCall.split('.')[1]; | |
| if (expressionBody.expression.arguments[1].elements[1].body) { | |
| const value = expressionBody.expression.arguments[1].elements[1].body.body[0].argument.arguments[2].properties.filter( | |
| (p: any) => p.key.name === key | |
| ); | |
| if (value && value.length > 0) { | |
| const method = value[0].value.properties[0].value.value; | |
| const params = value[0].value.properties.filter( | |
| (p: any) => p.key.name === 'params' | |
| ); | |
| let url: string = | |
| expressionBody.expression.arguments[1].elements[1].body.body[0] | |
| .argument.arguments[0].value; | |
| const urlParams = url | |
| .split('/') | |
| .filter((u: string) => u.startsWith(':')); | |
| if (params && params.length) { | |
| for (let i = 0; i < urlParams.length; i++) { | |
| for (let j = 0; j < params[0].value.properties.length; j++) { | |
| if ( | |
| ':' + params[0].value.properties[j].key.name === | |
| urlParams[i] | |
| ) { | |
| url = url.replace( | |
| urlParams[i], | |
| params[0].value.properties[j].value.value | |
| ); | |
| } | |
| } | |
| } | |
| } | |
| if (url.indexOf(':route') >= 0) { | |
| url = url.replace('/:route', ''); | |
| } | |
| if (url.indexOf(':innerroute') >= 0) { | |
| url = url.replace('/:innerroute', ''); | |
| } | |
| url = url.replace('//', '/'); | |
| url = url.replace(':id', '{id}'); | |
| urlsOut.push(method + ': /' + url); | |
| } | |
| } | |
| }); | |
| } | |
| } | |
| }); | |
| } | |
| }); | |
| }); | |
| urlsOut = Array.from(new Set(urlsOut)); | |
| urlsOut.sort().forEach((url: string) => console.log(url)); |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Install: npm install -g typescript
Run: tsc parser.ts --lib es6 && node parser.js