248 lines
9.1 KiB
TypeScript
248 lines
9.1 KiB
TypeScript
import { PrivateMetadataMjmlConfigurator } from "./mjml-configurator";
|
|
import { logger as pinoLogger } from "../../../lib/logger";
|
|
import {
|
|
mjmlCreateConfigurationSchema,
|
|
mjmlDeleteConfigurationInputSchema,
|
|
mjmlGetConfigurationInputSchema,
|
|
mjmlGetConfigurationsInputSchema,
|
|
mjmlGetEventConfigurationInputSchema,
|
|
mjmlUpdateEventConfigurationInputSchema,
|
|
mjmlUpdateOrCreateConfigurationSchema,
|
|
} from "./mjml-config-input-schema";
|
|
import { GetMjmlConfigurationService } from "./get-mjml-configuration.service";
|
|
import { router } from "../../trpc/trpc-server";
|
|
import { protectedClientProcedure } from "../../trpc/protected-client-procedure";
|
|
import { createSettingsManager } from "../../app-configuration/metadata-manager";
|
|
import { z } from "zod";
|
|
import { compileMjml } from "../compile-mjml";
|
|
import Handlebars from "handlebars";
|
|
import { MjmlConfigContainer } from "./mjml-config-container";
|
|
import { TRPCError } from "@trpc/server";
|
|
|
|
export const mjmlConfigurationRouter = router({
|
|
fetch: protectedClientProcedure.query(async ({ ctx }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
|
|
logger.debug("mjmlConfigurationRouter.fetch called");
|
|
|
|
return new GetMjmlConfigurationService({
|
|
apiClient: ctx.apiClient,
|
|
saleorApiUrl: ctx.saleorApiUrl,
|
|
}).getConfiguration();
|
|
}),
|
|
getConfiguration: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlGetConfigurationInputSchema)
|
|
.query(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
|
|
logger.debug(input, "mjmlConfigurationRouter.get called");
|
|
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
return MjmlConfigContainer.getConfiguration(configRoot)(input);
|
|
}),
|
|
getConfigurations: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlGetConfigurationsInputSchema)
|
|
.query(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
logger.debug(input, "mjmlConfigurationRouter.getConfigurations called");
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
return MjmlConfigContainer.getConfigurations(configRoot)(input);
|
|
}),
|
|
createConfiguration: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlCreateConfigurationSchema)
|
|
.mutation(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
logger.debug(input, "mjmlConfigurationRouter.create called");
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
const newConfigurationRoot = MjmlConfigContainer.createConfiguration(configRoot)(input);
|
|
|
|
await mjmlConfigurator.setConfig(newConfigurationRoot);
|
|
|
|
return null;
|
|
}),
|
|
deleteConfiguration: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlDeleteConfigurationInputSchema)
|
|
.mutation(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
logger.debug(input, "mjmlConfigurationRouter.delete called");
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
const newConfigurationRoot = MjmlConfigContainer.deleteConfiguration(configRoot)(input);
|
|
|
|
await mjmlConfigurator.setConfig(newConfigurationRoot);
|
|
|
|
return null;
|
|
}),
|
|
updateOrCreateConfiguration: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlUpdateOrCreateConfigurationSchema)
|
|
.mutation(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
|
|
logger.debug(input, "mjmlConfigurationRouter.update or create called");
|
|
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
|
|
const { id } = input;
|
|
if (!!id) {
|
|
const existingConfiguration = MjmlConfigContainer.getConfiguration(configRoot)({ id });
|
|
if (!existingConfiguration) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Configuration not found",
|
|
});
|
|
}
|
|
// checking typeof id is not enough to satisfy typescript, so need to override id field issue
|
|
const configuration = {
|
|
id,
|
|
...input,
|
|
events: existingConfiguration.events,
|
|
};
|
|
|
|
const newConfigurationRoot =
|
|
MjmlConfigContainer.updateConfiguration(configRoot)(configuration);
|
|
await mjmlConfigurator.setConfig(newConfigurationRoot);
|
|
return configuration;
|
|
} else {
|
|
const newConfigurationRoot = MjmlConfigContainer.createConfiguration(configRoot)(input);
|
|
await mjmlConfigurator.setConfig(newConfigurationRoot);
|
|
return newConfigurationRoot.configurations[newConfigurationRoot.configurations.length - 1];
|
|
}
|
|
}),
|
|
getEventConfiguration: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlGetEventConfigurationInputSchema)
|
|
.query(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
|
|
logger.debug(input, "mjmlConfigurationRouter.getEventConfiguration or create called");
|
|
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
|
|
const configuration = MjmlConfigContainer.getConfiguration(configRoot)({
|
|
id: input.configurationId,
|
|
});
|
|
if (!configuration) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Configuration not found",
|
|
});
|
|
}
|
|
const event = configuration.events.find((e) => e.eventType === input.eventType);
|
|
if (!event) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Event configuration not found",
|
|
});
|
|
}
|
|
return event;
|
|
}),
|
|
updateEventConfiguration: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(mjmlUpdateEventConfigurationInputSchema)
|
|
.mutation(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
|
|
logger.debug(input, "mjmlConfigurationRouter.updateEventConfiguration or create called");
|
|
|
|
const mjmlConfigurator = new PrivateMetadataMjmlConfigurator(
|
|
createSettingsManager(ctx.apiClient),
|
|
ctx.saleorApiUrl
|
|
);
|
|
|
|
const configRoot = await mjmlConfigurator.getConfig();
|
|
|
|
const configuration = MjmlConfigContainer.getConfiguration(configRoot)({
|
|
id: input.configurationId,
|
|
});
|
|
if (!configuration) {
|
|
throw new TRPCError({
|
|
code: "BAD_REQUEST",
|
|
message: "Configuration not found",
|
|
});
|
|
}
|
|
const eventIndex = configuration.events.findIndex((e) => e.eventType === input.eventType);
|
|
configuration.events[eventIndex] = {
|
|
active: input.active,
|
|
eventType: input.eventType,
|
|
template: input.template,
|
|
subject: input.subject,
|
|
};
|
|
const newConfigurationRoot =
|
|
MjmlConfigContainer.updateConfiguration(configRoot)(configuration);
|
|
await mjmlConfigurator.setConfig(newConfigurationRoot);
|
|
return configuration;
|
|
}),
|
|
|
|
renderTemplate: protectedClientProcedure
|
|
.meta({ requiredClientPermissions: ["MANAGE_APPS"] })
|
|
.input(
|
|
z.object({
|
|
template: z.string().optional(),
|
|
subject: z.string().optional(),
|
|
payload: z.string(),
|
|
})
|
|
)
|
|
.mutation(async ({ ctx, input }) => {
|
|
const logger = pinoLogger.child({ saleorApiUrl: ctx.saleorApiUrl });
|
|
logger.debug(input, "mjmlConfigurationRouter.renderTemplate called");
|
|
|
|
let renderedSubject = "";
|
|
|
|
const payload = JSON.parse(input.payload);
|
|
|
|
if (input.subject) {
|
|
const compiledSubjectTemplate = Handlebars.compile(input.subject);
|
|
logger.warn("subject part");
|
|
renderedSubject = compiledSubjectTemplate(payload);
|
|
}
|
|
|
|
let renderedEmail = "";
|
|
if (input.template) {
|
|
const compiledSubjectTemplate = Handlebars.compile(input.template);
|
|
const templatedEmail = compiledSubjectTemplate(payload);
|
|
|
|
const { html: rawHtml } = compileMjml(templatedEmail);
|
|
if (rawHtml) {
|
|
renderedEmail = rawHtml;
|
|
}
|
|
}
|
|
|
|
return {
|
|
renderedSubject,
|
|
renderedEmailBody: renderedEmail,
|
|
};
|
|
}),
|
|
});
|