diff --git a/docs/docs/reference/enum-types.mdx b/docs/docs/reference/enum-types.mdx
index 99bef6b7..b12dc5da 100644
--- a/docs/docs/reference/enum-types.mdx
+++ b/docs/docs/reference/enum-types.mdx
@@ -6,6 +6,16 @@ sidebar_position: 32
These are the supported enum types and the possible values that can be used in the configuration.
+## AttachmentOrderField
+
+Represents an attachment field to be ordered by for processing.
+
+| Value | Description |
+|-------|-------------|
+| `contentType` | Order by the content type of the attachment. |
+| `hash` | Order by the hash of the attachment. |
+| `name` | Order by the name of the attachment. |
+
## ConflictStrategy
Strategy that defines how to deal in case of conflicts with already existing files at the desired location in Google Drive.
@@ -85,6 +95,17 @@ A flag to match messages with certain properties.
| `unread` | Matches unread messages. |
| `unstarred` | Matches un-starred messages. |
+## MessageOrderField
+
+Represents a message field to be ordered by for processing.
+
+| Value | Description |
+|-------|-------------|
+| `date` | Order by the date of the message. |
+| `from` | Order by the sender of the message. |
+| `id` | Order by the ID of the message. |
+| `subject` | Order by the subject of the message. |
+
## MetaInfoType
The type of meta information used for context substitution placeholders.
@@ -97,6 +118,15 @@ The type of meta information used for context substitution placeholders.
| `string` | A string data type. |
| `variable` | A custom configuration variable. |
+## OrderDirection
+
+Represents the direction a list should be ordered.
+
+| Value | Description |
+|-------|-------------|
+| `asc` | Order ascending. |
+| `desc` | Order descending. |
+
## PlaceholderModifierType
The modifiers for placeholder expressions.
@@ -148,3 +178,13 @@ The runtime mode in which processing takes place.
| `dangerous` | This run-mode will execute all configured actions including possibly destructive actions like overwriting files or removing threads or messages.
ATTENTION: Use this only if you know exactly what you're doing and won't complain if something goes wrong! |
| `dry-run` | This run-mode skips execution of writing actions. Use this for testing config changes or library upgrades. |
| `safe-mode` | This run-mode can be used for normal operation but will skip possibly destructive actions like overwriting files or removing threads or messages. |
+
+## ThreadOrderField
+
+Represents a thread field to be ordered by for processing.
+
+| Value | Description |
+|-------|-------------|
+| `lastMessageDate` | Order by the date of the last message in the thread. |
+| `id` | Order by the ID of the thread. |
+| `firstMessageSubject` | Order by the subject of the first message in the thread. |
diff --git a/src/lib/config/AttachmentConfig.ts b/src/lib/config/AttachmentConfig.ts
index 809d879b..4fdba03f 100644
--- a/src/lib/config/AttachmentConfig.ts
+++ b/src/lib/config/AttachmentConfig.ts
@@ -12,6 +12,25 @@ import {
essentialAttachmentMatchConfig,
newAttachmentMatchConfig,
} from "./AttachmentMatchConfig"
+import { OrderDirection } from "./CommonConfig"
+
+/**
+ * Represents an attachment field to be ordered by for processing.
+ */
+export enum AttachmentOrderField {
+ /**
+ * Order by the content type of the attachment.
+ */
+ CONTENT_TYPE = "contentType",
+ /**
+ * Order by the hash of the attachment.
+ */
+ HASH = "hash",
+ /**
+ * Order by the name of the attachment.
+ */
+ NAME = "name",
+}
/**
* Represents a config to handle a certain GMail attachment
@@ -39,6 +58,16 @@ export class AttachmentConfig {
*/
@Expose()
name? = ""
+ /**
+ * The field to order attachments by for processing.
+ */
+ @Expose()
+ orderBy?: AttachmentOrderField = undefined
+ /**
+ * The direction to order attachments for processing.
+ */
+ @Expose()
+ orderDirection?: OrderDirection = undefined
}
export type RequiredAttachmentConfig = RequiredDeep
diff --git a/src/lib/config/CommonConfig.ts b/src/lib/config/CommonConfig.ts
new file mode 100644
index 00000000..5f8a6114
--- /dev/null
+++ b/src/lib/config/CommonConfig.ts
@@ -0,0 +1,18 @@
+/**
+ * Represents the direction a list should be ordered.
+ */
+export enum OrderDirection {
+ /**
+ * Order ascending.
+ */
+ ASC = "asc",
+ /**
+ * Order descending.
+ */
+ DESC = "desc",
+}
+
+export type OrderableEntityConfig = {
+ orderBy: T
+ orderDirection: OrderDirection
+}
diff --git a/src/lib/config/MessageConfig.ts b/src/lib/config/MessageConfig.ts
index 66ff69c4..9a16516c 100644
--- a/src/lib/config/MessageConfig.ts
+++ b/src/lib/config/MessageConfig.ts
@@ -12,12 +12,35 @@ import {
essentialAttachmentConfig,
normalizeAttachmentConfigs,
} from "./AttachmentConfig"
+import { OrderDirection } from "./CommonConfig"
import {
MessageMatchConfig,
essentialMessageMatchConfig,
newMessageMatchConfig,
} from "./MessageMatchConfig"
+/**
+ * Represents a message field to be ordered by for processing.
+ */
+export enum MessageOrderField {
+ /**
+ * Order by the date of the message.
+ */
+ DATE = "date",
+ /**
+ * Order by the sender of the message.
+ */
+ FROM = "from",
+ /**
+ * Order by the ID of the message.
+ */
+ ID = "id",
+ /**
+ * Order by the subject of the message.
+ */
+ SUBJECT = "subject",
+}
+
/**
* Represents a config to handle a certain GMail message
*/
@@ -50,6 +73,16 @@ export class MessageConfig {
*/
@Expose()
name? = ""
+ /**
+ * The field to order messages by for processing.
+ */
+ @Expose()
+ orderBy?: MessageOrderField = undefined
+ /**
+ * The direction to order messages for processing.
+ */
+ @Expose()
+ orderDirection?: OrderDirection = undefined
}
export type RequiredMessageConfig = RequiredDeep
diff --git a/src/lib/config/ThreadConfig.ts b/src/lib/config/ThreadConfig.ts
index 8da0c910..1a786dd8 100644
--- a/src/lib/config/ThreadConfig.ts
+++ b/src/lib/config/ThreadConfig.ts
@@ -8,6 +8,7 @@ import {
essentialThreadActionConfig,
} from "./ActionConfig"
import { AttachmentConfig, essentialAttachmentConfig } from "./AttachmentConfig"
+import { OrderDirection } from "./CommonConfig"
import {
MessageConfig,
essentialMessageConfig,
@@ -19,6 +20,24 @@ import {
newThreadMatchConfig,
} from "./ThreadMatchConfig"
+/**
+ * Represents a thread field to be ordered by for processing.
+ */
+export enum ThreadOrderField {
+ /**
+ * Order by the date of the last message in the thread.
+ */
+ DATE = "lastMessageDate",
+ /**
+ * Order by the ID of the thread.
+ */
+ ID = "id",
+ /**
+ * Order by the subject of the first message in the thread.
+ */
+ SUBJECT = "firstMessageSubject",
+}
+
/**
* Represents a config handle a certain GMail thread
*/
@@ -57,6 +76,16 @@ export class ThreadConfig {
*/
@Expose()
name? = ""
+ /**
+ * The field to order threads by for processing.
+ */
+ @Expose()
+ orderBy?: ThreadOrderField = undefined
+ /**
+ * The direction to order threads for processing.
+ */
+ @Expose()
+ orderDirection?: OrderDirection = undefined
}
export type RequiredThreadConfig = RequiredDeep
diff --git a/src/lib/config/config-schema-v2.json b/src/lib/config/config-schema-v2.json
index 4a5c12a9..50ca2ade 100644
--- a/src/lib/config/config-schema-v2.json
+++ b/src/lib/config/config-schema-v2.json
@@ -31,6 +31,25 @@
"description": "The unique name of the attachment config (will be generated if not set)",
"title": "name",
"type": "string"
+ },
+ "orderBy": {
+ "description": "The field to order attachments by for processing.",
+ "enum": [
+ "contentType",
+ "hash",
+ "name"
+ ],
+ "title": "orderBy",
+ "type": "string"
+ },
+ "orderDirection": {
+ "description": "The direction to order attachments for processing.",
+ "enum": [
+ "asc",
+ "desc"
+ ],
+ "title": "orderDirection",
+ "type": "string"
}
},
"title": "AttachmentConfig",
@@ -1548,6 +1567,26 @@
"description": "The unique name of the message config (will be generated if not set)",
"title": "name",
"type": "string"
+ },
+ "orderBy": {
+ "description": "The field to order messages by for processing.",
+ "enum": [
+ "date",
+ "from",
+ "id",
+ "subject"
+ ],
+ "title": "orderBy",
+ "type": "string"
+ },
+ "orderDirection": {
+ "description": "The direction to order messages for processing.",
+ "enum": [
+ "asc",
+ "desc"
+ ],
+ "title": "orderDirection",
+ "type": "string"
}
},
"title": "MessageConfig",
@@ -3046,6 +3085,25 @@
"description": "The unique name of the thread config (will be generated if not set)",
"title": "name",
"type": "string"
+ },
+ "orderBy": {
+ "description": "The field to order threads by for processing.",
+ "enum": [
+ "firstMessageSubject",
+ "id",
+ "lastMessageDate"
+ ],
+ "title": "orderBy",
+ "type": "string"
+ },
+ "orderDirection": {
+ "description": "The direction to order threads for processing.",
+ "enum": [
+ "asc",
+ "desc"
+ ],
+ "title": "orderDirection",
+ "type": "string"
}
},
"title": "ThreadConfig",
diff --git a/src/lib/processors/AttachmentProcessor.spec.ts b/src/lib/processors/AttachmentProcessor.spec.ts
index fccbb368..8e86a2da 100644
--- a/src/lib/processors/AttachmentProcessor.spec.ts
+++ b/src/lib/processors/AttachmentProcessor.spec.ts
@@ -1,12 +1,16 @@
import { GMailMocks } from "../../test/mocks/GMailMocks"
import { MockFactory, Mocks } from "../../test/mocks/MockFactory"
import { ProcessingStatus } from "../Context"
-import { newAttachmentConfig } from "../config/AttachmentConfig"
+import {
+ AttachmentOrderField,
+ newAttachmentConfig,
+} from "../config/AttachmentConfig"
import {
AttachmentMatchConfig,
RequiredAttachmentMatchConfig,
newAttachmentMatchConfig,
} from "../config/AttachmentMatchConfig"
+import { OrderDirection } from "../config/CommonConfig"
import { AttachmentProcessor } from "./AttachmentProcessor"
let mocks: Mocks
@@ -187,3 +191,42 @@ it("should process an attachment entity", () => {
status: ProcessingStatus.OK,
})
})
+
+describe("order attachments", () => {
+ let attachments = [
+ GMailMocks.newAttachmentMock({
+ hash: "a1",
+ name: "2",
+ }),
+ GMailMocks.newAttachmentMock({
+ hash: "a2",
+ name: "1",
+ }),
+ GMailMocks.newAttachmentMock({
+ hash: "a3",
+ name: "3",
+ }),
+ ]
+ it("should order threads ascending", () => {
+ attachments = AttachmentProcessor.ordered(
+ attachments,
+ {
+ orderBy: AttachmentOrderField.NAME,
+ orderDirection: OrderDirection.ASC,
+ },
+ AttachmentProcessor.orderRules,
+ )
+ expect(attachments.map((t) => t.getHash())).toEqual(["a2", "a1", "a3"])
+ })
+ it("should order threads ascending", () => {
+ attachments = AttachmentProcessor.ordered(
+ attachments,
+ {
+ orderBy: AttachmentOrderField.NAME,
+ orderDirection: OrderDirection.DESC,
+ },
+ AttachmentProcessor.orderRules,
+ )
+ expect(attachments.map((t) => t.getHash())).toEqual(["a3", "a1", "a2"])
+ })
+})
diff --git a/src/lib/processors/AttachmentProcessor.ts b/src/lib/processors/AttachmentProcessor.ts
index 450aa1d7..bca2fb4d 100644
--- a/src/lib/processors/AttachmentProcessor.ts
+++ b/src/lib/processors/AttachmentProcessor.ts
@@ -1,9 +1,13 @@
import { ProcessingStage } from "../config/ActionConfig"
-import { RequiredAttachmentConfig } from "../config/AttachmentConfig"
+import {
+ AttachmentOrderField,
+ RequiredAttachmentConfig,
+} from "../config/AttachmentConfig"
import {
AttachmentMatchConfig,
RequiredAttachmentMatchConfig,
} from "../config/AttachmentMatchConfig"
+import { OrderableEntityConfig, OrderDirection } from "../config/CommonConfig"
import {
Attachment,
AttachmentContext,
@@ -226,6 +230,22 @@ export class AttachmentProcessor extends BaseProcessor {
return result
}
+ public static orderRules(
+ a: GoogleAppsScript.Gmail.GmailAttachment,
+ b: GoogleAppsScript.Gmail.GmailAttachment,
+ config: OrderableEntityConfig,
+ ): number {
+ return (
+ {
+ [AttachmentOrderField.CONTENT_TYPE]: a
+ .getContentType()
+ .localeCompare(b.getContentType()),
+ [AttachmentOrderField.HASH]: a.getHash().localeCompare(b.getHash()),
+ [AttachmentOrderField.NAME]: a.getName().localeCompare(b.getName()),
+ }[config.orderBy] * (config.orderDirection == OrderDirection.ASC ? 1 : -1)
+ )
+ }
+
public static processConfig(
ctx: MessageContext,
config: RequiredAttachmentConfig,
@@ -245,7 +265,11 @@ export class AttachmentProcessor extends BaseProcessor {
includeAttachments: matchConfig.includeAttachments,
includeInlineImages: matchConfig.includeInlineImages,
}
- const attachments = ctx.message.object.getAttachments(opts)
+ const attachments = this.ordered(
+ ctx.message.object.getAttachments(opts),
+ config,
+ this.orderRules,
+ )
for (let index = 0; index < attachments.length; index++) {
const attachment = attachments[index]
if (!this.matches(ctx, matchConfig, attachment)) {
diff --git a/src/lib/processors/BaseProcessor.ts b/src/lib/processors/BaseProcessor.ts
index 5308339e..cb0b94e8 100644
--- a/src/lib/processors/BaseProcessor.ts
+++ b/src/lib/processors/BaseProcessor.ts
@@ -20,6 +20,7 @@ import {
import { ActionArgsType, ActionReturnType } from "../actions/ActionRegistry"
import { ActionConfig, ProcessingStage } from "../config/ActionConfig"
import { AttachmentMatchConfig } from "../config/AttachmentMatchConfig"
+import { OrderableEntityConfig } from "../config/CommonConfig"
import { MessageMatchConfig } from "../config/MessageMatchConfig"
import { ThreadMatchConfig } from "../config/ThreadMatchConfig"
import { PatternUtil } from "../utils/PatternUtil"
@@ -441,32 +442,14 @@ export abstract class BaseProcessor {
return `${description}See [${title}](https://developers.google.com/apps-script/reference/gmail/gmail-${type}#${method}\\(\\)) reference docs.`
}
- protected static getConfigName(
- // TODO: Remove, is obsolete now.
- ctx: ThreadContext | MessageContext | AttachmentContext,
- namePrefix = "",
- ) {
- let threadName = ""
- let messageName = ""
- let attachmentName = ""
- if ((ctx as ThreadContext).thread) {
- const threadCtx = ctx as ThreadContext
- threadName =
- threadCtx.thread.config.name ??
- `${threadCtx.thread.config.name}-${threadCtx.thread.configIndex}`
- }
- if ((ctx as MessageContext).message) {
- const messageCtx = ctx as MessageContext
- messageName =
- messageCtx.message.config.name ??
- `-${messageCtx.message.config.name}-${messageCtx.message.configIndex}`
- }
- if ((ctx as AttachmentContext).message) {
- const attachmentCtx = ctx as AttachmentContext
- attachmentName =
- attachmentCtx.attachment.config.name ??
- `-${attachmentCtx.attachment.config.name}-${attachmentCtx.attachment.configIndex}`
+ public static ordered(
+ entities: T[],
+ config: OrderableEntityConfig,
+ orderRulesFn: (a: T, b: T, config: OrderableEntityConfig) => number,
+ ): T[] {
+ if (config.orderBy && config.orderDirection) {
+ entities = entities.sort((a: T, b: T) => orderRulesFn(a, b, config))
}
- return `${namePrefix}${threadName}${messageName}${attachmentName}`
+ return entities
}
}
diff --git a/src/lib/processors/MessageProcessor.spec.ts b/src/lib/processors/MessageProcessor.spec.ts
index 0552e712..9a096d2c 100644
--- a/src/lib/processors/MessageProcessor.spec.ts
+++ b/src/lib/processors/MessageProcessor.spec.ts
@@ -1,6 +1,7 @@
import { GMailMocks } from "../../test/mocks/GMailMocks"
import { MockFactory, Mocks } from "../../test/mocks/MockFactory"
-import { newMessageConfig } from "../config/MessageConfig"
+import { OrderDirection } from "../config/CommonConfig"
+import { MessageOrderField, newMessageConfig } from "../config/MessageConfig"
import { MessageFlag } from "../config/MessageFlag"
import { MessageMatchConfig } from "../config/MessageMatchConfig"
import { MessageProcessor } from "./MessageProcessor"
@@ -131,3 +132,36 @@ describe("processEntity()", () => {
MessageProcessor.processEntity(ctx)
})
})
+
+describe("order messages", () => {
+ let messages = [
+ GMailMocks.newMessageMock({
+ id: "m1",
+ date: new Date(2024, 5, 10),
+ }),
+ GMailMocks.newMessageMock({
+ id: "m2",
+ date: new Date(2024, 5, 9),
+ }),
+ GMailMocks.newMessageMock({
+ id: "m3",
+ date: new Date(2024, 5, 11),
+ }),
+ ]
+ it("should order threads ascending", () => {
+ messages = MessageProcessor.ordered(
+ messages,
+ { orderBy: MessageOrderField.DATE, orderDirection: OrderDirection.ASC },
+ MessageProcessor.orderRules,
+ )
+ expect(messages.map((t) => t.getId())).toEqual(["m2", "m1", "m3"])
+ })
+ it("should order threads ascending", () => {
+ messages = MessageProcessor.ordered(
+ messages,
+ { orderBy: MessageOrderField.DATE, orderDirection: OrderDirection.DESC },
+ MessageProcessor.orderRules,
+ )
+ expect(messages.map((t) => t.getId())).toEqual(["m3", "m1", "m2"])
+ })
+})
diff --git a/src/lib/processors/MessageProcessor.ts b/src/lib/processors/MessageProcessor.ts
index 5ac701bb..79384cc9 100644
--- a/src/lib/processors/MessageProcessor.ts
+++ b/src/lib/processors/MessageProcessor.ts
@@ -11,7 +11,11 @@ import {
newProcessingResult,
} from "../Context"
import { ProcessingStage } from "../config/ActionConfig"
-import { RequiredMessageConfig } from "../config/MessageConfig"
+import { OrderDirection, OrderableEntityConfig } from "../config/CommonConfig"
+import {
+ MessageOrderField,
+ RequiredMessageConfig,
+} from "../config/MessageConfig"
import { MessageFlag } from "../config/MessageFlag"
import {
MessageMatchConfig,
@@ -370,6 +374,23 @@ export class MessageProcessor extends BaseProcessor {
return m
}
+ public static orderRules(
+ a: GoogleAppsScript.Gmail.GmailMessage,
+ b: GoogleAppsScript.Gmail.GmailMessage,
+ config: OrderableEntityConfig,
+ ): number {
+ return (
+ {
+ [MessageOrderField.DATE]: a.getDate().getTime() - b.getDate().getTime(),
+ [MessageOrderField.FROM]: a.getFrom().localeCompare(b.getFrom()),
+ [MessageOrderField.ID]: a.getId().localeCompare(b.getId()),
+ [MessageOrderField.SUBJECT]: a
+ .getSubject()
+ .localeCompare(b.getSubject()),
+ }[config.orderBy] * (config.orderDirection == OrderDirection.ASC ? 1 : -1)
+ )
+ }
+
public static processConfig(
ctx: ThreadContext,
config: RequiredMessageConfig,
@@ -380,7 +401,11 @@ export class MessageProcessor extends BaseProcessor {
location: "MessageProcessor.processConfig()",
message: `Processing message config '${configIndex}' started ...`,
})
- const messages = ctx.thread.object.getMessages()
+ const messages = this.ordered(
+ ctx.thread.object.getMessages(),
+ config,
+ this.orderRules,
+ )
const matchConfig = this.buildMatchConfig(
ctx,
ctx.proc.config.global.message.match,
diff --git a/src/lib/processors/ThreadProcessor.spec.ts b/src/lib/processors/ThreadProcessor.spec.ts
index 9edd672a..16e0d021 100644
--- a/src/lib/processors/ThreadProcessor.spec.ts
+++ b/src/lib/processors/ThreadProcessor.spec.ts
@@ -1,10 +1,12 @@
import { ConfigMocks } from "../../test/mocks/ConfigMocks"
import { ContextMocks } from "../../test/mocks/ContextMocks"
+import { GMailMocks } from "../../test/mocks/GMailMocks"
import { MockFactory, Mocks } from "../../test/mocks/MockFactory"
import { ProcessingStatus } from "../Context"
+import { OrderDirection } from "../config/CommonConfig"
import { newConfig } from "../config/Config"
import { MarkProcessedMethod } from "../config/SettingsConfig"
-import { newThreadConfig } from "../config/ThreadConfig"
+import { ThreadOrderField, newThreadConfig } from "../config/ThreadConfig"
import { ThreadProcessor } from "./ThreadProcessor"
let mocks: Mocks
@@ -108,3 +110,40 @@ it("should process an thread entity", () => {
status: ProcessingStatus.OK,
})
})
+
+describe("order threads", () => {
+ let threads: GoogleAppsScript.Gmail.GmailThread[]
+ beforeAll(() => {
+ jest.useRealTimers()
+ threads = [
+ GMailMocks.newThreadMock({
+ id: "t1",
+ lastMessageDate: new Date(2024, 5, 10),
+ }),
+ GMailMocks.newThreadMock({
+ id: "t2",
+ lastMessageDate: new Date(2024, 5, 9),
+ }),
+ GMailMocks.newThreadMock({
+ id: "t3",
+ lastMessageDate: new Date(2024, 5, 11),
+ }),
+ ]
+ })
+ it("should order threads ascending", () => {
+ threads = ThreadProcessor.ordered(
+ threads,
+ { orderBy: ThreadOrderField.DATE, orderDirection: OrderDirection.ASC },
+ ThreadProcessor.orderRules,
+ )
+ expect(threads.map((t) => t.getId())).toEqual(["t2", "t1", "t3"])
+ })
+ it("should order threads ascending", () => {
+ threads = ThreadProcessor.ordered(
+ threads,
+ { orderBy: ThreadOrderField.DATE, orderDirection: OrderDirection.DESC },
+ ThreadProcessor.orderRules,
+ )
+ expect(threads.map((t) => t.getId())).toEqual(["t3", "t1", "t2"])
+ })
+})
diff --git a/src/lib/processors/ThreadProcessor.ts b/src/lib/processors/ThreadProcessor.ts
index d7445254..85fe880f 100644
--- a/src/lib/processors/ThreadProcessor.ts
+++ b/src/lib/processors/ThreadProcessor.ts
@@ -11,6 +11,7 @@ import {
newProcessingResult,
} from "../Context"
import { ProcessingStage } from "../config/ActionConfig"
+import { OrderDirection, OrderableEntityConfig } from "../config/CommonConfig"
import { RequiredThreadConfig } from "../config/ThreadConfig"
import {
RequiredThreadMatchConfig,
@@ -18,6 +19,7 @@ import {
} from "../config/ThreadMatchConfig"
import { PatternUtil } from "../utils/PatternUtil"
import { RegexUtils } from "../utils/RegexUtils"
+import { ThreadOrderField } from "./../config/ThreadConfig"
import { BaseProcessor } from "./BaseProcessor"
import { MessageProcessor } from "./MessageProcessor"
@@ -350,6 +352,23 @@ export class ThreadProcessor extends BaseProcessor {
return result
}
+ public static orderRules(
+ a: GoogleAppsScript.Gmail.GmailThread,
+ b: GoogleAppsScript.Gmail.GmailThread,
+ config: OrderableEntityConfig,
+ ): number {
+ return (
+ {
+ [ThreadOrderField.DATE]:
+ a.getLastMessageDate().getTime() - b.getLastMessageDate().getTime(),
+ [ThreadOrderField.ID]: a.getId().localeCompare(b.getId()),
+ [ThreadOrderField.SUBJECT]: a
+ .getFirstMessageSubject()
+ .localeCompare(b.getFirstMessageSubject()),
+ }[config.orderBy] * (config.orderDirection == OrderDirection.ASC ? 1 : -1)
+ )
+ }
+
public static processConfig(
ctx: ProcessingContext,
config: RequiredThreadConfig,
@@ -368,9 +387,13 @@ export class ThreadProcessor extends BaseProcessor {
const query = PatternUtil.substitute(ctx, this.buildQuery(matchConfig))
ctx.log.info(`GMail search query: ${query}`)
// Process all threads matching the search expression:
- const threads = ctx.proc.gmailAdapter.search(
- query,
- ctx.proc.config.settings.maxBatchSize,
+ const threads = this.ordered(
+ ctx.proc.gmailAdapter.search(
+ query,
+ ctx.proc.config.settings.maxBatchSize,
+ ),
+ config,
+ this.orderRules,
)
ctx.log.info(`-> got ${threads.length} threads`)
for (let threadIndex = 0; threadIndex < threads.length; threadIndex++) {
diff --git a/src/test/mocks/GMailMocks.ts b/src/test/mocks/GMailMocks.ts
index 59c267f8..91ce9a2c 100644
--- a/src/test/mocks/GMailMocks.ts
+++ b/src/test/mocks/GMailMocks.ts
@@ -225,12 +225,14 @@ export class GMailMocks {
isInTrash: data.isInTrash ?? false,
isUnread: data.isUnread ?? true,
labels: data.labels ?? [],
- lastMessageDate: messages.reduce((lastMessage, currentMessage) =>
- lastMessage.date.getMilliseconds() <
- currentMessage.date.getMilliseconds()
- ? currentMessage
- : lastMessage,
- ).date,
+ lastMessageDate:
+ data.lastMessageDate ??
+ messages.reduce((lastMessage, currentMessage) =>
+ lastMessage.date.getMilliseconds() <
+ currentMessage.date.getMilliseconds()
+ ? currentMessage
+ : lastMessage,
+ ).date,
messageCount: messages.length,
messages: messages,
permalink: data.permalink ?? "some-permalink-url",
@@ -296,9 +298,11 @@ export class GMailMocks {
const sampleContent = data.content ?? "Sample text content"
const sampleData: RequiredAttachmentData = {
contentType: data.contentType ?? "text/plain",
- hash: crypto.createHash("sha1").update(sampleContent).digest("hex"),
+ hash:
+ data.hash ??
+ crypto.createHash("sha1").update(sampleContent).digest("hex"),
name: data.name ?? "attachment.txt",
- size: this.lengthInUtf8Bytes(sampleContent),
+ size: data.size ?? this.lengthInUtf8Bytes(sampleContent),
isGoogleType: data.isGoogleType ?? false,
content: sampleContent,
}