* refactor: simplify link-as-an-app template to config.json only - Remove api/, components/, index.ts, package.json from link-as-an-app template - Add externalLink field to AppMetaSchema for external URL configuration - Update API handler to dynamically create handlers for external link apps - External link apps no longer create credentials (just redirect to URL) - Update CLI to handle externalLinkUrl field for link-as-an-app template - CLI now skips package.json update for apps without package.json Co-Authored-By: peer@cal.com <peer@cal.com> * fix: simplify external link handler to bypass credential creation External link apps now directly return the redirect URL without going through the AppDeclarativeHandler type, avoiding type conflicts with the createCredential return type requirement. Co-Authored-By: peer@cal.com <peer@cal.com> * refactor: migrate 24 external link apps to simplified structure Migrated the following apps to use config.json with externalLink field instead of api/add.ts handlers: - amie, autocheckin, baa-for-hipaa, bolna, chatbase, clic, cron, deel - elevenlabs, fonio-ai, framer, granola, greetmate-ai, lindy, millis-ai - monobot, n8n, pipedream, raycast, retell-ai, synthflow, telli, vimcal - wordpress Each app now only contains: config.json, DESCRIPTION.md, static/ Removed: api/, components/, index.ts, package.json Co-Authored-By: peer@cal.com <peer@cal.com> * nit * Fix merge conflict issue * refactor: generate REDIRECT_APPS dynamically during app-store build - Add logic to build.ts to detect apps with externalLink field - Generate redirect-apps.generated.ts with list of redirect app slugs - Update redirectApps.ts to import from generated file - Revert [...]args].ts to original state (Flow 1 is preferred) Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * fix: cast REDIRECT_APPS to readonly string[] for includes check Co-Authored-By: hariom@cal.com <hariombalhara@gmail.com> * Fix error with React * Take exteral link URL as input * deleted bun.lockb --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
125 lines
3.4 KiB
TypeScript
125 lines
3.4 KiB
TypeScript
import { z } from "zod";
|
|
|
|
const eventLocationTypeSchema = z.object({
|
|
type: z.string(),
|
|
label: z.string(),
|
|
messageForOrganizer: z.string().optional(),
|
|
iconUrl: z.string().optional(),
|
|
variable: z.literal("locationLink").optional(),
|
|
defaultValueVariable: z.literal("link").optional(),
|
|
attendeeInputType: z.null().optional(),
|
|
attendeeInputPlaceholder: z.null().optional(),
|
|
linkType: z.enum(["static", "dynamic"]),
|
|
urlRegExp: z.string().optional(),
|
|
organizerInputPlaceholder: z.string().optional(),
|
|
organizerInputType: z.enum(["text", "phone"]).optional(),
|
|
default: z.boolean().optional(),
|
|
});
|
|
|
|
const appDataSchema = z
|
|
.object({
|
|
location: eventLocationTypeSchema.optional(),
|
|
tag: z
|
|
.object({
|
|
scripts: z
|
|
.array(
|
|
z
|
|
.object({
|
|
src: z.string().optional(),
|
|
content: z.string().optional(),
|
|
attrs: z.record(z.any()).optional(),
|
|
})
|
|
.passthrough()
|
|
)
|
|
.optional(),
|
|
})
|
|
.passthrough()
|
|
.optional(),
|
|
})
|
|
.passthrough()
|
|
.nullable()
|
|
.optional();
|
|
|
|
const paidAppDataSchema = z.object({
|
|
priceInUsd: z.number(),
|
|
priceId: z.string().optional(),
|
|
trial: z.number().optional(),
|
|
mode: z.enum(["subscription", "one_time"]).optional(),
|
|
});
|
|
|
|
export const AppMetaSchema = z
|
|
.object({
|
|
name: z.string(),
|
|
description: z.string(),
|
|
type: z.string(),
|
|
variant: z.enum([
|
|
"calendar",
|
|
"payment",
|
|
"conferencing",
|
|
"video",
|
|
"other",
|
|
"other_calendar",
|
|
"automation",
|
|
"crm",
|
|
"analytics",
|
|
"messaging",
|
|
]),
|
|
slug: z.string(),
|
|
categories: z.array(z.string()),
|
|
logo: z.string(),
|
|
publisher: z.string(),
|
|
url: z.string().optional(),
|
|
email: z.string(),
|
|
installed: z.boolean().optional(),
|
|
title: z.string().optional(),
|
|
category: z.string().optional(),
|
|
extendsFeature: z.enum(["EventType", "User"]).optional(),
|
|
docsUrl: z.string().optional(),
|
|
verified: z.boolean().optional(),
|
|
trending: z.boolean().optional(),
|
|
rating: z.number().optional(),
|
|
reviews: z.number().optional(),
|
|
isGlobal: z.boolean().optional(),
|
|
simplePath: z.string().optional(),
|
|
key: z.any().optional(),
|
|
feeType: z.enum(["monthly", "usage-based", "one-time", "free"]).optional(),
|
|
price: z.number().optional(),
|
|
commission: z.number().optional(),
|
|
licenseRequired: z.boolean().optional(),
|
|
teamsPlanRequired: z
|
|
.object({
|
|
upgradeUrl: z.string(),
|
|
})
|
|
.passthrough()
|
|
.optional(),
|
|
appData: appDataSchema,
|
|
paid: paidAppDataSchema.optional(),
|
|
dirName: z.string().optional(),
|
|
isTemplate: z.boolean().optional(),
|
|
__template: z.string().optional(),
|
|
dependencies: z.array(z.string()).optional(),
|
|
concurrentMeetings: z.boolean().optional(),
|
|
createdAt: z.string().optional(),
|
|
isOAuth: z.boolean().optional(),
|
|
isAuth: z.boolean().optional(),
|
|
delegationCredential: z
|
|
.object({
|
|
workspacePlatformSlug: z.string(),
|
|
})
|
|
.passthrough()
|
|
.optional(),
|
|
__createdUsingCli: z.boolean().optional(),
|
|
imageSrc: z.string().optional(),
|
|
label: z.string().optional(),
|
|
linkType: z.string().optional(),
|
|
externalLink: z
|
|
.object({
|
|
url: z.string(),
|
|
newTab: z.boolean().optional(),
|
|
})
|
|
.optional(),
|
|
})
|
|
.passthrough();
|
|
|
|
export type AppMetaType = z.infer<typeof AppMetaSchema>;
|