Initial Commit

This commit is contained in:
Dries Augustyns
2024-07-23 13:49:48 +02:00
commit 91a8840c3c
191 changed files with 36022 additions and 0 deletions
+264
View File
@@ -0,0 +1,264 @@
import {z} from 'zod';
import {TemplateStyle, TemplateType} from '@prisma/client';
const email = z
.string({invalid_type_error: 'Email needs to be a string', required_error: 'Email is required'})
.email({message: 'Invalid email address'})
.transform(e => e.toLowerCase());
const password = z.string().min(6, 'Password needs to be at least 6 characters long');
const id = z
.string({invalid_type_error: 'ID needs to be a string', required_error: 'ID is required'})
.uuid({message: 'Id needs to be a valid UUID'});
export const UtilitySchemas = {
id: z.object({
id,
}),
email: z.object({
email,
}),
pagination: z.object({
page: z
.number({
invalid_type_error: 'Page needs to be a number',
required_error: 'Page is required',
})
.min(1, 'Page needs to be at least 1')
.default(1)
.or(
z.string().transform(s => {
return Number(s);
}),
),
}),
};
export const UserSchemas = {
credentials: z.object({
email: email,
password: password,
}),
};
const zodSchema = z.record(
z.union(
[
z
.string({
invalid_type_error:
'Metadata can only be a string, array of strings or a non-persistent object (https://docs.useplunk.com/working-with-contacts/metadata#non-persistent-metadata)',
})
.transform(s => {
return {persistent: true, value: s};
}),
z
.array(
z.string({
invalid_type_error:
'Metadata can only be a string, array of strings or a non-persistent object (https://docs.useplunk.com/working-with-contacts/metadata#non-persistent-metadata)',
}),
)
.transform(s => {
return {persistent: true, value: s};
}),
z.object(
{
persistent: z.boolean({invalid_type_error: 'Persistent should be a boolean'}).optional().default(true),
value: z.union([z.string(), z.array(z.string())], {
invalid_type_error:
'Metadata can only be a string, array of strings or a non-persistent object (https://docs.useplunk.com/working-with-contacts/metadata#non-persistent-metadata)',
}),
},
{
invalid_type_error:
'Metadata can only be a string, array of strings or a non-persistent object (https://docs.useplunk.com/working-with-contacts/metadata#non-persistent-metadata)',
},
),
],
{
invalid_type_error:
'Metadata can only be a string, array of strings or a non-persistent object (https://docs.useplunk.com/working-with-contacts/metadata#non-persistent-metadata)',
},
),
{invalid_type_error: 'Metadata should be an object (https://docs.useplunk.com/working-with-contacts/metadata)'},
);
export const EventSchemas = {
post: z.object({
email,
subscribed: z
.boolean({
invalid_type_error:
'Subscribed should be a boolean. Read more: https://docs.useplunk.com/api-reference/actions/track',
})
.nullish(),
event: z
.string({
required_error: 'Event is required. Read more: https://docs.useplunk.com/api-reference/actions/track',
invalid_type_error:
'Event can only be a string. Read more: https://docs.useplunk.com/api-reference/actions/track',
})
.transform(n => n.toLowerCase())
.transform(n => n.replace(/ /g, '-')),
data: zodSchema.nullish(),
}),
send: z.object({
subscribed: z.boolean({invalid_type_error: 'Subscribed should be a boolean'}).nullish(),
from: email.nullish(),
name: z.string().nullish(),
reply: email.nullish(),
to: z
.array(email)
.max(5, 'You can only send transactional emails to 5 people at a time')
.or(email.transform(e => [e])),
subject: z.string({
required_error: 'Subject is required. Read more: https://docs.useplunk.com/api-reference/transactional/send',
}),
body: z.string({
required_error: 'Body is required. Read more: https://docs.useplunk.com/api-reference/transactional/send',
}),
headers: z.record(z.string()).nullish(),
}),
};
export const CampaignSchemas = {
send: z.object({
id,
live: z.boolean().default(false),
delay: z.number().int('Delay needs to be a whole number').nonnegative('Delay needs to be a positive number'),
}),
create: z.object({
subject: z
.string()
.min(1, 'Subject needs to be at least 1 character long')
.max(70, 'Subject needs to be less than 70 characters long'),
body: z.string().min(1, 'Body needs to be at least 1 character long'),
recipients: z.array(z.string()),
style: z.nativeEnum(TemplateStyle).default('PLUNK'),
}),
update: z.object({
id,
subject: z
.string()
.min(1, 'Subject needs to be at least 1 character long')
.max(70, 'Subject needs to be less than 70 characters long'),
body: z.string().min(1, 'Body needs to be at least 1 character long'),
recipients: z.array(z.string()),
style: z.nativeEnum(TemplateStyle).default('PLUNK'),
}),
};
export const ActionSchemas = {
create: z.object({
name: z.string().min(1, 'Name needs to be at least 1 character long'),
runOnce: z.boolean().default(false),
delay: z.number().int('Delay needs to be a whole number').nonnegative('Delay needs to be a positive number'),
template: id,
events: z.array(id).min(1, 'Select at least one event'),
notevents: z.array(id).optional().default([]),
}),
update: z.object({
id,
name: z.string().min(1, 'Name needs to be at least 1 character long'),
runOnce: z.boolean().default(false),
delay: z.number().int('Delay needs to be a whole number').nonnegative('Delay needs to be a positive number'),
template: id,
events: z.array(id).default([]),
notevents: z.array(id).optional().default([]),
}),
};
export const ContactSchemas = {
create: z.object({
email,
data: z
.object({})
.catchall(z.union([z.string(), z.array(z.string())]))
.or(z.string().transform(s => (s === '' ? null : JSON.parse(s))))
.nullish(),
subscribed: z.boolean(),
}),
update: z.object({
id,
email,
data: z
.object({})
.catchall(z.union([z.string(), z.array(z.string())]))
.or(z.string().transform(s => (s === '' ? null : JSON.parse(s))))
.nullish(),
subscribed: z.boolean(),
}),
};
export const TemplateSchemas = {
create: z.object({
subject: z.string().min(1, "Subject can't be empty").max(70, 'Subject needs to be less than 70 characters long'),
body: z.string().min(1, "Body can't be empty"),
type: z.nativeEnum(TemplateType).default('MARKETING'),
style: z.nativeEnum(TemplateStyle).default('PLUNK'),
}),
update: z.object({
id,
subject: z.string().min(1, "Subject can't be empty").max(70, 'Subject needs to be less than 70 characters long'),
body: z.string().min(1, "Body can't be empty"),
type: z.nativeEnum(TemplateType).default('MARKETING'),
style: z.nativeEnum(TemplateStyle).default('PLUNK'),
}),
};
export const MembershipSchemas = {
invite: z.object({
id,
email,
role: z.enum(['MEMBER', 'ADMIN']).default('MEMBER'),
}),
kick: z.object({
id,
email,
}),
};
export const ProjectSchemas = {
secret: z.object({
secret: z.string(),
}),
create: z.object({
name: z.string().min(1, "Name can't be empty"),
url: z
.string()
.regex(/^(?:(?:https?):\/\/)?(?:[\w-]+\.)+[a-z]{2,}(?:\/[^\s]*)?$/)
.transform(u => (u.startsWith('http') ? u : `https://${u}`)),
}),
update: z.object({
id: id,
name: z.string().min(1, "Name can't be empty"),
url: z
.string()
.regex(/^(?:(?:https?):\/\/)?(?:[\w-]+\.)+[a-z]{2,}(?:\/[^\s]*)?$/)
.transform(u => (u.startsWith('http') ? u : `https://${u}`)),
}),
analytics: z.object({
method: z.enum(['week', 'month', 'year']).default('week'),
}),
};
export const IdentitySchemas = {
create: z.object({
id: id,
email: email.refine(
e => {
return !['gmail.com', 'outlook.com', 'hotmail.com', 'yahoo.com', 'useplunk.com', 'useplunk.dev'].includes(
e.split('@')[1],
);
},
{message: 'Please use your own domain'},
),
}),
update: z.object({
id: id,
from: z.string().min(1, "Name can't be empty"),
}),
};