Files
calendar/packages/prisma/seed.ts
T
Omar López 2e6bc5e5b4 Fixes/app store keys in db (#2651)
* Adds available apps

* Adds App Model

* WIP

* Updates seeder script

* Seeder fixes

* lowercase categories

* Upgrades prisma

* WIP

* WIP

* Hopefully fixes circular deps

* Type fixes

* Fixes seeder

* Adds migration to connect Credentials to Apps

* Updates app store callbacks

* Updates google credentials

* Uses dirName from DB

* Type fixes

* Update reschedule.ts

* Seeder fixes

* Fixes categories listing

* Update index.ts

* Update schema.prisma

* Updates dependencies

* Renames giphy app

* Uses dynamic imports for app metadata

* Fixes credentials error

* Uses dynamic import for api handlers

* Dynamic import fixes

* Allows for simple folder names in app store

* Squashes app migrations

* seeder fixes

* Fixes dyamic imports

* Update apiHandlers.tsx
2022-05-02 16:21:11 -06:00

456 lines
10 KiB
TypeScript

import { MembershipRole, Prisma, UserPlan } from "@prisma/client";
import dayjs from "dayjs";
import { uuid } from "short-uuid";
import { hashPassword } from "@calcom/lib/auth";
import { DEFAULT_SCHEDULE, getAvailabilityFromSchedule } from "@calcom/lib/availability";
import prisma from ".";
import "./seed-app-store";
require("dotenv").config({ path: "../../.env" });
async function createUserAndEventType(opts: {
user: {
email: string;
password: string;
username: string;
plan: UserPlan;
name: string;
completedOnboarding?: boolean;
timeZone?: string;
};
eventTypes: Array<
Prisma.EventTypeCreateInput & {
_bookings?: Prisma.BookingCreateInput[];
}
>;
}) {
const userData = {
...opts.user,
password: await hashPassword(opts.user.password),
emailVerified: new Date(),
completedOnboarding: opts.user.completedOnboarding ?? true,
locale: "en",
schedules:
opts.user.completedOnboarding ?? true
? {
create: {
name: "Working Hours",
availability: {
createMany: {
data: getAvailabilityFromSchedule(DEFAULT_SCHEDULE),
},
},
},
}
: undefined,
};
const user = await prisma.user.upsert({
where: { email: opts.user.email },
update: userData,
create: userData,
});
console.log(
`👤 Upserted '${opts.user.username}' with email "${opts.user.email}" & password "${opts.user.password}". Booking page 👉 ${process.env.NEXT_PUBLIC_WEBAPP_URL}/${opts.user.username}`
);
for (const eventTypeInput of opts.eventTypes) {
const { _bookings: bookingInputs = [], ...eventTypeData } = eventTypeInput;
eventTypeData.userId = user.id;
eventTypeData.users = { connect: { id: user.id } };
const eventType = await prisma.eventType.findFirst({
where: {
slug: eventTypeData.slug,
users: {
some: {
id: eventTypeData.userId,
},
},
},
select: {
id: true,
},
});
if (eventType) {
console.log(
`\t📆 Event type ${eventTypeData.slug} already seems seeded - ${process.env.NEXT_PUBLIC_WEBAPP_URL}/${user.username}/${eventTypeData.slug}`
);
continue;
}
const { id } = await prisma.eventType.create({
data: eventTypeData,
});
console.log(
`\t📆 Event type ${eventTypeData.slug}, length ${eventTypeData.length}min - ${process.env.NEXT_PUBLIC_WEBAPP_URL}/${user.username}/${eventTypeData.slug}`
);
for (const bookingInput of bookingInputs) {
await prisma.booking.create({
data: {
...bookingInput,
user: {
connect: {
email: opts.user.email,
},
},
attendees: {
create: {
email: opts.user.email,
name: opts.user.name,
timeZone: "Europe/London",
},
},
eventType: {
connect: {
id,
},
},
confirmed: bookingInput.confirmed,
},
});
console.log(
`\t\t☎️ Created booking ${bookingInput.title} at ${new Date(
bookingInput.startTime
).toLocaleDateString()}`
);
}
}
return user;
}
async function createTeamAndAddUsers(
teamInput: Prisma.TeamCreateInput,
users: { id: number; username: string; role?: MembershipRole }[]
) {
const createTeam = async (team: Prisma.TeamCreateInput) => {
try {
return await prisma.team.create({
data: {
...team,
},
});
} catch (_err) {
if (_err instanceof Error && _err.message.indexOf("Unique constraint failed on the fields") !== -1) {
console.log(`Team '${team.name}' already exists, skipping.`);
return;
}
throw _err;
}
};
const team = await createTeam(teamInput);
if (!team) {
return;
}
console.log(
`🏢 Created team '${teamInput.name}' - ${process.env.NEXT_PUBLIC_WEBAPP_URL}/team/${team.slug}`
);
for (const user of users) {
const { role = MembershipRole.OWNER, id, username } = user;
await prisma.membership.create({
data: {
teamId: team.id,
userId: id,
role: role,
accepted: true,
},
});
console.log(`\t👤 Added '${teamInput.name}' membership for '${username}' with role '${role}'`);
}
}
async function main() {
await createUserAndEventType({
user: {
email: "delete-me@example.com",
password: "delete-me",
username: "delete-me",
name: "delete-me",
plan: "FREE",
},
eventTypes: [],
});
await createUserAndEventType({
user: {
email: "onboarding@example.com",
password: "onboarding",
username: "onboarding",
name: "onboarding",
plan: "TRIAL",
completedOnboarding: false,
},
eventTypes: [],
});
await createUserAndEventType({
user: {
email: "free-first-hidden@example.com",
password: "free-first-hidden",
username: "free-first-hidden",
name: "Free First Hidden Example",
plan: "FREE",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
hidden: true,
},
{
title: "60min",
slug: "60min",
length: 30,
},
],
});
await createUserAndEventType({
user: {
email: "pro@example.com",
name: "Pro Example",
password: "pro",
username: "pro",
plan: "PRO",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
_bookings: [
{
uid: uuid(),
title: "30min",
startTime: dayjs().add(1, "day").toDate(),
endTime: dayjs().add(1, "day").add(30, "minutes").toDate(),
},
{
uid: uuid(),
title: "30min",
startTime: dayjs().add(2, "day").toDate(),
endTime: dayjs().add(2, "day").add(30, "minutes").toDate(),
confirmed: false,
},
],
},
{
title: "60min",
slug: "60min",
length: 60,
},
{
title: "paid",
slug: "paid",
length: 60,
price: 100,
},
{
title: "In person meeting",
slug: "in-person",
length: 60,
locations: [{ type: "inPerson", address: "London" }],
},
{
title: "Zoom Event",
slug: "zoom",
length: 60,
locations: [{ type: "integrations:zoom" }],
},
{
title: "Daily Event",
slug: "daily",
length: 60,
locations: [{ type: "integrations:daily" }],
},
{
title: "Google Meet",
slug: "google-meet",
length: 60,
locations: [{ type: "integrations:google:meet" }],
},
],
});
await createUserAndEventType({
user: {
email: "trial@example.com",
password: "trial",
username: "trial",
name: "Trial Example",
plan: "TRIAL",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
},
{
title: "60min",
slug: "60min",
length: 60,
},
],
});
await createUserAndEventType({
user: {
email: "free@example.com",
password: "free",
username: "free",
name: "Free Example",
plan: "FREE",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
},
{
title: "60min",
slug: "60min",
length: 30,
},
],
});
await createUserAndEventType({
user: {
email: "usa@example.com",
password: "usa",
username: "usa",
name: "USA Timezone Example",
plan: "FREE",
timeZone: "America/Phoenix",
},
eventTypes: [
{
title: "30min",
slug: "30min",
length: 30,
},
],
});
const freeUserTeam = await createUserAndEventType({
user: {
email: "teamfree@example.com",
password: "teamfree",
username: "teamfree",
name: "Team Free Example",
plan: "FREE",
},
eventTypes: [],
});
const proUserTeam = await createUserAndEventType({
user: {
email: "teampro@example.com",
password: "teampro",
username: "teampro",
name: "Team Pro Example",
plan: "PRO",
},
eventTypes: [],
});
const pro2UserTeam = await createUserAndEventType({
user: {
email: "teampro2@example.com",
password: "teampro2",
username: "teampro2",
name: "Team Pro Example 2",
plan: "PRO",
},
eventTypes: [],
});
const pro3UserTeam = await createUserAndEventType({
user: {
email: "teampro3@example.com",
password: "teampro3",
username: "teampro3",
name: "Team Pro Example 3",
plan: "PRO",
},
eventTypes: [],
});
const pro4UserTeam = await createUserAndEventType({
user: {
email: "teampro4@example.com",
password: "teampro4",
username: "teampro4",
name: "Team Pro Example 4",
plan: "PRO",
},
eventTypes: [],
});
await createTeamAndAddUsers(
{
name: "Seeded Team",
slug: "seeded-team",
eventTypes: {
createMany: {
data: [
{
title: "Collective Seeded Team Event",
slug: "collective-seeded-team-event",
length: 15,
schedulingType: "COLLECTIVE",
},
{
title: "Round Robin Seeded Team Event",
slug: "round-robin-seeded-team-event",
length: 15,
schedulingType: "ROUND_ROBIN",
},
],
},
},
},
[
{
id: proUserTeam.id,
username: proUserTeam.name || "Unknown",
},
{
id: freeUserTeam.id,
username: freeUserTeam.name || "Unknown",
},
{
id: pro2UserTeam.id,
username: pro2UserTeam.name || "Unknown",
},
{
id: pro3UserTeam.id,
username: pro3UserTeam.name || "Unknown",
},
{
id: pro4UserTeam.id,
username: pro4UserTeam.name || "Unknown",
},
]
);
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});