feat: adds module transpiling so api can require @calcom/prisma and not @prisma/client directly
This commit is contained in:
@@ -39,3 +39,6 @@ We aim to provide a fully tested API for our peace of mind, this is accomplished
|
||||
|
||||
Since this will only support an API, we redirect the requests to root to the /api folder.
|
||||
We also added a redirect for future-proofing API versioning when we might need it, without having to resort to dirty hacks like a v1/v2 folders with lots of duplicated code, instead we redirect /api/v*/:rest to /api/:rest?version=*
|
||||
|
||||
|
||||
The priority is the booking-related API routes so people can build their own booking flow, then event type management routes, then availability management routes etc
|
||||
@@ -0,0 +1,16 @@
|
||||
import { withValidation } from "next-validations";
|
||||
import { z } from "zod";
|
||||
|
||||
const schemaApiKey = z
|
||||
.object({
|
||||
expiresAt: z.date().optional(), // default is 30 days
|
||||
note: z.string().min(1).optional(),
|
||||
})
|
||||
.strict(); // Adding strict so that we can disallow passing in extra fields
|
||||
const withValidApiKey = withValidation({
|
||||
schema: schemaApiKey,
|
||||
type: "Zod",
|
||||
mode: "body",
|
||||
});
|
||||
|
||||
export { schemaApiKey, withValidApiKey };
|
||||
+7
-2
@@ -1,4 +1,9 @@
|
||||
module.exports = {
|
||||
const withTM = require("next-transpile-modules")([
|
||||
"@calcom/prisma",
|
||||
]);
|
||||
|
||||
|
||||
module.exports = withTM({
|
||||
async rewrites() {
|
||||
return [
|
||||
// This redirects requests recieved at / the root to the /api/ folder.
|
||||
@@ -13,4 +18,4 @@ module.exports = {
|
||||
},
|
||||
];
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
+2
-1
@@ -31,9 +31,10 @@
|
||||
"node-mocks-http": "^1.11.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"typescript": "^4.6.3",
|
||||
"next": "^12.1.0",
|
||||
"next-transpile-modules": "^9.0.0",
|
||||
"next-validations": "^0.1.11",
|
||||
"typescript": "^4.6.3",
|
||||
"zod": "^3.14.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { schemaQueryId, withValidQueryId } from "@lib/validations/queryIdTransformParseInt";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
type ResponseData = {
|
||||
message?: string;
|
||||
error?: unknown;
|
||||
};
|
||||
|
||||
export async function eventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
|
||||
const { query, method } = req;
|
||||
const safe = await schemaQueryId.safeParse(query);
|
||||
if (safe.success) {
|
||||
if (method === "DELETE") {
|
||||
// DELETE WILL DELETE THE EVENT TYPE
|
||||
prisma.eventType
|
||||
.delete({ where: { id: safe.data.id } })
|
||||
.then(() => {
|
||||
// We only remove the event type from the database if there's an existing resource.
|
||||
res.status(200).json({ message: `event-type with id: ${safe.data.id} deleted successfully` });
|
||||
})
|
||||
.catch((error) => {
|
||||
// This catches the error thrown by prisma.eventType.delete() if the resource is not found.
|
||||
res.status(400).json({ message: `Resource with id:${safe.data.id} was not found`, error: error });
|
||||
});
|
||||
} else {
|
||||
// Reject any other HTTP method than POST
|
||||
res.status(405).json({ message: "Only DELETE Method allowed in /event-types/[id]/delete endpoint" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default withValidQueryId(eventType);
|
||||
@@ -0,0 +1,37 @@
|
||||
import { PrismaClient, EventType } from "@prisma/client";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { schemaEventType, withValidEventType } from "@lib/validations/eventType";
|
||||
import { schemaQueryId, withValidQueryId } from "@lib/validations/queryIdTransformParseInt";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
type ResponseData = {
|
||||
data?: EventType;
|
||||
message?: string;
|
||||
error?: unknown;
|
||||
};
|
||||
|
||||
export async function editEventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
|
||||
const { query, body, method } = req;
|
||||
const safeQuery = await schemaQueryId.safeParse(query);
|
||||
const safeBody = await schemaEventType.safeParse(body);
|
||||
|
||||
if (method === "PATCH") {
|
||||
if (safeQuery.success && safeBody.success) {
|
||||
await prisma.eventType.update({
|
||||
where: { id: safeQuery.data.id },
|
||||
data: safeBody.data,
|
||||
}).then(event => {
|
||||
res.status(200).json({ data: event });
|
||||
}).catch(error => {
|
||||
res.status(404).json({ message: `Event type with ID ${safeQuery.data.id} not found and wasn't updated`, error })
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// Reject any other HTTP method than POST
|
||||
res.status(405).json({ message: "Only PATCH Method allowed for updating event-types" });
|
||||
}
|
||||
}
|
||||
|
||||
export default withValidQueryId(withValidEventType(editEventType));
|
||||
@@ -0,0 +1,31 @@
|
||||
import { PrismaClient, EventType } from "@prisma/client";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { schemaQueryId, withValidQueryId } from "@lib/validations/queryIdTransformParseInt";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
type ResponseData = {
|
||||
data?: EventType;
|
||||
message?: string;
|
||||
error?: unknown;
|
||||
};
|
||||
|
||||
export async function eventType(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
|
||||
const { query, method } = req;
|
||||
const safe = await schemaQueryId.safeParse(query);
|
||||
if (safe.success) {
|
||||
if (method === "GET") {
|
||||
const event = await prisma.eventType.findUnique({ where: { id: safe.data.id } });
|
||||
|
||||
if (event) res.status(200).json({ data: event });
|
||||
if (!event) res.status(404).json({ message: "Event type not found" });
|
||||
} else {
|
||||
// Reject any other HTTP method than POST
|
||||
res.status(405).json({ message: "Only GET Method allowed" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default withValidQueryId(eventType);
|
||||
@@ -0,0 +1,19 @@
|
||||
import { PrismaClient, ApiKey } from "@prisma/client";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
type ResponseData = {
|
||||
data?: ApiKey[];
|
||||
error?: unknown;
|
||||
};
|
||||
|
||||
export default async function apiKey(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
|
||||
try {
|
||||
const apiKeys = await prisma.apiKey.findMany({ where: { id: `${req.query.eventTypeId}` } });
|
||||
res.status(200).json({ data: { ...apiKeys } });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
// FIXME: Add zod for validation/error handling
|
||||
res.status(400).json({ error: error });
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { PrismaClient, ApiKey } from "@prisma/client";
|
||||
import type { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
import { schemaApiKey, withValidApiKey } from "@lib/validations/apiKey";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
type ResponseData = {
|
||||
data?: ApiKey;
|
||||
message?: string;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
async function createApiKey(req: NextApiRequest, res: NextApiResponse<ResponseData>) {
|
||||
const { body, method } = req;
|
||||
if (method === "POST") {
|
||||
const safe = schemaApiKey.safeParse(body);
|
||||
if (safe.success && safe.data) {
|
||||
await prisma.apiKey
|
||||
.create({ data: { ...safe.data, user: { connect: { id: 1 } }
|
||||
}})
|
||||
.then((event) => res.status(201).json({ data: event }))
|
||||
.catch((error) => res.status(400).json({ message: "Could not create event type", error: error }));
|
||||
}
|
||||
} else {
|
||||
// Reject any other HTTP method than POST
|
||||
res.status(405).json({ error: "Only POST Method allowed" });
|
||||
}
|
||||
}
|
||||
|
||||
export default withValidApiKey(createApiKey);
|
||||
@@ -21,7 +21,9 @@
|
||||
"jsx": "preserve",
|
||||
"paths": {
|
||||
"@api/*": ["pages/api/*"],
|
||||
"@prisma/client/*": ["@calcom/prisma/client/*"],
|
||||
"@lib/*": ["lib/*"]
|
||||
|
||||
},
|
||||
},
|
||||
"include": [
|
||||
|
||||
Reference in New Issue
Block a user