koas-parameters
Version:
Koas parameters attempts to coerce path and query parameters to the type specified in their respective JSON schema.
101 lines (100 loc) • 3.75 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.createParameterHandler = void 0;
/**
* Create a full JSON schema for objects from a list of OpenAPI parameter objects.
*
* @param definitions - The parameter objects to create a schema from.
* @returns The resulting JSON schema.
*/
function createSchema(definitions) {
if (definitions.length === 0) {
return null;
}
const r = definitions.filter(({ required }) => required).map(({ name }) => name);
const fullSchema = {
type: 'object',
additionalProperties: true,
properties: Object.fromEntries(definitions.map(({ name, schema = {} }) => [name, schema])),
};
if (r.length) {
fullSchema.required = r;
}
return fullSchema;
}
/**
* Create a function for parsing and validating query and path parameters.
*
* @param operationObject - The active OpenAPI operation object.
* @param parameters - The active OpenAPI parameters object.
* @param parsers - Provided parameter parser functions.
* @param validate - The schema validator function.
* @param resolveRef - A JSON reference resolver.
* @returns A function for parsing and validating query and path parameters.
*/
function createParameterHandler(operationObject, parameters, parsers, validate, resolveRef) {
const queryDefinitions = [];
const pathDefinitions = [];
for (const maybeRef of [...(parameters || []), ...(operationObject.parameters || [])]) {
const definition = resolveRef(maybeRef);
if (definition.in === 'query') {
queryDefinitions.push(definition);
}
else if (definition.in === 'path') {
pathDefinitions.push(definition);
}
}
const querySchema = createSchema(queryDefinitions);
const pathSchema = createSchema(pathDefinitions);
/**
* Parse a valud using a parser function based on the type.
*
* @param value - The value to parse.
* @param type - The type of the SJON schma.
* @returns The parsed value.
*/
function parse(value, type = 'string') {
if (Object.hasOwnProperty.call(parsers, type)) {
return parsers[type](value);
}
return value;
}
/**
* Parse a parameters object based on a JSON schema.
*
* @param rawParams - The raw parameters to parse.
* @param schema - The JSON schema to base tpe conversions on.
* @param message - The schema validation message to throw.
* @returns The parsed object.
*/
function parseObject(rawParams, schema, message) {
if (!schema) {
return;
}
const params = {};
for (const [key, value] of Object.entries(rawParams)) {
if (!Object.hasOwnProperty.call(schema.properties, key)) {
params[key] = value;
continue;
}
const subSchema = resolveRef(schema.properties[key]);
if (subSchema.type === 'array') {
const values = Array.isArray(value) ? value : [value];
params[key] = values.map((val) => parse(val, resolveRef(subSchema.items).type));
continue;
}
if (Array.isArray(value)) {
params[key] = value;
continue;
}
params[key] = parse(value, subSchema.type);
}
validate(params, schema, { message });
return params;
}
return (ctx) => {
ctx.pathParams = parseObject(ctx.params, pathSchema, 'Path parameter validation failed');
ctx.queryParams = parseObject(ctx.query, querySchema, 'Query parameter validation failed');
};
}
exports.createParameterHandler = createParameterHandler;