Skip to content

Commit 86e0cd9

Browse files
fix: add fix for some letters in ruleclasses and finished flow for validate endpoint
Signed-off-by: Fredrik Nordlander <fredrik.nordlander@digg.se>
1 parent 83ff233 commit 86e0cd9

23 files changed

+131
-101
lines changed

src/cli-mode.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -127,12 +127,8 @@ export async function execCLI<T extends CliArgs>(argv: T) {
127127
// Import and create rule instances in RAP-LP
128128
const enabledRulesAndCategorys = await importAndCreateRuleInstances(ruleCategories);
129129
// Load API specification into a Document object
130-
const apiSpecDocument = new Document(
131-
fs.readFileSync(join(apiSpecFileName), 'utf-8').trim(),
132-
Parsers.Yaml,
133-
apiSpecFileName,
134-
);
135-
130+
const parser: IParser<any> = (parseResult.format === 'json' ? Parsers.Json : Parsers.Yaml) as unknown as IParser<any>;
131+
apiSpecDocument = new SpectralDocument(parseResult.raw, parser, apiSpecFileName);
136132
try {
137133
/**
138134
* CustomSpectral
@@ -175,7 +171,7 @@ export async function execCLI<T extends CliArgs>(argv: T) {
175171
const formatLintingResult = (result: any) => {
176172
return `allvarlighetsgrad: ${colorizeSeverity(result.allvarlighetsgrad)} \nid: ${result.id} \nkrav: ${
177173
result.krav
178-
} \nområde: ${result.omrade} \nsökväg:[${result.sokvag}] \nomfattning:${JSON.stringify(
174+
} \nområde: ${result.område} \nsökväg:[${result.sökväg}] \nomfattning:${JSON.stringify(
179175
result.omfattning,
180176
null,
181177
2,
@@ -211,7 +207,7 @@ export async function execCLI<T extends CliArgs>(argv: T) {
211207
customDiagnostic.diagnosticInformation.executedUniqueRules
212208
.sort((a, b) => a.id.localeCompare(b.id, 'sv'))
213209
.forEach((item) => {
214-
console.log(chalk.bgGreen('OK') + '\t' + item.omrade + ' / ' + item.id);
210+
console.log(chalk.bgGreen('OK') + '\t' + item.område + ' / ' + item.id);
215211
});
216212
}
217213
if (
@@ -223,7 +219,7 @@ export async function execCLI<T extends CliArgs>(argv: T) {
223219
customDiagnostic.diagnosticInformation.executedUniqueRulesWithError
224220
.sort((a, b) => a.id.localeCompare(b.id, 'sv'))
225221
.forEach((item) => {
226-
console.log(chalk.bgRed('EJ OK') + '\t' + item.omrade + ' / ' + item.id);
222+
console.log(chalk.bgRed('EJ OK') + '\t' + item.område + ' / ' + item.id);
227223
});
228224
}
229225
if (
@@ -235,7 +231,7 @@ export async function execCLI<T extends CliArgs>(argv: T) {
235231
customDiagnostic.diagnosticInformation.notApplicableRules
236232
.sort((a, b) => a.id.localeCompare(b.id, 'sv'))
237233
.forEach((item) => {
238-
console.log(chalk.bgGrey('N/A') + '\t' + item.omrade + '/' + item.id);
234+
console.log(chalk.bgGrey('N/A') + '\t' + item.område + '/' + item.id);
239235
});
240236
}
241237
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export class SpecValidationRequestDto {
2+
/** Base 64 encoded OpenAPI spec (YAML or JSON) */
3+
spec!: string;
4+
5+
/** Rule categories to enable */
6+
categories?: string[];
7+
8+
/** Enable strict OpenAPI validation (structural and sematic) */
9+
strict?: boolean;
10+
}

src/routes/validate.ts

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@ import * as IssueHelper from '../util/RapLPIssueHelpers.js';
1717
import { parseApiSpecInput,detectSpecFormatPreference, ParseResult} from '../util/validateUtil.js';
1818
import { SpecParseError } from '../util/RapLPSpecParseError.js';
1919
import { 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

2227
export 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

src/ruleinterface/CustomProperties.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,6 @@
44

55
// Define a type for CustomProperties
66
export interface CustomProperties {
7-
omrade: string;
7+
område: string;
88
id: string;
99
}

src/rulesets/AmeRules.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface StateExecutionLog {
2828
}
2929
export class Ame07 extends BaseRuleset {
3030
static customProperties: CustomProperties = {
31-
omrade: 'API Message',
31+
område: 'API Message',
3232
id: 'AME.07',
3333
};
3434
description = 'Fältnamn BÖR använda tecken som är alfanumeriska.';
@@ -64,7 +64,7 @@ export class Ame07 extends BaseRuleset {
6464

6565
export class Ame04 extends BaseRuleset {
6666
static customProperties: CustomProperties = {
67-
omrade: 'API Message',
67+
område: 'API Message',
6868
id: 'AME.04',
6969
};
7070
description = 'För fältnamn i request och response body BÖR camelCase eller snake_case notation användas.';
@@ -100,7 +100,7 @@ export class Ame04 extends BaseRuleset {
100100
export class Ame01 extends BaseRuleset {
101101
static errorMessage = 'Datamodellen för en representation BÖR beskrivas med JSON enligt senaste versionen, RFC 8259.';
102102
static customProperties: CustomProperties = {
103-
omrade: 'API Message',
103+
område: 'API Message',
104104
id: 'AME.01',
105105
};
106106
description = 'Denna regel validerar att request och response är application/json.';
@@ -148,7 +148,7 @@ export class Ame02 extends BaseRuleset {
148148
static errorMessage =
149149
"Det BÖR förutsättas att alla request headers som standard använder 'Accept' med värde 'application/json'";
150150
static customProperties: CustomProperties = {
151-
omrade: 'API Message',
151+
område: 'API Message',
152152
id: 'AME.02',
153153
};
154154
description = 'Denna regel validerar att response är application/json.';
@@ -193,7 +193,7 @@ export class Ame02 extends BaseRuleset {
193193
}
194194
export class Ame05 extends BaseRuleset {
195195
static customProperties: CustomProperties = {
196-
omrade: 'API Message',
196+
område: 'API Message',
197197
id: 'AME.05',
198198
};
199199
description = 'Inom ett API SKALL namnsättningen vara konsekvent, dvs blanda inte camelCase och snake_case.';

src/rulesets/ArqRules.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export class Arq05ComplexStructure extends Arq05Base {
112112
}
113113
export class Arq01 extends BaseRuleset {
114114
static customProperties: CustomProperties = {
115-
omrade: 'API Request',
115+
område: 'API Request',
116116
id: 'ARQ.01',
117117
};
118118
description = 'Ett request BÖR skickas i UTF-8';
@@ -157,7 +157,7 @@ export class Arq01 extends BaseRuleset {
157157
}
158158
export class Arq03 extends BaseRuleset {
159159
static customProperties: CustomProperties = {
160-
omrade: 'API Request',
160+
område: 'API Request',
161161
id: 'ARQ.03',
162162
};
163163
description =

src/rulesets/BaseRuleset.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { logRuleExecution } from '../util/RuleExecutionStatusModule.js';
1010
import Format from '@stoplight/spectral-formats';
1111

1212
export class BaseRuleset implements RulesetInterface {
13-
static customProperties: CustomProperties = { omrade: undefined!, id: '' };
13+
static customProperties: CustomProperties = { område: undefined!, id: '' };
1414
static getCustomProperties(): CustomProperties {
1515
return BaseRuleset.customProperties;
1616
}

0 commit comments

Comments
 (0)