@webitel/api-services 0.1.70 → 0.1.72
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/package.json +1 -1
- package/src/api/clients/emails/emails.ts +50 -49
- package/src/api/clients/imClients/imClients.ts +102 -0
- package/src/api/clients/index.ts +2 -0
- package/src/api/clients/phones/phones.ts +148 -104
- package/src/api/clients/queues/defaults/__tests__/queueTypeDefaults.spec.ts +46 -0
- package/src/api/clients/queues/defaults/amd.ts +1 -1
- package/src/api/clients/queues/defaults/defaultQueue.ts +2 -2
- package/src/api/clients/queues/defaults/processing.ts +1 -1
- package/src/api/clients/queues/defaults/queueTypeDefaults.ts +33 -33
- package/src/api/clients/queues/queueLogs.ts +2 -1
- package/src/api/clients/queues/queueMembers.ts +12 -3
- package/src/api/clients/variables/variables.ts +293 -0
- package/src/api/clients//321/201ontacts/index.ts +1 -0
- package/src/api/clients//321/201ontacts/types/ContactEntity.types.ts +25 -0
- package/src/validations/contact/contact.validations.ts +13 -0
- package/src/validations/contactEmail/contactEmail.validations.ts +9 -0
- package/src/validations/contactPhone/contactPhone.validations.ts +9 -0
- package/src/validations/index.ts +4 -0
- package/src/validations/variable/variable.validations.ts +8 -0
- package/types/.tsbuildinfo +1 -1
- package/types/api/clients/emails/emails.d.ts +10 -9
- package/types/api/clients/imClients/imClients.d.ts +19 -0
- package/types/api/clients/index.d.ts +2 -0
- package/types/api/clients/phones/phones.d.ts +29 -39
- package/types/api/clients/queues/defaults/amd.d.ts +1 -1
- package/types/api/clients/queues/defaults/defaultQueue.d.ts +2 -2
- package/types/api/clients/queues/defaults/processing.d.ts +1 -1
- package/types/api/clients/variables/variables.d.ts +51 -0
- package/types/api/clients//321/201ontacts/index.d.ts +1 -0
- package/types/api/clients//321/201ontacts/types/ContactEntity.types.d.ts +14 -0
- package/types/validations/contact/contact.validations.d.ts +25 -0
- package/types/validations/contactEmail/contactEmail.validations.d.ts +14 -0
- package/types/validations/contactPhone/contactPhone.validations.d.ts +14 -0
- package/types/validations/index.d.ts +4 -0
- package/types/validations/variable/variable.validations.d.ts +12 -0
|
@@ -141,3 +141,49 @@ describe('getQueueDefaults', () => {
|
|
|
141
141
|
expect(hasQueueTypeDefaults(undefined)).toBe(false);
|
|
142
142
|
});
|
|
143
143
|
});
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* A lookup the user has not filled must be seeded as `undefined`, not `{}`.
|
|
147
|
+
*
|
|
148
|
+
* The key still has to be there — regle builds its `$fields` from the state
|
|
149
|
+
* keys — but an empty *object* makes regle treat the field as a collection and
|
|
150
|
+
* file a root-level `superRefine` issue for it under an index, where nothing
|
|
151
|
+
* reads it: the field shows no error, `r$.$error` stays false so the save
|
|
152
|
+
* button stays enabled, and the save then aborts silently on `$validate()`.
|
|
153
|
+
*
|
|
154
|
+
* [WTEL-10140](https://webitel.atlassian.net/browse/WTEL-10140)
|
|
155
|
+
*/
|
|
156
|
+
describe('lookup defaults', () => {
|
|
157
|
+
const lookupKeys = [
|
|
158
|
+
'calendar',
|
|
159
|
+
'dncList',
|
|
160
|
+
'team',
|
|
161
|
+
'ringtone',
|
|
162
|
+
'grantee',
|
|
163
|
+
'schema',
|
|
164
|
+
'doSchema',
|
|
165
|
+
'afterSchema',
|
|
166
|
+
'formSchema',
|
|
167
|
+
];
|
|
168
|
+
|
|
169
|
+
it('seeds unset lookups as undefined, keeping the key', () => {
|
|
170
|
+
for (const type of allQueueTypes) {
|
|
171
|
+
const defaults = getQueueDefaults(type) as Record<string, unknown>;
|
|
172
|
+
|
|
173
|
+
for (const key of lookupKeys) {
|
|
174
|
+
if (!(key in defaults)) continue;
|
|
175
|
+
|
|
176
|
+
expect(
|
|
177
|
+
defaults[key],
|
|
178
|
+
`${key} on queue type ${type} must be undefined, not an empty object`,
|
|
179
|
+
).toBeUndefined();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it('keeps taskProcessing.formSchema out of the empty-object shape too', () => {
|
|
185
|
+
const taskProcessing = processing() as Record<string, unknown>;
|
|
186
|
+
|
|
187
|
+
expect(taskProcessing.formSchema).toBeUndefined();
|
|
188
|
+
});
|
|
189
|
+
});
|
|
@@ -33,11 +33,11 @@ export interface QueueDefaults {
|
|
|
33
33
|
const offlineQueue = (): QueueDefaults => ({
|
|
34
34
|
...defaultQueue(),
|
|
35
35
|
type: QueueType.OFFLINE_QUEUE,
|
|
36
|
-
team:
|
|
36
|
+
team: undefined,
|
|
37
37
|
strategy: QueueStrategy.FIFO,
|
|
38
|
-
doSchema:
|
|
39
|
-
afterSchema:
|
|
40
|
-
grantee:
|
|
38
|
+
doSchema: undefined,
|
|
39
|
+
afterSchema: undefined,
|
|
40
|
+
grantee: undefined,
|
|
41
41
|
taskProcessing: processing(),
|
|
42
42
|
payload: {
|
|
43
43
|
maxAttempts: 3,
|
|
@@ -54,9 +54,9 @@ const offlineQueue = (): QueueDefaults => ({
|
|
|
54
54
|
const inboundQueue = (): QueueDefaults => ({
|
|
55
55
|
...defaultQueue(),
|
|
56
56
|
type: QueueType.INBOUND_QUEUE,
|
|
57
|
-
team:
|
|
58
|
-
ringtone:
|
|
59
|
-
grantee:
|
|
57
|
+
team: undefined,
|
|
58
|
+
ringtone: undefined,
|
|
59
|
+
grantee: undefined,
|
|
60
60
|
stickyAgent: false,
|
|
61
61
|
taskProcessing: processing(),
|
|
62
62
|
payload: {
|
|
@@ -80,10 +80,10 @@ const outboundIVRQueue = (): QueueDefaults => ({
|
|
|
80
80
|
...defaultQueue(),
|
|
81
81
|
type: QueueType.OUTBOUND_IVR_QUEUE,
|
|
82
82
|
strategy: QueueStrategy.FIFO,
|
|
83
|
-
schema:
|
|
84
|
-
doSchema:
|
|
85
|
-
afterSchema:
|
|
86
|
-
grantee:
|
|
83
|
+
schema: undefined,
|
|
84
|
+
doSchema: undefined,
|
|
85
|
+
afterSchema: undefined,
|
|
86
|
+
grantee: undefined,
|
|
87
87
|
payload: {
|
|
88
88
|
minDuration: 3,
|
|
89
89
|
maxAttempts: 3,
|
|
@@ -104,11 +104,11 @@ const outboundIVRQueue = (): QueueDefaults => ({
|
|
|
104
104
|
const previewDialer = (): QueueDefaults => ({
|
|
105
105
|
...defaultQueue(),
|
|
106
106
|
type: QueueType.PREVIEW_DIALER,
|
|
107
|
-
team:
|
|
107
|
+
team: undefined,
|
|
108
108
|
strategy: QueueStrategy.FIFO,
|
|
109
|
-
doSchema:
|
|
110
|
-
afterSchema:
|
|
111
|
-
grantee:
|
|
109
|
+
doSchema: undefined,
|
|
110
|
+
afterSchema: undefined,
|
|
111
|
+
grantee: undefined,
|
|
112
112
|
stickyAgent: false,
|
|
113
113
|
taskProcessing: processing(),
|
|
114
114
|
payload: {
|
|
@@ -132,12 +132,12 @@ const previewDialer = (): QueueDefaults => ({
|
|
|
132
132
|
const progressiveDialer = (): QueueDefaults => ({
|
|
133
133
|
...defaultQueue(),
|
|
134
134
|
type: QueueType.PROGRESSIVE_DIALER,
|
|
135
|
-
team:
|
|
135
|
+
team: undefined,
|
|
136
136
|
strategy: QueueStrategy.FIFO,
|
|
137
|
-
doSchema:
|
|
138
|
-
afterSchema:
|
|
139
|
-
ringtone:
|
|
140
|
-
grantee:
|
|
137
|
+
doSchema: undefined,
|
|
138
|
+
afterSchema: undefined,
|
|
139
|
+
ringtone: undefined,
|
|
140
|
+
grantee: undefined,
|
|
141
141
|
stickyAgent: false,
|
|
142
142
|
taskProcessing: processing(),
|
|
143
143
|
payload: {
|
|
@@ -165,11 +165,11 @@ const predictiveDialer = (): QueueDefaults => ({
|
|
|
165
165
|
...defaultQueue(),
|
|
166
166
|
type: QueueType.PREDICTIVE_DIALER,
|
|
167
167
|
strategy: QueueStrategy.FIFO,
|
|
168
|
-
team:
|
|
169
|
-
doSchema:
|
|
170
|
-
afterSchema:
|
|
171
|
-
ringtone:
|
|
172
|
-
grantee:
|
|
168
|
+
team: undefined,
|
|
169
|
+
doSchema: undefined,
|
|
170
|
+
afterSchema: undefined,
|
|
171
|
+
ringtone: undefined,
|
|
172
|
+
grantee: undefined,
|
|
173
173
|
stickyAgent: false,
|
|
174
174
|
taskProcessing: processing(),
|
|
175
175
|
payload: {
|
|
@@ -209,9 +209,9 @@ const predictiveDialer = (): QueueDefaults => ({
|
|
|
209
209
|
const chatInboundQueue = (): QueueDefaults => ({
|
|
210
210
|
...defaultQueue(),
|
|
211
211
|
type: QueueType.CHAT_INBOUND_QUEUE,
|
|
212
|
-
team:
|
|
212
|
+
team: undefined,
|
|
213
213
|
strategy: QueueStrategy.FIFO,
|
|
214
|
-
formSchema:
|
|
214
|
+
formSchema: undefined,
|
|
215
215
|
stickyAgent: false,
|
|
216
216
|
taskProcessing: processing(),
|
|
217
217
|
payload: {
|
|
@@ -241,10 +241,10 @@ const imChatQueue = (): QueueDefaults => ({
|
|
|
241
241
|
const inboundJobQueue = (): QueueDefaults => ({
|
|
242
242
|
...defaultQueue(),
|
|
243
243
|
type: QueueType.INBOUND_JOB_QUEUE,
|
|
244
|
-
team:
|
|
244
|
+
team: undefined,
|
|
245
245
|
strategy: QueueStrategy.FIFO,
|
|
246
|
-
doSchema:
|
|
247
|
-
afterSchema:
|
|
246
|
+
doSchema: undefined,
|
|
247
|
+
afterSchema: undefined,
|
|
248
248
|
stickyAgent: false,
|
|
249
249
|
taskProcessing: processing(),
|
|
250
250
|
payload: {
|
|
@@ -262,9 +262,9 @@ const outboundJobQueue = (): QueueDefaults => ({
|
|
|
262
262
|
...defaultQueue(),
|
|
263
263
|
type: QueueType.OUTBOUND_JOB_QUEUE,
|
|
264
264
|
strategy: QueueStrategy.FIFO,
|
|
265
|
-
schema:
|
|
266
|
-
doSchema:
|
|
267
|
-
afterSchema:
|
|
265
|
+
schema: undefined,
|
|
266
|
+
doSchema: undefined,
|
|
267
|
+
afterSchema: undefined,
|
|
268
268
|
payload: {
|
|
269
269
|
maxAttempts: 3,
|
|
270
270
|
originateTimeout: 60,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getMemberService } from '@webitel/api-services/gen';
|
|
2
|
+
import type { SearchAttemptsHistoryParams } from '@webitel/api-services/gen/models';
|
|
2
3
|
import { normalizeDatetimeRange } from '../../../scripts';
|
|
3
4
|
import { getDefaultGetListResponse, getDefaultGetParams } from '../../defaults';
|
|
4
5
|
import {
|
|
@@ -59,7 +60,7 @@ const getQueueLogs = async (params: ApiParams) => {
|
|
|
59
60
|
'offering_at.to': offeringAt?.to,
|
|
60
61
|
'duration.from': duration?.from,
|
|
61
62
|
'duration.to': duration?.to,
|
|
62
|
-
});
|
|
63
|
+
} as SearchAttemptsHistoryParams);
|
|
63
64
|
const { items, next } = applyTransform(response.data, [
|
|
64
65
|
snakeToCamel(),
|
|
65
66
|
merge(getDefaultGetListResponse()),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getMemberService } from '@webitel/api-services/gen';
|
|
2
|
+
import type { SearchMemberInQueueParams } from '@webitel/api-services/gen/models';
|
|
2
3
|
import { getShallowFieldsToSendFromZodSchema } from '@webitel/api-services/gen/utils';
|
|
3
4
|
import { queueMemberSchema } from '@webitel/api-services/validations';
|
|
4
5
|
import deepCopy from 'deep-copy';
|
|
@@ -152,7 +153,7 @@ const getMembersList = async (params: ApiParams) => {
|
|
|
152
153
|
'attempts.to': attempts?.to,
|
|
153
154
|
name,
|
|
154
155
|
destination,
|
|
155
|
-
},
|
|
156
|
+
} as SearchMemberInQueueParams,
|
|
156
157
|
);
|
|
157
158
|
const { items, next } = applyTransform(response.data, [
|
|
158
159
|
snakeToCamel(doNotConvertKeys),
|
|
@@ -383,12 +384,20 @@ const deleteMembersBulk = async ({
|
|
|
383
384
|
id?: ApiId[];
|
|
384
385
|
filters?: ApiParams;
|
|
385
386
|
}) => {
|
|
386
|
-
const created =
|
|
387
|
+
const created = normalizeDatetimeRange(
|
|
388
|
+
filters.createdAt ??
|
|
389
|
+
(filters.from != null || filters.to != null
|
|
390
|
+
? {
|
|
391
|
+
from: filters.from,
|
|
392
|
+
to: filters.to,
|
|
393
|
+
}
|
|
394
|
+
: undefined),
|
|
395
|
+
);
|
|
387
396
|
|
|
388
397
|
let body: ApiParams = {
|
|
389
398
|
id,
|
|
390
399
|
q: filters.search,
|
|
391
|
-
createdAt: created
|
|
400
|
+
createdAt: created?.from || created?.to ? created : undefined,
|
|
392
401
|
priority: filters.memberPriority ?? filters.priority,
|
|
393
402
|
stopCause: filters.stopCause ?? filters.cause,
|
|
394
403
|
bucketId: filters.bucket,
|
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getVariables,
|
|
3
|
+
ListVariablesQueryParams,
|
|
4
|
+
MergeVariablesBodyItem,
|
|
5
|
+
UpdateVariableBody,
|
|
6
|
+
} from '@webitel/api-services/gen';
|
|
7
|
+
import type {
|
|
8
|
+
ContactsInputVariable,
|
|
9
|
+
DeleteVariablesParams,
|
|
10
|
+
MergeVariablesParams,
|
|
11
|
+
ResetVariablesParams,
|
|
12
|
+
} from '@webitel/api-services/gen/models';
|
|
13
|
+
import { getShallowFieldsToSendFromZodSchema } from '@webitel/api-services/gen/utils';
|
|
14
|
+
import type { AxiosRequestConfig } from 'axios';
|
|
15
|
+
import { getDefaultGetListResponse, getDefaultGetParams } from '../../defaults';
|
|
16
|
+
import {
|
|
17
|
+
applyTransform,
|
|
18
|
+
camelToSnake,
|
|
19
|
+
merge,
|
|
20
|
+
notify,
|
|
21
|
+
sanitize,
|
|
22
|
+
snakeToCamel,
|
|
23
|
+
starToSearch,
|
|
24
|
+
} from '../../transformers';
|
|
25
|
+
|
|
26
|
+
const getVariablesList = async ({
|
|
27
|
+
parentId,
|
|
28
|
+
...rest
|
|
29
|
+
}: Record<string, unknown> & {
|
|
30
|
+
parentId: string;
|
|
31
|
+
}) => {
|
|
32
|
+
const listFieldsToSend = getShallowFieldsToSendFromZodSchema(
|
|
33
|
+
ListVariablesQueryParams,
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
const { fields = [], ...queryParams } = applyTransform(rest, [
|
|
37
|
+
sanitize(listFieldsToSend),
|
|
38
|
+
merge(getDefaultGetParams()),
|
|
39
|
+
starToSearch('q'),
|
|
40
|
+
]);
|
|
41
|
+
try {
|
|
42
|
+
const response = await getVariables().listVariables(parentId, {
|
|
43
|
+
...queryParams,
|
|
44
|
+
fields: [
|
|
45
|
+
'etag',
|
|
46
|
+
...fields,
|
|
47
|
+
],
|
|
48
|
+
});
|
|
49
|
+
const { data, next } = applyTransform(response.data, [
|
|
50
|
+
snakeToCamel(),
|
|
51
|
+
merge(getDefaultGetListResponse()),
|
|
52
|
+
]);
|
|
53
|
+
return {
|
|
54
|
+
items: data,
|
|
55
|
+
next,
|
|
56
|
+
};
|
|
57
|
+
} catch (err) {
|
|
58
|
+
throw applyTransform(err, [
|
|
59
|
+
notify,
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// no dedicated "locate one" endpoint exists for variables — reuse the list
|
|
65
|
+
// endpoint filtered to a single id, matching what the crm-local adapter did
|
|
66
|
+
const getVariable = async ({
|
|
67
|
+
itemId,
|
|
68
|
+
parentId,
|
|
69
|
+
}: {
|
|
70
|
+
itemId: string;
|
|
71
|
+
parentId: string;
|
|
72
|
+
}) => {
|
|
73
|
+
try {
|
|
74
|
+
const response = await getVariables().listVariables(parentId, {
|
|
75
|
+
page: 1,
|
|
76
|
+
size: 1,
|
|
77
|
+
fields: [
|
|
78
|
+
'key',
|
|
79
|
+
'value',
|
|
80
|
+
'etag',
|
|
81
|
+
],
|
|
82
|
+
id: [
|
|
83
|
+
itemId,
|
|
84
|
+
],
|
|
85
|
+
});
|
|
86
|
+
const { data } = applyTransform(response.data, [
|
|
87
|
+
snakeToCamel(),
|
|
88
|
+
]);
|
|
89
|
+
return data[0];
|
|
90
|
+
} catch (err) {
|
|
91
|
+
throw applyTransform(err, [
|
|
92
|
+
notify,
|
|
93
|
+
]);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const addFieldsToSend = getShallowFieldsToSendFromZodSchema(
|
|
98
|
+
MergeVariablesBodyItem,
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const addVariable = async ({
|
|
102
|
+
parentId,
|
|
103
|
+
itemInstance,
|
|
104
|
+
}: {
|
|
105
|
+
parentId: string;
|
|
106
|
+
itemInstance: Record<string, unknown>;
|
|
107
|
+
}) => {
|
|
108
|
+
const item = applyTransform(itemInstance, [
|
|
109
|
+
sanitize(addFieldsToSend),
|
|
110
|
+
camelToSnake(),
|
|
111
|
+
]);
|
|
112
|
+
try {
|
|
113
|
+
const response = await getVariables().mergeVariables(parentId, [
|
|
114
|
+
item,
|
|
115
|
+
]);
|
|
116
|
+
const { data } = applyTransform(response.data, [
|
|
117
|
+
snakeToCamel(),
|
|
118
|
+
]);
|
|
119
|
+
return data[0];
|
|
120
|
+
} catch (err) {
|
|
121
|
+
throw applyTransform(err, [
|
|
122
|
+
notify,
|
|
123
|
+
]);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
const updateFieldsToSend =
|
|
128
|
+
getShallowFieldsToSendFromZodSchema(UpdateVariableBody);
|
|
129
|
+
|
|
130
|
+
const updateVariable = async ({
|
|
131
|
+
itemInstance,
|
|
132
|
+
parentId,
|
|
133
|
+
}: {
|
|
134
|
+
itemInstance: Record<string, unknown> & {
|
|
135
|
+
etag: string;
|
|
136
|
+
};
|
|
137
|
+
parentId: string;
|
|
138
|
+
}) => {
|
|
139
|
+
const item = applyTransform(itemInstance, [
|
|
140
|
+
sanitize(updateFieldsToSend),
|
|
141
|
+
camelToSnake(),
|
|
142
|
+
]);
|
|
143
|
+
try {
|
|
144
|
+
const response = await getVariables().updateVariable(
|
|
145
|
+
parentId,
|
|
146
|
+
itemInstance.etag,
|
|
147
|
+
item,
|
|
148
|
+
);
|
|
149
|
+
const { data } = applyTransform(response.data, [
|
|
150
|
+
snakeToCamel(),
|
|
151
|
+
]);
|
|
152
|
+
return data[0];
|
|
153
|
+
} catch (err) {
|
|
154
|
+
throw applyTransform(err, [
|
|
155
|
+
notify,
|
|
156
|
+
]);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
const deleteVariable = async ({
|
|
161
|
+
etag,
|
|
162
|
+
parentId,
|
|
163
|
+
}: {
|
|
164
|
+
etag: string;
|
|
165
|
+
parentId: string;
|
|
166
|
+
}) => {
|
|
167
|
+
try {
|
|
168
|
+
const response = await getVariables().deleteVariable(parentId, etag);
|
|
169
|
+
return applyTransform(response.data, []);
|
|
170
|
+
} catch (err) {
|
|
171
|
+
throw applyTransform(err, [
|
|
172
|
+
notify,
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const getVariablesLookup = (
|
|
178
|
+
params: Record<string, unknown> & {
|
|
179
|
+
parentId: string;
|
|
180
|
+
},
|
|
181
|
+
) =>
|
|
182
|
+
getVariablesList({
|
|
183
|
+
...params,
|
|
184
|
+
fields: (params.fields as string[]) || [
|
|
185
|
+
'etag',
|
|
186
|
+
'key',
|
|
187
|
+
'value',
|
|
188
|
+
],
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* raw bulk endpoints — take/return the whole variables array in one call,
|
|
193
|
+
* unlike add/update above which normalize a single item for createCardStore
|
|
194
|
+
*/
|
|
195
|
+
const mergeVariables = async ({
|
|
196
|
+
contactId,
|
|
197
|
+
variables,
|
|
198
|
+
params,
|
|
199
|
+
options,
|
|
200
|
+
}: {
|
|
201
|
+
contactId: string;
|
|
202
|
+
variables: ContactsInputVariable[];
|
|
203
|
+
params?: MergeVariablesParams;
|
|
204
|
+
options?: AxiosRequestConfig;
|
|
205
|
+
}) => {
|
|
206
|
+
const body = applyTransform(variables, [
|
|
207
|
+
camelToSnake(),
|
|
208
|
+
]);
|
|
209
|
+
try {
|
|
210
|
+
const response = await getVariables().mergeVariables(
|
|
211
|
+
contactId,
|
|
212
|
+
body,
|
|
213
|
+
params,
|
|
214
|
+
options,
|
|
215
|
+
);
|
|
216
|
+
return applyTransform(response.data, [
|
|
217
|
+
snakeToCamel(),
|
|
218
|
+
]);
|
|
219
|
+
} catch (err) {
|
|
220
|
+
throw applyTransform(err, [
|
|
221
|
+
notify,
|
|
222
|
+
]);
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
|
|
226
|
+
const resetVariables = async ({
|
|
227
|
+
contactId,
|
|
228
|
+
variables,
|
|
229
|
+
params,
|
|
230
|
+
options,
|
|
231
|
+
}: {
|
|
232
|
+
contactId: string;
|
|
233
|
+
variables: ContactsInputVariable[];
|
|
234
|
+
params?: ResetVariablesParams;
|
|
235
|
+
options?: AxiosRequestConfig;
|
|
236
|
+
}) => {
|
|
237
|
+
const body = applyTransform(variables, [
|
|
238
|
+
camelToSnake(),
|
|
239
|
+
]);
|
|
240
|
+
try {
|
|
241
|
+
const response = await getVariables().resetVariables(
|
|
242
|
+
contactId,
|
|
243
|
+
body,
|
|
244
|
+
params,
|
|
245
|
+
options,
|
|
246
|
+
);
|
|
247
|
+
return applyTransform(response.data, [
|
|
248
|
+
snakeToCamel(),
|
|
249
|
+
]);
|
|
250
|
+
} catch (err) {
|
|
251
|
+
throw applyTransform(err, [
|
|
252
|
+
notify,
|
|
253
|
+
]);
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
const deleteVariables = async ({
|
|
258
|
+
contactId,
|
|
259
|
+
params,
|
|
260
|
+
options,
|
|
261
|
+
}: {
|
|
262
|
+
contactId: string;
|
|
263
|
+
params: DeleteVariablesParams;
|
|
264
|
+
options?: AxiosRequestConfig;
|
|
265
|
+
}) => {
|
|
266
|
+
try {
|
|
267
|
+
const response = await getVariables().deleteVariables(
|
|
268
|
+
contactId,
|
|
269
|
+
params,
|
|
270
|
+
options,
|
|
271
|
+
);
|
|
272
|
+
return applyTransform(response.data, [
|
|
273
|
+
snakeToCamel(),
|
|
274
|
+
]);
|
|
275
|
+
} catch (err) {
|
|
276
|
+
throw applyTransform(err, [
|
|
277
|
+
notify,
|
|
278
|
+
]);
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
export const VariablesAPI = {
|
|
283
|
+
getList: getVariablesList,
|
|
284
|
+
get: getVariable,
|
|
285
|
+
add: addVariable,
|
|
286
|
+
update: updateVariable,
|
|
287
|
+
delete: deleteVariable,
|
|
288
|
+
getLookup: getVariablesLookup,
|
|
289
|
+
|
|
290
|
+
merge: mergeVariables,
|
|
291
|
+
reset: resetVariables,
|
|
292
|
+
deleteMany: deleteVariables,
|
|
293
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ContactsManager,
|
|
3
|
+
ContactsTimezone,
|
|
4
|
+
WebitelContactsContact,
|
|
5
|
+
WebitelContactsLabel,
|
|
6
|
+
WebitelContactsLookup,
|
|
7
|
+
} from '@webitel/api-services/gen/models';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* `ContactsAPI` (../contacts.ts) unwraps the generated `WebitelContactsContact`'s
|
|
11
|
+
* paginated `{data:[...]}` envelopes for these fields into plain arrays (and
|
|
12
|
+
* `name` into a plain string) on read, and wraps them back on write. This type
|
|
13
|
+
* reflects that actual runtime shape.
|
|
14
|
+
*/
|
|
15
|
+
export interface ContactEntity
|
|
16
|
+
extends Omit<
|
|
17
|
+
WebitelContactsContact,
|
|
18
|
+
'name' | 'timezones' | 'managers' | 'labels' | 'groups'
|
|
19
|
+
> {
|
|
20
|
+
name?: string;
|
|
21
|
+
timezones?: ContactsTimezone[];
|
|
22
|
+
managers?: ContactsManager[];
|
|
23
|
+
labels?: WebitelContactsLabel[];
|
|
24
|
+
groups?: WebitelContactsLookup[];
|
|
25
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { ContactEntity } from '../../api/clients/сontacts/types/ContactEntity.types';
|
|
3
|
+
import type { ZodShape } from '../types';
|
|
4
|
+
|
|
5
|
+
export const contactSchema = z.object<ZodShape<ContactEntity>>({
|
|
6
|
+
name: z.string().optional(),
|
|
7
|
+
timezones: z.array(z.any()).optional(),
|
|
8
|
+
managers: z.array(z.any()).optional(),
|
|
9
|
+
groups: z.array(z.any()).optional(),
|
|
10
|
+
labels: z.array(z.any()).optional(),
|
|
11
|
+
about: z.string().nullish(),
|
|
12
|
+
user: z.any().nullish(),
|
|
13
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ContactsEmailAddress } from '@webitel/api-services/gen/models';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { ZodShape } from '../types';
|
|
4
|
+
|
|
5
|
+
export const contactEmailSchema = z.object<ZodShape<ContactsEmailAddress>>({
|
|
6
|
+
email: z.string().min(1).email(),
|
|
7
|
+
type: z.any(),
|
|
8
|
+
primary: z.boolean().optional(),
|
|
9
|
+
});
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ContactsPhoneNumber } from '@webitel/api-services/gen/models';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { ZodShape } from '../types';
|
|
4
|
+
|
|
5
|
+
export const contactPhoneSchema = z.object<ZodShape<ContactsPhoneNumber>>({
|
|
6
|
+
number: z.string().min(1),
|
|
7
|
+
type: z.any(),
|
|
8
|
+
primary: z.boolean().optional(),
|
|
9
|
+
});
|
package/src/validations/index.ts
CHANGED
|
@@ -12,8 +12,11 @@ export * from './caseServiceCatalog/caseServiceCatalog.validations';
|
|
|
12
12
|
export * from './caseSource/caseSource.validations';
|
|
13
13
|
export * from './caseStatus/caseStatus.validations';
|
|
14
14
|
export * from './caseStatusCondition/caseStatusCondition.validations';
|
|
15
|
+
export * from './contact/contact.validations';
|
|
16
|
+
export * from './contactEmail/contactEmail.validations';
|
|
15
17
|
export * from './contactGroup/contactGroup.validations';
|
|
16
18
|
export * from './contactGroupCondition/contactGroupCondition.validations';
|
|
19
|
+
export * from './contactPhone/contactPhone.validations';
|
|
17
20
|
export * from './OAuth/OAuth.validations';
|
|
18
21
|
export * from './onlineSkill/onlineSkill.validations';
|
|
19
22
|
export * from './queue/queue.rules';
|
|
@@ -30,3 +33,4 @@ export * from './queueSkill/queueSkill.validations';
|
|
|
30
33
|
export * from './sla/sla.validations';
|
|
31
34
|
export * from './slaCondition/slaCondition.validations';
|
|
32
35
|
export * from './types';
|
|
36
|
+
export * from './variable/variable.validations';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ContactsVariable } from '@webitel/api-services/gen/models';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import type { ZodShape } from '../types';
|
|
4
|
+
|
|
5
|
+
export const variableSchema = z.object<ZodShape<ContactsVariable>>({
|
|
6
|
+
key: z.string().min(1),
|
|
7
|
+
value: z.string().min(1),
|
|
8
|
+
});
|