@mintlify/validation
Version:
Validates mint.json files
116 lines (115 loc) • 4.74 kB
JavaScript
const MAX_DEPTH = 100;
export const isDataSchemaArray = (schemaArray) => {
return Array.isArray(schemaArray) && schemaArray.length > 0;
};
const filterXMint = (schema) => {
var _a, _b;
if (schema.type === 'object') {
const propertiesWithXMintFiltered = Object.entries(schema.properties).filter(([_, [schema]]) => !('x-mint' in schema));
return Object.assign(Object.assign({}, schema), { properties: Object.fromEntries(propertiesWithXMintFiltered) });
}
if (schema.type === 'array') {
const itemsWithXMintFiltered = schema.items.filter((schema) => !('x-mint' in schema));
if (isDataSchemaArray(itemsWithXMintFiltered)) {
return Object.assign(Object.assign({}, schema), { items: itemsWithXMintFiltered });
}
}
if (schema.type === 'enum<string>') {
const enumValues = schema.enum;
const xFilteredEnumValues = [];
Object.entries((_a = schema['x-mint-enum']) !== null && _a !== void 0 ? _a : {}).forEach(([enumKey]) => {
xFilteredEnumValues.push(enumKey.toString());
});
return Object.assign(Object.assign({}, schema), { enum: enumValues.filter((enumValue) => !xFilteredEnumValues.includes(enumValue)) });
}
if (schema.type === 'enum<number>' || schema.type === 'enum<integer>') {
const enumValues = schema.enum;
const xFilteredEnumValues = [];
Object.entries((_b = schema['x-mint-enum']) !== null && _b !== void 0 ? _b : {}).forEach(([enumKey]) => {
xFilteredEnumValues.push(Number(enumKey));
});
return Object.assign(Object.assign({}, schema), { enum: enumValues.filter((enumValue) => !xFilteredEnumValues.includes(enumValue)) });
}
return schema;
};
export const generateExampleFromSchema = (schema, depth = 0) => {
if (schema.example !== undefined) {
return schema.example;
}
if (schema.default !== undefined) {
return schema.default;
}
const schemaForExampleGeneration = filterXMint(schema);
switch (schemaForExampleGeneration.type) {
case 'string':
return generateStringExample(schemaForExampleGeneration);
case 'boolean':
return true;
case 'number':
case 'integer':
return generateNumericExample(schemaForExampleGeneration);
case 'enum<string>':
case 'enum<number>':
case 'enum<integer>':
return schemaForExampleGeneration.enum[0];
case 'null':
return null;
case 'any':
return '<any>';
case 'object':
const entries = Object.entries(schemaForExampleGeneration.properties)
// generate examples for all properties until depth reached - then only required properties
.filter(([_, [{ required }]]) => depth < MAX_DEPTH || required)
.map(([propName, subschema]) => [
propName,
generateExampleFromSchema(subschema[0], depth + 1),
]);
return Object.fromEntries(entries);
case 'array':
return depth < MAX_DEPTH
? [
generateExampleFromSchema(schemaForExampleGeneration.items[0],
// prevent the weird [{}] example value by counting array<object> as one level
schemaForExampleGeneration.items[0].type === 'object' ? depth : depth + 1),
]
: [];
}
};
const generateStringExample = (schema) => {
var _a;
switch ((_a = schema.format) === null || _a === void 0 ? void 0 : _a.toLowerCase()) {
case 'byte':
case 'base64':
return 'aSDinaTvuI8gbWludGxpZnk=';
case 'date':
return '2023-12-25';
case 'date-time':
return '2023-11-07T05:31:56Z';
case 'email':
return 'jsmith@example.com';
case 'uuid':
return '3c90c3cc-0d44-4b50-8888-8dd25736052a';
case 'ipv4':
return '127.0.0.1';
case 'ipv6':
return '2606:4700:3108::ac42:2835';
default:
return '<string>';
}
};
const generateNumericExample = (schema) => {
// if schema type is integer, make sure example is integer
const format = schema.type === 'integer' ? Math.floor : (n) => n;
if (schema.minimum !== undefined && schema.maximum !== undefined) {
return format((schema.minimum + schema.maximum) / 2);
}
else if (schema.minimum !== undefined) {
return format(schema.minimum + 1);
}
else if (schema.maximum !== undefined) {
return 123 < schema.maximum ? 123 : format(schema.maximum - 1);
}
else {
return 123;
}
};