UNPKG

node-postman-generator

Version:

📦 CLI tool that automatically converts Express.js routes to Postman collections - handles path/query/body params, and generates ready-to-import JSON with route config.

116 lines (102 loc) 3.15 kB
const acorn = require('acorn'); const walk = require('acorn-walk'); const parseComment = require('./comment.js') class ExpressParser { constructor(code) { this.comments = []; this.ast; this.code = code; } // 整合的路径提取方法 _getRoutePath(args) { for (const arg of args) { // 处理对象式定义 (Vue Router) if (arg.type === 'ObjectExpression') { const pathProp = arg.properties.find(p => p.key.name === 'path' && p.value.type === 'Literal' ); if (pathProp) return pathProp.value.value; } // 处理字符串式定义 (Express) else if (arg.type === 'Literal' && typeof arg.value === 'string') { return arg.value; } } return ''; } // 增强版路由解析逻辑 parseRouteCode(code) { const comments = []; let ast; let that = this; // 改进的AST解析配置 try { ast = acorn.parse(code, { ecmaVersion: 2020, locations: true, allowHashBang: true, onComment: (isBlock, text, start, end) => { if (isBlock) { const startLine = code.slice(0, start).split('\n').length; const endLine = code.slice(0, end).split('\n').length; comments.push({ text: text.replace(/^\s*\* ?/gm, ''), // 清理注释格式 startLine, endLine, type: 'jsdoc' }); } } }); } catch (e) { // console.error('AST解析失败:', e.message); console.error('❌ AST parsing failed:', e.message); // AST解析失败 return []; } const routes = []; // 整合后的路由遍历逻辑 walk.simple(ast, { CallExpression(node) { const callee = node.callee; let isRoute = false; let method = ''; // 增强路由类型检测 if (callee.object?.name === 'router' && /^(get|post|put|delete|all)$/i.test(callee.property?.name)) { isRoute = true; method = callee.property.name.toUpperCase(); } else if (callee.name === 'createRouter') { isRoute = true; method = 'VUE_ROUTER'; } if (isRoute) { const routeLine = node.loc.start.line; const path = that._getRoutePath(node.arguments); // 智能注释匹配算法 const relatedComment = comments.find(c => c.endLine >= routeLine - 3 && c.endLine <= routeLine && c.text.includes('@api') ); // 在这里解析注释,并存储在 parseInfo 中 const parseInfo = parseComment(relatedComment?.text) routes.push({ method, path, comment: relatedComment?.text || '', loc: node.loc, parseInfo }); } }, }); // return routes; return routes.filter(r => { // 保留有有效路径且未标记跳过的路由 return r.path && !r.parseInfo.skip; }); } } module.exports = ExpressParser; // 确保使用 module.exports 导出类