93 lines
2.1 KiB
JavaScript
93 lines
2.1 KiB
JavaScript
import { oas2, oas3_0 } from '@stoplight/spectral-formats';
|
|
import { printValue } from '@stoplight/spectral-runtime';
|
|
import { createRulesetFunction } from '@stoplight/spectral-core';
|
|
|
|
function getDataType(input, checkForInteger) {
|
|
const type = typeof input;
|
|
switch (type) {
|
|
case 'string':
|
|
case 'boolean':
|
|
return type;
|
|
case 'number':
|
|
if (checkForInteger && Number.isInteger(input)) {
|
|
return 'integer';
|
|
}
|
|
|
|
return 'number';
|
|
case 'object':
|
|
if (input === null) {
|
|
return 'null';
|
|
}
|
|
|
|
return Array.isArray(input) ? 'array' : 'object';
|
|
default:
|
|
throw TypeError('Unknown input type');
|
|
}
|
|
}
|
|
|
|
function getTypes(input, formats) {
|
|
const { type } = input;
|
|
|
|
if (
|
|
(input.nullable === true && formats?.has(oas3_0) === true) ||
|
|
(input['x-nullable'] === true && formats?.has(oas2) === true)
|
|
) {
|
|
return Array.isArray(type) ? [...type, 'null'] : [type, 'null'];
|
|
}
|
|
|
|
return type;
|
|
}
|
|
|
|
export const typedEnum = createRulesetFunction(
|
|
{
|
|
input: {
|
|
type: 'object',
|
|
properties: {
|
|
enum: {
|
|
type: 'array',
|
|
},
|
|
type: {
|
|
oneOf: [
|
|
{
|
|
type: 'array',
|
|
items: {
|
|
type: 'string',
|
|
},
|
|
},
|
|
{
|
|
type: 'string',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
required: ['enum', 'type'],
|
|
},
|
|
options: null,
|
|
},
|
|
function (input, opts, context) {
|
|
const { enum: enumValues } = input;
|
|
const type = getTypes(input, context.document.formats);
|
|
const checkForInteger = type === 'integer' || (Array.isArray(type) && type.includes('integer'));
|
|
|
|
let results;
|
|
|
|
enumValues.forEach((value, i) => {
|
|
const valueType = getDataType(value, checkForInteger);
|
|
|
|
if (valueType === type || (Array.isArray(type) && type.includes(valueType))) {
|
|
return;
|
|
}
|
|
|
|
results ??= [];
|
|
results.push({
|
|
message: `Enum value ${printValue(enumValues[i])} must be "${String(type)}".`,
|
|
path: [...context.path, 'enum', i],
|
|
});
|
|
});
|
|
|
|
return results;
|
|
},
|
|
);
|
|
|
|
export default typedEnum;
|