UNPKG

fastify-openapi-glue

Version:

generate a fastify configuration from an openapi specification

738 lines (711 loc) 14.3 kB
// Fastify plugin autogenerated by fastify-openapi-glue import fastifyPlugin from "fastify-plugin"; import { Security } from "./security.js"; import { SecurityError } from "./securityHandlers.js"; import { Service } from "./service.js"; function notImplemented(operationId) { return async () => { throw new Error(`Operation ${operationId} not implemented`); }; } function buildHandler(serviceHandlers, operationId) { if (operationId in serviceHandlers) { return serviceHandlers[operationId]; } return notImplemented(operationId); } function buildPreHandler(securityHandlers, schemes) { if (schemes.length === 0) { return async () => {}; } return async (req, reply) => { const handlerErrors = []; const schemeList = []; let statusCode = 401; for (const scheme of schemes) { try { await securityHandlers[scheme.name](req, reply, scheme.parameters); return; // If one security check passes, no need to try any others } catch (err) { req.log.debug(`Security handler '${scheme.name}' failed: '${err}'`); handlerErrors.push(err); if (err.statusCode !== undefined) { statusCode = err.statusCode; } } schemeList.push(scheme.name); } // if we get this far no security handlers validated this request throw new SecurityError( `None of the security schemes (${schemeList.join(", ")}) successfully authenticated this request.`, statusCode, "Unauthorized", handlerErrors, ); }; } export default fastifyPlugin( async (instance, _opts) => { instance.register(generateRoutes, { prefix: "/v2" }); }, { fastify: "^4.x" }, ); async function generateRoutes(fastify, _opts) { const service = new Service(); const security = new Security(); fastify.route({ method: "POST", url: "/pet", schema: { body: { type: "object", required: ["name", "photoUrls"], properties: { id: { type: "integer", format: "int64", }, category: { type: "object", properties: { id: { type: "integer", format: "int64", }, name: { type: "string", }, }, xml: { name: "Category", }, }, name: { type: "string", example: "doggie", }, photoUrls: { type: "array", xml: { name: "photoUrl", wrapped: true, }, items: { type: "string", }, }, tags: { type: "array", xml: { name: "tag", wrapped: true, }, items: { type: "object", properties: { id: { type: "integer", format: "int64", }, name: { type: "string", }, }, xml: { name: "Tag", }, }, }, status: { type: "string", description: "pet status in the store", enum: ["available", "pending", "sold"], }, }, xml: { name: "Pet", }, }, }, handler: buildHandler(service, "addPet").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "PUT", url: "/pet", schema: { body: { type: "object", required: ["name", "photoUrls"], properties: { id: { type: "integer", format: "int64", }, category: { type: "object", properties: { id: { type: "integer", format: "int64", }, name: { type: "string", }, }, xml: { name: "Category", }, }, name: { type: "string", example: "doggie", }, photoUrls: { type: "array", xml: { name: "photoUrl", wrapped: true, }, items: { type: "string", }, }, tags: { type: "array", xml: { name: "tag", wrapped: true, }, items: { type: "object", properties: { id: { type: "integer", format: "int64", }, name: { type: "string", }, }, xml: { name: "Tag", }, }, }, status: { type: "string", description: "pet status in the store", enum: ["available", "pending", "sold"], }, }, xml: { name: "Pet", }, }, }, handler: buildHandler(service, "updatePet").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "GET", url: "/pet/findByStatus", schema: { querystring: { type: "object", properties: { status: { type: "array", description: "Status values that need to be considered for filter", items: { type: "string", enum: ["available", "pending", "sold"], default: "available", }, collectionFormat: "multi", }, }, required: ["status"], }, }, handler: buildHandler(service, "findPetsByStatus").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "GET", url: "/pet/findByTags", schema: { querystring: { type: "object", properties: { tags: { type: "array", description: "Tags to filter by", items: { type: "string", }, collectionFormat: "multi", }, }, required: ["tags"], }, }, handler: buildHandler(service, "findPetsByTags").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "GET", url: "/pet/:petId", schema: { params: { type: "object", properties: { petId: { type: "integer", description: "ID of pet to return", format: "int64", }, }, required: ["petId"], }, }, handler: buildHandler(service, "getPetById").bind(Service), prehandler: buildPreHandler(security, [{ api_key: [] }]).bind(Security), }); fastify.route({ method: "POST", url: "/pet/:petId", schema: { body: { type: "object", properties: { name: { type: "string", description: "Updated name of the pet", }, status: { type: "string", description: "Updated status of the pet", }, }, }, params: { type: "object", properties: { petId: { type: "integer", description: "ID of pet that needs to be updated", format: "int64", }, }, required: ["petId"], }, }, handler: buildHandler(service, "updatePetWithForm").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "DELETE", url: "/pet/:petId", schema: { params: { type: "object", properties: { petId: { type: "integer", description: "Pet id to delete", format: "int64", }, }, required: ["petId"], }, }, handler: buildHandler(service, "deletePet").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "POST", url: "/pet/:petId/uploadImage", schema: { body: { type: "object", properties: { additionalMetadata: { type: "string", description: "Additional data to pass to server", }, file: { type: "string", description: "file to upload", }, }, }, params: { type: "object", properties: { petId: { type: "integer", description: "ID of pet to update", format: "int64", }, }, required: ["petId"], }, }, handler: buildHandler(service, "uploadFile").bind(Service), prehandler: buildPreHandler(security, [ { petstore_auth: ["write:pets", "read:pets"] }, ]).bind(Security), }); fastify.route({ method: "GET", url: "/store/inventory", schema: {}, handler: buildHandler(service, "getInventory").bind(Service), prehandler: buildPreHandler(security, [{ api_key: [] }]).bind(Security), }); fastify.route({ method: "POST", url: "/store/order", schema: { body: { type: "object", properties: { id: { type: "integer", format: "int64", }, petId: { type: "integer", format: "int64", }, quantity: { type: "integer", format: "int32", }, shipDate: { type: "string", format: "date-time", }, status: { type: "string", description: "Order Status", enum: ["placed", "approved", "delivered"], }, complete: { type: "boolean", default: false, }, }, xml: { name: "Order", }, }, }, handler: buildHandler(service, "placeOrder").bind(Service), }); fastify.route({ method: "GET", url: "/store/order/:orderId", schema: { params: { type: "object", properties: { orderId: { type: "integer", description: "ID of pet that needs to be fetched", format: "int64", maximum: 10, minimum: 1, }, }, required: ["orderId"], }, }, handler: buildHandler(service, "getOrderById").bind(Service), }); fastify.route({ method: "DELETE", url: "/store/order/:orderId", schema: { params: { type: "object", properties: { orderId: { type: "integer", description: "ID of the order that needs to be deleted", format: "int64", minimum: 1, }, }, required: ["orderId"], }, }, handler: buildHandler(service, "deleteOrder").bind(Service), }); fastify.route({ method: "POST", url: "/user", schema: { body: { type: "object", properties: { id: { type: "integer", format: "int64", }, username: { type: "string", }, firstName: { type: "string", }, lastName: { type: "string", }, email: { type: "string", }, password: { type: "string", }, phone: { type: "string", }, userStatus: { type: "integer", format: "int32", description: "User Status", }, }, xml: { name: "User", }, }, }, handler: buildHandler(service, "createUser").bind(Service), }); fastify.route({ method: "POST", url: "/user/createWithArray", schema: { body: { type: "array", items: { type: "object", properties: { id: { type: "integer", format: "int64", }, username: { type: "string", }, firstName: { type: "string", }, lastName: { type: "string", }, email: { type: "string", }, password: { type: "string", }, phone: { type: "string", }, userStatus: { type: "integer", format: "int32", description: "User Status", }, }, xml: { name: "User", }, }, }, }, handler: buildHandler(service, "createUsersWithArrayInput").bind(Service), }); fastify.route({ method: "POST", url: "/user/createWithList", schema: { body: { type: "array", items: { type: "object", properties: { id: { type: "integer", format: "int64", }, username: { type: "string", }, firstName: { type: "string", }, lastName: { type: "string", }, email: { type: "string", }, password: { type: "string", }, phone: { type: "string", }, userStatus: { type: "integer", format: "int32", description: "User Status", }, }, xml: { name: "User", }, }, }, }, handler: buildHandler(service, "createUsersWithListInput").bind(Service), }); fastify.route({ method: "GET", url: "/user/login", schema: { querystring: { type: "object", properties: { username: { type: "string", description: "The user name for login", }, password: { type: "string", description: "The password for login in clear text", }, }, required: ["username", "password"], }, }, handler: buildHandler(service, "loginUser").bind(Service), }); fastify.route({ method: "GET", url: "/user/logout", schema: {}, handler: buildHandler(service, "logoutUser").bind(Service), }); fastify.route({ method: "GET", url: "/user/:username", schema: { params: { type: "object", properties: { username: { type: "string", description: "The name that needs to be fetched. Use user1 for testing. ", }, }, required: ["username"], }, }, handler: buildHandler(service, "getUserByName").bind(Service), }); fastify.route({ method: "PUT", url: "/user/:username", schema: { body: { type: "object", properties: { id: { type: "integer", format: "int64", }, username: { type: "string", }, firstName: { type: "string", }, lastName: { type: "string", }, email: { type: "string", }, password: { type: "string", }, phone: { type: "string", }, userStatus: { type: "integer", format: "int32", description: "User Status", }, }, xml: { name: "User", }, }, params: { type: "object", properties: { username: { type: "string", description: "name that need to be updated", }, }, required: ["username"], }, }, handler: buildHandler(service, "updateUser").bind(Service), }); fastify.route({ method: "DELETE", url: "/user/:username", schema: { params: { type: "object", properties: { username: { type: "string", description: "The name that needs to be deleted", }, }, required: ["username"], }, }, handler: buildHandler(service, "deleteUser").bind(Service), }); } export const options = { ajv: { customOptions: { strict: false, }, }, };