import type {
MonicaActivity,
MonicaActivityType,
MonicaActivityTypeCategory,
MonicaAddress,
MonicaContact,
MonicaContactField,
MonicaContactFieldType,
MonicaCountry,
MonicaGender,
MonicaGroup,
MonicaReminder,
MonicaRelationship,
MonicaRelationshipType,
MonicaRelationshipTypeGroup,
MonicaNote,
MonicaTask,
MonicaTag
} from '../types.js';
export function normalizeContactSummary(contact: MonicaContact) {
return {
id: contact.id,
name: [contact.first_name, contact.last_name].filter(Boolean).join(' ').trim(),
nickname: contact.nickname ?? undefined,
gender: contact.gender ?? undefined,
emails: contact.information?.emails?.map((email) => email.value) ?? [],
phones: contact.information?.phones?.map((phone) => phone.value) ?? [],
isPartial: contact.is_partial
};
}
export function normalizeContactDetail(contact: MonicaContact) {
return {
...normalizeContactSummary(contact),
description: contact.information?.description ?? undefined,
dates: contact.information?.dates ?? [],
createdAt: contact.created_at,
updatedAt: contact.updated_at,
customFields: contact.contactFields?.map(normalizeContactField) ?? []
};
}
export function buildContactSummary(contact: MonicaContact): string {
const name = [contact.first_name, contact.last_name].filter(Boolean).join(' ').trim();
const emails = contact.information?.emails?.map((email) => email.value) ?? [];
const phones = contact.information?.phones?.map((phone) => phone.value) ?? [];
const parts = [name || `Contact #${contact.id}`];
if (emails.length) {
parts.push(`Emails: ${emails.join(', ')}`);
}
if (phones.length) {
parts.push(`Phones: ${phones.join(', ')}`);
}
// Include contact fields if available
if (contact.contactFields && contact.contactFields.length > 0) {
const fieldLines = contact.contactFields.map(field => {
const typeName = field.contact_field_type?.name || 'Unknown';
return `${typeName}: ${field.data}`;
});
parts.push(`Contact Fields:\n ${fieldLines.join('\n ')}`);
}
if (contact.information?.description) {
parts.push(`Notes: ${contact.information.description}`);
}
return parts.join('\n');
}
export function normalizeTask(task: MonicaTask) {
return {
id: task.id,
title: task.title,
description: task.description ?? undefined,
completed: task.completed,
status: task.completed ? 'completed' : 'open',
completedAt: task.completed_at ?? undefined,
dueAt: task.due_at ?? undefined,
contactId: task.contact?.id,
contact: task.contact ? normalizeContactSummary(task.contact) : undefined,
createdAt: task.created_at,
updatedAt: task.updated_at
};
}
export function normalizeNote(note: MonicaNote) {
return {
id: note.id,
body: note.body,
isFavorited: note.is_favorited,
favoritedAt: note.favorited_at ?? undefined,
contactId: note.contact.id,
contact: normalizeContactSummary(note.contact),
createdAt: note.created_at,
updatedAt: note.updated_at
};
}
export function normalizeActivity(activity: MonicaActivity) {
return {
id: activity.id,
summary: activity.summary,
description: activity.description ?? undefined,
happenedAt: activity.happened_at,
activityType: activity.activity_type
? {
id: activity.activity_type.id,
name: activity.activity_type.name,
locationType: activity.activity_type.location_type,
category: activity.activity_type.activity_type_category?.name ?? null
}
: null,
attendees: activity.attendees.contacts.map((contact) => normalizeContactSummary(contact)),
attendeeCount: activity.attendees.total,
createdAt: activity.created_at,
updatedAt: activity.updated_at
};
}
export function normalizeAddress(address: MonicaAddress) {
return {
id: address.id,
name: address.name,
street: address.street ?? undefined,
city: address.city ?? undefined,
province: address.province ?? undefined,
postalCode: address.postal_code ?? undefined,
country: address.country
? {
id: address.country.id,
name: address.country.name,
iso: address.country.iso
}
: null,
contact: normalizeContactSummary(address.contact),
createdAt: address.created_at ?? undefined,
updatedAt: address.updated_at ?? undefined
};
}
export function normalizeContactFieldType(type: MonicaContactFieldType) {
return {
id: type.id,
name: type.name,
icon: type.fontawesome_icon ?? undefined,
protocol: type.protocol ?? undefined,
delible: typeof type.delible === 'boolean' ? type.delible : type.delible === 1,
kind: type.type ?? undefined,
createdAt: type.created_at ?? undefined,
updatedAt: type.updated_at ?? undefined
};
}
export function normalizeContactField(field: MonicaContactField) {
return {
id: field.id,
value: field.data,
type: normalizeContactFieldType(field.contact_field_type),
contactId: field.contact.id,
createdAt: field.created_at ?? undefined,
updatedAt: field.updated_at ?? undefined
};
}
export function normalizeActivityType(activityType: MonicaActivityType) {
return {
id: activityType.id,
name: activityType.name,
locationType: activityType.location_type ?? undefined,
category: activityType.activity_type_category
? normalizeActivityTypeCategory(activityType.activity_type_category)
: null,
createdAt: activityType.created_at ?? undefined,
updatedAt: activityType.updated_at ?? undefined
};
}
export function normalizeActivityTypeCategory(category: MonicaActivityTypeCategory) {
return {
id: category.id,
name: category.name,
createdAt: category.created_at ?? undefined,
updatedAt: category.updated_at ?? undefined
};
}
export function normalizeCountry(country: MonicaCountry) {
return {
id: country.id,
name: country.name,
iso: country.iso
};
}
export function normalizeGender(gender: MonicaGender) {
return {
id: gender.id,
name: gender.name,
createdAt: gender.created_at ?? undefined,
updatedAt: gender.updated_at ?? undefined
};
}
export function normalizeRelationshipType(type: MonicaRelationshipType) {
return {
id: type.id,
name: type.name,
reverseName: type.name_reverse_relationship,
groupId: type.relationship_type_group_id ?? undefined,
isDeletable: Boolean(type.delible),
createdAt: type.created_at ?? undefined,
updatedAt: type.updated_at ?? undefined
};
}
export function normalizeRelationship(relationship: MonicaRelationship) {
return {
id: relationship.id,
contactId: relationship.contact_is.id,
contact: normalizeContactSummary(relationship.contact_is),
relatedContactId: relationship.of_contact.id,
relatedContact: normalizeContactSummary(relationship.of_contact),
relationshipType: normalizeRelationshipType(relationship.relationship_type),
createdAt: relationship.created_at,
updatedAt: relationship.updated_at
};
}
export function normalizeGroup(group: MonicaGroup) {
return {
id: group.id,
name: group.name,
contactCount: group.contacts.length,
contacts: group.contacts.map(normalizeContactSummary),
createdAt: group.created_at ?? undefined,
updatedAt: group.updated_at ?? undefined
};
}
export function normalizeReminder(reminder: MonicaReminder) {
return {
id: reminder.id,
title: reminder.title,
description: reminder.description ?? undefined,
frequencyType: reminder.frequency_type,
frequencyNumber: reminder.frequency_number ?? undefined,
lastTriggeredDate: reminder.last_triggered_date ?? undefined,
nextExpectedDate: reminder.next_expected_date ?? undefined,
contactId: reminder.contact.id,
contact: normalizeContactSummary(reminder.contact),
createdAt: reminder.created_at,
updatedAt: reminder.updated_at
};
}
export function normalizeRelationshipTypeGroup(group: MonicaRelationshipTypeGroup) {
return {
id: group.id,
name: group.name,
isDeletable: Boolean(group.delible),
createdAt: group.created_at ?? undefined,
updatedAt: group.updated_at ?? undefined
};
}
export function normalizeTag(tag: MonicaTag) {
return {
id: tag.id,
name: tag.name,
nameSlug: tag.name_slug,
createdAt: tag.created_at,
updatedAt: tag.updated_at
};
}