@zimbra/api-client 99.0.0 → 100.0.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 +201 -153
- 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 +72 -42
- 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/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zimbra/api-client",
|
|
3
3
|
"amdName": "zmApiJsClient",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "100.0.0",
|
|
5
5
|
"description": "Zimbra JS API Client and GraphQL client for making requests against the Zimbra SOAP API.",
|
|
6
6
|
"main": "dist/zm-api-js-client.js",
|
|
7
7
|
"source": "index.ts",
|
|
@@ -47,11 +47,11 @@
|
|
|
47
47
|
]
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
-
"@apollo/client": "3.
|
|
50
|
+
"@apollo/client": "^3.14.0",
|
|
51
51
|
"@graphql-tools/schema": "^10.0.25",
|
|
52
52
|
"dataloader": "^2.2.2",
|
|
53
|
+
"es-toolkit": "^1.39.10",
|
|
53
54
|
"graphql": "^16.9.0",
|
|
54
|
-
"lodash": "^4.17.21",
|
|
55
55
|
"mitt": "^3.0.0"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
package/rollup.config.js
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { Operation } from '@apollo/client/core';
|
|
2
|
-
import get from 'lodash/get';
|
|
3
2
|
import { OfflineOperationEntry, OperationEntry } from './types';
|
|
4
3
|
|
|
5
4
|
export function hasSensitiveVariables(operation: Operation) {
|
|
6
|
-
return !!
|
|
5
|
+
return !!operation?.variables?.password;
|
|
7
6
|
}
|
|
8
7
|
|
|
9
8
|
export function isMutationOperation({ query }: Operation) {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ErrorLink } from '@apollo/client/link/error';
|
|
2
|
-
import get from 'lodash/get';
|
|
3
2
|
|
|
4
3
|
class ZimbraErrorLink extends ErrorLink {
|
|
5
4
|
handlers: any[] = [];
|
|
@@ -7,8 +6,10 @@ class ZimbraErrorLink extends ErrorLink {
|
|
|
7
6
|
constructor() {
|
|
8
7
|
super(({ graphQLErrors, networkError }) => {
|
|
9
8
|
graphQLErrors &&
|
|
10
|
-
graphQLErrors.map((
|
|
11
|
-
|
|
9
|
+
graphQLErrors.map((error: any) => {
|
|
10
|
+
const { message, ...rest } = error;
|
|
11
|
+
const originalError = error.originalError;
|
|
12
|
+
const errorCode = (originalError as any)?.faults?.[0]?.Detail?.Error?.Code || '';
|
|
12
13
|
|
|
13
14
|
this.executeHandlers({
|
|
14
15
|
errorCode,
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { FieldFunctionOptions } from '@apollo/client';
|
|
2
2
|
import { defaultDataIdFromObject, InMemoryCache, InMemoryCacheConfig } from '@apollo/client/core';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import { uniqWith } from 'es-toolkit';
|
|
4
|
+
import { getValueByPath } from '../utils/map-values-deep';
|
|
5
5
|
import { EmailAddress } from './types';
|
|
6
6
|
|
|
7
7
|
const dataIdFromPath = (result: any, path: string) => {
|
|
8
8
|
if (result.__typename) {
|
|
9
|
-
const id =
|
|
9
|
+
const id = getValueByPath(result, path);
|
|
10
10
|
return id ? `${result.__typename}:${id}` : defaultDataIdFromObject(result);
|
|
11
11
|
}
|
|
12
12
|
};
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import DataLoader from 'dataloader';
|
|
2
|
-
import
|
|
3
|
-
import get from 'lodash/get';
|
|
4
|
-
import isError from 'lodash/isError';
|
|
5
|
-
import mapValues from 'lodash/mapValues';
|
|
2
|
+
import { mapValues } from 'es-toolkit';
|
|
6
3
|
import { denormalize, normalize } from '../normalize';
|
|
7
4
|
import {
|
|
8
5
|
AccountRights,
|
|
@@ -35,6 +32,7 @@ import {
|
|
|
35
32
|
GetDocumentShareURLEntity,
|
|
36
33
|
GetDocumentShareURLResponseEntity,
|
|
37
34
|
GetFolderRequest as GetFolderRequestEntity,
|
|
35
|
+
GetItem,
|
|
38
36
|
GetRightsRequest,
|
|
39
37
|
HabGroup,
|
|
40
38
|
InviteReply,
|
|
@@ -75,6 +73,7 @@ import {
|
|
|
75
73
|
ExternalAccountImportInput,
|
|
76
74
|
ExternalAccountTestInput,
|
|
77
75
|
FilterInput,
|
|
76
|
+
FilterMatchCondition,
|
|
78
77
|
FolderActionChangeColorInput,
|
|
79
78
|
FolderActionCheckCalendarInput,
|
|
80
79
|
FolderView,
|
|
@@ -186,7 +185,7 @@ function normalizeMessage(
|
|
|
186
185
|
}
|
|
187
186
|
|
|
188
187
|
const hasUnreadDescendent = (folder: any): any => {
|
|
189
|
-
const unreadDescendent =
|
|
188
|
+
const unreadDescendent = folder?.unreadDescendent;
|
|
190
189
|
|
|
191
190
|
if (
|
|
192
191
|
folder[
|
|
@@ -199,7 +198,7 @@ const hasUnreadDescendent = (folder: any): any => {
|
|
|
199
198
|
return true;
|
|
200
199
|
}
|
|
201
200
|
|
|
202
|
-
const folderArray =
|
|
201
|
+
const folderArray = folder?.folders || [];
|
|
203
202
|
for (let i = 0, len = folderArray.length; i < len; i++) {
|
|
204
203
|
return hasUnreadDescendent(folderArray[i]);
|
|
205
204
|
}
|
|
@@ -209,7 +208,7 @@ const hasUnreadDescendent = (folder: any): any => {
|
|
|
209
208
|
|
|
210
209
|
const updateGroupName = (habGroup: any) => ({
|
|
211
210
|
...habGroup,
|
|
212
|
-
name:
|
|
211
|
+
name: habGroup?.attributes?.displayName
|
|
213
212
|
});
|
|
214
213
|
|
|
215
214
|
const updateGroupNameRecur = (habGroups: any) =>
|
|
@@ -220,8 +219,8 @@ const updateGroupNameRecur = (habGroups: any) =>
|
|
|
220
219
|
});
|
|
221
220
|
|
|
222
221
|
const setUnreadDescendentFlag = (folder: any) => {
|
|
223
|
-
const folderArray =
|
|
224
|
-
const view =
|
|
222
|
+
const folderArray = folder?.folders || [];
|
|
223
|
+
const view = folder?.view;
|
|
225
224
|
|
|
226
225
|
// setting this flag only in message view has we dont want to show unread count in
|
|
227
226
|
// other views
|
|
@@ -406,7 +405,7 @@ export class ZimbraBatchClient {
|
|
|
406
405
|
[<string>accountType]: mapValuesDeep(accountInfo, coerceBooleanToString)
|
|
407
406
|
},
|
|
408
407
|
singleRequest: true
|
|
409
|
-
}).then(res =>
|
|
408
|
+
}).then(res => res?.[<string>accountType]?.[0]?.id);
|
|
410
409
|
|
|
411
410
|
public addMessage = (message: AddMsgInput) => {
|
|
412
411
|
const { folderId, content, meta } = message;
|
|
@@ -457,7 +456,7 @@ export class ZimbraBatchClient {
|
|
|
457
456
|
}
|
|
458
457
|
}
|
|
459
458
|
}).then(res => {
|
|
460
|
-
const ids =
|
|
459
|
+
const ids = res?.m?.[0]?.ids;
|
|
461
460
|
return ids ? ids.split(',') : [];
|
|
462
461
|
});
|
|
463
462
|
|
|
@@ -532,8 +531,7 @@ export class ZimbraBatchClient {
|
|
|
532
531
|
password,
|
|
533
532
|
username,
|
|
534
533
|
dryRun = false,
|
|
535
|
-
authToken
|
|
536
|
-
csrfToken
|
|
534
|
+
authToken
|
|
537
535
|
}: ChangePasswordOptions) => {
|
|
538
536
|
if (authToken) {
|
|
539
537
|
return this.jsonRequest({
|
|
@@ -547,8 +545,7 @@ export class ZimbraBatchClient {
|
|
|
547
545
|
oldPassword: password,
|
|
548
546
|
password: loginNewPassword,
|
|
549
547
|
dryRun,
|
|
550
|
-
authToken: { _content: authToken }
|
|
551
|
-
csrfToken: { _content: csrfToken }
|
|
548
|
+
authToken: { _content: authToken }
|
|
552
549
|
},
|
|
553
550
|
singleRequest: true
|
|
554
551
|
});
|
|
@@ -676,13 +673,11 @@ export class ZimbraBatchClient {
|
|
|
676
673
|
identity: {
|
|
677
674
|
...rest,
|
|
678
675
|
_attrs: {
|
|
679
|
-
...mapValues(attrs, coerceBooleanToString),
|
|
676
|
+
...mapValues(attrs || {}, coerceBooleanToString),
|
|
680
677
|
zimbraPrefWhenSentToAddresses: convertStringAndArrayValues(
|
|
681
|
-
|
|
678
|
+
attrs?.zimbraPrefWhenSentToAddresses
|
|
682
679
|
),
|
|
683
|
-
zimbraPrefWhenInFolderIds: convertStringAndArrayValues(
|
|
684
|
-
get(attrs, 'zimbraPrefWhenInFolderIds')
|
|
685
|
-
)
|
|
680
|
+
zimbraPrefWhenInFolderIds: convertStringAndArrayValues(attrs?.zimbraPrefWhenInFolderIds)
|
|
686
681
|
}
|
|
687
682
|
}
|
|
688
683
|
},
|
|
@@ -692,7 +687,7 @@ export class ZimbraBatchClient {
|
|
|
692
687
|
const {
|
|
693
688
|
_attrs: { zimbraPrefWhenSentToAddresses, zimbraPrefWhenInFolderIds, ...restAttr },
|
|
694
689
|
...restIdentityProps
|
|
695
|
-
} =
|
|
690
|
+
} = mappedResult?.identity?.[0];
|
|
696
691
|
|
|
697
692
|
return {
|
|
698
693
|
...mappedResult,
|
|
@@ -942,7 +937,6 @@ export class ZimbraBatchClient {
|
|
|
942
937
|
Header: {
|
|
943
938
|
context: {
|
|
944
939
|
_jsns: Namespace.All,
|
|
945
|
-
csrfToken: this.csrfToken,
|
|
946
940
|
account: {
|
|
947
941
|
by: 'name',
|
|
948
942
|
_content: options.accountName
|
|
@@ -1074,7 +1068,7 @@ export class ZimbraBatchClient {
|
|
|
1074
1068
|
this.jsonRequest({
|
|
1075
1069
|
name: 'GetConv',
|
|
1076
1070
|
body: {
|
|
1077
|
-
c: mapValues(options, coerceBooleanToInt)
|
|
1071
|
+
c: mapValues(options || {}, coerceBooleanToInt)
|
|
1078
1072
|
}
|
|
1079
1073
|
}).then(res => {
|
|
1080
1074
|
const conversation = this.normalizeConversation(res.c[0]);
|
|
@@ -1115,7 +1109,7 @@ export class ZimbraBatchClient {
|
|
|
1115
1109
|
this.jsonRequest({
|
|
1116
1110
|
name: 'GetDeviceStatus',
|
|
1117
1111
|
namespace: Namespace.Sync
|
|
1118
|
-
}).then(res =>
|
|
1112
|
+
}).then(res => res?.device || []);
|
|
1119
1113
|
|
|
1120
1114
|
public getDistributionList = (dl: String, needOwners: Boolean, needRights: String, by: String) =>
|
|
1121
1115
|
this.jsonRequest({
|
|
@@ -1166,7 +1160,24 @@ export class ZimbraBatchClient {
|
|
|
1166
1160
|
public getFilterRules = () =>
|
|
1167
1161
|
this.jsonRequest({
|
|
1168
1162
|
name: 'GetFilterRules'
|
|
1169
|
-
}).then(res =>
|
|
1163
|
+
}).then(res => {
|
|
1164
|
+
const filterRules = res?.filterRules?.[0]?.filterRule || [];
|
|
1165
|
+
|
|
1166
|
+
// Set default condition to anyof in case of null or undefined :: Classic UI approach
|
|
1167
|
+
for (let i = 0; i < filterRules.length; i++) {
|
|
1168
|
+
const rule = filterRules[i];
|
|
1169
|
+
if (rule?.filterTests && Array.isArray(rule.filterTests)) {
|
|
1170
|
+
for (let j = 0; j < rule.filterTests.length; j++) {
|
|
1171
|
+
const test = rule?.filterTests[j];
|
|
1172
|
+
if (test?.condition === null || test?.condition === undefined) {
|
|
1173
|
+
test.condition = FilterMatchCondition.Anyof;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
return normalize(Filter)(filterRules);
|
|
1180
|
+
});
|
|
1170
1181
|
|
|
1171
1182
|
public getFolder = (options: GetFolderOptions) => {
|
|
1172
1183
|
return this.jsonRequest({
|
|
@@ -1174,7 +1185,7 @@ export class ZimbraBatchClient {
|
|
|
1174
1185
|
body: denormalize(GetFolderRequestEntity)(options)
|
|
1175
1186
|
}).then(res => {
|
|
1176
1187
|
const foldersResponse = normalize(Folder)(res);
|
|
1177
|
-
const folders =
|
|
1188
|
+
const folders = foldersResponse?.folders?.[0] || {};
|
|
1178
1189
|
|
|
1179
1190
|
if (folders.folders) {
|
|
1180
1191
|
folders.folders = folders.folders.map(setUnreadDescendentFlag);
|
|
@@ -1239,7 +1250,7 @@ export class ZimbraBatchClient {
|
|
|
1239
1250
|
},
|
|
1240
1251
|
namespace: Namespace.Account
|
|
1241
1252
|
}).then(res => {
|
|
1242
|
-
const habGroups =
|
|
1253
|
+
const habGroups = res?.ou?.[0] || {};
|
|
1243
1254
|
return {
|
|
1244
1255
|
...habGroups,
|
|
1245
1256
|
habGroups: [...updateGroupNameRecur(habGroups.habGroup)]
|
|
@@ -1281,6 +1292,22 @@ export class ZimbraBatchClient {
|
|
|
1281
1292
|
name: 'GetImportStatus'
|
|
1282
1293
|
});
|
|
1283
1294
|
|
|
1295
|
+
public getItem = ({ id }: any) =>
|
|
1296
|
+
this.jsonRequest({
|
|
1297
|
+
name: 'GetItem',
|
|
1298
|
+
namespace: Namespace.Mail,
|
|
1299
|
+
body: {
|
|
1300
|
+
item: {
|
|
1301
|
+
id
|
|
1302
|
+
}
|
|
1303
|
+
}
|
|
1304
|
+
}).then(response => {
|
|
1305
|
+
const data = normalize(GetItem)(response);
|
|
1306
|
+
return {
|
|
1307
|
+
docs: data.documents
|
|
1308
|
+
};
|
|
1309
|
+
});
|
|
1310
|
+
|
|
1284
1311
|
public getMailboxMetadata = ({ section }: GetMailboxMetadataOptions) =>
|
|
1285
1312
|
this.jsonRequest({
|
|
1286
1313
|
name: 'GetMailboxMetadata',
|
|
@@ -1346,7 +1373,12 @@ export class ZimbraBatchClient {
|
|
|
1346
1373
|
|
|
1347
1374
|
for (const pref in prefs) {
|
|
1348
1375
|
if (CASTING_PREFS.indexOf(pref) !== -1) {
|
|
1349
|
-
prefs[pref] =
|
|
1376
|
+
prefs[pref] =
|
|
1377
|
+
typeof prefs[pref] === 'string'
|
|
1378
|
+
? prefs[pref] !== undefined
|
|
1379
|
+
? [prefs[pref]]
|
|
1380
|
+
: []
|
|
1381
|
+
: prefs[pref];
|
|
1350
1382
|
}
|
|
1351
1383
|
}
|
|
1352
1384
|
return prefs;
|
|
@@ -1607,13 +1639,11 @@ export class ZimbraBatchClient {
|
|
|
1607
1639
|
identity: {
|
|
1608
1640
|
...rest,
|
|
1609
1641
|
_attrs: {
|
|
1610
|
-
...mapValues(attrs, coerceBooleanToString),
|
|
1642
|
+
...mapValues(attrs || {}, coerceBooleanToString),
|
|
1611
1643
|
zimbraPrefWhenSentToAddresses: convertStringAndArrayValues(
|
|
1612
|
-
|
|
1644
|
+
attrs?.zimbraPrefWhenSentToAddresses
|
|
1613
1645
|
),
|
|
1614
|
-
zimbraPrefWhenInFolderIds: convertStringAndArrayValues(
|
|
1615
|
-
get(attrs, 'zimbraPrefWhenInFolderIds')
|
|
1616
|
-
)
|
|
1646
|
+
zimbraPrefWhenInFolderIds: convertStringAndArrayValues(attrs?.zimbraPrefWhenInFolderIds)
|
|
1617
1647
|
}
|
|
1618
1648
|
}
|
|
1619
1649
|
},
|
|
@@ -2037,7 +2067,7 @@ export class ZimbraBatchClient {
|
|
|
2037
2067
|
[<string>accountType]: mapValuesDeep(accountInfo, coerceBooleanToString)
|
|
2038
2068
|
},
|
|
2039
2069
|
singleRequest: true
|
|
2040
|
-
}).then(res => mapValuesDeep(
|
|
2070
|
+
}).then(res => mapValuesDeep(res?.[<string>accountType]?.[0], coerceStringToBoolean));
|
|
2041
2071
|
|
|
2042
2072
|
public uploadMessage = (message: string): any => {
|
|
2043
2073
|
const contentDisposition = 'attachment';
|
|
@@ -2086,9 +2116,9 @@ export class ZimbraBatchClient {
|
|
|
2086
2116
|
requests,
|
|
2087
2117
|
...this.getAdditionalRequestOptions()
|
|
2088
2118
|
}).then(response => {
|
|
2089
|
-
const sessionId =
|
|
2090
|
-
const notifications =
|
|
2091
|
-
const refresh =
|
|
2119
|
+
const sessionId = response?.header?.context?.session?.id;
|
|
2120
|
+
const notifications = response?.header?.context?.notify?.[0];
|
|
2121
|
+
const refresh = response?.header?.context?.refresh;
|
|
2092
2122
|
|
|
2093
2123
|
this.checkAndUpdateSessionId(sessionId);
|
|
2094
2124
|
|
|
@@ -2106,7 +2136,7 @@ export class ZimbraBatchClient {
|
|
|
2106
2136
|
if (DEBUG) {
|
|
2107
2137
|
console.log(`[Batch Client Request] ${requests[i].name}`, requests[i].body, r);
|
|
2108
2138
|
}
|
|
2109
|
-
return
|
|
2139
|
+
return r instanceof Error ? r : r.body;
|
|
2110
2140
|
});
|
|
2111
2141
|
});
|
|
2112
2142
|
|
|
@@ -2124,9 +2154,9 @@ export class ZimbraBatchClient {
|
|
|
2124
2154
|
// check if login request then don't add csrfToken
|
|
2125
2155
|
...this.getAdditionalRequestOptions(requests[0].name !== 'Auth')
|
|
2126
2156
|
}).then(response => {
|
|
2127
|
-
const sessionId =
|
|
2128
|
-
const notifications =
|
|
2129
|
-
const refresh =
|
|
2157
|
+
const sessionId = response?.header?.context?.session?.id;
|
|
2158
|
+
const notifications = response?.header?.context?.notify?.[0];
|
|
2159
|
+
const refresh = response?.header?.context?.refresh;
|
|
2130
2160
|
|
|
2131
2161
|
this.checkAndUpdateSessionId(sessionId);
|
|
2132
2162
|
|
|
@@ -2140,7 +2170,7 @@ export class ZimbraBatchClient {
|
|
|
2140
2170
|
}
|
|
2141
2171
|
}
|
|
2142
2172
|
|
|
2143
|
-
return
|
|
2173
|
+
return response instanceof Error ? [response] : [response.body];
|
|
2144
2174
|
});
|
|
2145
2175
|
|
|
2146
2176
|
private download = ({ isSecure, url }: any) =>
|
|
@@ -178,6 +178,7 @@ export interface AppointmentOptions {
|
|
|
178
178
|
}
|
|
179
179
|
|
|
180
180
|
export interface SaveDocumentInput {
|
|
181
|
+
content: string;
|
|
181
182
|
ct: string;
|
|
182
183
|
descEnabled: Boolean;
|
|
183
184
|
id: string;
|
|
@@ -234,7 +235,6 @@ export interface ShareInfoOptions {
|
|
|
234
235
|
|
|
235
236
|
export interface ChangePasswordOptions {
|
|
236
237
|
authToken: string;
|
|
237
|
-
csrfToken: string;
|
|
238
238
|
dryRun: boolean;
|
|
239
239
|
loginNewPassword: string;
|
|
240
240
|
password: string;
|
|
@@ -533,6 +533,10 @@ export const ListDocumentRevisions = new Entity({
|
|
|
533
533
|
doc: ['documents', Document]
|
|
534
534
|
});
|
|
535
535
|
|
|
536
|
+
export const GetItem = new Entity({
|
|
537
|
+
doc: ['documents', Document]
|
|
538
|
+
});
|
|
539
|
+
|
|
536
540
|
export const MessagePartInputForDocuments = new Entity({
|
|
537
541
|
id: 'messageId',
|
|
538
542
|
part: 'attachmentPart'
|
|
@@ -545,7 +549,8 @@ export const SaveDocument = new Entity({
|
|
|
545
549
|
ct: 'contentType',
|
|
546
550
|
descEnabled: 'descriptionEnabled',
|
|
547
551
|
m: ['messageData', MessagePartInputForDocuments],
|
|
548
|
-
doc: ['document', Document]
|
|
552
|
+
doc: ['document', Document],
|
|
553
|
+
content: 'content'
|
|
549
554
|
});
|
|
550
555
|
|
|
551
556
|
export const SearchResponse = new Entity({
|
package/src/normalize/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import reduce from 'lodash/reduce';
|
|
2
|
-
|
|
3
1
|
import { EntityMapping, EntityMappingValue, NormalizedKey } from './types';
|
|
4
2
|
|
|
5
3
|
function normalizeKey(key: string, schema: Entity, inverse: Boolean = false): NormalizedKey {
|
|
@@ -19,25 +17,28 @@ function normalizeKey(key: string, schema: Entity, inverse: Boolean = false): No
|
|
|
19
17
|
return { key };
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
function _normalize(data: {}, schema: Entity, inverse:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
20
|
+
function _normalize(data: {}, schema: Entity, inverse: boolean = false) {
|
|
21
|
+
const result: { [key: string]: any } = {};
|
|
22
|
+
|
|
23
|
+
for (const k in data) {
|
|
24
|
+
if (!Object.prototype.hasOwnProperty.call(data, k)) {
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const v = (data as any)[k];
|
|
29
|
+
const { key, nestedSchema } = normalizeKey(k, schema, inverse);
|
|
30
|
+
const type = typeof v;
|
|
31
|
+
|
|
32
|
+
if (Array.isArray(v)) {
|
|
33
|
+
result[key] = v.map(i => (nestedSchema ? _normalize(i, nestedSchema, inverse) : i));
|
|
34
|
+
} else if (type === 'object' && v !== null) {
|
|
35
|
+
result[key] = nestedSchema ? _normalize(v, nestedSchema, inverse) : v;
|
|
36
|
+
} else {
|
|
37
|
+
result[key] = v;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return result;
|
|
41
42
|
}
|
|
42
43
|
|
|
43
44
|
/**
|
|
@@ -74,24 +75,26 @@ export class Entity {
|
|
|
74
75
|
this.inverseMapping = this.initInverseMapping(this.mapping);
|
|
75
76
|
}
|
|
76
77
|
|
|
77
|
-
initInverseMapping(mapping: EntityMapping, accumulator = {}) {
|
|
78
|
-
|
|
79
|
-
mapping,
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
78
|
+
initInverseMapping(mapping: EntityMapping, accumulator: EntityMapping = {}): EntityMapping {
|
|
79
|
+
for (const k in mapping) {
|
|
80
|
+
if (!Object.prototype.hasOwnProperty.call(mapping, k)) {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const v: any = mapping[k];
|
|
85
|
+
|
|
86
|
+
if (Array.isArray(v)) {
|
|
87
|
+
accumulator[v[0]] = [k, v[1]];
|
|
88
|
+
} else if (typeof v === 'object' && !(v instanceof Entity)) {
|
|
89
|
+
accumulator[k] = this.initInverseMapping(v) as EntityMappingValue;
|
|
90
|
+
} else if (typeof v === 'string') {
|
|
91
|
+
accumulator[v] = k;
|
|
92
|
+
} else {
|
|
93
|
+
accumulator[k] = v;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return accumulator;
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
public inverseKey(k: string) {
|
package/src/request/index.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import get from 'lodash/get';
|
|
2
|
-
import reduce from 'lodash/reduce';
|
|
3
1
|
import {
|
|
4
2
|
BatchRequestOptions,
|
|
5
3
|
BatchRequestResponse,
|
|
@@ -39,7 +37,7 @@ function parseJSON(response: Response): Promise<ParsedResponse> {
|
|
|
39
37
|
// for the rest of the cases (as of now only 500 error), parse and return the error response so that it can
|
|
40
38
|
// be handled properly by the caller
|
|
41
39
|
return parseErrorJSON(response).then(parsedResponse => {
|
|
42
|
-
const fault =
|
|
40
|
+
const fault = parsedResponse?.parsed?.Body?.Fault;
|
|
43
41
|
throw faultError(parsedResponse, [fault]);
|
|
44
42
|
});
|
|
45
43
|
}
|
|
@@ -71,7 +69,7 @@ function networkError(response: ParsedResponse) {
|
|
|
71
69
|
|
|
72
70
|
(error as NetworkError).message = message;
|
|
73
71
|
(error as NetworkError).response = response;
|
|
74
|
-
(error as NetworkError).parseError = response
|
|
72
|
+
(error as NetworkError).parseError = response?.parseError;
|
|
75
73
|
|
|
76
74
|
return error as NetworkError;
|
|
77
75
|
}
|
|
@@ -80,7 +78,7 @@ function faultReasonText(faults: any = []): string {
|
|
|
80
78
|
if (!Array.isArray(faults)) faults = [faults];
|
|
81
79
|
|
|
82
80
|
return faults
|
|
83
|
-
.map((f: any) =>
|
|
81
|
+
.map((f: any) => f?.Reason?.Text)
|
|
84
82
|
.filter(Boolean)
|
|
85
83
|
.join(', ');
|
|
86
84
|
}
|
|
@@ -88,7 +86,7 @@ function faultReasonText(faults: any = []): string {
|
|
|
88
86
|
function faultError(response: ParsedResponse, faults: any) {
|
|
89
87
|
const error = new Error(`Fault error: ${faults ? faultReasonText(faults) : 'Unknown Error'}`);
|
|
90
88
|
(error as SingleBatchRequestError).response = response;
|
|
91
|
-
(error as SingleBatchRequestError).parseError = response
|
|
89
|
+
(error as SingleBatchRequestError).parseError = response?.parseError;
|
|
92
90
|
(error as SingleBatchRequestError).faults = faults;
|
|
93
91
|
return error as SingleBatchRequestError;
|
|
94
92
|
}
|
|
@@ -98,20 +96,20 @@ function faultError(response: ParsedResponse, faults: any) {
|
|
|
98
96
|
* containing an array of the requests for that command.
|
|
99
97
|
*/
|
|
100
98
|
function batchBody(requests: ReadonlyArray<RequestOptions>) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
99
|
+
const body: { [key: string]: any } = {};
|
|
100
|
+
|
|
101
|
+
for (const request of requests) {
|
|
102
|
+
const key = `${request.name}Request`;
|
|
103
|
+
const value = soapCommandBody(request);
|
|
104
|
+
|
|
105
|
+
if (body[key]) {
|
|
106
|
+
body[key].push(value);
|
|
107
|
+
} else {
|
|
108
|
+
body[key] = [value];
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return body;
|
|
115
113
|
}
|
|
116
114
|
|
|
117
115
|
/**
|
|
@@ -127,34 +125,26 @@ function batchResponse(requests: any, response: RequestResponse) {
|
|
|
127
125
|
// For each request type, track which responses have been
|
|
128
126
|
// pulled out of the batch request body by incrementing
|
|
129
127
|
// indexes.
|
|
130
|
-
|
|
128
|
+
const indexes: { [key: string]: number } = {};
|
|
129
|
+
const responses: Array<SingleBatchRequestResponse | SingleBatchRequestError> = [];
|
|
130
|
+
|
|
131
|
+
for (const request of requests) {
|
|
132
|
+
const batchResponses = batchBody[`${request.name}Response`];
|
|
133
|
+
const index = indexes[request.name] || 0;
|
|
134
|
+
const singleResponse = batchResponses?.[index];
|
|
135
|
+
|
|
136
|
+
if (singleResponse) {
|
|
137
|
+
responses.push({ body: singleResponse });
|
|
138
|
+
} else {
|
|
139
|
+
responses.push(faultError(request.originalResponse, batchBody.Fault));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
indexes[request.name] = index + 1;
|
|
143
|
+
}
|
|
131
144
|
|
|
132
145
|
return {
|
|
133
146
|
...res,
|
|
134
|
-
requests:
|
|
135
|
-
requests,
|
|
136
|
-
(responses: Array<SingleBatchRequestResponse | SingleBatchRequestError>, request) => {
|
|
137
|
-
const batchResponses = batchBody[`${request.name}Response`];
|
|
138
|
-
const index = indexes[request.name];
|
|
139
|
-
const response: any = batchResponses && batchResponses[index || 0];
|
|
140
|
-
if (response) {
|
|
141
|
-
responses.push({
|
|
142
|
-
body: response
|
|
143
|
-
});
|
|
144
|
-
} else {
|
|
145
|
-
responses.push(faultError(res.originalResponse, batchBody.Fault));
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (index) {
|
|
149
|
-
indexes[request.name] += 1;
|
|
150
|
-
} else {
|
|
151
|
-
indexes[request.name] = 1;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
return responses;
|
|
155
|
-
},
|
|
156
|
-
[]
|
|
157
|
-
)
|
|
147
|
+
requests: responses
|
|
158
148
|
};
|
|
159
149
|
}
|
|
160
150
|
|
|
@@ -232,8 +222,6 @@ export function jsonRequest(requestOptions: JsonRequestOptions): Promise<Request
|
|
|
232
222
|
|
|
233
223
|
if (requestOptions.csrfToken) {
|
|
234
224
|
options.headers['X-Zimbra-Csrf-Token'] = requestOptions.csrfToken;
|
|
235
|
-
|
|
236
|
-
header.context.csrfToken = requestOptions.csrfToken;
|
|
237
225
|
}
|
|
238
226
|
|
|
239
227
|
// Allow to set Auth Token in Cookie in case `ZimbraBatchClient` is used on non-web platforms, like nodejs
|
|
@@ -267,7 +255,7 @@ export function jsonRequest(requestOptions: JsonRequestOptions): Promise<Request
|
|
|
267
255
|
})
|
|
268
256
|
.then(parseJSON)
|
|
269
257
|
.then((response: any) => {
|
|
270
|
-
const globalFault =
|
|
258
|
+
const globalFault = response?.parsed?.Body?.Fault;
|
|
271
259
|
|
|
272
260
|
if (globalFault) {
|
|
273
261
|
throw faultError(response, globalFault);
|