Tweaks to parameters, allows for listing providers

This commit is contained in:
Chris Anderson 2023-01-26 22:58:30 -06:00
parent eefbe15747
commit c366722efb
8 changed files with 112 additions and 55 deletions

View file

@ -99,7 +99,7 @@ const campaignUpdateParams: JSONSchemaType<Partial<CampaignParams>> = {
router.patch('/:campaignId', async ctx => {
const payload = validate(campaignUpdateParams, ctx.request.body)
ctx.body = await updateCampaign(ctx.state.campaign!.id, payload)
ctx.body = await updateCampaign(ctx.state.campaign!.id, ctx.state.project.id, payload)
})
router.post('/:campaignId/send', async ctx => {

View file

@ -57,8 +57,9 @@ export const createCampaign = async (projectId: number, params: CampaignParams):
})
}
export const updateCampaign = async (id: number, params: Partial<CampaignParams>): Promise<Campaign | undefined> => {
return await Campaign.updateAndFetch(id, params)
export const updateCampaign = async (id: number, projectId: number, params: Partial<CampaignParams>): Promise<Campaign | undefined> => {
await Campaign.update(qb => qb.where('id', id), params)
return getCampaign(id, projectId)
}
export const getCampaignUsers = async (id: number, params: SearchParams, projectId: number) => {

View file

@ -1,10 +1,12 @@
import Router from '@koa/router'
import { ProjectState } from '../auth/AuthMiddleware'
import { loadEmailControllers } from './email'
import { allProviders } from './ProviderService'
import { loadPushControllers } from './push'
import { loadTextControllers } from './text'
import { loadWebhookControllers } from './webhook'
const router = new Router({
const router = new Router<ProjectState>({
prefix: '/providers',
})
@ -13,4 +15,8 @@ loadEmailControllers(router)
loadWebhookControllers(router)
loadPushControllers(router)
router.get('/', async ctx => {
ctx.body = await allProviders(ctx.state.project.id)
})
export default router

View file

@ -4,6 +4,10 @@ import { JSONSchemaType, validate } from '../core/validate'
import Provider, { ExternalProviderParams, ProviderGroup } from './Provider'
import { createProvider, getProvider, updateProvider } from './ProviderRepository'
export const allProviders = async (projectId: number) => {
return await Provider.all(qb => qb.where('project_id', projectId))
}
export const createController = <T extends ExternalProviderParams>(group: ProviderGroup, name: string, schema: JSONSchemaType<T>): Router => {
const router = new Router<
ProjectState & { provider?: Provider }

View file

@ -6,7 +6,6 @@ import Model, { ModelParams } from '../core/Model'
export default class Template extends Model {
project_id!: number
campaign_id!: number
name!: string
type!: ChannelType
data!: Record<string, any>
locale!: string
@ -29,6 +28,7 @@ export default class Template extends Model {
}
export type TemplateParams = Omit<Template, ModelParams | 'map' | 'screenshotUrl'>
export type TemplateUpdateParams = Pick<Template, 'type' | 'data'>
export type TemplateType = EmailTemplate | TextTemplate | PushTemplate | WebhookTemplate
export interface CompiledEmail {

View file

@ -3,7 +3,7 @@ import { ProjectState } from '../auth/AuthMiddleware'
import { JSONSchemaType, validate } from '../core/validate'
import { searchParamsSchema } from '../core/searchParams'
import { extractQueryParams } from '../utilities'
import Template, { TemplateParams } from './Template'
import Template, { TemplateParams, TemplateUpdateParams } from './Template'
import { createTemplate, getTemplate, pagedTemplates, updateTemplate } from './TemplateService'
import { Variables } from '.'
import { User } from '../users/User'
@ -20,8 +20,54 @@ router.get('/', async ctx => {
ctx.body = await pagedTemplates(params, ctx.state.project.id)
})
const templateParams: JSONSchemaType<TemplateParams> = {
$id: 'templateParams',
const templateDataEmailParams = {
type: 'object',
required: ['from', 'subject', 'text', 'html'],
properties: {
from: { type: 'string' },
cc: {
type: 'string',
nullable: true,
},
bcc: {
type: 'string',
nullable: true,
},
reply_to: {
type: 'string',
nullable: true,
},
subject: { type: 'string' },
text: { type: 'string' },
html: { type: 'string' },
},
}
const templateDataTextParams = {
type: 'object',
required: ['text'],
properties: {
text: { type: 'string' },
},
}
const templateDataPushParams = {
type: 'object',
required: ['title', 'topic', 'body'],
properties: {
title: { type: 'string' },
topic: { type: 'string' },
body: { type: 'string' },
custom: {
type: 'object',
nullable: true,
additionalProperties: true,
},
},
}
const templateCreateParams: JSONSchemaType<TemplateParams> = {
$id: 'templateCreateParams',
oneOf: [{
type: 'object',
required: ['type', 'campaign_id', 'locale', 'data'],
@ -36,28 +82,7 @@ const templateParams: JSONSchemaType<TemplateParams> = {
locale: {
type: 'string',
},
data: {
type: 'object',
required: ['from', 'subject', 'text', 'html'],
properties: {
from: { type: 'string' },
cc: {
type: 'string',
nullable: true,
},
bcc: {
type: 'string',
nullable: true,
},
reply_to: {
type: 'string',
nullable: true,
},
subject: { type: 'string' },
text: { type: 'string' },
html: { type: 'string' },
},
} as any,
data: templateDataEmailParams as any,
},
additionalProperties: false,
},
@ -75,13 +100,7 @@ const templateParams: JSONSchemaType<TemplateParams> = {
locale: {
type: 'string',
},
data: {
type: 'object',
required: ['text'],
properties: {
text: { type: 'string' },
},
} as any,
data: templateDataTextParams as any,
},
additionalProperties: false,
},
@ -99,26 +118,13 @@ const templateParams: JSONSchemaType<TemplateParams> = {
locale: {
type: 'string',
},
data: {
type: 'object',
required: ['title', 'topic', 'body'],
properties: {
title: { type: 'string' },
topic: { type: 'string' },
body: { type: 'string' },
custom: {
type: 'object',
nullable: true,
additionalProperties: true,
},
},
} as any,
data: templateDataPushParams as any,
},
additionalProperties: false,
}],
}
router.post('/', async ctx => {
const payload = validate(templateParams, ctx.request.body)
const payload = validate(templateCreateParams, ctx.request.body)
ctx.body = await createTemplate(ctx.state.project.id, payload)
})
@ -135,8 +141,47 @@ router.get('/:templateId', async ctx => {
ctx.body = ctx.state.template
})
const templateUpdateParams: JSONSchemaType<TemplateUpdateParams> = {
$id: 'templateUpdateParams',
oneOf: [{
type: 'object',
required: ['type', 'data'],
properties: {
type: {
type: 'string',
enum: ['email'],
},
data: templateDataEmailParams as any,
},
additionalProperties: false,
},
{
type: 'object',
required: ['type', 'data'],
properties: {
type: {
type: 'string',
enum: ['text'],
},
data: templateDataTextParams as any,
},
additionalProperties: false,
},
{
type: 'object',
required: ['type', 'data'],
properties: {
type: {
type: 'string',
enum: ['push'],
},
data: templateDataPushParams as any,
},
additionalProperties: false,
}],
}
router.patch('/:templateId', async ctx => {
const payload = validate(templateParams, ctx.request.body)
const payload = validate(templateUpdateParams, ctx.request.body)
ctx.body = await updateTemplate(ctx.state.template!.id, payload)
})

View file

@ -1,6 +1,6 @@
import { Readable } from 'stream'
import { SearchParams } from '../core/searchParams'
import Template, { TemplateParams, TemplateType } from './Template'
import Template, { TemplateParams, TemplateType, TemplateUpdateParams } from './Template'
import nodeHtmlToImage from 'node-html-to-image'
import App from '../app'
import TemplateSnapshotJob from './TemplateSnapshotJob'
@ -40,7 +40,7 @@ export const createTemplate = async (projectId: number, params: TemplateParams)
return template
}
export const updateTemplate = async (templateId: number, params: TemplateParams) => {
export const updateTemplate = async (templateId: number, params: TemplateUpdateParams) => {
const template = await Template.updateAndFetch(templateId, prune(params))
App.main.queue.enqueue(

View file

@ -44,6 +44,7 @@ export class User extends Model {
data!: Record<string, any> // first_name, last_name live in data
attributes!: UserAttribute[] // ???
timezone!: string
locale!: string
static jsonAttributes = ['data', 'devices']
static virtualAttributes = ['firstName', 'lastName', 'fullName']