From 8f6d415762a50d5b82d1bf03db3a2ee4e38aa62a Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Mon, 8 Jul 2024 18:35:12 +0300 Subject: [PATCH 1/8] feat: introduced CLI mode to the parser --- bin/cli.mjs | 82 ++++++++++++ package-lock.json | 335 +++++++++++++++++++++++++++++++++++++++++++--- package.json | 7 +- 3 files changed, 407 insertions(+), 17 deletions(-) create mode 100755 bin/cli.mjs diff --git a/bin/cli.mjs b/bin/cli.mjs new file mode 100755 index 0000000..661cc9f --- /dev/null +++ b/bin/cli.mjs @@ -0,0 +1,82 @@ +#!/usr/bin/env node + +import { Command } from 'commander'; +import { glob } from 'glob'; +import { basename, join } from 'node:path'; +import { argv, exit } from 'node:process'; + +/** + * @fileoverview + * + * The CLI used to help create API documentation for the Node.js project. + * The CLI processes files and generates API documentation based on the provided options. + */ + +/** + * Process files based on provided command line arguments. + * + * @param {string} filePath - The path of the file to be processed. + * @param {Options['output']} outputDir - The directory where the processed file will be saved. + * @param {Options['target']} target - The processing mode to be applied to the file. + * @returns {Promise} A promise that resolves when the file processing is complete. + */ +const processFile = async (filePath, outputDir, target) => { + try { + const fileName = basename(filePath); + const outputPath = join(outputDir, fileName); + + console.info( + `Processing file ${filePath} to ${outputPath} with target ${target}...` + ); + + // TODO: Implement file processing logic here + return new Promise(); + } catch (error) { + console.error(`Error processing file ${filePath}:`, error); + exit(1); + } +}; + +(async () => { + const program = new Command(); + + program + .requiredOption( + '-i, --input ', + 'Specify input file patterns using glob syntax' + ) + .option( + '-e, --exclude ', + 'Specify patterns to exclude files from being processed' + ) + .requiredOption('-o, --output ', 'Specify the output directory path') + .option('-t, --target ', 'Set the processing mode', 'mdx') + .parse(argv); + + /** + * Defines the structure for command line options after parsing. + * + * @typedef {Object} Options + * @property {Array|string} input - Specifies the glob/path for input files. + * @property {string} output - Specifies the directory where output files will be saved. + * @property {Array|string} exclude - Specifies the glob patterns for files to exclude from processing. + * @property {'mdx'} target - Specifies the execution target mode. Currently, only 'mdx' mode is supported. + */ + + /** @type {Options} */ + const { input, output, exclude, target } = program.opts(); + + try { + // Get all files based on the input glob pattern + const files = await glob(input, exclude ? { ignore: exclude } : {}); + + console.info(`${files.length} files found.`); + + await Promise.all( + files.map(filePath => processFile(filePath, output, target)) + ); + } catch (error) { + console.error(error); + exit(1); + } +})(); diff --git a/package-lock.json b/package-lock.json index 748101f..1357fe1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,8 +4,12 @@ "requires": true, "packages": { "": { + "dependencies": { + "glob": "^10.4.2" + }, "devDependencies": { "@eslint/js": "^9.5.0", + "@types/node": "^20.14.10", "eslint": "^9.5.0", "eslint-config-prettier": "^9.1.0", "globals": "^15.6.0", @@ -143,6 +147,95 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -178,6 +271,24 @@ "node": ">= 8" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@types/node": { + "version": "20.14.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.10.tgz", + "integrity": "sha512-MdiXf+nDuMvY0gJKxyfZ7/6UFsETO7mGKF54MVD/ekJS6HdFtpZFBgrh6Pseu64XTb2MLyFPlbW6hj8HYRQNOQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/acorn": { "version": "8.11.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", @@ -231,7 +342,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "engines": { "node": ">=8" } @@ -240,7 +350,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -260,8 +369,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/brace-expansion": { "version": "1.1.11", @@ -345,7 +453,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -356,8 +463,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colorette": { "version": "2.0.20", @@ -384,7 +490,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -417,6 +522,11 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" + }, "node_modules/emoji-regex": { "version": "10.3.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", @@ -700,6 +810,21 @@ "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", "dev": true }, + "node_modules/foreground-child": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.2.1.tgz", + "integrity": "sha512-PXUUyLqrR2XCWICfv6ukppP96sdFwWbNEnfEMt7jNsISjMsvaLNinAHNDYyvkyU+SZG2BTSbT5NjG+vZslfGTA==", + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/get-east-asian-width": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", @@ -724,6 +849,28 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/glob": { + "version": "10.4.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.2.tgz", + "integrity": "sha512-GwMlUF6PkPo3Gk21UxkCohOv0PLcIXVtKyLlpEI28R/cO/4eNOdmLk3CMW1wROV/WR/EsZOWAfBbBOqYvs88/w==", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -736,6 +883,28 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/globals": { "version": "15.6.0", "resolved": "https://registry.npmjs.org/globals/-/globals-15.6.0.tgz", @@ -881,8 +1050,24 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/jackspeak": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.0.tgz", + "integrity": "sha512-JVYhQnN59LVPFCEcVa2C3CrEKYacvjRfqIQl+h8oi91aLYQVWRYbxjPcv1bUiUy/kLmQaANrYfNMCO3kuEDHfw==", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } }, "node_modules/js-yaml": { "version": "4.1.0", @@ -1114,6 +1299,14 @@ "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, + "node_modules/lru-cache": { + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.3.0.tgz", + "integrity": "sha512-CQl19J/g+Hbjbv4Y3mFNNXFEL/5t/KCg8POCuUqd4rMKjGG+j1ybER83hxV58zL+dFI1PTkt3GNFSHRt+d8qEQ==", + "engines": { + "node": "14 || >=16.14" + } + }, "node_modules/merge-stream": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", @@ -1157,6 +1350,14 @@ "node": "*" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1258,6 +1459,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.0.tgz", + "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -1283,11 +1489,25 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -1463,7 +1683,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -1475,7 +1694,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -1484,7 +1702,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", - "dev": true, "engines": { "node": ">=14" }, @@ -1546,6 +1763,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -1577,7 +1821,18 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -1651,6 +1906,12 @@ "node": ">= 0.8.0" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", @@ -1664,7 +1925,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -1701,6 +1961,49 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", diff --git a/package.json b/package.json index be97791..58cebfe 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "format": "prettier --write .", "prepare": "husky" }, + "bin": "./bin/cli.mjs", "devDependencies": { "@eslint/js": "^9.5.0", "eslint": "^9.5.0", @@ -11,6 +12,10 @@ "globals": "^15.6.0", "husky": "^9.0.11", "lint-staged": "^15.2.7", - "prettier": "3.2.5" + "prettier": "3.2.5", + "@types/node": "^20.14.10" + }, + "dependencies": { + "glob": "^10.4.2" } } From 3513f2c95b15fda3da7a36347e533f92395651c7 Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Mon, 8 Jul 2024 20:41:43 +0300 Subject: [PATCH 2/8] fix: top level await --- bin/cli.mjs | 72 +++++++++++++++++++++++------------------------ package-lock.json | 2 +- package.json | 5 ++-- 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/bin/cli.mjs b/bin/cli.mjs index 661cc9f..d5ad695 100755 --- a/bin/cli.mjs +++ b/bin/cli.mjs @@ -37,46 +37,44 @@ const processFile = async (filePath, outputDir, target) => { } }; -(async () => { - const program = new Command(); +const program = new Command(); - program - .requiredOption( - '-i, --input ', - 'Specify input file patterns using glob syntax' - ) - .option( - '-e, --exclude ', - 'Specify patterns to exclude files from being processed' - ) - .requiredOption('-o, --output ', 'Specify the output directory path') - .option('-t, --target ', 'Set the processing mode', 'mdx') - .parse(argv); +program + .requiredOption( + '-i, --input ', + 'Specify input file patterns using glob syntax' + ) + .option( + '-e, --exclude ', + 'Specify patterns to exclude files from being processed' + ) + .requiredOption('-o, --output ', 'Specify the output directory path') + .option('-t, --target ', 'Set the processing mode', 'mdx') + .parse(argv); - /** - * Defines the structure for command line options after parsing. - * - * @typedef {Object} Options - * @property {Array|string} input - Specifies the glob/path for input files. - * @property {string} output - Specifies the directory where output files will be saved. - * @property {Array|string} exclude - Specifies the glob patterns for files to exclude from processing. - * @property {'mdx'} target - Specifies the execution target mode. Currently, only 'mdx' mode is supported. - */ +/** + * Defines the structure for command line options after parsing. + * + * @typedef {Object} Options + * @property {Array|string} input - Specifies the glob/path for input files. + * @property {string} output - Specifies the directory where output files will be saved. + * @property {Array|string} exclude - Specifies the glob patterns for files to exclude from processing. + * @property {'mdx'} target - Specifies the execution target mode. Currently, only 'mdx' mode is supported. + */ - /** @type {Options} */ - const { input, output, exclude, target } = program.opts(); +/** @type {Options} */ +const { input, output, exclude, target } = program.opts(); - try { - // Get all files based on the input glob pattern - const files = await glob(input, exclude ? { ignore: exclude } : {}); +try { + // Get all files based on the input glob pattern + const files = await glob(input, exclude ? { ignore: exclude } : {}); - console.info(`${files.length} files found.`); + console.info(`${files.length} files found.`); - await Promise.all( - files.map(filePath => processFile(filePath, output, target)) - ); - } catch (error) { - console.error(error); - exit(1); - } -})(); + await Promise.all( + files.map(filePath => processFile(filePath, output, target)) + ); +} catch (error) { + console.error(error); + exit(1); +} diff --git a/package-lock.json b/package-lock.json index 1357fe1..607e12f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,6 +5,7 @@ "packages": { "": { "dependencies": { + "commander": "^12.1.0", "glob": "^10.4.2" }, "devDependencies": { @@ -475,7 +476,6 @@ "version": "12.1.0", "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", - "dev": true, "engines": { "node": ">=18" } diff --git a/package.json b/package.json index 58cebfe..a903b62 100644 --- a/package.json +++ b/package.json @@ -7,15 +7,16 @@ "bin": "./bin/cli.mjs", "devDependencies": { "@eslint/js": "^9.5.0", + "@types/node": "^20.14.10", "eslint": "^9.5.0", "eslint-config-prettier": "^9.1.0", "globals": "^15.6.0", "husky": "^9.0.11", "lint-staged": "^15.2.7", - "prettier": "3.2.5", - "@types/node": "^20.14.10" + "prettier": "3.2.5" }, "dependencies": { + "commander": "^12.1.0", "glob": "^10.4.2" } } From 09dd7ff6b56003f6d03638b6d92a0eb3ca66b470 Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Sun, 21 Jul 2024 00:02:10 +0300 Subject: [PATCH 3/8] chore: remove .gitkeep --- bin/.gitkeep | 1 - 1 file changed, 1 deletion(-) delete mode 100644 bin/.gitkeep diff --git a/bin/.gitkeep b/bin/.gitkeep deleted file mode 100644 index f935021..0000000 --- a/bin/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -!.gitignore From 4c4c5ec50c24bf79f9ac0906b3445ec121c95aa6 Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Mon, 22 Jul 2024 00:26:12 +0300 Subject: [PATCH 4/8] refactor: uses loaders, parsers, and generators --- bin/cli.mjs | 84 +++++++++++++++-------------------------------- src/constants.mjs | 7 ++++ 2 files changed, 34 insertions(+), 57 deletions(-) diff --git a/bin/cli.mjs b/bin/cli.mjs index d5ad695..0ebe3a2 100755 --- a/bin/cli.mjs +++ b/bin/cli.mjs @@ -1,41 +1,12 @@ #!/usr/bin/env node -import { Command } from 'commander'; -import { glob } from 'glob'; -import { basename, join } from 'node:path'; -import { argv, exit } from 'node:process'; - -/** - * @fileoverview - * - * The CLI used to help create API documentation for the Node.js project. - * The CLI processes files and generates API documentation based on the provided options. - */ - -/** - * Process files based on provided command line arguments. - * - * @param {string} filePath - The path of the file to be processed. - * @param {Options['output']} outputDir - The directory where the processed file will be saved. - * @param {Options['target']} target - The processing mode to be applied to the file. - * @returns {Promise} A promise that resolves when the file processing is complete. - */ -const processFile = async (filePath, outputDir, target) => { - try { - const fileName = basename(filePath); - const outputPath = join(outputDir, fileName); - - console.info( - `Processing file ${filePath} to ${outputPath} with target ${target}...` - ); - - // TODO: Implement file processing logic here - return new Promise(); - } catch (error) { - console.error(`Error processing file ${filePath}:`, error); - exit(1); - } -}; +import { Command, Option } from 'commander'; +import { argv } from 'node:process'; +import { resolve } from 'node:path'; +import createGenerator from '../src/generators.mjs'; +import createLoader from '../src/loader.mjs'; +import createParser from '../src/parser.mjs'; +import { CLI_TARGET_MAPPING } from '../src/constants.mjs'; const program = new Command(); @@ -44,37 +15,36 @@ program '-i, --input ', 'Specify input file patterns using glob syntax' ) - .option( - '-e, --exclude ', - 'Specify patterns to exclude files from being processed' - ) .requiredOption('-o, --output ', 'Specify the output directory path') - .option('-t, --target ', 'Set the processing mode', 'mdx') + .addOption( + new Option('-t, --target ', 'Set the processing target mode').choices( + Object.keys(CLI_TARGET_MAPPING) + ) + ) .parse(argv); /** * Defines the structure for command line options after parsing. * * @typedef {Object} Options - * @property {Array|string} input - Specifies the glob/path for input files. - * @property {string} output - Specifies the directory where output files will be saved. - * @property {Array|string} exclude - Specifies the glob patterns for files to exclude from processing. - * @property {'mdx'} target - Specifies the execution target mode. Currently, only 'mdx' mode is supported. + * @property {Array|string} input Specifies the glob/path for input files. + * @property {string} output Specifies the directory where output files will be saved. + * @property {keyof CLI_TARGET_MAPPING} target Specifies the execution target mode. */ /** @type {Options} */ -const { input, output, exclude, target } = program.opts(); +const { input, output, target } = program.opts(); + +const { loadFiles } = createLoader(); +const { parseApiDocs } = createParser(); + +const apiDocFiles = loadFiles(input); -try { - // Get all files based on the input glob pattern - const files = await glob(input, exclude ? { ignore: exclude } : {}); +const parsedApiDocs = await parseApiDocs(apiDocFiles); - console.info(`${files.length} files found.`); +const { runGenerators } = createGenerator(parsedApiDocs); - await Promise.all( - files.map(filePath => processFile(filePath, output, target)) - ); -} catch (error) { - console.error(error); - exit(1); -} +await runGenerators({ + generators: CLI_TARGET_MAPPING[target], + output: resolve(output), +}); diff --git a/src/constants.mjs b/src/constants.mjs index 34ef83c..c85660b 100644 --- a/src/constants.mjs +++ b/src/constants.mjs @@ -328,3 +328,10 @@ export const DOC_TYPES_MAPPING_OTHER = { Response: `${DOC_MDN_BASE_URL}/API/Response`, Request: `${DOC_MDN_BASE_URL}/API/Request`, }; + +// Mapping that determines which generators are run on the target modes used in the CLI +export const CLI_TARGET_MAPPING = { + mdx: [], + json: ['jsonSimple'], + html: ['legacyHtml'], +}; From 32ed6d2aa990cee5b4724aec3b1462cc9c40351c Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Mon, 22 Jul 2024 00:54:34 +0300 Subject: [PATCH 5/8] refactor: multiple target mode --- bin/cli.mjs | 9 +++++---- src/constants.mjs | 6 +++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/bin/cli.mjs b/bin/cli.mjs index 0ebe3a2..ce014f2 100755 --- a/bin/cli.mjs +++ b/bin/cli.mjs @@ -17,9 +17,10 @@ program ) .requiredOption('-o, --output ', 'Specify the output directory path') .addOption( - new Option('-t, --target ', 'Set the processing target mode').choices( - Object.keys(CLI_TARGET_MAPPING) - ) + new Option( + '-t, --target [mode...]', + 'Set the processing target mode' + ).choices(Object.keys(CLI_TARGET_MAPPING)) ) .parse(argv); @@ -45,6 +46,6 @@ const parsedApiDocs = await parseApiDocs(apiDocFiles); const { runGenerators } = createGenerator(parsedApiDocs); await runGenerators({ - generators: CLI_TARGET_MAPPING[target], + generators: target.map(mode => CLI_TARGET_MAPPING[mode]), output: resolve(output), }); diff --git a/src/constants.mjs b/src/constants.mjs index c85660b..9da3c55 100644 --- a/src/constants.mjs +++ b/src/constants.mjs @@ -331,7 +331,7 @@ export const DOC_TYPES_MAPPING_OTHER = { // Mapping that determines which generators are run on the target modes used in the CLI export const CLI_TARGET_MAPPING = { - mdx: [], - json: ['jsonSimple'], - html: ['legacyHtml'], + mdx: 'mdx', + json: 'jsonSimple', + html: 'legacyHtml', }; From 0ab7045297404c5fca6cb4ab859ed7c16fee58e0 Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Fri, 26 Jul 2024 17:27:29 +0300 Subject: [PATCH 6/8] refactor: import order changed --- bin/cli.mjs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bin/cli.mjs b/bin/cli.mjs index ce014f2..2211d19 100755 --- a/bin/cli.mjs +++ b/bin/cli.mjs @@ -1,8 +1,10 @@ #!/usr/bin/env node -import { Command, Option } from 'commander'; import { argv } from 'node:process'; import { resolve } from 'node:path'; + +import { Command, Option } from 'commander'; + import createGenerator from '../src/generators.mjs'; import createLoader from '../src/loader.mjs'; import createParser from '../src/parser.mjs'; From a47ee14da8de4506652006944e6c32f4c42fce0a Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Fri, 26 Jul 2024 17:33:48 +0300 Subject: [PATCH 7/8] chore: package name added --- package.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index eed239c..835878f 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,13 @@ { + "name": "@node-core/api-docs-tooling", "scripts": { "lint": "eslint .", "format": "prettier --write .", "prepare": "husky" }, - "bin": "./bin/cli.mjs", + "bin": { + "api-docs-tooling": "./bin/cli.mjs" + }, "devDependencies": { "@eslint/js": "^9.7.0", "@types/node": "^20.14.10", From a1478443bcb2f2eb55721da7500af37f708c6f66 Mon Sep 17 00:00:00 2001 From: Caner Akdas Date: Mon, 29 Jul 2024 18:54:35 +0300 Subject: [PATCH 8/8] refactor: code review --- bin/cli.mjs | 18 +++++++++++------- src/constants.mjs | 7 ------- src/generators/index.mjs | 2 +- src/generators/json-simple/index.mjs | 2 +- src/generators/legacy-html/index.mjs | 2 +- 5 files changed, 14 insertions(+), 17 deletions(-) diff --git a/bin/cli.mjs b/bin/cli.mjs index 2211d19..11daeab 100755 --- a/bin/cli.mjs +++ b/bin/cli.mjs @@ -8,11 +8,13 @@ import { Command, Option } from 'commander'; import createGenerator from '../src/generators.mjs'; import createLoader from '../src/loader.mjs'; import createParser from '../src/parser.mjs'; -import { CLI_TARGET_MAPPING } from '../src/constants.mjs'; +import generators from '../src/generators/index.mjs'; const program = new Command(); program + .name('api-docs-tooling') + .description('CLI tool to generate API documentation of a Node.js project.') .requiredOption( '-i, --input ', 'Specify input file patterns using glob syntax' @@ -22,20 +24,22 @@ program new Option( '-t, --target [mode...]', 'Set the processing target mode' - ).choices(Object.keys(CLI_TARGET_MAPPING)) + ).choices(Object.keys(generators)) ) .parse(argv); /** - * Defines the structure for command line options after parsing. + * @typedef {keyof generators} Target A list of the available generator names. * * @typedef {Object} Options * @property {Array|string} input Specifies the glob/path for input files. * @property {string} output Specifies the directory where output files will be saved. - * @property {keyof CLI_TARGET_MAPPING} target Specifies the execution target mode. + * @property {Target} target Specifies the generator target mode. + * + * @name ProgramOptions + * @type {Options} + * @description The return type for values sent to the program from the CLI. */ - -/** @type {Options} */ const { input, output, target } = program.opts(); const { loadFiles } = createLoader(); @@ -48,6 +52,6 @@ const parsedApiDocs = await parseApiDocs(apiDocFiles); const { runGenerators } = createGenerator(parsedApiDocs); await runGenerators({ - generators: target.map(mode => CLI_TARGET_MAPPING[mode]), + generators: target, output: resolve(output), }); diff --git a/src/constants.mjs b/src/constants.mjs index 9da3c55..34ef83c 100644 --- a/src/constants.mjs +++ b/src/constants.mjs @@ -328,10 +328,3 @@ export const DOC_TYPES_MAPPING_OTHER = { Response: `${DOC_MDN_BASE_URL}/API/Response`, Request: `${DOC_MDN_BASE_URL}/API/Request`, }; - -// Mapping that determines which generators are run on the target modes used in the CLI -export const CLI_TARGET_MAPPING = { - mdx: 'mdx', - json: 'jsonSimple', - html: 'legacyHtml', -}; diff --git a/src/generators/index.mjs b/src/generators/index.mjs index 3bb6177..be8af5b 100644 --- a/src/generators/index.mjs +++ b/src/generators/index.mjs @@ -3,4 +3,4 @@ import jsonSimple from './json-simple/index.mjs'; import legacyHtml from './legacy-html/index.mjs'; -export default { jsonSimple, legacyHtml }; +export default { 'json-simple': jsonSimple, 'legacy-html': legacyHtml }; diff --git a/src/generators/json-simple/index.mjs b/src/generators/json-simple/index.mjs index e04bf32..5433bdc 100644 --- a/src/generators/json-simple/index.mjs +++ b/src/generators/json-simple/index.mjs @@ -15,7 +15,7 @@ import { join } from 'node:path'; * @type {import('../types.d.ts').GeneratorMetadata} */ export default { - name: 'jsonSimple', + name: 'json-simple', version: '1.0.0', diff --git a/src/generators/legacy-html/index.mjs b/src/generators/legacy-html/index.mjs index 23824ef..ed12ee1 100644 --- a/src/generators/legacy-html/index.mjs +++ b/src/generators/legacy-html/index.mjs @@ -12,7 +12,7 @@ * @type {import('../types.d.ts').GeneratorMetadata} */ export default { - name: 'legacyHtml', + name: 'legacy-html', version: '1.0.0',