feat(mail): add governed JMAP mailbox sync and search
Module Package Release / publish-packages (push) Successful in 12s

This commit is contained in:
2026-08-22 17:09:05 +02:00
parent fd808336bc
commit 1cbf4acaf4
29 changed files with 2481 additions and 183 deletions
+60 -9
View File
@@ -164,6 +164,20 @@ export type MailMailboxMessageResponse = {
message: MailMailboxMessageDetail;
};
export type MailMailboxProtocol = "imap" | "jmap";
export type MailMailboxChangesResponse = {
profile_id: string;
protocol: "jmap";
account_id: string;
old_state: string;
new_state: string;
has_more_changes: boolean;
created: string[];
updated: string[];
destroyed: string[];
};
export type MailSettingsDeltaResponse = {
profiles: MailServerProfile[];
policy?: MailProfilePolicyResponse | null;
@@ -296,7 +310,7 @@ export async function createMailServerProfile(settings: ApiSettings, payload: Ma
export type MailServerProfileUpdatePayload = Partial<MailServerProfilePayload> & { clear_imap?: boolean };
export type MailServerEndpointPayload = {
protocol: "smtp" | "imap" | "pop3";
protocol: "smtp" | "imap" | "jmap" | "pop3";
name: string;
config: Record<string, unknown>;
inherit_to_lower_scopes?: boolean | null;
@@ -574,6 +588,23 @@ export async function testMailProfileImap(
);
}
export async function testMailProfileJmap(
settings: ApiSettings,
profileId: string,
serverId?: string | null,
credentialId?: string | null,
campaignId?: string | null
): Promise<MailConnectionTestResponse> {
return apiPost<MailConnectionTestResponse>(
settings,
apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/test-jmap`, {
server_id: serverId,
credential_id: credentialId,
campaign_id: campaignId
})
);
}
export async function testMailProfilePop3(
settings: ApiSettings,
profileId: string,
@@ -648,10 +679,11 @@ export async function listMailProfileImapFolders(
);
}
export async function listMailboxFolders(settings: ApiSettings, profileId: string, includeStatus = false, refresh = false): Promise<MailImapFolderListResponse> {
export async function listMailboxFolders(settings: ApiSettings, profileId: string, includeStatus = false, refresh = false, protocol: MailMailboxProtocol = "imap"): Promise<MailImapFolderListResponse> {
return apiFetch<MailImapFolderListResponse>(settings, apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/folders`, {
include_status: includeStatus ? true : undefined,
refresh: refresh ? true : undefined
refresh: refresh ? true : undefined,
protocol
}));
}
@@ -661,13 +693,15 @@ export async function bootstrapMailbox(
folder = "INBOX",
limit = 50,
offset = 0,
refresh = false
refresh = false,
protocol: MailMailboxProtocol = "imap"
): Promise<MailMailboxBootstrapResponse> {
return apiFetch<MailMailboxBootstrapResponse>(settings, apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/bootstrap`, {
folder,
limit,
offset,
refresh: refresh ? true : undefined
refresh: refresh ? true : undefined,
protocol
}));
}
@@ -678,14 +712,18 @@ export async function listMailboxMessages(
limit = 50,
offset = 0,
cursor?: string | null,
refresh = false
refresh = false,
protocol: MailMailboxProtocol = "imap",
query?: string | null
): Promise<MailMailboxMessageListResponse> {
return apiFetch<MailMailboxMessageListResponse>(settings, apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/messages`, {
folder,
limit,
offset,
cursor,
refresh: refresh ? true : undefined
refresh: refresh ? true : undefined,
protocol,
q: query || undefined
}));
}
@@ -693,9 +731,22 @@ export async function getMailboxMessage(
settings: ApiSettings,
profileId: string,
folder: string,
uid: string
uid: string,
protocol: MailMailboxProtocol = "imap"
): Promise<MailMailboxMessageResponse> {
return apiFetch<MailMailboxMessageResponse>(settings, apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/messages/${encodeURIComponent(uid)}`, { folder }));
return apiFetch<MailMailboxMessageResponse>(settings, apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/messages/${encodeURIComponent(uid)}`, { folder, protocol }));
}
export async function getMailboxChanges(
settings: ApiSettings,
profileId: string,
sinceState: string,
maxChanges = 500
): Promise<MailMailboxChangesResponse> {
return apiFetch<MailMailboxChangesResponse>(settings, apiPath(`/api/v1/mail/profiles/${encodeURIComponent(profileId)}/mailbox/changes`, {
since_state: sinceState,
max_changes: maxChanges
}));
}
export async function testSmtpSettings(