diff --git a/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useExportProcessRecordsForCSV.ts b/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useExportProcessRecordsForCSV.ts index 817d6ea9107..319e1f1d592 100644 --- a/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useExportProcessRecordsForCSV.ts +++ b/packages/twenty-front/src/modules/object-record/object-options-dropdown/hooks/useExportProcessRecordsForCSV.ts @@ -1,5 +1,6 @@ import { useObjectMetadataItem } from '@/object-metadata/hooks/useObjectMetadataItem'; import { type FieldCurrencyValue } from '@/object-record/record-field/ui/types/FieldMetadata'; +import { isFieldCurrencyValue } from '@/object-record/record-field/ui/types/guards/isFieldCurrencyValue'; import { type ObjectRecord } from '@/object-record/types/ObjectRecord'; import { isDefined } from 'twenty-shared/utils'; import { FieldMetadataType } from '~/generated-metadata/graphql'; @@ -19,16 +20,24 @@ export const useExportProcessRecordsForCSV = (objectNameSingular: string) => { } switch (field.type) { - case FieldMetadataType.CURRENCY: + case FieldMetadataType.CURRENCY: { + const currencyValue = record[field.name]; + if (!isFieldCurrencyValue(currencyValue)) { + return processedRecord; + } return { ...processedRecord, [field.name]: { - amountMicros: convertCurrencyMicrosToCurrencyAmount( - record[field.name].amountMicros, - ), - currencyCode: record[field.name].currencyCode, + amountMicros: + currencyValue.amountMicros !== null + ? convertCurrencyMicrosToCurrencyAmount( + currencyValue.amountMicros, + ) + : null, + currencyCode: currencyValue.currencyCode, } satisfies FieldCurrencyValue, }; + } case FieldMetadataType.MULTI_SELECT: case FieldMetadataType.ARRAY: case FieldMetadataType.RAW_JSON: diff --git a/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx b/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx index 4148cdb4694..ebf6fa67435 100644 --- a/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx +++ b/packages/twenty-front/src/modules/ui/field/display/components/PhonesDisplay.tsx @@ -116,18 +116,20 @@ export const PhonesDisplay = ({ ); }; -const parseAdditionalPhones = (additionalPhones?: any) => { +const parseAdditionalPhones = (additionalPhones?: unknown) => { if (!additionalPhones) { return []; } - if (typeof additionalPhones === 'object') { + if (Array.isArray(additionalPhones)) { return additionalPhones; } if (typeof additionalPhones === 'string') { try { - return JSON.parse(additionalPhones); + const parsed = JSON.parse(additionalPhones); + + return Array.isArray(parsed) ? parsed : []; } catch (error) { logError(t`Error parsing additional phones: ${error}`); } diff --git a/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts b/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts index 461572d5d84..79422176e14 100644 --- a/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts +++ b/packages/twenty-server/src/engine/core-modules/record-transformer/utils/transform-emails-value.util.ts @@ -17,14 +17,12 @@ export const transformEmailsValue = ( if (additionalEmails) { try { - const emailArray = ( - isNonEmptyString(additionalEmails) - ? JSON.parse(additionalEmails) - : additionalEmails - ) as string[]; + const emailArray = isNonEmptyString(additionalEmails) + ? JSON.parse(additionalEmails) + : additionalEmails; additionalEmails = isNonEmptyArray(emailArray) - ? JSON.stringify(emailArray.map((email) => email.toLowerCase())) + ? JSON.stringify(emailArray.map((email: string) => email.toLowerCase())) : null; } catch { /* empty */ diff --git a/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts b/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts index 07005788658..56a5b24e247 100644 --- a/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts +++ b/packages/twenty-server/src/modules/calendar/calendar-event-participant-manager/listeners/calendar-event-participant-person.listener.ts @@ -45,8 +45,7 @@ export class CalendarEventParticipantPersonListener { const personEmails = personWithEmails .flatMap((eventPayload) => [ eventPayload.properties.after.emails.primaryEmail, - ...((eventPayload.properties.after.emails?.additionalEmails ?? - []) as string[]), + ...(eventPayload.properties.after.emails?.additionalEmails ?? []), ]) .filter(isDefined); @@ -82,8 +81,7 @@ export class CalendarEventParticipantPersonListener { const personEmails = personWithEmails .flatMap((eventPayload) => [ eventPayload.properties.after.emails.primaryEmail, - ...((eventPayload.properties.after.emails?.additionalEmails ?? - []) as string[]), + ...(eventPayload.properties.after.emails?.additionalEmails ?? []), ]) .filter(isDefined); @@ -115,8 +113,7 @@ export class CalendarEventParticipantPersonListener { const personEmails = peopleHavingEmails .flatMap((eventPayload) => [ eventPayload.properties.before.emails.primaryEmail, - ...((eventPayload.properties.before.emails?.additionalEmails ?? - []) as string[]), + ...(eventPayload.properties.before.emails?.additionalEmails ?? []), ]) .filter(isDefined); diff --git a/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts b/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts index 3dd2fd89bcd..d7be0d92b6a 100644 --- a/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts +++ b/packages/twenty-server/src/modules/contact-creation-manager/services/create-company-and-contact.service.ts @@ -8,7 +8,7 @@ import { ConnectedAccountProvider, type FieldActorSource, } from 'twenty-shared/types'; -import { isDefined } from 'twenty-shared/utils'; +import { isDefined, isNonEmptyArray } from 'twenty-shared/utils'; import { type DeepPartial, type Repository } from 'typeorm'; import { v4 } from 'uuid'; @@ -251,7 +251,7 @@ export class CreateCompanyAndPersonService { const existingPersonOnAdditionalEmails = alreadyCreatedPeople.find( (person) => { return ( - Array.isArray(person.emails?.additionalEmails) && + isNonEmptyArray(person.emails?.additionalEmails) && person.emails.additionalEmails.some( (email) => email.toLowerCase() === contact.handle.toLowerCase(), ) diff --git a/packages/twenty-server/src/modules/contact-creation-manager/utils/compute-changed-additional-emails.ts b/packages/twenty-server/src/modules/contact-creation-manager/utils/compute-changed-additional-emails.ts index 83728d48ba0..3f5fe446c03 100644 --- a/packages/twenty-server/src/modules/contact-creation-manager/utils/compute-changed-additional-emails.ts +++ b/packages/twenty-server/src/modules/contact-creation-manager/utils/compute-changed-additional-emails.ts @@ -5,8 +5,8 @@ import { type PersonWorkspaceEntity } from 'src/modules/person/standard-objects/ export const computeChangedAdditionalEmails = ( diff: Partial>, ) => { - const before = diff.emails?.before?.additionalEmails as string[]; - const after = diff.emails?.after?.additionalEmails as string[]; + const before = diff.emails?.before?.additionalEmails; + const after = diff.emails?.after?.additionalEmails; if (!Array.isArray(before) || !Array.isArray(after)) { return { diff --git a/packages/twenty-server/src/modules/match-participant/utils/find-person-by-primary-or-additional-email.ts b/packages/twenty-server/src/modules/match-participant/utils/find-person-by-primary-or-additional-email.ts index 2b203c28e05..285962dd8d5 100644 --- a/packages/twenty-server/src/modules/match-participant/utils/find-person-by-primary-or-additional-email.ts +++ b/packages/twenty-server/src/modules/match-participant/utils/find-person-by-primary-or-additional-email.ts @@ -1,3 +1,5 @@ +import { isNonEmptyArray } from 'twenty-shared/utils'; + import { type PersonWorkspaceEntity } from 'src/modules/person/standard-objects/person.workspace-entity'; export const findPersonByPrimaryOrAdditionalEmail = ({ @@ -20,7 +22,7 @@ export const findPersonByPrimaryOrAdditionalEmail = ({ const personWithAdditionalEmail = people.find((person) => { const additionalEmails = person.emails?.additionalEmails; - if (!Array.isArray(additionalEmails)) { + if (!isNonEmptyArray(additionalEmails)) { return false; } diff --git a/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts b/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts index fcf8676a603..a60df0c4a9e 100644 --- a/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts +++ b/packages/twenty-server/src/modules/messaging/message-participant-manager/listeners/message-participant-person.listener.ts @@ -45,8 +45,7 @@ export class MessageParticipantPersonListener { const personEmails = personWithEmails .flatMap((eventPayload) => [ eventPayload.properties.after.emails.primaryEmail, - ...((eventPayload.properties.after.emails?.additionalEmails ?? - []) as string[]), + ...(eventPayload.properties.after.emails?.additionalEmails ?? []), ]) .filter(isDefined); @@ -82,8 +81,7 @@ export class MessageParticipantPersonListener { const personEmails = personWithEmails .flatMap((eventPayload) => [ eventPayload.properties.after.emails.primaryEmail, - ...((eventPayload.properties.after.emails?.additionalEmails ?? - []) as string[]), + ...(eventPayload.properties.after.emails?.additionalEmails ?? []), ]) .filter(isDefined); @@ -121,8 +119,8 @@ export class MessageParticipantPersonListener { personEmails: personWithEmails .flatMap((eventPayload) => [ eventPayload.properties.before.emails.primaryEmail, - ...((eventPayload.properties.before.emails?.additionalEmails ?? - []) as string[]), + ...(eventPayload.properties.before.emails?.additionalEmails ?? + []), ]) .filter(isDefined), workspaceMemberIds: [],