cal.pub0.org/packages/prisma/seed-app-store.ts

321 lines
10 KiB
TypeScript
Raw Normal View History

import { Prisma } from "@prisma/client";
import dotEnv from "dotenv";
import fs from "fs";
import path from "path";
import prisma from ".";
dotEnv.config({ path: "../../.env.appStore" });
export const seededForm = {
id: "948ae412-d995-4865-875a-48302588de03",
name: "Seeded Form - Pro",
};
async function seedAppData() {
const form = await prisma.app_RoutingForms_Form.findUnique({
where: {
id: seededForm.id,
},
});
if (form) {
console.log(`Skipping Routing Form - Form Seed, "Seeded Form - Pro" already exists`);
return;
}
const proUser = await prisma.user.findFirst({
where: {
username: "pro",
},
});
if (!proUser) {
console.log(`Skipping Routing Form - Seeding - Pro User not found`);
return;
}
await prisma.app_RoutingForms_Form.create({
data: {
id: seededForm.id,
routes: [
{
id: "8a898988-89ab-4cde-b012-31823f708642",
action: { type: "eventTypeRedirectUrl", value: "pro/30min" },
queryValue: {
id: "8a898988-89ab-4cde-b012-31823f708642",
type: "group",
children1: {
"8988bbb8-0123-4456-b89a-b1823f70c5ff": {
type: "rule",
properties: {
field: "c4296635-9f12-47b1-8153-c3a854649182",
value: ["event-routing"],
operator: "equal",
valueSrc: ["value"],
valueType: ["text"],
},
},
},
},
},
{
id: "aa8aaba9-cdef-4012-b456-71823f70f7ef",
action: { type: "customPageMessage", value: "Custom Page Result" },
queryValue: {
id: "aa8aaba9-cdef-4012-b456-71823f70f7ef",
type: "group",
children1: {
"b99b8a89-89ab-4cde-b012-31823f718ff5": {
type: "rule",
properties: {
field: "c4296635-9f12-47b1-8153-c3a854649182",
value: ["custom-page"],
operator: "equal",
valueSrc: ["value"],
valueType: ["text"],
},
},
},
},
},
{
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
action: { type: "externalRedirectUrl", value: "https://google.com" },
queryValue: {
id: "a8ba9aab-4567-489a-bcde-f1823f71b4ad",
type: "group",
children1: {
"998b9b9a-0123-4456-b89a-b1823f7232b9": {
type: "rule",
properties: {
field: "c4296635-9f12-47b1-8153-c3a854649182",
value: ["external-redirect"],
operator: "equal",
valueSrc: ["value"],
valueType: ["text"],
},
},
},
},
},
{
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
action: { type: "customPageMessage", value: "Multiselect chosen" },
queryValue: {
id: "aa8ba8b9-0123-4456-b89a-b182623406d8",
type: "group",
children1: {
"b98a8abb-cdef-4012-b456-718262343d27": {
type: "rule",
properties: {
field: "d4292635-9f12-17b1-9153-c3a854649182",
value: [["Option-2"]],
operator: "multiselect_equals",
valueSrc: ["value"],
valueType: ["multiselect"],
},
},
},
},
},
{
id: "898899aa-4567-489a-bcde-f1823f708646",
action: { type: "customPageMessage", value: "Fallback Message" },
isFallback: true,
queryValue: { id: "898899aa-4567-489a-bcde-f1823f708646", type: "group" },
},
],
fields: [
{ id: "c4296635-9f12-47b1-8153-c3a854649182", type: "text", label: "Test field", required: true },
{
id: "d4292635-9f12-17b1-9153-c3a854649182",
type: "multiselect",
label: "Multi Select",
identifier: "multi",
selectText: "Option-1\nOption-2",
required: false,
},
],
user: {
connect: {
username: "pro",
},
},
name: seededForm.name,
},
});
}
async function createApp(
/** The App identifier in the DB also used for public page in `/apps/[slug]` */
slug: Prisma.AppCreateInput["slug"],
/** The directory name for `/packages/app-store/[dirName]` */
dirName: Prisma.AppCreateInput["dirName"],
categories: Prisma.AppCreateInput["categories"],
/** This is used so credentials gets linked to the correct app */
2022-05-02 22:02:45 +00:00
type: Prisma.CredentialCreateInput["type"],
keys?: Prisma.AppCreateInput["keys"],
isTemplate?: boolean
) {
await prisma.app.upsert({
where: { slug },
Admin apps UI (#5494) * Abstract app category navigation * Send key schema to frontend Co-authored-by: Omar López <zomars@users.noreply.github.com> * Render keys for apps on admin * Add enabled col for apps * Save app keys to DB * Add checks for admin role * Abstract setup components * Add AdminAppsList to setup wizard * Migrate to v10 tRPC * Default hide keys * Display enabled apps * Merge branch 'main' into admin-apps-ui * Toggle calendars * WIP * Add params and include AppCategoryNavigation * Refactor getEnabledApps * Add warning for disabling apps * Fallback to cal video when a video app is disabled * WIP send disabled email * Send email to all users of event types with payment app * Disable Stripe when app is disabled * Disable apps in event types * Send email to users on disabled apps * Send email based on what app was disabled * WIP type fix * Disable navigation to apps list if already setup * UI import fixes * Waits for session data before redirecting * Updates admin seeded password To comply with admin password requirements * Update yarn.lock * Flex fixes * Adds admin middleware * Clean up * WIP * WIP * NTS * Add dirName to app metadata * Upsert app if not in db * Upsert app if not in db * Add dirName to app metadata * Add keys to app packages w/ keys * Merge with main * Toggle show keys & on enable * Fix empty keys * Fix lark calendar metadata * Fix some type errors * Fix Lark metadata & check for category when upserting * More type fixes * Fix types & add keys to google cal * WIP * WIP * WIP * More type fixes * Fix type errors * Fix type errors * More type fixes * More type fixes * More type fixes * Feedback * Fixes default value * Feedback * Migrate credential invalid col default value "false" * Upsert app on saving keys * Clean up * Validate app keys on frontend * Add nonempty to app keys schemas * Add web3 * Listlocale filter on categories / category * Grab app metadata via category or categories * Show empty screen if no apps are enabled * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Fix type checks * Replace .nonempty() w/ .min(1) * Fix type error * Address feedback * Added migration to keep current apps enabled * Update apps.tsx * Fix bug * Add keys schema to Plausible app * Add appKeysSchema to zod.ts template * Update AdminAppsList.tsx Co-authored-by: Omar López <zomars@users.noreply.github.com> Co-authored-by: Peer Richelsen <peeroke@gmail.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
2022-12-07 21:47:02 +00:00
create: { slug, dirName, categories, keys, enabled: true },
update: { dirName, categories, keys, enabled: true },
});
2022-05-02 22:02:45 +00:00
await prisma.credential.updateMany({
where: { type },
data: { appId: slug },
});
console.log(`📲 Upserted ${isTemplate ? "template" : "app"}: '${slug}'`);
}
export default async function main() {
// Calendar apps
2022-05-02 22:02:45 +00:00
await createApp("apple-calendar", "applecalendar", ["calendar"], "apple_calendar");
await createApp("caldav-calendar", "caldavcalendar", ["calendar"], "caldav_calendar");
try {
const { client_secret, client_id, redirect_uris } = JSON.parse(
process.env.GOOGLE_API_CREDENTIALS || ""
).web;
2022-05-02 22:02:45 +00:00
await createApp("google-calendar", "googlecalendar", ["calendar"], "google_calendar", {
client_id,
client_secret,
redirect_uris,
});
await createApp("google-meet", "googlevideo", ["video"], "google_video", {
client_id,
client_secret,
redirect_uris,
});
} catch (e) {
if (e instanceof Error) console.error("Error adding google credentials to DB:", e.message);
}
if (process.env.MS_GRAPH_CLIENT_ID && process.env.MS_GRAPH_CLIENT_SECRET) {
2022-05-02 22:02:45 +00:00
await createApp("office365-calendar", "office365calendar", ["calendar"], "office365_calendar", {
client_id: process.env.MS_GRAPH_CLIENT_ID,
client_secret: process.env.MS_GRAPH_CLIENT_SECRET,
});
await createApp("msteams", "office365video", ["video"], "office365_video", {
client_id: process.env.MS_GRAPH_CLIENT_ID,
client_secret: process.env.MS_GRAPH_CLIENT_SECRET,
});
}
if (
process.env.LARK_OPEN_APP_ID &&
process.env.LARK_OPEN_APP_SECRET &&
process.env.LARK_OPEN_VERIFICATION_TOKEN
) {
await createApp("lark-calendar", "larkcalendar", ["calendar"], "lark_calendar", {
app_id: process.env.LARK_OPEN_APP_ID,
app_secret: process.env.LARK_OPEN_APP_SECRET,
open_verification_token: process.env.LARK_OPEN_VERIFICATION_TOKEN,
});
}
// Video apps
if (process.env.DAILY_API_KEY) {
2022-05-05 22:34:26 +00:00
await createApp("daily-video", "dailyvideo", ["video"], "daily_video", {
api_key: process.env.DAILY_API_KEY,
scale_plan: process.env.DAILY_SCALE_PLAN,
});
}
if (process.env.TANDEM_CLIENT_ID && process.env.TANDEM_CLIENT_SECRET) {
2022-05-02 22:02:45 +00:00
await createApp("tandem", "tandemvideo", ["video"], "tandem_video", {
client_id: process.env.TANDEM_CLIENT_ID as string,
client_secret: process.env.TANDEM_CLIENT_SECRET as string,
base_url: (process.env.TANDEM_BASE_URL as string) || "https://tandem.chat",
});
}
if (process.env.ZOOM_CLIENT_ID && process.env.ZOOM_CLIENT_SECRET) {
2022-05-02 22:02:45 +00:00
await createApp("zoom", "zoomvideo", ["video"], "zoom_video", {
client_id: process.env.ZOOM_CLIENT_ID,
client_secret: process.env.ZOOM_CLIENT_SECRET,
});
}
2022-05-02 22:02:45 +00:00
await createApp("jitsi", "jitsivideo", ["video"], "jitsi_video");
// Other apps
if (process.env.HUBSPOT_CLIENT_ID && process.env.HUBSPOT_CLIENT_SECRET) {
await createApp("hubspot", "hubspot", ["other"], "hubspot_other_calendar", {
client_id: process.env.HUBSPOT_CLIENT_ID,
client_secret: process.env.HUBSPOT_CLIENT_SECRET,
});
}
if (process.env.SALESFORCE_CONSUMER_KEY && process.env.SALESFORCE_CONSUMER_SECRET) {
await createApp("salesforce", "salesforce", ["other"], "salesforce_other_calendar", {
consumer_key: process.env.SALESFORCE_CONSUMER_KEY,
consumer_secret: process.env.SALESFORCE_CONSUMER_SECRET,
});
}
2022-05-02 22:02:45 +00:00
await createApp("wipe-my-cal", "wipemycalother", ["other"], "wipemycal_other");
if (process.env.GIPHY_API_KEY) {
2022-05-02 22:02:45 +00:00
await createApp("giphy", "giphy", ["other"], "giphy_other", {
api_key: process.env.GIPHY_API_KEY,
});
}
if (process.env.VITAL_API_KEY && process.env.VITAL_WEBHOOK_SECRET) {
await createApp("vital-automation", "vital", ["other"], "vital_other", {
mode: process.env.VITAL_DEVELOPMENT_MODE || "sandbox",
region: process.env.VITAL_REGION || "us",
api_key: process.env.VITAL_API_KEY,
webhook_secret: process.env.VITAL_WEBHOOK_SECRET,
});
}
if (process.env.ZAPIER_INVITE_LINK) {
await createApp("zapier", "zapier", ["automation"], "zapier_automation", {
invite_link: process.env.ZAPIER_INVITE_LINK,
});
}
Routing Forms (#2785) * Add Routing logic to Query builder * Make a working redirect * Make it an app * Move pages and components to App * Integrate all pages in the app * Integrate prisma everywhere * Fix Routing Link * Add routing preview * Fixes * Get deplouyed on preview with ts disabled * Fix case * add reordering for routes * Move away from react DnD * Add sidebar * Add sidebar support and select support * Various fixes and improvements * Ignore eslint temporarly * Route might be falsy * Make CalNumber support required validation * Loader improvements * Add SSR support * Fix few typescript issues * More typesafety, download csv, bug fiees * Add seo friendly link * Avoid seding credebtials to frontend * Self review fixes * Improvements in app-store * Cahnge Form layout * Add scaffolding for app tests * Add playwright tests and add user check in serving data * Add CI tests * Add route builder test * Styling * Apply suggestions from code review Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com> * Changes as per loom feedback * Increase time for tests * Fix PR suggestions * Import CSS only in the module * Fix codacy issues * Move the codebbase to ee and add PRO and license check * Add Badge * Avoid lodash import * Fix TS error * Fix lint errors * Fix bug to merge conflicts resolution - me query shouldnt cause the Shell to go in loading state Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> Co-authored-by: zomars <zomars@me.com> Co-authored-by: Agusti Fernandez Pardo <6601142+agustif@users.noreply.github.com>
2022-07-14 12:40:53 +00:00
// Web3 apps
2022-05-02 22:02:45 +00:00
await createApp("huddle01", "huddle01video", ["web3", "video"], "huddle01_video");
// Payment apps
if (
process.env.STRIPE_CLIENT_ID &&
process.env.STRIPE_PRIVATE_KEY &&
process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY &&
process.env.STRIPE_WEBHOOK_SECRET &&
process.env.PAYMENT_FEE_FIXED &&
process.env.PAYMENT_FEE_PERCENTAGE
) {
2022-05-02 22:02:45 +00:00
await createApp("stripe", "stripepayment", ["payment"], "stripe_payment", {
client_id: process.env.STRIPE_CLIENT_ID,
client_secret: process.env.STRIPE_PRIVATE_KEY,
payment_fee_fixed: Number(process.env.PAYMENT_FEE_FIXED),
payment_fee_percentage: Number(process.env.PAYMENT_FEE_PERCENTAGE),
public_key: process.env.NEXT_PUBLIC_STRIPE_PUBLIC_KEY,
webhook_secret: process.env.STRIPE_WEBHOOK_SECRET,
});
}
const generatedApps = JSON.parse(
fs.readFileSync(path.join(__dirname, "seed-app-store.config.json"), "utf8")
);
for (let i = 0; i < generatedApps.length; i++) {
const generatedApp = generatedApps[i];
if (generatedApp.isTemplate && process.argv[2] !== "seed-templates") {
continue;
}
await createApp(
generatedApp.slug,
generatedApp.dirName,
generatedApp.categories,
generatedApp.type,
undefined,
generatedApp.isTemplate
);
}
await seedAppData();
}
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});