Skip to content

Commit

Permalink
fix: issue where attachments columns in CSVs could only start with at…
Browse files Browse the repository at this point in the history
…tachment
  • Loading branch information
Gum-Joe committed Aug 13, 2024
1 parent 79697c5 commit 181353f
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 22 deletions.
26 changes: 23 additions & 3 deletions email/mailmerge/src/pipelines/generate.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ describe("generatePreviews", () => {
mockDataSource = {
loadRecords: jest.fn().mockResolvedValue({
headers: new Set(["header1", "header2"]),
records: [{ header1: "value1", header2: "value2" }],
records: [{ header1: "value1", header2: "value2", addThis: "./test.txt" }],
}),
};

Expand Down Expand Up @@ -64,7 +64,7 @@ describe("generatePreviews", () => {
["header1", "field1"],
["header2", "field2"],
]),
keysForAttachments: [],
keysForAttachments: ["addThis"],
},
};

Expand All @@ -74,7 +74,27 @@ describe("generatePreviews", () => {
expect(mockEngine.loadTemplate).toHaveBeenCalled();
expect(mockEngine.extractFields).toHaveBeenCalled();
expect(mockEngine.renderPreview).toHaveBeenCalled();
expect(mockStorageBackend.storeOriginalMergeResults).toHaveBeenCalled();
expect(mockStorageBackend.storeOriginalMergeResults).toHaveBeenCalledWith(
[
{
record: {
field1: "value1",
field2: "value2",
},
previews: { preview: "preview" },
engineInfo: {
name: "testEngine",
options: {},
},
attachmentPaths: ["./test.txt"],
email: { email: "emailData" },
},
],
{
headers: new Set(["header1", "header2"]),
records: [{ header1: "value1", header2: "value2", addThis: "./test.txt" }],
},
);
});

it("should handle attachments provided in options", async () => {
Expand Down
40 changes: 22 additions & 18 deletions email/mailmerge/src/pipelines/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import "dotenv/config";

import { TemplateEngineOptions, TemplateEngine, TemplatePreviews } from "../engines/index.js";
import { validateRecord, createEmailData } from "../previews/index.js";
import { DEFAULT_FIELD_NAMES, MappedRecord } from "../util/index.js";
import { DEFAULT_FIELD_NAMES, MappedRecord, RawRecord } from "../util/index.js";
import { DataSource } from "./loaders";
import { StorageBackend, MergeResult } from "./storage/types";

Expand Down Expand Up @@ -119,10 +119,12 @@ export async function generatePreviews(

// 6.5: handle attachments
logger.debug("Handling attachments...");
let getAttachmentsFromRecord: (record: MappedRecord) => string[];
// NOTE: This is designed to operate on the original record
let getAttachmentsFromRecord: (record: RawRecord) => string[];
let attachmentHeaders: string[] = [];
if (typeof opts.attachments === "undefined" || opts.attachments.length <= 0) {
logger.info("Using attachments from records");
const attachmentHeaders = Array.isArray(opts.mappings.keysForAttachments)
attachmentHeaders = Array.isArray(opts.mappings.keysForAttachments)
? opts.mappings.keysForAttachments
: await opts.mappings.keysForAttachments(headers);
getAttachmentsFromRecord = (record) =>
Expand All @@ -135,21 +137,22 @@ export async function generatePreviews(
// 8: Render intermediate results
logger.info("Rendering template previews/intermediates...");
// NOTE: MappedRecord here is the record with its fields mapped to the template fields, rather than with the raw template fields
const previews: [TemplatePreviews, MappedRecord][] = await Promise.all(
const previews: [TemplatePreviews, MappedRecord, RawRecord][] = await Promise.all(
records
.map((record) =>
.map((originalRecord) =>
// Only include fields that are mapped
Object.fromEntries(
Object.entries(record)
.filter(
([key]) => fieldsMaptoTemplate.has(key) || key.startsWith("attachment"),
)
.map(([key, value]) => {
return [fieldsMaptoTemplate.get(key) ?? key, value];
}),
),
[
Object.fromEntries(
Object.entries(originalRecord)
.filter(([key]) => fieldsMaptoTemplate.has(key))
.map(([key, value]) => {
return [fieldsMaptoTemplate.get(key) ?? key, value];
}),
),
originalRecord,
],
)
.filter((preparedRecord) => {
.filter(([preparedRecord]) => {
const validState = validateRecord(preparedRecord);
if (!validState.valid) {
logger.warn(
Expand All @@ -161,22 +164,23 @@ export async function generatePreviews(
}
return true;
})
.map(async (preparedRecord) => [
.map(async ([preparedRecord, originalRecord]) => [
await engine.renderPreview(preparedRecord),
preparedRecord,
originalRecord,
]),
);

// 9: Write to file
logger.info("Writing results...");
const results: MergeResult[] = previews.map(([previews, record]) => ({
const results: MergeResult[] = previews.map(([previews, record, originalRecord]) => ({
record,
previews,
engineInfo: {
name: opts.engineInfo.name,
options: opts.engineInfo.options,
},
attachmentPaths: getAttachmentsFromRecord(record),
attachmentPaths: getAttachmentsFromRecord(originalRecord),
email: createEmailData(record),
}));

Expand Down
2 changes: 1 addition & 1 deletion email/workspace/data/names.csv
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
name,to,subject,attachment1,attachment2,bcc,cc
name,to,subject,a1,a2,bcc,cc
Kishan,kishansambhi@hotmail.co.uk,DoCSoc x Kishan,./attachments/DoCSoc Sponsorship Proposal 24-25.pdf,./attachments/munch.jpg,kishansambhi@hotmail.co.uk,jaskishansaran@gmail.com kishansambhi@outlook.com
NotKishan,kishansambhi@hotmail.co.uk," DoCSoc x NotKishan",./attachments/DoCSoc Sponsorship Proposal 24-25.pdf,./attachments/munch.jpg,,

0 comments on commit 181353f

Please sign in to comment.