next-rest-framework
Version:
Next REST Framework - write type-safe, self-documenting REST APIs in Next.js
89 lines (88 loc) • 4.07 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.defineApiRoute = void 0;
const constants_1 = require("./constants");
const utils_1 = require("./utils");
const defineApiRoute = ({ config }) => {
return (methodHandlers = {}) => {
return async (req, res) => {
try {
const { method, body, query, headers, url: pathname } = req;
const { openApiJsonPath, openApiYamlPath, swaggerUiPath, exposeOpenApiSpec } = config;
if ([openApiJsonPath, openApiYamlPath, swaggerUiPath].includes(pathname) &&
exposeOpenApiSpec &&
method === constants_1.ValidMethod.GET) {
(0, utils_1.handleReservedPathWarnings)({ pathname, config });
}
if (headers['user-agent'] === constants_1.NEXT_REST_FRAMEWORK_USER_AGENT) {
const route = decodeURIComponent(pathname ?? '');
try {
const nextRestFrameworkPaths = (0, utils_1.getPathsFromMethodHandlers)({
config,
methodHandlers: methodHandlers,
route
});
res.status(200).json({ nextRestFrameworkPaths });
return;
}
catch (error) {
throw Error(`OpenAPI spec generation failed for route: ${route}
${error}`);
}
}
const methodHandler = methodHandlers[method];
if (!methodHandler) {
res.setHeader('Allow', Object.keys(methodHandlers).join(', '));
res.status(405).json({ message: constants_1.DEFAULT_ERRORS.methodNotAllowed });
return;
}
const { input, handler } = methodHandler;
if (input) {
const { body: bodySchema, query: querySchema, contentType } = input;
if (headers['content-type']?.split(';')[0] !== contentType) {
res.status(415).json({ message: constants_1.DEFAULT_ERRORS.invalidMediaType });
return;
}
if (bodySchema) {
const validateBody = await (0, utils_1.validateSchema)?.({
schema: bodySchema,
obj: body
});
if (validateBody) {
const { valid, errors } = validateBody;
if (!valid) {
res
.status(400)
.json({ message: `Invalid request body: ${errors}` });
return;
}
}
}
if (querySchema) {
const validateQuery = await (0, utils_1.validateSchema)?.({
schema: querySchema,
obj: query
});
if (validateQuery) {
const { valid, errors } = validateQuery;
if (!valid) {
res
.status(400)
.json({ message: `Invalid query parameters: ${errors}` });
return;
}
}
}
}
await handler(req, res);
}
catch (error) {
await config.errorHandler?.({ req, error });
if (!res.writableEnded) {
res.status(500).json({ message: constants_1.DEFAULT_ERRORS.unexpectedError });
}
}
};
};
};
exports.defineApiRoute = defineApiRoute;