/** * Datasources are used to dynamically fetch and display configuration * information within the configuration wizard. You can fetch data from * a third-party API, and present the data as input boxes, dropdown * menus, or JSON Forms. * * For information on data sources, see * https://prismatic.io/docs/custom-connectors/data-sources/ */ import { type Element, dataSource, input, util } from "@prismatic-io/spectral"; import { createCakemailClient, buildQueryParams } from "./client"; interface Item { id: number; name: string; quantity: number; } interface CakemailList { id: string; name: string; description?: string; created_at: string; updated_at: string; } interface CakemailSender { id: string; name: string; email: string; confirmed: boolean; created_at: string; updated_at: string; } interface CakemailTemplate { id: number; name: string; description?: string; created_on: number; updated_on: number; tags?: string[]; is_owner: boolean; sharing: { shared: boolean; }; thumbnail?: string; } /** * Create a dropdown menu populated with Cakemail lists * for use in the config wizard */ export const selectCakemailList = dataSource({ display: { label: "Select Cakemail List", description: "This data source fetches a list of Cakemail lists, and presents them as a dropdown menu", }, dataSourceType: "picklist", inputs: { cakemailConnection: input({ label: "Cakemail Connection", required: true, type: "connection", }), account_id: input({ label: "Account ID", type: "string", required: false, comments: "The Cakemail account ID to fetch lists from", }), page: input({ label: "Page", type: "string", required: false, comments: "Page number for pagination", }), per_page: input({ label: "Per Page", type: "string", required: false, comments: "Number of items per page", }), with_count: input({ label: "With count", type: "string", required: false, comments: "Include count in the response", }), }, perform: async ( context, { cakemailConnection, account_id, page, per_page, with_count } ) => { const client = createCakemailClient(cakemailConnection); const finalAccountId = account_id || cakemailConnection.fields.account_id; // Build query parameters like in your actions const queryParams = buildQueryParams({ account_id: finalAccountId, ...(page ? { page } : {}), ...(per_page ? { per_page } : {}), ...(with_count ? { with_count } : {}), }); const { data: response } = await client.get<{ data: CakemailList[] }>( `/lists${queryParams}` ); const result = response.data.map((list) => ({ key: util.types.toString(list.id), label: util.types.toString(list.name), })); console.log(result); return { result }; }, examplePayload: { result: [ { key: "list_123", label: "Newsletter Subscribers" }, { key: "list_456", label: "VIP Customers" }, { key: "list_789", label: "Product Updates" }, ], }, }); export const selectSendersList = dataSource({ display: { label: "Select Cakemail Sender", description: "This data source fetches a list of Cakemail senders, and presents them as a dropdown menu", }, dataSourceType: "picklist", inputs: { cakemailConnection: input({ label: "Cakemail Connection", required: true, type: "connection", }), account_id: input({ label: "Account ID", type: "string", required: true, comments: "The Cakemail account ID to fetch senders from", }), page: input({ label: "Page", type: "string", required: false, comments: "Page number for pagination", }), per_page: input({ label: "Per Page", type: "string", required: false, comments: "Number of items per page", }), with_count: input({ label: "With count", type: "string", required: false, comments: "Include count in the response", }), sort: input({ label: "Sort", type: "string", required: false, comments: "Sort senders by field and direction using syntax [-|+]field", }), }, perform: async ( context, { cakemailConnection, account_id, page, per_page, with_count, sort } ) => { const client = createCakemailClient(cakemailConnection); // Build query parameters like in your actions const queryParams = buildQueryParams({ account_id, ...(page ? { page } : {}), ...(per_page ? { per_page } : {}), ...(with_count ? { with_count } : {}), ...(sort ? { sort } : {}), }); const { data: response } = await client.get<{ data: CakemailSender[] }>( `/brands/default/senders${queryParams}` ); // Filter to only show confirmed senders const confirmedSenders = response.data.filter( (sender) => sender.confirmed === true ); const options: Element[] = confirmedSenders.map((sender) => ({ key: sender.id, label: `${sender.name} (${sender.email})`, })); return { result: options }; }, examplePayload: { result: [ { key: "sender_123", label: "John Doe (john@example.com)" }, { key: "sender_456", label: "Jane Smith (jane@example.com)" }, { key: "sender_789", label: "Support Team (support@example.com)" }, ], }, }); export const selectTemplatesList = dataSource({ display: { label: "Select Cakemail Template", description: "This data source fetches a list of Cakemail templates, and presents them as a dropdown menu", }, dataSourceType: "picklist", inputs: { cakemailConnection: input({ label: "Cakemail Connection", required: true, type: "connection", }), account_id: input({ label: "Account ID", type: "string", required: true, comments: "The Cakemail account ID to fetch templates from", }), page: input({ label: "Page", type: "string", required: false, comments: "Page number for pagination", }), per_page: input({ label: "Per Page", type: "string", required: false, comments: "Number of items per page", }), with_count: input({ label: "With count", type: "string", required: false, comments: "Include count in the response", }), filter: input({ label: "Filter", type: "string", required: false, comments: "Filter templates using valid terms (tag, not_tag, name, is_owner, is_not_owner) and operators (==, !=, >, <, >=, <=). Use ; as separator", }), sort: input({ label: "Sort", type: "string", required: false, comments: "Sort templates by field and direction using syntax [-|+]field. Valid fields: id, created_on, updated_on, name", }), }, perform: async ( context, { cakemailConnection, account_id, page, per_page, with_count, filter, sort } ) => { const client = createCakemailClient(cakemailConnection); // Build query parameters like in your actions const queryParams = buildQueryParams({ account_id, ...(page ? { page } : {}), ...(per_page ? { per_page } : {}), ...(with_count ? { with_count } : {}), ...(filter ? { filter } : {}), ...(sort ? { sort } : {}), }); try { const { data: response } = await client.get<{ data: CakemailTemplate[]; pagination: { page: number; per_page: number; count: number }; }>(`/templates${queryParams}`); // The response has the correct structure with data array const templates = response.data; if (!templates || !Array.isArray(templates)) { return { result: [] }; } const options: Element[] = templates.map((template) => ({ key: template.id.toString(), label: template.name, })); return { result: options }; } catch (error) { throw new Error( `Failed to fetch templates: ${error instanceof Error ? error.message : "Unknown error"}` ); } }, examplePayload: { result: [ { key: "943261", label: "Testing stuff" }, { key: "943262", label: "Newsletter Template" }, { key: "943263", label: "Promotional Template" }, ], }, }); export default { selectCakemailList, selectSendersList, selectTemplatesList };