diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant.ts index 7955744559b..d28f17058da 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant.ts @@ -4,10 +4,6 @@ export const POSTGRES_DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE = ''; export const DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE = ''; -export const DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE = {}; - -export const POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE = '{}'; - export const DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE = []; export const POSTGRES_DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE = '{}'; @@ -46,7 +42,6 @@ const DEFAULT_FULL_NAME_FIELD_NULL_EQUIVALENT_VALUE = { const DEFAULT_ACTOR_FIELD_NULL_EQUIVALENT_VALUE = { name: DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE, - context: DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE, }; const DEFAULT_RICH_TEXT_V2_FIELD_NULL_EQUIVALENT_VALUE = { diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/__tests__/find-postgres-default-null-equivalent-value.util.spec.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/__tests__/find-postgres-default-null-equivalent-value.util.spec.ts index 03e4fbd5ea0..8ab8c5e1965 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/__tests__/find-postgres-default-null-equivalent-value.util.spec.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/__tests__/find-postgres-default-null-equivalent-value.util.spec.ts @@ -2,7 +2,6 @@ import { FieldMetadataType } from 'twenty-shared/types'; import { POSTGRES_DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE, - POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE, POSTGRES_DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE, } from 'src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant'; import { findPostgresDefaultNullEquivalentValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/find-postgres-default-null-equivalent-value.util'; @@ -41,35 +40,6 @@ describe('findPostgresDefaultNullEquivalentValue', () => { }); }); - describe('RAW_JSON', () => { - it('should return POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE for null', () => { - expect( - findPostgresDefaultNullEquivalentValue( - null, - FieldMetadataType.RAW_JSON, - ), - ).toBe(POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE); - }); - - it('should return POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE for empty object', () => { - expect( - findPostgresDefaultNullEquivalentValue( - {}, - FieldMetadataType.RAW_JSON, - ), - ).toBe(POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE); - }); - - it("should return POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE for 'NULL'", () => { - expect( - findPostgresDefaultNullEquivalentValue( - 'NULL', - FieldMetadataType.RAW_JSON, - ), - ).toBe(POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE); - }); - }); - describe('ARRAY', () => { it('should return POSTGRES_DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE for null', () => { expect( @@ -112,7 +82,7 @@ describe('findPostgresDefaultNullEquivalentValue', () => { FieldMetadataType.ACTOR, 'context', ), - ).toBe(POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE); + ).toBe(undefined); }); }); @@ -209,7 +179,7 @@ describe('findPostgresDefaultNullEquivalentValue', () => { FieldMetadataType.RICH_TEXT_V2, 'blocknote', ), - ).toBe(POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE); + ).toBe(undefined); }); it('should return text default for markdown', () => { diff --git a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/find-postgres-default-null-equivalent-value.util.ts b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/find-postgres-default-null-equivalent-value.util.ts index e18a5de4c55..19deed20536 100644 --- a/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/find-postgres-default-null-equivalent-value.util.ts +++ b/packages/twenty-server/src/engine/api/common/common-args-processors/data-arg-processor/utils/find-postgres-default-null-equivalent-value.util.ts @@ -2,11 +2,9 @@ import { FieldMetadataType } from 'twenty-shared/types'; import { POSTGRES_DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE, - POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE, POSTGRES_DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE, } from 'src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant'; import { isNullEquivalentArrayFieldValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/is-null-equivalent-array-field-value.util'; -import { isNullEquivalentRawJsonFieldValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/is-null-equivalent-raw-json-field-value.util'; import { isNullEquivalentTextFieldValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/is-null-equivalent-text-field-value.util'; export const findPostgresDefaultNullEquivalentValue = ( @@ -19,10 +17,7 @@ export const findPostgresDefaultNullEquivalentValue = ( return isNullEquivalentTextFieldValue(value) || value === 'NULL' ? POSTGRES_DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE : undefined; - case FieldMetadataType.RAW_JSON: - return isNullEquivalentRawJsonFieldValue(value) || value === 'NULL' - ? POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE - : undefined; + case FieldMetadataType.MULTI_SELECT: case FieldMetadataType.ARRAY: return isNullEquivalentArrayFieldValue(value) || value === 'NULL' ? POSTGRES_DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE @@ -33,10 +28,6 @@ export const findPostgresDefaultNullEquivalentValue = ( return isNullEquivalentTextFieldValue(value) || value === 'NULL' ? POSTGRES_DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE : undefined; - case 'context': - return isNullEquivalentRawJsonFieldValue(value) || value === 'NULL' - ? POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE - : undefined; default: return undefined; } @@ -128,10 +119,6 @@ export const findPostgresDefaultNullEquivalentValue = ( } case FieldMetadataType.RICH_TEXT_V2: { switch (key) { - case 'blocknote': - return isNullEquivalentRawJsonFieldValue(value) || value === 'NULL' - ? POSTGRES_DEFAULT_RAW_JSON_FIELD_NULL_EQUIVALENT_VALUE - : undefined; case 'markdown': return isNullEquivalentTextFieldValue(value) || value === 'NULL' ? POSTGRES_DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts index 7bb8633c0c0..01b408956e5 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/evaluate-filter-conditions.util.spec.ts @@ -501,8 +501,24 @@ describe('evaluateFilterConditions', () => { 'TEXT', ); + const filter3 = createFilter( + ViewFilterOperand.CONTAINS, + null, + '', + 'TEXT', + ); + + const filter4 = createFilter( + ViewFilterOperand.CONTAINS, + '', + null, + 'TEXT', + ); + expect(evaluateFilterConditions({ filters: [filter1] })).toBe(true); expect(evaluateFilterConditions({ filters: [filter2] })).toBe(false); + expect(evaluateFilterConditions({ filters: [filter3] })).toBe(true); + expect(evaluateFilterConditions({ filters: [filter4] })).toBe(true); }); it('should handle DoesNotContain operand with strings', () => { @@ -519,8 +535,16 @@ describe('evaluateFilterConditions', () => { 'TEXT', ); + const filter3 = createFilter( + ViewFilterOperand.DOES_NOT_CONTAIN, + null, + '', + 'TEXT', + ); + expect(evaluateFilterConditions({ filters: [filter1] })).toBe(false); expect(evaluateFilterConditions({ filters: [filter2] })).toBe(true); + expect(evaluateFilterConditions({ filters: [filter3] })).toBe(false); }); it('should handle Contains operand with arrays', () => { @@ -537,8 +561,32 @@ describe('evaluateFilterConditions', () => { 'ARRAY', ); + const filter3 = createFilter( + ViewFilterOperand.CONTAINS, + null, + [], + 'ARRAY', + ); + + const filter4 = createFilter( + ViewFilterOperand.CONTAINS, + [], + null, + 'ARRAY', + ); + + const filter5 = createFilter( + ViewFilterOperand.CONTAINS, + null, + ['apple'], + 'ARRAY', + ); + expect(evaluateFilterConditions({ filters: [filter1] })).toBe(true); expect(evaluateFilterConditions({ filters: [filter2] })).toBe(false); + expect(evaluateFilterConditions({ filters: [filter3] })).toBe(true); + expect(evaluateFilterConditions({ filters: [filter4] })).toBe(true); + expect(evaluateFilterConditions({ filters: [filter5] })).toBe(false); }); it('should handle DoesNotContain operand with arrays', () => { @@ -555,8 +603,16 @@ describe('evaluateFilterConditions', () => { 'ARRAY', ); + const filter3 = createFilter( + ViewFilterOperand.DOES_NOT_CONTAIN, + null, + ['apple'], + 'ARRAY', + ); + expect(evaluateFilterConditions({ filters: [filter1] })).toBe(false); expect(evaluateFilterConditions({ filters: [filter2] })).toBe(true); + expect(evaluateFilterConditions({ filters: [filter3] })).toBe(true); }); }); diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/find-default-null-equivalent-value.util.spec.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/find-default-null-equivalent-value.util.spec.ts new file mode 100644 index 00000000000..d1307a7a37d --- /dev/null +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/__tests__/find-default-null-equivalent-value.util.spec.ts @@ -0,0 +1,233 @@ +import { FieldMetadataType } from 'twenty-shared/types'; + +import { + DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE, + DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE, +} from 'src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant'; +import { findDefaultNullEquivalentValue } from 'src/modules/workflow/workflow-executor/workflow-actions/filter/utils/find-default-null-equivalent-value.util'; + +describe('findDefaultNullEquivalentValue', () => { + describe('Simple Types', () => { + describe('TEXT', () => { + it('should return DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE for null', () => { + expect( + findDefaultNullEquivalentValue({ + value: null, + fieldMetadataType: FieldMetadataType.TEXT, + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE for empty string', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.TEXT, + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return undefined for non-null equivalent value', () => { + expect( + findDefaultNullEquivalentValue({ + value: 'value', + fieldMetadataType: FieldMetadataType.TEXT, + }), + ).toBeUndefined(); + }); + }); + + describe('ARRAY', () => { + it('should return DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE for null', () => { + expect( + findDefaultNullEquivalentValue({ + value: null, + fieldMetadataType: FieldMetadataType.ARRAY, + }), + ).toBe(DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE for empty array', () => { + expect( + findDefaultNullEquivalentValue({ + value: [], + fieldMetadataType: FieldMetadataType.ARRAY, + }), + ).toBe(DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE); + }); + }); + }); + + describe('ACTOR', () => { + it('should return text default for name', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.ACTOR, + key: 'name', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return undefined for context', () => { + expect( + findDefaultNullEquivalentValue({ + value: {}, + fieldMetadataType: FieldMetadataType.ACTOR, + key: 'context', + }), + ).toBe(undefined); + }); + }); + + describe('ADDRESS', () => { + it.each([ + 'addressStreet1', + 'addressStreet2', + 'addressCity', + 'addressState', + 'addressPostcode', + 'addressCountry', + ])('should return text default for %s', (key) => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.ADDRESS, + key, + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + }); + + describe('EMAILS', () => { + it('should return text default for primaryEmail', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.EMAILS, + key: 'primaryEmail', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return array default for additionalEmails', () => { + expect( + findDefaultNullEquivalentValue({ + value: [], + fieldMetadataType: FieldMetadataType.EMAILS, + key: 'additionalEmails', + }), + ).toBe(DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE); + }); + }); + + describe('LINKS', () => { + it('should return text default for primaryLinkUrl', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.LINKS, + key: 'primaryLinkUrl', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return text default for primaryLinkLabel', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.LINKS, + key: 'primaryLinkLabel', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + }); + + describe('PHONES', () => { + it('should return text default for primaryPhoneNumber', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.PHONES, + key: 'primaryPhoneNumber', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return text default for primaryPhoneCountryCode', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.PHONES, + key: 'primaryPhoneCountryCode', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + + it('should return text default for primaryPhoneCallingCode', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.PHONES, + key: 'primaryPhoneCallingCode', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + }); + + describe('RICH_TEXT_V2', () => { + it('should return undefined for blocknote', () => { + expect( + findDefaultNullEquivalentValue({ + value: {}, + fieldMetadataType: FieldMetadataType.RICH_TEXT_V2, + key: 'blocknote', + }), + ).toBe(undefined); + }); + + it('should return text default for markdown', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.RICH_TEXT_V2, + key: 'markdown', + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }); + }); + + describe('FULL_NAME', () => { + it.each(['firstName', 'lastName'])( + 'should return text default for %s', + (key) => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.FULL_NAME, + key, + }), + ).toBe(DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE); + }, + ); + }); +}); + +it('should return undefined for unknown type', () => { + expect( + findDefaultNullEquivalentValue({ + value: null, + fieldMetadataType: 'UNKNOWN' as any, + }), + ).toBeUndefined(); +}); + +it('should return undefined for unknown composite key', () => { + expect( + findDefaultNullEquivalentValue({ + value: '', + fieldMetadataType: FieldMetadataType.ACTOR, + key: 'unknown', + }), + ).toBeUndefined(); +}); diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts index 98ebd49cec6..743a659ec0b 100644 --- a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/evaluate-filter-conditions.util.ts @@ -10,9 +10,13 @@ import { ViewFilterOperand, type ViewFilterOperandDeprecated, } from 'twenty-shared/types'; -import { convertViewFilterOperandToCoreOperand as convertViewFilterOperandDeprecated } from 'twenty-shared/utils'; +import { + convertViewFilterOperandToCoreOperand as convertViewFilterOperandDeprecated, + isDefined, +} from 'twenty-shared/utils'; import { parseBooleanFromStringValue } from 'twenty-shared/workflow'; +import { findDefaultNullEquivalentValue } from 'src/modules/workflow/workflow-executor/workflow-actions/filter/utils/find-default-null-equivalent-value.util'; import { parseAndEvaluateRelativeDateFilter } from 'src/modules/workflow/workflow-executor/workflow-actions/filter/utils/parse-and-evaluate-relative-date-filter.util'; type ResolvedFilterWithPotentiallyDeprecatedOperand = Omit< @@ -59,7 +63,11 @@ function evaluateFilter( case 'ARRAY': case 'array': case 'RAW_JSON': - return evaluateTextAndArrayFilter(filterWithConvertedOperand); + return evaluateTextAndArrayFilter( + filterWithConvertedOperand, + filter.type, + filter.compositeFieldSubFieldName, + ); case 'SELECT': return evaluateSelectFilter(filterWithConvertedOperand); case 'BOOLEAN': @@ -146,12 +154,31 @@ function contains(leftValue: unknown, rightValue: unknown): boolean { return String(leftValue).includes(String(rightValue)); } -function evaluateTextAndArrayFilter(filter: ResolvedFilter): boolean { +function evaluateTextAndArrayFilter( + filter: ResolvedFilter, + filterType: string, + compositeFieldSubFieldName: string | undefined, +): boolean { + //TODO : nullEquivalentRightValue to remove once feature flag removed + workflow action based on common api + const nullEquivalentRightValue = findDefaultNullEquivalentValue({ + value: filter.rightOperand, + fieldMetadataType: filterType, + key: compositeFieldSubFieldName, + }); + switch (filter.operand) { case ViewFilterOperand.CONTAINS: - return contains(filter.leftOperand, filter.rightOperand); + return ( + contains(filter.leftOperand, filter.rightOperand) || + (isDefined(nullEquivalentRightValue) && + !isNotEmptyTextOrArray(filter.leftOperand)) + ); case ViewFilterOperand.DOES_NOT_CONTAIN: - return !contains(filter.leftOperand, filter.rightOperand); + return ( + !contains(filter.leftOperand, filter.rightOperand) || + (isDefined(nullEquivalentRightValue) && + isNotEmptyTextOrArray(filter.leftOperand)) + ); case ViewFilterOperand.IS_EMPTY: return !isNotEmptyTextOrArray(filter.leftOperand); diff --git a/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/find-default-null-equivalent-value.util.ts b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/find-default-null-equivalent-value.util.ts new file mode 100644 index 00000000000..6e51dc7fd86 --- /dev/null +++ b/packages/twenty-server/src/modules/workflow/workflow-executor/workflow-actions/filter/utils/find-default-null-equivalent-value.util.ts @@ -0,0 +1,151 @@ +import { FieldMetadataType } from 'twenty-shared/types'; + +import { + DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE, + DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE, +} from 'src/engine/api/common/common-args-processors/data-arg-processor/constants/null-equivalent-values.constant'; +import { isNullEquivalentArrayFieldValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/is-null-equivalent-array-field-value.util'; +import { isNullEquivalentTextFieldValue } from 'src/engine/api/common/common-args-processors/data-arg-processor/utils/is-null-equivalent-text-field-value.util'; + +export const findDefaultNullEquivalentValue = ({ + value, + fieldMetadataType, + key, +}: { + value: unknown; + fieldMetadataType: string; + key?: string; +}) => { + switch (fieldMetadataType) { + case FieldMetadataType.TEXT: + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case FieldMetadataType.MULTI_SELECT: + case FieldMetadataType.ARRAY: + return isNullEquivalentArrayFieldValue(value) + ? DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case FieldMetadataType.ACTOR: { + switch (key) { + case 'name': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + default: + return undefined; + } + } + case FieldMetadataType.ADDRESS: { + switch (key) { + case 'addressStreet1': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'addressStreet2': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'addressCity': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'addressState': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'addressPostcode': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'addressCountry': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + default: + return undefined; + } + } + case FieldMetadataType.EMAILS: { + switch (key) { + case 'primaryEmail': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'additionalEmails': + return isNullEquivalentArrayFieldValue(value) + ? DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + default: + return undefined; + } + } + case FieldMetadataType.LINKS: { + switch (key) { + case 'primaryLinkUrl': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'primaryLinkLabel': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'secondaryLinks': + return isNullEquivalentArrayFieldValue(value) + ? DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + + default: + return undefined; + } + } + case FieldMetadataType.PHONES: { + switch (key) { + case 'primaryPhoneNumber': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'primaryPhoneCountryCode': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'primaryPhoneCallingCode': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'additionalPhones': + return isNullEquivalentArrayFieldValue(value) + ? DEFAULT_ARRAY_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + default: + return undefined; + } + } + case FieldMetadataType.RICH_TEXT_V2: { + switch (key) { + case 'markdown': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + default: + return undefined; + } + } + case FieldMetadataType.FULL_NAME: { + switch (key) { + case 'firstName': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + case 'lastName': + return isNullEquivalentTextFieldValue(value) + ? DEFAULT_TEXT_FIELD_NULL_EQUIVALENT_VALUE + : undefined; + default: + return undefined; + } + } + } + + return undefined; +};