11#!/usr/bin/env node
22
3- import { readFileSync } from 'fs'
4- import { dirname , resolve } from 'path'
5- import { fileURLToPath } from 'url '
3+ import { readFileSync , writeFileSync } from 'fs'
4+ import { resolve } from 'path'
5+ import { ApiCoverage } from './api-coverage.js '
66
7- const __filename = fileURLToPath ( import . meta. url )
8- const __dirname = dirname ( __filename )
7+ function printHelp ( ) {
8+ console . log ( `
9+ API Coverage Tracker CLI
910
10- const config = JSON . parse ( readFileSync ( resolve ( __dirname , '../config.json' ) , 'utf8' ) )
11+ Commands:
1112
12- import { ApiCoverage } from '../utils/api-coverage.js'
13+ --init Initialize configuration file
14+ --spec <path> Path to OpenAPI/Swagger specification
15+ --collection <path> Path to Postman collection
16+ --coverage <type> Coverage type (basic/detailed)
17+ --help Show this help message
1318
14- function parseArgs ( args ) {
19+ Examples:
20+
21+ # Initialize config
22+ npx api-coverage-tracker --init
23+
24+ # Generate coverage report
25+ npx api-coverage-tracker --spec https://api.example.com/swagger.json --collection ./collection.json --coverage detailed
26+ ` )
27+ }
28+
29+ function parseArgs ( ) {
30+ const args = process . argv . slice ( 2 )
1531 const params = { }
32+
1633 for ( let i = 0 ; i < args . length ; i ++ ) {
17- if ( args [ i ] . startsWith ( '--' ) ) {
18- const key = args [ i ] . slice ( 2 )
19- const value = args [ i + 1 ] . replace ( / ^ [ ' " ] | [ ' " ] $ / g, '' )
20- params [ key ] = value
21- i ++
34+ const arg = args [ i ]
35+
36+ if ( arg === '--help' ) {
37+ printHelp ( )
38+ process . exit ( 0 )
39+ }
40+
41+ if ( arg . startsWith ( '--' ) ) {
42+ const key = arg . slice ( 2 )
43+ if ( key === 'init' ) {
44+ params . init = true
45+ continue
46+ }
47+ const value = args [ i + 1 ] ?. startsWith ( '--' ) ? true : args [ i + 1 ]
48+ if ( value ) {
49+ params [ key ] = value . replace ( / ^ [ ' " ] | [ ' " ] $ / g, '' )
50+ i ++
51+ }
2252 }
2353 }
2454 return params
2555}
2656
57+ function initConfig ( ) {
58+ const template = {
59+ services : [
60+ {
61+ key : '<service key OBLIGATORY>' ,
62+ name : '<Service API name OPTIONAL>' ,
63+ tags : [ 'api' , 'rest' ] ,
64+ repository : '<your repo>' ,
65+ swaggerUrl : '<your swagger url or leave empty if swagger file is used>' ,
66+ swaggerFile : '<your swagger file or leave empty if swagger URL is used>'
67+ }
68+ ] ,
69+ 'report-path' : "<relative path to the report directory, e.g. './reports'> OBLIGATORY>"
70+ }
71+
72+ try {
73+ const configPath = resolve ( process . cwd ( ) , 'config.json' )
74+ readFileSync ( configPath )
75+ console . error ( 'Configuration file already exists at:' , configPath )
76+ process . exit ( 1 )
77+ } catch {
78+ try {
79+ const configJson = JSON . stringify ( template , null , 2 )
80+ writeFileSync ( resolve ( process . cwd ( ) , 'config.json' ) , configJson )
81+ console . log ( 'Configuration file initialized successfully!' )
82+ console . log ( 'Please update the configuration with your service details.' )
83+ process . exit ( 0 )
84+ } catch ( error ) {
85+ console . error ( 'Failed to create configuration file:' , error . message )
86+ process . exit ( 1 )
87+ }
88+ }
89+ }
90+
2791async function run ( ) {
28- const args = process . argv . slice ( 2 )
29- const params = parseArgs ( args )
92+ const params = parseArgs ( )
93+
94+ if ( params . init ) {
95+ return initConfig ( )
96+ }
3097
3198 const { spec, collection, coverage = 'basic' } = params
3299
33100 if ( ! spec || ! collection ) {
34- console . error ( `
35- Usage: api-coverage-tracker --spec <specPath> --collection <collectionPath> [--coverage <type>]
36-
37- Arguments:
38- --spec URL or path to OpenAPI/Swagger specification
39- --collection Path to Postman collection JSON file
40- --coverage Coverage type: 'basic' or 'detailed' (default: 'basic')
41-
42- Example:
43- npx api-coverage-tracker --spec https://api.example.com/swagger.json --collection ./collection.json --coverage detailed
44- ` )
101+ printHelp ( )
45102 process . exit ( 1 )
46103 }
47104
48105 try {
106+ let config
107+ try {
108+ const configPath = resolve ( process . cwd ( ) , 'config.json' )
109+ config = JSON . parse ( readFileSync ( configPath , 'utf8' ) )
110+ } catch {
111+ console . error ( 'Configuration file not found. Run --init to create one.' )
112+ process . exit ( 1 )
113+ }
114+
49115 const apiCoverage = new ApiCoverage ( config )
50116 await apiCoverage . loadSpec ( spec )
51117 await apiCoverage . registerPostmanRequests ( {
@@ -60,4 +126,7 @@ Example:
60126 }
61127}
62128
63- run ( ) . catch ( console . error )
129+ run ( ) . catch ( error => {
130+ console . error ( 'Unexpected error:' , error . message )
131+ process . exit ( 1 )
132+ } )
0 commit comments