1- import * as fs from " node:fs" ;
2- import { join } from " path" ;
3- import Parsers from " @stoplight/spectral-parsers" ;
4- import { Document } from " @stoplight/spectral-core" ;
5- import { importAndCreateRuleInstances } from " ./util/ruleUtil.js" ; // Import the helper function
1+ import * as fs from ' node:fs' ;
2+ import { join } from ' path' ;
3+ import Parsers from ' @stoplight/spectral-parsers' ;
4+ import { Document } from ' @stoplight/spectral-core' ;
5+ import { importAndCreateRuleInstances } from ' ./util/ruleUtil.js' ; // Import the helper function
66import util from 'util' ;
7- import { RapLPCustomSpectral } from " ./util/RapLPCustomSpectral.js" ;
8- import { DiagnosticReport , RapLPDiagnostic } from " ./util/RapLPDiagnostic.js" ;
9- import { AggregateError } from " ./util/RapLPCustomErrorInfo.js" ;
7+ import { RapLPCustomSpectral } from ' ./util/RapLPCustomSpectral.js' ;
8+ import { DiagnosticReport , RapLPDiagnostic } from ' ./util/RapLPDiagnostic.js' ;
9+ import { AggregateError } from ' ./util/RapLPCustomErrorInfo.js' ;
1010import chalk from 'chalk' ;
11- import { ExcelReportProcessor } from " ./util/excelReportProcessor.js" ;
11+ import { ExcelReportProcessor } from ' ./util/excelReportProcessor.js' ;
1212
1313declare var AggregateError : {
14- prototype : AggregateError ;
15- new ( errors : any [ ] , message ?: string ) : AggregateError ;
14+ prototype : AggregateError ;
15+ new ( errors : any [ ] , message ?: string ) : AggregateError ;
1616} ;
1717
1818const writeFileAsync = util . promisify ( fs . writeFile ) ;
@@ -24,153 +24,184 @@ export type CliArgs = {
2424 logError ?: string ;
2525 append : boolean ;
2626 logDiagnostic ?: string ;
27- dex ?: string
28- }
27+ dex ?: string ;
28+ } ;
2929
3030export async function execCLI < T extends CliArgs > ( argv : T ) {
31+ try {
32+ // Parse command-line arguments using yargs
33+ const apiSpecFileName = ( argv . file as string ) || '' ;
34+ const ruleCategories = argv . categories ? ( argv . categories as string ) . split ( ',' ) : undefined ;
35+ const logErrorFilePath = argv . logError as string | undefined ;
36+ const logDiagnosticFilePath = argv . logDiagnostic as string | undefined ;
3137 try {
32- // Parse command-line arguments using yargs
33- const apiSpecFileName = ( argv . file as string ) || "" ;
34- const ruleCategories = argv . categories ? ( argv . categories as string ) . split ( "," ) : undefined ;
35- const logErrorFilePath = argv . logError as string | undefined ;
36- const logDiagnosticFilePath = argv . logDiagnostic as string | undefined ;
37- try {
38-
39- // Import and create rule instances in RAP-LP
40- const enabledRulesAndCategorys = await importAndCreateRuleInstances ( ruleCategories ) ;
41- // Load API specification into a Document object
42- const apiSpecDocument = new Document (
43- fs . readFileSync ( join ( apiSpecFileName ) , "utf-8" ) . trim ( ) ,
44- Parsers . Yaml ,
45- apiSpecFileName
46- ) ;
47-
48- try {
49- /**
50- * CustomSpectral
51- */
52- const customSpectral = new RapLPCustomSpectral ( ) ;
53- customSpectral . setCategorys ( enabledRulesAndCategorys . instanceCategoryMap ) ;
54- customSpectral . setRuleset ( enabledRulesAndCategorys . rules ) ;
55- const result = await customSpectral . run ( apiSpecDocument ) ;
56-
57- const customDiagnostic = new RapLPDiagnostic ( ) ;
58- customDiagnostic . processRuleExecutionInformation ( result , enabledRulesAndCategorys . instanceCategoryMap ) ;
59- const diagnosticReports : DiagnosticReport [ ] = customDiagnostic . processDiagnosticInformation ( ) ;
60-
61- if ( argv . dex != null ) {
62- const reportHandler = new ExcelReportProcessor ( {
63- outputFilePath : argv . dex ,
64- } ) ;
65- reportHandler . generateReportDocument ( customDiagnostic )
38+ // Import and create rule instances in RAP-LP
39+ const enabledRulesAndCategorys = await importAndCreateRuleInstances ( ruleCategories ) ;
40+ // Load API specification into a Document object
41+ const apiSpecDocument = new Document (
42+ fs . readFileSync ( join ( apiSpecFileName ) , 'utf-8' ) . trim ( ) ,
43+ Parsers . Yaml ,
44+ apiSpecFileName ,
45+ ) ;
46+
47+ try {
48+ /**
49+ * CustomSpectral
50+ */
51+ const customSpectral = new RapLPCustomSpectral ( ) ;
52+ customSpectral . setCategorys ( enabledRulesAndCategorys . instanceCategoryMap ) ;
53+ customSpectral . setRuleset ( enabledRulesAndCategorys . rules ) ;
54+ const result = await customSpectral . run ( apiSpecDocument ) ;
55+
56+ const customDiagnostic = new RapLPDiagnostic ( ) ;
57+ customDiagnostic . processRuleExecutionInformation ( result , enabledRulesAndCategorys . instanceCategoryMap ) ;
58+ const diagnosticReports : DiagnosticReport [ ] = customDiagnostic . processDiagnosticInformation ( ) ;
59+
60+ if ( argv . dex != null ) {
61+ const reportHandler = new ExcelReportProcessor ( {
62+ outputFilePath : argv . dex ,
63+ } ) ;
64+ reportHandler . generateReportDocument ( customDiagnostic ) ;
65+ }
66+
67+ /**
68+ * Chalk impl.
69+ * @param allvarlighetsgrad
70+ * @returns
71+ */
72+ // Run Spectral on the API specification and log the result
73+ const colorizeSeverity = ( allvarlighetsgrad : string ) => {
74+ switch ( allvarlighetsgrad ) {
75+ case 'ERROR' : // Error
76+ return chalk . red ( 'Error' ) ;
77+ case 'WARNING' : // Warning
78+ return chalk . yellow ( 'Warning' ) ;
79+ case 'HINT' : // Info
80+ return chalk . greenBright ( 'Hint' ) ;
81+ default :
82+ return chalk . white ( 'Info' ) ;
6683 }
84+ } ;
85+ const formatLintingResult = ( result : any ) => {
86+ return `allvarlighetsgrad: ${ colorizeSeverity ( result . allvarlighetsgrad ) } \nid: ${ result . id } \nkrav: ${
87+ result . krav
88+ } \nområde: ${ result . omrade } \nsökväg:[${ result . sokvag } ] \nomfattning:${ JSON . stringify (
89+ result . omfattning ,
90+ null ,
91+ 2 ,
92+ ) } `;
93+ } ;
94+ //Check specified option from yargs input
95+
96+ const currentDate = new Date ( ) ; //.toISOString(); // Get current date and time in ISO format
97+ const formattedDate = `${ currentDate . getFullYear ( ) } -${ padZero ( currentDate . getMonth ( ) + 1 ) } -${ padZero (
98+ currentDate . getDate ( ) ,
99+ ) } ${ padZero ( currentDate . getHours ( ) ) } :${ padZero ( currentDate . getMinutes ( ) ) } :${ padZero (
100+ currentDate . getSeconds ( ) ,
101+ ) } `;
67102
68- /**
69- * Chalk impl.
70- * @param allvarlighetsgrad
71- * @returns
72- */
73- // Run Spectral on the API specification and log the result
74- const colorizeSeverity = ( allvarlighetsgrad : string ) => {
75- switch ( allvarlighetsgrad ) {
76- case 'ERROR' : // Error
77- return chalk . red ( 'Error' ) ;
78- case 'WARNING' : // Warning
79- return chalk . yellow ( 'Warning' ) ;
80- case 'HINT' : // Info
81- return chalk . greenBright ( 'Hint' ) ;
82- default :
83- return chalk . white ( 'Info' ) ;
84- }
85- } ;
86- const formatLintingResult = ( result : any ) => {
87- return `allvarlighetsgrad: ${ colorizeSeverity ( result . allvarlighetsgrad ) } \nid: ${ result . id } \nkrav: ${ result . krav } \nområde: ${ result . omrade } \nsökväg:[${ result . sokvag } ] \nomfattning:${ JSON . stringify ( result . omfattning , null , 2 ) } ` ;
88- } ;
89- //Check specified option from yargs input
90-
91- const currentDate = new Date ( ) //.toISOString(); // Get current date and time in ISO format
92- const formattedDate = `${ currentDate . getFullYear ( ) } -${ padZero ( currentDate . getMonth ( ) + 1 ) } -${ padZero ( currentDate . getDate ( ) ) } ${ padZero ( currentDate . getHours ( ) ) } :${ padZero ( currentDate . getMinutes ( ) ) } :${ padZero ( currentDate . getSeconds ( ) ) } ` ;
93-
94- function padZero ( num : number ) : string {
95- return num < 10 ? `0${ num } ` : `${ num } ` ;
96- }
97- if ( logDiagnosticFilePath ) {
98- let allDiagnosticReports = JSON . stringify ( diagnosticReports , null , 2 ) ;
99- let logEntry = `${ formattedDate } \n${ allDiagnosticReports } \n` ; // Prepend datestamp to log entry
100- let utf8EncodedContent = Buffer . from ( logEntry , 'utf8' ) ;
101- //Log to disc
102- await writeFileAsync ( logDiagnosticFilePath , utf8EncodedContent ) ;
103- console . log ( chalk . green ( `Skriver diagnostiseringsinformation från RAP-LP till ${ logDiagnosticFilePath } ` ) ) ;
104- } else {
105- //STDOUT
106- if ( customDiagnostic . diagnosticInformation . executedUniqueRules != undefined &&
107- customDiagnostic . diagnosticInformation . executedUniqueRules . length > 0 ) {
108- console . log ( chalk . green ( "<<<Verkställda och godkända regler - RAP-LP>>>\r" ) ) ;
109- console . log ( chalk . whiteBright ( "STATUS\tOMRÅDE" ) + " / " + chalk . whiteBright ( "IDENTIFIKATIONSNUMMER" ) ) ;
110- customDiagnostic . diagnosticInformation . executedUniqueRules . forEach ( item => {
111- console . log ( chalk . bgGreen ( "OK" ) + "\t" + item . omrade + " / " + item . id ) ;
112- } ) ;
113- }
114- if ( customDiagnostic . diagnosticInformation . executedUniqueRulesWithError != undefined &&
115- customDiagnostic . diagnosticInformation . executedUniqueRulesWithError . length > 0 ) {
116- console . log ( chalk . green ( "<<<Verkställda och ej godkända regler - RAP-LP>>>\r" ) ) ;
117- console . log ( chalk . whiteBright ( "STATUS\tOMRÅDE" ) + " / " + chalk . whiteBright ( "IDENTIFIKATIONSNUMMER" ) ) ;
118- customDiagnostic . diagnosticInformation . executedUniqueRulesWithError . forEach ( item => {
119- console . log ( chalk . bgRed ( "EJ OK" ) + "\t" + item . omrade + " / " + item . id ) ;
120- } ) ;
121- }
122- if ( customDiagnostic . diagnosticInformation . notApplicableRules != undefined &&
123- customDiagnostic . diagnosticInformation . notApplicableRules . length > 0 ) {
124- console . log ( chalk . grey ( "<<<Ej tillämpade regler - RAP-LP>>>\r" ) ) ;
125- console . log ( chalk . whiteBright ( "STATUS\tOMRÅDE" ) + " / " + chalk . whiteBright ( "IDENTIFIKATIONSNUMMER" ) ) ;
126- customDiagnostic . diagnosticInformation . notApplicableRules . forEach ( item => {
127- console . log ( chalk . bgGrey ( "N/A" ) + "\t" + item . omrade + "/" + item . id ) ;
128- } ) ;
129- }
130- }
131- if ( logErrorFilePath ) {
132- let content = JSON . stringify ( result , null , 2 ) ;
133- let logEntry = `${ formattedDate } \n${ content } \n` ; // Prepend datestamp to log entry
134- let utf8EncodedContent = Buffer . from ( logEntry , 'utf8' ) ;
135- if ( argv . append ) {
136- await appendFileAsync ( logErrorFilePath , utf8EncodedContent ) ;
137- console . log ( chalk . green ( `Skriver inspektion/valideringsinformation från RAP-LP till ${ logErrorFilePath } ` ) ) ;
138- } else {
139- //Log to disc
140- await writeFileAsync ( logErrorFilePath , utf8EncodedContent ) ;
141- console . log ( chalk . green ( `Skriver inspektion/valideringsinformation från RAP-LP till ${ logErrorFilePath } ` ) ) ;
142- }
143- } else {
144- //Verbose error logging goes here with detailed result
145- console . log ( chalk . whiteBright ( '\n<<Regelutfall RAP-LP>> \n' ) ) ;
146- result . forEach ( item => {
147- console . log ( formatLintingResult ( item ) ) ;
103+ function padZero ( num : number ) : string {
104+ return num < 10 ? `0${ num } ` : `${ num } ` ;
105+ }
106+ if ( logDiagnosticFilePath ) {
107+ let allDiagnosticReports = JSON . stringify ( diagnosticReports , null , 2 ) ;
108+ let logEntry = `${ formattedDate } \n${ allDiagnosticReports } \n` ; // Prepend datestamp to log entry
109+ let utf8EncodedContent = Buffer . from ( logEntry , 'utf8' ) ;
110+ //Log to disc
111+ await writeFileAsync ( logDiagnosticFilePath , utf8EncodedContent ) ;
112+ console . log ( chalk . green ( `Skriver diagnostiseringsinformation från RAP-LP till ${ logDiagnosticFilePath } ` ) ) ;
113+ } else {
114+ //STDOUT
115+ if (
116+ customDiagnostic . diagnosticInformation . executedUniqueRules != undefined &&
117+ customDiagnostic . diagnosticInformation . executedUniqueRules . length > 0
118+ ) {
119+ console . log ( chalk . green ( '<<<Verkställda och godkända regler - RAP-LP>>>\r' ) ) ;
120+ console . log ( chalk . whiteBright ( 'STATUS\tOMRÅDE' ) + ' / ' + chalk . whiteBright ( 'IDENTIFIKATIONSNUMMER' ) ) ;
121+ customDiagnostic . diagnosticInformation . executedUniqueRules
122+ . sort ( ( a , b ) => a . omrade . localeCompare ( b . omrade , 'sv' ) || a . id . localeCompare ( b . id , 'sv' ) )
123+ . forEach ( ( item ) => {
124+ console . log ( chalk . bgGreen ( 'OK' ) + '\t' + item . omrade + ' / ' + item . id ) ;
125+ } ) ;
126+ }
127+ if (
128+ customDiagnostic . diagnosticInformation . executedUniqueRulesWithError != undefined &&
129+ customDiagnostic . diagnosticInformation . executedUniqueRulesWithError . length > 0
130+ ) {
131+ console . log ( chalk . green ( '<<<Verkställda och ej godkända regler - RAP-LP>>>\r' ) ) ;
132+ console . log ( chalk . whiteBright ( 'STATUS\tOMRÅDE' ) + ' / ' + chalk . whiteBright ( 'IDENTIFIKATIONSNUMMER' ) ) ;
133+ customDiagnostic . diagnosticInformation . executedUniqueRulesWithError
134+ . sort ( ( a , b ) => a . omrade . localeCompare ( b . omrade , 'sv' ) || a . id . localeCompare ( b . id , 'sv' ) )
135+ . forEach ( ( item ) => {
136+ console . log ( chalk . bgRed ( 'EJ OK' ) + '\t' + item . omrade + ' / ' + item . id ) ;
137+ } ) ;
138+ }
139+ if (
140+ customDiagnostic . diagnosticInformation . notApplicableRules != undefined &&
141+ customDiagnostic . diagnosticInformation . notApplicableRules . length > 0
142+ ) {
143+ console . log ( chalk . grey ( '<<<Ej tillämpade regler - RAP-LP>>>\r' ) ) ;
144+ console . log ( chalk . whiteBright ( 'STATUS\tOMRÅDE' ) + ' / ' + chalk . whiteBright ( 'IDENTIFIKATIONSNUMMER' ) ) ;
145+ customDiagnostic . diagnosticInformation . notApplicableRules
146+ . sort ( ( a , b ) => a . omrade . localeCompare ( b . omrade , 'sv' ) || a . id . localeCompare ( b . id , 'sv' ) )
147+ . forEach ( ( item ) => {
148+ console . log ( chalk . bgGrey ( 'N/A' ) + '\t' + item . omrade + '/' + item . id ) ;
148149 } ) ;
149- }
150- } catch ( spectralError : any ) {
151- logErrorToFile ( spectralError ) ; // Log stack
152- console . error ( chalk . red ( "Ett fel uppstod vid initiering/körning av regelklasser! Undersök felloggen för RAP-LP för mer information om felet" ) ) ;
153150 }
154- } catch ( initializingError : any ) {
155- logErrorToFile ( initializingError ) ;
156- console . error ( chalk . red ( "Ett fel uppstod vid inläsning av moduler och skapande av regelklasser! Undersök felloggen för RAP-LP för mer information om felet" ) ) ;
157- }
158- } catch ( error : any ) {
159- logErrorToFile ( error ) ;
160- console . error ( chalk . red ( "Ett oväntat fel uppstod! Undersök felloggen för RAP-LP för mer information om felet" , error . message ) ) ;
161- }
162- function logErrorToFile ( error : any ) {
163- const errorMessage = `${ new Date ( ) . toISOString ( ) } - ${ error . stack } \n` ;
164- fs . appendFileSync ( 'rap-lp-error.log' , errorMessage ) ;
165- if ( error . errors ) {
166- const detailedMessage = `${ new Date ( ) . toISOString ( ) } - ${ JSON . stringify ( error . errors , null , 2 ) } \n` ;
167- fs . appendFileSync ( 'rap-lp-error.log' , detailedMessage ) ;
168151 }
169- if ( error instanceof AggregateError ) {
170- error . errors . forEach ( ( err : any , index : number ) => {
171- const causeMessage = `Cause ${ index + 1 } : ${ err . stack || err } \n` ;
172- fs . appendFileSync ( 'rap-lp-error.log' , causeMessage ) ;
152+ if ( logErrorFilePath ) {
153+ let content = JSON . stringify ( result , null , 2 ) ;
154+ let logEntry = `${ formattedDate } \n${ content } \n` ; // Prepend datestamp to log entry
155+ let utf8EncodedContent = Buffer . from ( logEntry , 'utf8' ) ;
156+ if ( argv . append ) {
157+ await appendFileAsync ( logErrorFilePath , utf8EncodedContent ) ;
158+ console . log ( chalk . green ( `Skriver inspektion/valideringsinformation från RAP-LP till ${ logErrorFilePath } ` ) ) ;
159+ } else {
160+ //Log to disc
161+ await writeFileAsync ( logErrorFilePath , utf8EncodedContent ) ;
162+ console . log ( chalk . green ( `Skriver inspektion/valideringsinformation från RAP-LP till ${ logErrorFilePath } ` ) ) ;
163+ }
164+ } else {
165+ //Verbose error logging goes here with detailed result
166+ console . log ( chalk . whiteBright ( '\n<<Regelutfall RAP-LP>> \n' ) ) ;
167+ result . forEach ( ( item ) => {
168+ console . log ( formatLintingResult ( item ) ) ;
173169 } ) ;
174170 }
171+ } catch ( spectralError : any ) {
172+ logErrorToFile ( spectralError ) ; // Log stack
173+ console . error (
174+ chalk . red (
175+ 'Ett fel uppstod vid initiering/körning av regelklasser! Undersök felloggen för RAP-LP för mer information om felet' ,
176+ ) ,
177+ ) ;
175178 }
176- }
179+ } catch ( initializingError : any ) {
180+ logErrorToFile ( initializingError ) ;
181+ console . error (
182+ chalk . red (
183+ 'Ett fel uppstod vid inläsning av moduler och skapande av regelklasser! Undersök felloggen för RAP-LP för mer information om felet' ,
184+ ) ,
185+ ) ;
186+ }
187+ } catch ( error : any ) {
188+ logErrorToFile ( error ) ;
189+ console . error (
190+ chalk . red ( 'Ett oväntat fel uppstod! Undersök felloggen för RAP-LP för mer information om felet' , error . message ) ,
191+ ) ;
192+ }
193+ function logErrorToFile ( error : any ) {
194+ const errorMessage = `${ new Date ( ) . toISOString ( ) } - ${ error . stack } \n` ;
195+ fs . appendFileSync ( 'rap-lp-error.log' , errorMessage ) ;
196+ if ( error . errors ) {
197+ const detailedMessage = `${ new Date ( ) . toISOString ( ) } - ${ JSON . stringify ( error . errors , null , 2 ) } \n` ;
198+ fs . appendFileSync ( 'rap-lp-error.log' , detailedMessage ) ;
199+ }
200+ if ( error instanceof AggregateError ) {
201+ error . errors . forEach ( ( err : any , index : number ) => {
202+ const causeMessage = `Cause ${ index + 1 } : ${ err . stack || err } \n` ;
203+ fs . appendFileSync ( 'rap-lp-error.log' , causeMessage ) ;
204+ } ) ;
205+ }
206+ }
207+ }
0 commit comments