/
asyncApi2MessageExamplesValidation.ts
96 lines (86 loc) · 2.25 KB
/
asyncApi2MessageExamplesValidation.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
import { createRulesetFunction } from '@stoplight/spectral-core';
import { schema as schemaFn } from '@stoplight/spectral-functions';
import type { JsonPath } from '@stoplight/types';
import type { IFunctionResult, RulesetFunctionContext } from '@stoplight/spectral-core';
import type { JSONSchema7 } from 'json-schema';
interface MessageExample {
name?: string;
summary?: string;
payload?: unknown;
headers?: unknown;
}
export interface MessageFragment {
payload: unknown;
headers: unknown;
examples?: MessageExample[];
}
function getMessageExamples(message: MessageFragment): Array<{ path: JsonPath; value: MessageExample }> {
if (!Array.isArray(message.examples)) {
return [];
}
return (
message.examples.map((example, index) => {
return {
path: ['examples', index],
value: example,
};
}) ?? []
);
}
function validate(
value: unknown,
path: JsonPath,
type: 'payload' | 'headers',
schema: unknown,
ctx: RulesetFunctionContext,
): ReturnType<typeof schemaFn> {
return schemaFn(
value,
{
allErrors: true,
schema: schema as JSONSchema7,
},
{
...ctx,
path: [...ctx.path, ...path, type],
},
);
}
export default createRulesetFunction<MessageFragment, null>(
{
input: {
type: 'object',
properties: {
name: {
type: 'string',
},
summary: {
type: 'string',
},
},
},
options: null,
},
function asyncApi2MessageExamplesValidation(targetVal, _, ctx) {
if (!targetVal.examples) return;
const examples = getMessageExamples(targetVal);
const results: IFunctionResult[] = [];
for (const example of examples) {
// validate payload
if (example.value.payload !== undefined) {
const errors = validate(example.value.payload, example.path, 'payload', targetVal.payload, ctx);
if (Array.isArray(errors)) {
results.push(...errors);
}
}
// validate headers
if (example.value.headers !== undefined) {
const errors = validate(example.value.headers, example.path, 'headers', targetVal.headers, ctx);
if (Array.isArray(errors)) {
results.push(...errors);
}
}
}
return results;
},
);