saleor-apps-redis_apl/apps/crm/src/modules/mailchimp/mailchimp-config-settings-manager.ts
Lukasz Ostrowski 3acc1553a8
Introduce CRM App (#292)
* Add template

Cleanup

Update queries

Basic mailchimp client

Add Oauth flow

remove next auth

* Auth flow, mailchimp button

* Basic layouts

* session saver for appbridge

* ideas drop

* basic iframe flow

* iframe flow - with post message

* saving token in backend

* saving token in backend

* Extracted settings manager

* Refactor audience router

* Remove old macaw ui

* Nav and layout

* display lists and wip add customer

* Metadata updater

* Allow iframe to NOT have app layout

* Add segment coming soon

* App layout

* Add removing config button

* Add iframe

* Fix postmessages

* Display lists

* webhook settings

* Connect webhook

* remove comment

* batch customer adding client

* Update macaw

* Fetching customers component

* Add bulk sync

* add temp ts-ignore until macaw is fixed

* Improve ui

* redesign

* Extract sections

* Redesign mailchimp login

* Refactor sections

* Extract mailchimp list picker

* Add name mapping

* WIP tags, extracted colocated queries to folders

* Wip - not working CustomerUpdated subs

* Add instructions

* Fix webhook config state

* Add external links

* envs

* Protected Oauth handler

* Fix instructions

* Squash some todos

* Instructions update with gql

* empty trygger

* Add env validation

* Fix error message

* Update macaw and remove todos

* Add metadata manager test

* Replace Mailchimp enum to lowercase

* Update oauth routes

* Fix typo

* Add loader to removing config box

* Update labeler to include CRM app

* Apply suggestions from CR

* Fix linter
2023-04-06 09:26:56 +02:00

114 lines
3.1 KiB
TypeScript

import { Client } from "urql";
import { createSettingsManager } from "../../lib/metadata-manager";
import { SettingsManager } from "@saleor/app-sdk/settings-manager";
import { z } from "zod";
import { createLogger } from "../../lib/logger";
export const CustomerCreatedEventConfig = z
.object({
enabled: z.literal(true),
listId: z.string(),
})
.or(
z.object({
enabled: z.literal(false),
})
);
const ConfigV1 = z.object({
token: z.string().min(1).describe("OAuth config from Mailchimp API"),
dc: z.string().min(1).describe("Prefix for mailchimp API, received from Mailchimp metadata"),
customerCreateEvent: CustomerCreatedEventConfig.optional(),
});
const MetadataSchemaV1 = z.object({
configVersion: z.literal("v1"),
config: ConfigV1,
});
/**
* V1 config. In case of changing config, create another instance and perform migration
*
* todo save domain?
* todo add test
*/
export class MailchimpConfigSettingsManagerV1 {
private settingsManager: SettingsManager;
private readonly metadataKey = "mailchimp_config_v1";
private logger = createLogger({
context: "MailchimpConfigSettingsManagerV1",
});
constructor(
private apiClient: Pick<Client, "query" | "mutation">,
metadataManagerFactory = createSettingsManager
) {
this.settingsManager = metadataManagerFactory(apiClient);
}
private parseEmptyResponse = (value?: string) => {
return value === "undefined" ? undefined : value;
};
setConfig(config: z.infer<typeof ConfigV1>) {
const configSchema = MetadataSchemaV1.parse({
config,
configVersion: "v1",
});
if (!configSchema.config.customerCreateEvent) {
configSchema.config.customerCreateEvent = {
enabled: false,
};
}
this.logger.debug(configSchema, "Will set config");
return this.settingsManager.set({
key: this.metadataKey,
value: JSON.stringify(configSchema),
});
}
async getConfig(): Promise<z.infer<typeof ConfigV1> | null> {
this.logger.debug(`Will fetched metadata key: ${this.metadataKey}`);
const rawMetadata = await this.settingsManager
.get(this.metadataKey)
.then(this.parseEmptyResponse);
this.logger.debug({ rawMetadata }, "Received raw metadata");
/**
* Check for "undefined" string because after config is deleted, its actually set to "undefined" instead removing
* TODO remove config instead setting it to "undefined"
*/
if (!rawMetadata) {
this.logger.debug("Raw metadata is nullable");
return null;
}
try {
const parsedMetadata = MetadataSchemaV1.parse(JSON.parse(rawMetadata));
if (!parsedMetadata.config.customerCreateEvent) {
parsedMetadata.config.customerCreateEvent = {
enabled: false,
};
}
return parsedMetadata.config;
} catch (e) {
console.error(e);
return null;
}
}
async removeConfig() {
// todo = implement settingsManager.delete
return this.settingsManager.set({ key: this.metadataKey, value: "undefined" });
}
}
export const MailchimpConfigSettingsManager = MailchimpConfigSettingsManagerV1;
export const MailchimpConfig = ConfigV1;