@@ -17,6 +17,11 @@ import * as IssueHelper from '../util/RapLPIssueHelpers.js';
1717import { parseApiSpecInput , detectSpecFormatPreference , ParseResult } from '../util/validateUtil.js' ;
1818import { SpecParseError } from '../util/RapLPSpecParseError.js' ;
1919import { ProblemDetailsDTO } from '../model/ProblemDetailsDto.js' ;
20+ import { SpecValidationRequestDto } from '../model/SpecValidationRequestDto.js' ;
21+ import { ERROR_TYPE , RapLPBaseApiError } from '../util/RapLPBaseApiErrorHandling.js' ;
22+ import type { IParser } from '@stoplight/spectral-parsers' ;
23+ import { stringify } from 'node:querystring' ;
24+
2025
2126
2227export const registerValidationRoutes = ( app : Express ) => {
@@ -83,49 +88,69 @@ export const registerValidationRoutes = (app: Express) => {
8388 next ( e ) ;
8489 }
8590 } ) ;
91+ /**
92+ * Endpoint
93+ */
8694 app . post ( '/api/v1/validation/validatespec' , async ( req , res , next ) => {
8795 try {
88- const body : YamlContentDto = req . body ;
96+ const body : SpecValidationRequestDto = req . body ;
97+
98+ //0.5 Check input
99+ if ( ! body . spec ) {
100+ throw new RapLPBaseApiError (
101+ 'Invalid request' ,
102+ 'Missing required field: spec' ,
103+ ERROR_TYPE . BAD_REQUEST ,
104+ ) ;
105+ }
89106
90107 // 1. Decode input
91- const raw = decodeBase64String ( body . yaml ) ;
108+ const raw = decodeBase64String ( body . spec ) ;
109+ const strict = body . strict ?? true ;
110+ const categories = body . categories ?? [ ] ;
92111
93- // 2. Avgör format-preferens (samma som CLI)
112+ // 2. Detect format-preferens
94113 const prefer = detectSpecFormatPreference (
95114 undefined ,
96115 raw ,
97116 'auto' ,
98117 ) ;
99-
100- // 3. Parse + strict-validate (Spectral + AJV)
118+ // 3. Parse handling + strict-validate (Structural / Semantic errors)
101119 const parseResult = await parseApiSpecInput (
102120 { raw } ,
103- {
104- strict : true ,
105- preferJsonError : prefer ,
106- } ,
121+ { strict, preferJsonError : prefer } ,
107122 ) ;
108123
109- // 4. Om strict -issues → returnera validation response
124+ // 4. Strict -issues →
110125 if ( parseResult . strictIssues ?. length ) {
111126 const sorted = IssueHelper . sortIssues ( parseResult . strictIssues ) ;
112127 const snippet = IssueHelper . formatIssuesAsEditorText ( sorted ) ;
113128
114- return res . status ( 200 ) . json ( {
115- ok : false ,
116- kind : 'validation' ,
117- issues : sorted ,
118- snippet,
119- } ) ;
129+ return res . status ( 400 ) . json (
130+ new ProblemDetailsDTO ( {
131+ type : 'https://rap-lp./problems/semantic-validation' ,
132+ title : 'Rule validation failed' ,
133+ status : 400 ,
134+ detail : 'The specification contains structural or semantic errors' ,
135+ instance : req . originalUrl ,
136+
137+ // Put in kind field to indicate violation
138+ kind : 'spec-validation' ,
139+ //Payload
140+ issues : sorted ,
141+ snippet,
142+ } ) ,
143+ ) ;
120144 }
121145
122- // 5. Inga strict-fel → kör domänregler
123- const apiSpecDocument = new Document ( raw , Parsers . Yaml , '' ) ;
124- const rules = await importAndCreateRuleInstances ( body . categories ) ;
146+ // 5. No strict-errors → run raplp ruleengine
147+ const parser : IParser < any > = ( parseResult . format === 'json' ? Parsers . Json : Parsers . Yaml ) as unknown as IParser < any > ;
148+ const apiSpecDocument = new Document ( parseResult . raw , parser , '' ) ;
149+ const rules = await importAndCreateRuleInstances ( categories ) ;
125150 const result = await processApiSpec ( rules , apiSpecDocument ) ;
126151
127152 const hasRuleViolations = result . result . some (
128- d => d . allvarlighetsgrad === 'Error ' || d . allvarlighetsgrad === 'Warning '
153+ d => d . allvarlighetsgrad === 'ERROR ' || d . allvarlighetsgrad === 'WARNING '
129154 ) ;
130155 if ( hasRuleViolations ) {
131156 //Rulevalidation occured in RapLP-ruleengine
0 commit comments