koas-parameters
Advanced tools
Comparing version 0.4.1 to 0.5.0
import { Plugin } from 'koas-core'; | ||
declare module 'koa' { | ||
interface DefaultContext { | ||
/** | ||
* The path parameters coerced according to the type defined in their JSON schema in the OpenAPI | ||
* document. | ||
*/ | ||
pathParams: Record<string, unknown>; | ||
/** | ||
* The query parameters coerced according to the type defined in their JSON schema in the | ||
* OpenAPI document. | ||
*/ | ||
queryParams: Record<string, unknown>; | ||
} | ||
} | ||
export interface ParameterParsers { | ||
@@ -3,0 +17,0 @@ /** |
@@ -16,4 +16,16 @@ "use strict"; | ||
}, | ||
integer: (value) => Number.parseInt(value), | ||
number: (value) => Number.parseFloat(value), | ||
integer(value) { | ||
const integer = Number(value); | ||
if (Number.isInteger(integer)) { | ||
return integer; | ||
} | ||
return value; | ||
}, | ||
number(value) { | ||
const number = Number(value); | ||
if (Number.isFinite(number)) { | ||
return number; | ||
} | ||
return value; | ||
}, | ||
string: String, | ||
@@ -33,16 +45,16 @@ }; | ||
}; | ||
return ({ spec, validate }) => { | ||
return ({ document, resolveRef, validate }) => { | ||
const handlers = new Map(); | ||
Object.values(spec.paths).forEach(({ delete: del, get, head, options, parameters: parametersObjects, patch, post, put, trace, }) => { | ||
Object.values(document.paths).forEach(({ delete: del, get, head, options, parameters: parametersObjects, patch, post, put, trace, }) => { | ||
[del, get, head, options, patch, post, put, trace] | ||
.filter(Boolean) | ||
.forEach((operationObject) => { | ||
handlers.set(operationObject, utils_1.createParameterHandler(operationObject, parametersObjects, combinedParsers, validate)); | ||
handlers.set(operationObject, utils_1.createParameterHandler(operationObject, parametersObjects, combinedParsers, validate, resolveRef)); | ||
}); | ||
}); | ||
return async (ctx, next) => { | ||
return (ctx, next) => { | ||
const { operationObject } = ctx.openApi; | ||
if (handlers.has(operationObject)) { | ||
const handler = handlers.get(operationObject); | ||
await handler(ctx); | ||
handler(ctx); | ||
} | ||
@@ -49,0 +61,0 @@ return next(); |
import { Context } from 'koa'; | ||
import { Validator } from 'koas-core'; | ||
import { JSONRefResolver, Validator } from 'koas-core'; | ||
import { OpenAPIV3 } from 'openapi-types'; | ||
@@ -12,5 +12,5 @@ import { ParameterParsers } from '.'; | ||
* @param validate - The schema validator function. | ||
* | ||
* @param resolveRef - A JSON reference resolver. | ||
* @returns A function for parsing and validating query and path parameters. | ||
*/ | ||
export declare function createParameterHandler(operationObject: OpenAPIV3.OperationObject, parameters: OpenAPIV3.ParameterObject[], parsers: ParameterParsers, validate: Validator): (ctx: Context) => Promise<void>; | ||
export declare function createParameterHandler(operationObject: OpenAPIV3.OperationObject, parameters: (OpenAPIV3.ParameterObject | OpenAPIV3.ReferenceObject)[], parsers: ParameterParsers, validate: Validator, resolveRef: JSONRefResolver): (ctx: Context) => void; |
101
lib/utils.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createParameterHandler = void 0; | ||
const koas_core_1 = require("koas-core"); | ||
/** | ||
@@ -9,3 +8,2 @@ * 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. | ||
@@ -21,6 +19,3 @@ */ | ||
additionalProperties: true, | ||
properties: definitions.reduce((acc, { name, schema = {} }) => { | ||
acc[name] = schema; | ||
return acc; | ||
}, {}), | ||
properties: Object.fromEntries(definitions.map(({ name, schema = {} }) => [name, schema])), | ||
}; | ||
@@ -39,9 +34,11 @@ if (r.length) { | ||
* @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) { | ||
function createParameterHandler(operationObject, parameters, parsers, validate, resolveRef) { | ||
const queryDefinitions = []; | ||
const pathDefinitions = []; | ||
[...(parameters || []), ...(operationObject.parameters || [])].forEach((definition) => { | ||
[...(parameters || []), ...(operationObject.parameters || [])] | ||
.map(resolveRef) | ||
.forEach((definition) => { | ||
if (definition.in === 'query') { | ||
@@ -70,60 +67,40 @@ queryDefinitions.push(definition); | ||
} | ||
return async (ctx) => { | ||
if (pathSchema) { | ||
ctx.params = Object.entries(ctx.params).reduce((acc, [key, value]) => { | ||
if (!Object.hasOwnProperty.call(pathSchema.properties, key)) { | ||
acc[key] = value; | ||
return acc; | ||
} | ||
const schema = pathSchema.properties[key]; | ||
if (schema.type === 'array') { | ||
acc[key] = value | ||
.split('/') | ||
.map((val) => { var _a; return parse(val, (_a = schema.items) === null || _a === void 0 ? void 0 : _a.type); }); | ||
return acc; | ||
} | ||
acc[key] = parse(value, schema.type); | ||
return acc; | ||
}, {}); | ||
try { | ||
await validate(ctx.params, pathSchema); | ||
/** | ||
* 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 = {}; | ||
Object.entries(rawParams).forEach(([key, value]) => { | ||
if (!Object.hasOwnProperty.call(schema.properties, key)) { | ||
params[key] = value; | ||
return; | ||
} | ||
catch (err) { | ||
if (!(err instanceof koas_core_1.SchemaValidationError)) { | ||
throw err; | ||
} | ||
ctx.throw(400, err.message, err.errors); | ||
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)); | ||
return; | ||
} | ||
} | ||
if (querySchema) { | ||
ctx.query = Object.entries(ctx.query).reduce((acc, [key, value]) => { | ||
if (!Object.hasOwnProperty.call(querySchema.properties)) { | ||
acc[key] = value; | ||
return acc; | ||
} | ||
const schema = pathSchema.properties[key]; | ||
if (schema.type === 'array') { | ||
const values = Array.isArray(value) ? value : [value]; | ||
acc[key] = values.map((val) => { var _a; return parse(val, (_a = schema.items) === null || _a === void 0 ? void 0 : _a.type); }); | ||
return acc; | ||
} | ||
if (Array.isArray(value)) { | ||
acc[key] = value; | ||
return acc; | ||
} | ||
acc[key] = parse(value, schema.type); | ||
return acc; | ||
}, {}); | ||
try { | ||
await validate(ctx.query, querySchema); | ||
if (Array.isArray(value)) { | ||
params[key] = value; | ||
return; | ||
} | ||
catch (err) { | ||
if (!(err instanceof koas_core_1.SchemaValidationError)) { | ||
throw err; | ||
} | ||
ctx.throw(400, err.message, err.errors); | ||
} | ||
} | ||
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; |
{ | ||
"name": "koas-parameters", | ||
"version": "0.4.1", | ||
"version": "0.5.0", | ||
"keywords": [ | ||
@@ -29,11 +29,11 @@ "koa", | ||
"dependencies": { | ||
"openapi-types": "^7.0.1" | ||
"openapi-types": "^7.2.3" | ||
}, | ||
"devDependencies": { | ||
"axios-test-instance": "^3.1.1", | ||
"koa": "^2.13.0" | ||
"axios-test-instance": "^4.0.0", | ||
"koa": "^2.13.1" | ||
}, | ||
"peerDependencies": { | ||
"koa": "^2", | ||
"koas-core": "^0.4.1" | ||
"koas-core": "^0.5.0" | ||
}, | ||
@@ -40,0 +40,0 @@ "engines": { |
@@ -21,14 +21,12 @@ # Koas Operations | ||
async function main() { | ||
const app = new Koa(); | ||
app.use( | ||
await koas(api, [ | ||
parameters({ | ||
parsers: { | ||
// Additional parsers | ||
}, | ||
}), | ||
]), | ||
); | ||
} | ||
const app = new Koa(); | ||
app.use( | ||
koas(api, [ | ||
parameters({ | ||
parsers: { | ||
// Additional parsers | ||
}, | ||
}), | ||
]), | ||
); | ||
``` | ||
@@ -35,0 +33,0 @@ |
243
10079
37
+ Addedjsonschema@1.4.1(transitive)
+ Addedkoas-core@0.5.5(transitive)
+ Addedopenapi-types@10.0.0(transitive)
- Removed@apidevtools/json-schema-ref-parser@9.1.2(transitive)
- Removed@jsdevtools/ono@7.1.3(transitive)
- Removed@types/json-schema@7.0.15(transitive)
- Removed@types/lodash@4.17.0(transitive)
- Removedargparse@2.0.1(transitive)
- Removedcall-me-maybe@1.0.2(transitive)
- Removedcommander@2.20.3(transitive)
- Removedjs-yaml@4.1.0(transitive)
- Removedkoas-core@0.4.1(transitive)
- Removedlodash@4.17.21(transitive)
- Removedlodash.get@4.4.2(transitive)
- Removedlodash.isequal@4.5.0(transitive)
- Removedvalidator@13.11.0(transitive)
- Removedz-schema@4.2.4(transitive)
Updatedopenapi-types@^7.2.3