import fastify, { FastifyInstance, FastifyServerOptions } from "fastify"; import fastifySwagger, { FastifyDynamicSwaggerOptions } from "@fastify/swagger"; import { NotFound, BadRequest } from "http-errors"; import { buildJsonSchemas, withRefResolver } from ".."; import { BuildJsonSchemasOptions } from "../JsonSchema"; import { models, TodoItem, TodoItemId, TodoItems, TodoItemsGroupedByStatus, } from "./models.fixtures"; export const createLegacyTestServer = ( fastifyOptions: FastifyServerOptions, buildJsonSchemasOptions: BuildJsonSchemasOptions, swaggerOptions: FastifyDynamicSwaggerOptions, ): FastifyInstance => { const f = fastify(fastifyOptions); f.register(fastifySwagger, withRefResolver(swaggerOptions)); const { $ref, schemas } = buildJsonSchemas(models, buildJsonSchemasOptions); for (const schema of schemas) { f.addSchema(schema); } const state: TodoItems = { todoItems: [], }; f.get<{ Reply: TodoItems; }>( `/item`, { schema: { operationId: `getTodoItems`, response: { 200: $ref(`TodoItems`), }, }, }, async () => state, ); f.get<{ Reply: TodoItemsGroupedByStatus; }>( `/item/grouped-by-status`, { schema: { operationId: `getTodoItemsGroupedByStatus`, response: { 200: $ref(`TodoItemsGroupedByStatus`), }, }, }, async () => ({ done: state.todoItems.filter((item) => item.state === `done`), inProgress: state.todoItems.filter( (item) => item.state === `in progress`, ), todo: state.todoItems.filter((item) => item.state === `todo`), }), ); f.post<{ Body: TodoItem; Reply: TodoItems; }>( `/item`, { schema: { operationId: `postTodoItem`, body: $ref(`TodoItem`), response: { 200: $ref(`TodoItems`), }, }, }, async ({ body: nextItem }) => { if (state.todoItems.some((prevItem) => prevItem.id === nextItem.id)) { throw new BadRequest(`item already exists`); } state.todoItems = [...state.todoItems, nextItem]; return state; }, ); f.put<{ Body: TodoItem; Params: TodoItemId; Reply: TodoItem; }>( `/item/:id`, { schema: { operationId: `putTodoItem`, body: $ref(`TodoItem`), params: $ref(`TodoItemId`), response: { 200: $ref(`TodoItem`), }, }, }, async ({ params: { id }, body: nextItem }) => { if (!state.todoItems.some((prevItem) => prevItem.id === id)) { throw new NotFound(`no such item`); } state.todoItems = state.todoItems.map((prevItem) => prevItem.id === id ? nextItem : prevItem, ); return nextItem; }, ); return f; };