next-routes-readme
Advanced tools
Comparing version 0.0.6 to 0.0.7
218
lib/index.js
@@ -1,27 +0,2 @@ | ||
#!/usr/bin/env node | ||
"use strict"; | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
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 (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -31,157 +6,50 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const constants_1 = require("./config/constants"); | ||
const parser_1 = require("./route-parser/parser"); | ||
const traverseDictory_1 = require("./utils/traverseDictory"); | ||
const fs_1 = __importDefault(require("fs")); | ||
const path_1 = __importDefault(require("path")); | ||
const parser = __importStar(require("@babel/parser")); | ||
const traverse_1 = __importDefault(require("@babel/traverse")); | ||
const t = __importStar(require("@babel/types")); | ||
function parseRouteHandlers(routeFile) { | ||
const content = fs_1.default.readFileSync(routeFile, 'utf-8'); | ||
const handlers = []; | ||
const dependencies = []; | ||
const isHttpStatusValid = (status) => status >= 200 && status < 300; | ||
let currentHandler = null; | ||
const ast = parser.parse(content, { | ||
sourceType: 'module', | ||
plugins: ['jsx', 'typescript'], | ||
}); | ||
(0, traverse_1.default)(ast, { | ||
enter(path) { | ||
var _a, _b; | ||
if (t.isImportDeclaration(path.node)) { | ||
dependencies.push(path.toString()); | ||
} | ||
if (t.isFunctionDeclaration(path.node) && path.node.async) { | ||
const { name } = path.node.id; | ||
const params = path.node.params | ||
.map(param => content.substring(param.start, param.end)) | ||
.join(', '); | ||
const returnType = path.node.returnType | ||
? content.substring(path.node.returnType.start, path.node.returnType.end) | ||
: ''; | ||
currentHandler = { | ||
implementation: `async function ${name}(${params})${returnType}`, | ||
name, | ||
method: 'GET', | ||
doc: { | ||
variables: [], | ||
conditionals: [], | ||
errors: [], | ||
comments: [], | ||
}, | ||
dependencies, | ||
}; | ||
if (path.node.leadingComments) { | ||
path.node.leadingComments.forEach(comment => { | ||
const value = content.substring(comment.start, comment.end); | ||
currentHandler.doc.comments.push({ value, line: comment.loc.start.line }); | ||
}); | ||
async function generateMarkdownOutput(handlers, file) { | ||
const markdownOutput = handlers | ||
.map(handler => { | ||
return ` | ||
--- | ||
# Route: ${file} | ||
**Implementation**: \`${handler.implementation}\` | ||
**HTTP Method**: ${handler.method} | ||
**Documentation**: | ||
\`\`\`json | ||
${JSON.stringify(handler.doc, null, 2)} | ||
\`\`\` | ||
**Dependencies**: | ||
\`\`\`json | ||
${JSON.stringify(handler.dependencies, null, 2)} | ||
\`\`\` | ||
`; | ||
}) | ||
.join(''); | ||
fs_1.default.appendFileSync('ROUTES.md', markdownOutput); | ||
} | ||
async function main() { | ||
fs_1.default.writeFileSync('ROUTES.md', ''); // Clear existing content or create new file | ||
const folderPath = process.argv[2]; | ||
await (0, traverseDictory_1.traverseDirectory)(folderPath, async (file) => { | ||
try { | ||
if (file.endsWith(`${constants_1.constants.routeFilename}.ts`) || | ||
file.endsWith(`${constants_1.constants.routeFilename}.js`)) { | ||
const handlers = (0, parser_1.parseRouteHandlers)(file); | ||
for (const handler of handlers) { | ||
await generateMarkdownOutput([handler], file); | ||
} | ||
} | ||
if (currentHandler) { | ||
const currentLineNumber = ((_a = path.node.loc) === null || _a === void 0 ? void 0 : _a.start.line) || 0; | ||
if (t.isVariableDeclaration(path.node)) { | ||
const value = content.substring(path.node.start, path.node.end); | ||
currentHandler.doc.variables.push({ value, line: currentLineNumber }); | ||
} | ||
if (t.isIfStatement(path.node) || t.isConditionalExpression(path.node)) { | ||
const value = content.substring(path.node.start, path.node.end); | ||
currentHandler.doc.conditionals.push({ value, line: currentLineNumber }); | ||
} | ||
if (t.isThrowStatement(path.node)) { | ||
const value = content.substring(path.node.start, path.node.end); | ||
currentHandler.doc.errors.push({ value, line: currentLineNumber }); | ||
} | ||
if (t.isTryStatement(path.parent) && | ||
t.isCatchClause(path.parent.handler) && | ||
path.parent.handler === path.node) { | ||
const value = content.substring(path.node.start, path.node.end); | ||
const currentLineNumber = ((_b = path.node.loc) === null || _b === void 0 ? void 0 : _b.start.line) || 0; | ||
currentHandler.doc.errors.push({ value, line: currentLineNumber }); | ||
} | ||
if (t.isCallExpression(path.node) && | ||
t.isMemberExpression(path.node.callee) && | ||
t.isIdentifier(path.node.callee.object) && | ||
path.node.callee.object.name === 'Promise' && | ||
t.isIdentifier(path.node.callee.property) && | ||
path.node.callee.property.name === 'reject') { | ||
const value = content.substring(path.node.start, path.node.end); | ||
currentHandler.doc.errors.push({ value, line: currentLineNumber }); | ||
} | ||
if (path.node.leadingComments) { | ||
path.node.leadingComments.forEach(comment => { | ||
const value = content.substring(comment.start, comment.end); | ||
currentHandler.doc.comments.push({ value, line: comment.loc.start.line }); | ||
}); | ||
} | ||
if (t.isCallExpression(path.node)) { | ||
// Check if it's a NextResponse.json call | ||
if (t.isMemberExpression(path.node.callee) && | ||
t.isIdentifier(path.node.callee.object) && | ||
path.node.callee.object.name === 'NextResponse' && | ||
t.isIdentifier(path.node.callee.property) && | ||
path.node.callee.property.name === 'json') { | ||
// Check if it has an error status argument | ||
if (path.node.arguments.length >= 2) { | ||
const statusArg = path.node.arguments[1]; | ||
if (t.isObjectExpression(statusArg)) { | ||
// Check if it has a 'status' property | ||
for (const prop of statusArg.properties) { | ||
if (t.isObjectProperty(prop) && | ||
t.isIdentifier(prop.key) && | ||
prop.key.name === 'status' && | ||
t.isNumericLiteral(prop.value) && | ||
!isHttpStatusValid(prop.value.value)) { | ||
const value = content.substring(path.node.start, path.node.end); | ||
currentHandler.doc.errors.push({ value, line: currentLineNumber }); | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
} | ||
catch (error) { | ||
console.error(`Error processing file ${file}:`, error); | ||
} | ||
}); | ||
if (currentHandler) { | ||
handlers.push(currentHandler); | ||
} | ||
return handlers; | ||
} | ||
function traverseDirectory(directory, fileCallback, parentFolderName = '') { | ||
try { | ||
const files = fs_1.default.readdirSync(directory); | ||
for (const file of files) { | ||
const filePath = path_1.default.join(directory, file); | ||
const stat = fs_1.default.statSync(filePath); | ||
if (stat.isDirectory()) { | ||
traverseDirectory(filePath, fileCallback, path_1.default.join(parentFolderName, file)); | ||
} | ||
else { | ||
fileCallback(filePath, parentFolderName); | ||
} | ||
} | ||
} | ||
catch (error) { | ||
console.error(`Error while traversing directory ${directory}:`, error); | ||
} | ||
} | ||
const folderPath = process.argv[2]; | ||
traverseDirectory(folderPath, (file, parentFolderName) => { | ||
try { | ||
if (file.endsWith('route.ts')) { | ||
const handlers = parseRouteHandlers(file); | ||
for (const handler of handlers) { | ||
console.log(`Implementation: ${handler.implementation}`); | ||
console.log(`Route: app/${parentFolderName}/route.ts`); | ||
console.log(`HTTP Method: ${handler.method}`); | ||
console.log(`Documentation: ${JSON.stringify(handler.doc, null, 2)}`); | ||
console.log(`Dependencies: ${JSON.stringify(handler.dependencies, null, 2)}\n`); | ||
} | ||
} | ||
} | ||
catch (error) { | ||
console.error(`Error processing file ${file}:`, error); | ||
} | ||
}); | ||
main(); | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "next-routes-readme", | ||
"version": "0.0.6", | ||
"version": "0.0.7", | ||
"description": "Creates README badges from istanbul coverage report", | ||
@@ -9,2 +9,3 @@ "type": "commonjs", | ||
"start": "npm run build && node lib/index.js", | ||
"start:dev": "nodemon", | ||
"release": "standard-version", | ||
@@ -54,6 +55,9 @@ "prepublishOnly": "npm run build" | ||
"@typescript-eslint/parser": "^6.7.4", | ||
"ai": "^2.2.14", | ||
"eslint": "^8.51.0", | ||
"husky": "^8.0.3", | ||
"jest": "^29.7.0", | ||
"next": "^13.5.4", | ||
"nodemon": "^3.0.1", | ||
"openai-edge": "^1.2.2", | ||
"standard-version": "^9.5.0", | ||
@@ -60,0 +64,0 @@ "ts-jest": "^29.1.1", |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
21876
15
237
15
3
1