@zimbra/api-client 99.0.0 → 100.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc.json +1 -2
- package/dist/schema.graphql +10 -2
- package/dist/src/apollo/local-batch-link.d.ts +0 -1
- package/dist/src/apollo/offline-queue-link/index.d.ts +1 -4
- package/dist/src/batch-client/index.d.ts +4 -1
- package/dist/src/batch-client/types.d.ts +1 -1
- package/dist/src/normalize/entities.d.ts +1 -0
- package/dist/src/normalize/index.d.ts +1 -1
- package/dist/src/request/types.d.ts +0 -1
- package/dist/src/schema/generated-schema-types.d.ts +13 -2
- package/dist/src/utils/map-values-deep.d.ts +1 -0
- package/dist/zm-api-js-client.esm.js +210 -157
- package/dist/zm-api-js-client.esm.js.map +1 -1
- package/dist/zm-api-js-client.js +8 -8
- package/dist/zm-api-js-client.js.map +1 -1
- package/dist/zm-api-js-client.umd.js +8 -8
- package/dist/zm-api-js-client.umd.js.map +1 -1
- package/package-lock.json +339 -178
- package/package.json +3 -3
- package/rollup.config.js +1 -1
- package/src/apollo/offline-queue-link/util.ts +1 -2
- package/src/apollo/zimbra-error-link.ts +4 -3
- package/src/apollo/zimbra-in-memory-cache.ts +3 -3
- package/src/batch-client/index.ts +81 -47
- package/src/batch-client/types.ts +1 -1
- package/src/normalize/entities.ts +6 -1
- package/src/normalize/index.ts +42 -39
- package/src/request/index.ts +36 -48
- package/src/request/types.ts +0 -1
- package/src/schema/generated-schema-types.ts +15 -2
- package/src/schema/schema.graphql +10 -2
- package/src/schema/schema.ts +3 -2
- package/src/schema/session-handler.ts +1 -2
- package/src/utils/map-values-deep.ts +10 -2
- package/src/utils/normalize-attrs-custommetadata.ts +5 -6
- package/src/utils/normalize-otherAttribute-contact.ts +29 -19
package/src/request/types.ts
CHANGED
|
@@ -101,6 +101,7 @@ export type AccountInfoAttrs = {
|
|
|
101
101
|
zimbraFeatureBriefcasesEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
102
102
|
zimbraFeatureCalendarEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
103
103
|
zimbraFeatureChangePasswordEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
104
|
+
zimbraFeatureContactsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
104
105
|
zimbraFeatureConversationsEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
105
106
|
zimbraFeatureDeliveryStatusNotificationEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
106
107
|
zimbraFeatureDiscardInFiltersEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
@@ -1192,6 +1193,7 @@ export type CreateMountpointInput = {
|
|
|
1192
1193
|
export type CreateTagInput = {
|
|
1193
1194
|
color?: InputMaybe<Scalars['Int']['input']>;
|
|
1194
1195
|
name: Scalars['String']['input'];
|
|
1196
|
+
rgb?: InputMaybe<Scalars['String']['input']>;
|
|
1195
1197
|
};
|
|
1196
1198
|
|
|
1197
1199
|
export type CsrfToken = {
|
|
@@ -1716,7 +1718,7 @@ export type FilterCondition = {
|
|
|
1716
1718
|
__typename?: 'FilterCondition';
|
|
1717
1719
|
address?: Maybe<Array<Maybe<AddressCondition>>>;
|
|
1718
1720
|
addressBook?: Maybe<Array<Maybe<HeaderCheckCondition>>>;
|
|
1719
|
-
allOrAny
|
|
1721
|
+
allOrAny?: Maybe<FilterMatchCondition>;
|
|
1720
1722
|
attachment?: Maybe<Array<Maybe<BasicCondition>>>;
|
|
1721
1723
|
body?: Maybe<Array<Maybe<BodyCondition>>>;
|
|
1722
1724
|
bulk?: Maybe<Array<Maybe<BasicCondition>>>;
|
|
@@ -1860,6 +1862,7 @@ export type FolderActionInput = {
|
|
|
1860
1862
|
name?: InputMaybe<Scalars['String']['input']>;
|
|
1861
1863
|
op: Scalars['String']['input'];
|
|
1862
1864
|
retentionPolicy?: InputMaybe<Array<InputMaybe<RetentionPolicyInput>>>;
|
|
1865
|
+
rgb?: InputMaybe<Scalars['String']['input']>;
|
|
1863
1866
|
zimbraId?: InputMaybe<Scalars['ID']['input']>;
|
|
1864
1867
|
};
|
|
1865
1868
|
|
|
@@ -2425,6 +2428,7 @@ export type MailboxMetadataAttrs = {
|
|
|
2425
2428
|
zimbraPrefSMIMEDefaultSetting?: Maybe<Scalars['String']['output']>;
|
|
2426
2429
|
zimbraPrefSMIMELastOperation?: Maybe<Scalars['String']['output']>;
|
|
2427
2430
|
zimbraPrefSharedFolderTreeOpen?: Maybe<Scalars['Boolean']['output']>;
|
|
2431
|
+
zimbraPrefSidebarCollapsed?: Maybe<Scalars['Boolean']['output']>;
|
|
2428
2432
|
zimbraPrefSmartFolderTreeOpen?: Maybe<Scalars['Boolean']['output']>;
|
|
2429
2433
|
zimbraPrefTimeFormat?: Maybe<Scalars['String']['output']>;
|
|
2430
2434
|
zimbraPrefUndoSendEnabled?: Maybe<Scalars['Boolean']['output']>;
|
|
@@ -2458,6 +2462,7 @@ export type MailboxMetadataSectionAttrsInput = {
|
|
|
2458
2462
|
zimbraPrefSMIMEDefaultSetting?: InputMaybe<Scalars['String']['input']>;
|
|
2459
2463
|
zimbraPrefSMIMELastOperation?: InputMaybe<Scalars['String']['input']>;
|
|
2460
2464
|
zimbraPrefSharedFolderTreeOpen?: InputMaybe<Scalars['Boolean']['input']>;
|
|
2465
|
+
zimbraPrefSidebarCollapsed?: InputMaybe<Scalars['Boolean']['input']>;
|
|
2461
2466
|
zimbraPrefSmartFolderTreeOpen?: InputMaybe<Scalars['Boolean']['input']>;
|
|
2462
2467
|
zimbraPrefTimeFormat?: InputMaybe<Scalars['String']['input']>;
|
|
2463
2468
|
zimbraPrefUndoSendEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
|
@@ -2824,7 +2829,6 @@ export type MutationChangeFolderColorArgs = {
|
|
|
2824
2829
|
|
|
2825
2830
|
export type MutationChangePasswordArgs = {
|
|
2826
2831
|
authToken?: InputMaybe<Scalars['String']['input']>;
|
|
2827
|
-
csrfToken?: InputMaybe<Scalars['String']['input']>;
|
|
2828
2832
|
dryRun?: InputMaybe<Scalars['Boolean']['input']>;
|
|
2829
2833
|
loginNewPassword: Scalars['String']['input'];
|
|
2830
2834
|
password: Scalars['String']['input'];
|
|
@@ -3488,6 +3492,7 @@ export type Preferences = {
|
|
|
3488
3492
|
zimbraPrefDisplayExternalImages?: Maybe<Scalars['Boolean']['output']>;
|
|
3489
3493
|
zimbraPrefDisplayTimeInMailList?: Maybe<Scalars['Boolean']['output']>;
|
|
3490
3494
|
zimbraPrefExternalSendersType?: Maybe<ExternalSendersType>;
|
|
3495
|
+
zimbraPrefFolderTreeOpen?: Maybe<Scalars['Boolean']['output']>;
|
|
3491
3496
|
zimbraPrefForwardReplyInOriginalFormat?: Maybe<Scalars['Boolean']['output']>;
|
|
3492
3497
|
zimbraPrefGroupMailBy?: Maybe<Scalars['String']['output']>;
|
|
3493
3498
|
zimbraPrefHtmlEditorDefaultFontColor?: Maybe<Scalars['String']['output']>;
|
|
@@ -3559,6 +3564,7 @@ export type PreferencesInput = {
|
|
|
3559
3564
|
zimbraPrefDisplayExternalImages?: InputMaybe<Scalars['Boolean']['input']>;
|
|
3560
3565
|
zimbraPrefDisplayTimeInMailList?: InputMaybe<Scalars['Boolean']['input']>;
|
|
3561
3566
|
zimbraPrefExternalSendersType?: InputMaybe<ExternalSendersType>;
|
|
3567
|
+
zimbraPrefFolderTreeOpen?: InputMaybe<Scalars['Boolean']['input']>;
|
|
3562
3568
|
zimbraPrefForwardReplyInOriginalFormat?: InputMaybe<Scalars['Boolean']['input']>;
|
|
3563
3569
|
zimbraPrefGroupMailBy?: InputMaybe<Scalars['String']['input']>;
|
|
3564
3570
|
zimbraPrefHtmlEditorDefaultFontColor?: InputMaybe<Scalars['String']['input']>;
|
|
@@ -3664,6 +3670,7 @@ export type Query = {
|
|
|
3664
3670
|
getHAB?: Maybe<HabGroup>;
|
|
3665
3671
|
getIdentities?: Maybe<Identities>;
|
|
3666
3672
|
getImportStatus?: Maybe<ImportStatusResponse>;
|
|
3673
|
+
getItem?: Maybe<Document>;
|
|
3667
3674
|
getMailboxMetadata?: Maybe<MailboxMetadata>;
|
|
3668
3675
|
getMessage?: Maybe<MessageInfo>;
|
|
3669
3676
|
getMessagesMetadata?: Maybe<Array<Maybe<MessageInfo>>>;
|
|
@@ -3836,6 +3843,11 @@ export type QueryGetHabArgs = {
|
|
|
3836
3843
|
};
|
|
3837
3844
|
|
|
3838
3845
|
|
|
3846
|
+
export type QueryGetItemArgs = {
|
|
3847
|
+
id: Scalars['ID']['input'];
|
|
3848
|
+
};
|
|
3849
|
+
|
|
3850
|
+
|
|
3839
3851
|
export type QueryGetMailboxMetadataArgs = {
|
|
3840
3852
|
section?: InputMaybe<Scalars['String']['input']>;
|
|
3841
3853
|
};
|
|
@@ -4172,6 +4184,7 @@ export enum SaveDocumentAction {
|
|
|
4172
4184
|
|
|
4173
4185
|
export type SaveDocumentInput = {
|
|
4174
4186
|
action?: InputMaybe<SaveDocumentAction>;
|
|
4187
|
+
content?: InputMaybe<Scalars['String']['input']>;
|
|
4175
4188
|
contentType?: InputMaybe<Scalars['String']['input']>;
|
|
4176
4189
|
descriptionEnabled?: InputMaybe<Scalars['Boolean']['input']>;
|
|
4177
4190
|
document?: InputMaybe<SaveDocumentInput>;
|
|
@@ -1078,7 +1078,7 @@ type SizeCondition {
|
|
|
1078
1078
|
}
|
|
1079
1079
|
|
|
1080
1080
|
type FilterCondition {
|
|
1081
|
-
allOrAny: FilterMatchCondition
|
|
1081
|
+
allOrAny: FilterMatchCondition # condition
|
|
1082
1082
|
addressBook: [HeaderCheckCondition] # addressBookTest
|
|
1083
1083
|
address: [AddressCondition] # addressTest
|
|
1084
1084
|
attachment: [BasicCondition] # attachmentTest
|
|
@@ -1561,6 +1561,7 @@ type AccountInfoAttrs {
|
|
|
1561
1561
|
zimbraFeatureDeliveryStatusNotificationEnabled: Boolean
|
|
1562
1562
|
zimbraPop3Enabled: Boolean
|
|
1563
1563
|
zimbraFeatureOptionsEnabled: Boolean
|
|
1564
|
+
zimbraFeatureContactsEnabled: Boolean
|
|
1564
1565
|
}
|
|
1565
1566
|
|
|
1566
1567
|
type AccountCos {
|
|
@@ -1707,6 +1708,7 @@ type Preferences {
|
|
|
1707
1708
|
zimbraPrefUseTimeZoneListInCalendar: Boolean
|
|
1708
1709
|
zimbraPrefMailForwardingAddress: String
|
|
1709
1710
|
zimbraPrefMailLocalDeliveryDisabled: Boolean
|
|
1711
|
+
zimbraPrefFolderTreeOpen: Boolean
|
|
1710
1712
|
zimbraPrefTagTreeOpen: Boolean
|
|
1711
1713
|
zimbraPrefPowerPasteEnabled: Boolean
|
|
1712
1714
|
zimbraPrefDisplayTimeInMailList: Boolean
|
|
@@ -2151,6 +2153,7 @@ type MailboxMetadataAttrs {
|
|
|
2151
2153
|
zimbraPrefContactSourceFolderID: String
|
|
2152
2154
|
zimbraPrefHideMuteConvModal: Boolean
|
|
2153
2155
|
zimbraPrefColorMode: String
|
|
2156
|
+
zimbraPrefSidebarCollapsed: Boolean
|
|
2154
2157
|
}
|
|
2155
2158
|
|
|
2156
2159
|
type MailboxMetadataMeta {
|
|
@@ -2187,6 +2190,7 @@ input MailboxMetadataSectionAttrsInput {
|
|
|
2187
2190
|
zimbraPrefContactSourceFolderID: String
|
|
2188
2191
|
zimbraPrefHideMuteConvModal: Boolean
|
|
2189
2192
|
zimbraPrefColorMode: String
|
|
2193
|
+
zimbraPrefSidebarCollapsed: Boolean
|
|
2190
2194
|
}
|
|
2191
2195
|
|
|
2192
2196
|
type MimePart {
|
|
@@ -2639,6 +2643,7 @@ input FolderActionInput {
|
|
|
2639
2643
|
folderId: ID
|
|
2640
2644
|
zimbraId: ID
|
|
2641
2645
|
color: Int,
|
|
2646
|
+
rgb: String,
|
|
2642
2647
|
retentionPolicy: [RetentionPolicyInput]
|
|
2643
2648
|
}
|
|
2644
2649
|
|
|
@@ -2659,6 +2664,7 @@ input PolicyAttrsInput {
|
|
|
2659
2664
|
input CreateTagInput {
|
|
2660
2665
|
name: String!
|
|
2661
2666
|
color: Int
|
|
2667
|
+
rgb: String
|
|
2662
2668
|
}
|
|
2663
2669
|
|
|
2664
2670
|
# Special case of FolderAction for `changeFolderColor` resolver
|
|
@@ -2791,6 +2797,7 @@ input PreferencesInput {
|
|
|
2791
2797
|
zimbraPrefUseTimeZoneListInCalendar: Boolean
|
|
2792
2798
|
zimbraPrefMailForwardingAddress: String
|
|
2793
2799
|
zimbraPrefMailLocalDeliveryDisabled: Boolean
|
|
2800
|
+
zimbraPrefFolderTreeOpen: Boolean
|
|
2794
2801
|
zimbraPrefTagTreeOpen: Boolean
|
|
2795
2802
|
zimbraPrefPowerPasteEnabled: Boolean
|
|
2796
2803
|
zimbraPrefDisplayTimeInMailList: Boolean
|
|
@@ -3270,6 +3277,7 @@ input SaveDocumentInput {
|
|
|
3270
3277
|
name: String #name
|
|
3271
3278
|
version: Float #ver # Note :same item may have different versions (i.e same names) will need to implement ListDocumentRevisionsRequest
|
|
3272
3279
|
contentType: String #ct
|
|
3280
|
+
content: String
|
|
3273
3281
|
upload: uploadDocument #upload with a id
|
|
3274
3282
|
messageData: [messagePartForDocument] #m
|
|
3275
3283
|
descriptionEnabled: Boolean #descEnabled
|
|
@@ -3533,6 +3541,7 @@ type Query {
|
|
|
3533
3541
|
downloadAttachment(id: ID!, part: ID!): Attachment
|
|
3534
3542
|
downloadDocument(id: ID!, url: String!): Attachment
|
|
3535
3543
|
listDocumentRevisions(id: ID!, version: Int!, count: Int!): Document
|
|
3544
|
+
getItem(id: ID!): Document
|
|
3536
3545
|
discoverRights(right: [DiscoverRightInput!]!): DiscoverRights
|
|
3537
3546
|
freeBusy(names: [String!]!, start: Float, end: Float, excludeUid: String): [FreeBusy]
|
|
3538
3547
|
getContact(
|
|
@@ -3736,7 +3745,6 @@ type Mutation {
|
|
|
3736
3745
|
password: String!
|
|
3737
3746
|
username: String!
|
|
3738
3747
|
authToken: String
|
|
3739
|
-
csrfToken: String
|
|
3740
3748
|
): AuthResponse
|
|
3741
3749
|
modifyProfileImage(
|
|
3742
3750
|
content: String
|
package/src/schema/schema.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { makeExecutableSchema } from '@graphql-tools/schema';
|
|
2
|
-
import mapValues from '
|
|
2
|
+
import { mapValues } from 'es-toolkit';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
5
|
ActionOpResponse,
|
|
@@ -113,6 +113,7 @@ export function createZimbraSchema(options: ZimbraSchemaOptions): {
|
|
|
113
113
|
downloadAttachment: (_, variables) => client.downloadAttachment(variables),
|
|
114
114
|
downloadDocument: (_, variables) => client.downloadDocument(variables),
|
|
115
115
|
listDocumentRevisions: (_, variables) => client.listDocumentRevisions(variables),
|
|
116
|
+
getItem: (_, variables) => client.getItem(variables),
|
|
116
117
|
downloadMessage: (_, variables, context = {}) => {
|
|
117
118
|
const { local } = context;
|
|
118
119
|
|
|
@@ -414,7 +415,7 @@ export function createZimbraSchema(options: ZimbraSchemaOptions): {
|
|
|
414
415
|
body: {
|
|
415
416
|
meta: {
|
|
416
417
|
section: variables.section,
|
|
417
|
-
_attrs: mapValues(variables.attrs, coerceBooleanToString)
|
|
418
|
+
_attrs: mapValues(variables.attrs || {}, coerceBooleanToString)
|
|
418
419
|
}
|
|
419
420
|
}
|
|
420
421
|
})
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { gql } from '@apollo/client/core';
|
|
2
|
-
import get from 'lodash/get';
|
|
3
2
|
import { ZimbraInMemoryCache } from '../apollo/zimbra-in-memory-cache';
|
|
4
3
|
import { ZimbraSessionOptions } from './types';
|
|
5
4
|
|
|
@@ -22,7 +21,7 @@ export class SessionHandler {
|
|
|
22
21
|
id: this.cacheKeyForSession,
|
|
23
22
|
fragment: SESSION_GQL_FRAGMENT
|
|
24
23
|
});
|
|
25
|
-
return
|
|
24
|
+
return sessionIdFragment?.id || '1';
|
|
26
25
|
};
|
|
27
26
|
|
|
28
27
|
public writeSessionId = (sessionId: string) => {
|
|
@@ -1,10 +1,18 @@
|
|
|
1
|
-
import mapValues from '
|
|
1
|
+
import { mapValues } from 'es-toolkit';
|
|
2
2
|
|
|
3
3
|
export function mapValuesDeep(obj: {}, callback: (v: any) => any): {} {
|
|
4
|
-
if (typeof obj !== 'object') {
|
|
4
|
+
if (obj === null || typeof obj !== 'object') {
|
|
5
5
|
return callback(obj);
|
|
6
6
|
} else if (Array.isArray(obj)) {
|
|
7
7
|
return obj.map(v => mapValuesDeep(v, callback));
|
|
8
8
|
}
|
|
9
9
|
return mapValues(obj, v => mapValuesDeep(v, callback));
|
|
10
10
|
}
|
|
11
|
+
|
|
12
|
+
export function getValueByPath(obj: any, path: string): any {
|
|
13
|
+
if (!path) return undefined;
|
|
14
|
+
|
|
15
|
+
return path
|
|
16
|
+
.split('.')
|
|
17
|
+
.reduce((acc, key) => (acc && typeof acc === 'object' ? acc[key] : undefined), obj);
|
|
18
|
+
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import forEach from 'lodash/forEach';
|
|
2
|
-
|
|
3
1
|
export function setCustomMetaDataBody(data: any) {
|
|
4
2
|
const { attrs, id, section } = data;
|
|
5
|
-
const customMetaAttrs
|
|
3
|
+
const customMetaAttrs: Object[] = [];
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
for (const { key, value } of attrs) {
|
|
8
6
|
customMetaAttrs.push({
|
|
9
7
|
[key]: value
|
|
10
|
-
})
|
|
11
|
-
|
|
8
|
+
});
|
|
9
|
+
}
|
|
10
|
+
|
|
12
11
|
return {
|
|
13
12
|
id,
|
|
14
13
|
meta: {
|
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import differenceBy from 'lodash/differenceBy';
|
|
3
|
-
import forEach from 'lodash/forEach';
|
|
1
|
+
import { differenceBy } from 'es-toolkit';
|
|
4
2
|
import { denormalize } from '../normalize';
|
|
5
3
|
import { ContactInputRequest } from '../normalize/entities';
|
|
6
4
|
|
|
@@ -102,19 +100,29 @@ export function createContactBody(data: any, isDesktop: Boolean) {
|
|
|
102
100
|
const { attributes, ...rest } = data;
|
|
103
101
|
const contactAttrs = <Object[]>[];
|
|
104
102
|
|
|
105
|
-
|
|
106
|
-
key !== 'other'
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
103
|
+
for (const [key, val] of Object.entries(attributes)) {
|
|
104
|
+
if (key !== 'other') {
|
|
105
|
+
contactAttrs.push({
|
|
106
|
+
name: key,
|
|
107
|
+
[key === 'image' || (!isDesktop && key === 'userCertificate') ? 'aid' : 'content']: val
|
|
108
|
+
});
|
|
109
|
+
} else if (Array.isArray(val)) {
|
|
110
|
+
for (const otherValue of val) {
|
|
111
|
+
if (
|
|
112
|
+
typeof otherValue === 'object' &&
|
|
113
|
+
otherValue !== null &&
|
|
114
|
+
'key' in otherValue &&
|
|
115
|
+
'value' in otherValue
|
|
116
|
+
) {
|
|
117
|
+
const { key: otherKey, value: otherVal } = otherValue as { key: string; value: unknown };
|
|
112
118
|
contactAttrs.push({
|
|
113
|
-
name:
|
|
114
|
-
_content:
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
|
|
119
|
+
name: otherKey,
|
|
120
|
+
_content: otherVal
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
118
126
|
return {
|
|
119
127
|
cn: denormalize(ContactInputRequest)({
|
|
120
128
|
...rest,
|
|
@@ -162,15 +170,17 @@ export function normalizeOtherAttr(data: any) {
|
|
|
162
170
|
(a: any, b: any) => Number(a.key.match(/(\d+)/g)[0]) - Number(b.key.match(/(\d+)/g)[0])
|
|
163
171
|
);
|
|
164
172
|
|
|
165
|
-
const remainingOtherAttribute = differenceBy(
|
|
166
|
-
|
|
167
|
-
|
|
173
|
+
const remainingOtherAttribute = differenceBy(
|
|
174
|
+
other || [],
|
|
175
|
+
otherAttributewithCustomKey || [],
|
|
176
|
+
(item: any) => item.key
|
|
177
|
+
).sort((a: any, b: any) => a.key.localeCompare(b.key));
|
|
168
178
|
|
|
169
179
|
return {
|
|
170
180
|
...contact,
|
|
171
181
|
_attrs: {
|
|
172
182
|
...contact._attrs,
|
|
173
|
-
other:
|
|
183
|
+
other: (otherAttributewithCustomKey || []).concat(remainingOtherAttribute || [])
|
|
174
184
|
}
|
|
175
185
|
};
|
|
176
186
|
});
|