-
-
Notifications
You must be signed in to change notification settings - Fork 96
/
messageExamples.ts
102 lines (94 loc) · 2.67 KB
/
messageExamples.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
97
98
99
100
101
102
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';
import type { v2 } from 'spec-types';
function serializeSchema(schema: unknown, type: 'payload' | 'headers'): any {
if (!schema && typeof schema !== 'boolean') { // if schema is falsy then
if (type === 'headers') { // object for headers
schema = { type: 'object' };
} else { // anything for payload
schema = {};
}
} else if (typeof schema === 'boolean') { // spectral cannot handle boolean schemas
if (schema === true) {
schema = {}; // everything
} else {
schema = { not: {} }; // nothing
}
}
return schema;
}
function getMessageExamples(message: v2.MessageObject): Array<{ path: JsonPath; value: v2.MessageExampleObject }> {
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 const messageExamples = createRulesetFunction<v2.MessageObject, null>(
{
input: {
type: 'object',
properties: {
name: {
type: 'string',
},
summary: {
type: 'string',
},
},
},
options: null,
},
(targetVal, _, ctx) => {
if (!targetVal.examples) return;
const results: IFunctionResult[] = [];
const payloadSchema = serializeSchema(targetVal.payload, 'payload');
const headersSchema = serializeSchema(targetVal.headers, 'headers');
for (const example of getMessageExamples(targetVal)) {
const { path, value } = example;
// validate payload
if (value.payload !== undefined) {
const errors = validate(value.payload, path, 'payload', payloadSchema, ctx);
if (Array.isArray(errors)) {
results.push(...errors);
}
}
// validate headers
if (value.headers !== undefined) {
const errors = validate(value.headers, path, 'headers', headersSchema, ctx);
if (Array.isArray(errors)) {
results.push(...errors);
}
}
}
return results;
},
);