Skip to content

Commit

Permalink
Adds deployment settings to DB (#6706)
Browse files Browse the repository at this point in the history
* WIP

* Adds DeploymentTheme

* Add missing migrations

* Adds client extensions for deployment

* Cleanup
  • Loading branch information
zomars committed Jan 26, 2023
1 parent c02c149 commit 606e538
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 6 deletions.
62 changes: 62 additions & 0 deletions packages/prisma/extensions/index.ts
@@ -0,0 +1,62 @@
import { Prisma, PrismaClient } from "@prisma/client";

export function addPrismaExtensions(prisma: PrismaClient) {
const xprisma = prisma.$extends({
model: {
/**
* We extend deployment model since it's supposed to be a single record table.
* New settings should be added as Columns as needed.
* */
deployment: {
/**
* This is the preferred method for accessing deployment settings,
* it can be called without any arguments:
* @example
* ```
* const deployment = await prisma.deployment.get();
* ```
*/
async get(args?: Omit<Prisma.DeploymentFindUniqueArgs, "where">) {
return prisma.deployment.findUnique({ where: { id: 1 }, ...args });
},
async findFirst(args: Omit<Prisma.DeploymentFindFirstArgs, "where">) {
return prisma.deployment.findFirst({ where: { id: 1 }, ...args });
},
async findFirstOrThrow(args: Omit<Prisma.DeploymentFindFirstOrThrowArgs, "where">) {
return prisma.deployment.findFirstOrThrow({ where: { id: 1 }, ...args });
},
async findUnique(args: Omit<Prisma.DeploymentFindUniqueArgs, "where">) {
return prisma.deployment.findUnique({ where: { id: 1 }, ...args });
},
async findUniqueOrThrow(args: Omit<Prisma.DeploymentFindUniqueOrThrowArgs, "where">) {
return prisma.deployment.findUniqueOrThrow({ where: { id: 1 }, ...args });
},
async upsert(args: Omit<Prisma.DeploymentUpsertArgs, "where">) {
return prisma.deployment.upsert({ where: { id: 1 }, ...args });
},
async update(args: Omit<Prisma.DeploymentUpdateArgs, "where">) {
return prisma.deployment.update({ where: { id: 1 }, ...args });
},
async findMany() {
throw new Error("Use prisma.deployment.get method");
},
async updateMany() {
throw new Error("Use prisma.deployment.update method");
},
async create() {
throw new Error("Use prisma.deployment.upsert method");
},
async createMany() {
throw new Error("Use prisma.deployment.upsert method");
},
async delete() {
throw new Error("Deployment shouldn't be deleted");
},
async deleteMany() {
throw new Error("Deployment shouldn't be deleted");
},
},
},
});
return xprisma;
}
17 changes: 12 additions & 5 deletions packages/prisma/index.ts
@@ -1,27 +1,34 @@
import { Prisma, PrismaClient } from "@prisma/client";

import { addPrismaExtensions } from "./extensions";
import { bookingReferenceMiddleware, eventTypeDescriptionParseAndSanitizeMiddleware } from "./middleware";

declare global {
// eslint-disable-next-line no-var
var prisma: PrismaClient | undefined;
var prisma: ReturnType<typeof createPrismaClient> | undefined;
}

const prismaOptions: Prisma.PrismaClientOptions = {};

if (!!process.env.NEXT_PUBLIC_DEBUG) prismaOptions.log = ["query", "error", "warn"];

export const prisma = globalThis.prisma || new PrismaClient(prismaOptions);
function createPrismaClient(options: Prisma.PrismaClientOptions) {
const newPrisma = new PrismaClient(options);
bookingReferenceMiddleware(newPrisma);
eventTypeDescriptionParseAndSanitizeMiddleware(newPrisma);
const xprisma = addPrismaExtensions(newPrisma);
return xprisma;
}

export const prisma = globalThis.prisma || createPrismaClient(prismaOptions);

export const customPrisma = (options: Prisma.PrismaClientOptions) =>
new PrismaClient({ ...prismaOptions, ...options });
createPrismaClient({ ...prismaOptions, ...options });

if (process.env.NODE_ENV !== "production") {
globalThis.prisma = prisma;
}
// If any changed on middleware server restart is required
bookingReferenceMiddleware(prisma);
eventTypeDescriptionParseAndSanitizeMiddleware(prisma);

export default prisma;

Expand Down
@@ -0,0 +1,10 @@
-- CreateTable
CREATE TABLE "Deployment" (
"id" INTEGER NOT NULL DEFAULT 1,
"logo" TEXT,
"theme" JSONB,
"licenseKey" TEXT,
"agreedLicenseAt" TIMESTAMP(3),

CONSTRAINT "Deployment_pkey" PRIMARY KEY ("id")
);
12 changes: 11 additions & 1 deletion packages/prisma/schema.prisma
Expand Up @@ -8,7 +8,7 @@ datasource db {

generator client {
provider = "prisma-client-js"
previewFeatures = ["interactiveTransactions"]
previewFeatures = ["clientExtensions"]
}

generator zod {
Expand Down Expand Up @@ -615,6 +615,16 @@ model WorkflowsOnEventTypes {
eventTypeId Int
}

model Deployment {
/// This is a single row table, so we use a fixed id
id Int @id @default(1)
logo String?
/// @zod.custom(imports.DeploymentTheme)
theme Json?
licenseKey String?
agreedLicenseAt DateTime?
}

enum TimeUnit {
DAY @map("day")
HOUR @map("hour")
Expand Down
18 changes: 18 additions & 0 deletions packages/prisma/zod-utils.ts
Expand Up @@ -293,6 +293,24 @@ export const RoutingFormSettings = z
})
.nullable();

export const DeploymentTheme = z
.object({
brand: z.string().default("#292929"),
textBrand: z.string().default("#ffffff"),
darkBrand: z.string().default("#fafafa"),
textDarkBrand: z.string().default("#292929"),
bookingHighlight: z.string().default("#10B981"),
bookingLightest: z.string().default("#E1E1E1"),
bookingLighter: z.string().default("#ACACAC"),
bookingLight: z.string().default("#888888"),
bookingMedian: z.string().default("#494949"),
bookingDark: z.string().default("#313131"),
bookingDarker: z.string().default("#292929"),
fontName: z.string().default("Cal Sans"),
fontSrc: z.string().default("https://cal.com/cal.ttf"),
})
.optional();

export type ZodDenullish<T extends ZodTypeAny> = T extends ZodNullable<infer U> | ZodOptional<infer U>
? ZodDenullish<U>
: T;
Expand Down

0 comments on commit 606e538

Please sign in to comment.