@webitel/api-services 26.8.17 → 26.8.18
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/validations/_shared/clearableNumber.validations.ts +19 -0
- package/src/validations/index.ts +1 -0
- package/src/validations/queue/__tests__/queue.validations.spec.ts +41 -0
- package/src/validations/queue/queue.validations.ts +2 -1
- package/src/validations/queue/queueAmd.validations.ts +11 -9
- package/src/validations/queue/queuePayload.validations.ts +27 -25
- package/src/validations/queue/taskProcessing.validations.ts +6 -4
- package/types/.tsbuildinfo +1 -1
- package/types/validations/_shared/clearableNumber.validations.d.ts +18 -0
- package/types/validations/index.d.ts +1 -0
- package/types/validations/queue/queue.validations.d.ts +78 -78
- package/types/validations/queue/queueAmd.validations.d.ts +9 -9
- package/types/validations/queue/queuePayload.validations.d.ts +34 -34
- package/types/validations/queue/taskProcessing.validations.d.ts +6 -6
package/package.json
CHANGED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @description
|
|
5
|
+
* An optional number the user is allowed to clear.
|
|
6
|
+
*
|
|
7
|
+
* `wt-input-number` wraps PrimeVue's `InputNumber`, which emits `null` — not
|
|
8
|
+
* `undefined` — when its input is emptied. A plain `z.number().optional()`
|
|
9
|
+
* rejects that with "expected number, received null", which the form shows as
|
|
10
|
+
* a red field with a helper text indistinguishable from a required error, and
|
|
11
|
+
* which blocks saving. Worse, the failure is on the base object, so a
|
|
12
|
+
* `superRefine` carrying the real per-type rules never runs.
|
|
13
|
+
*
|
|
14
|
+
* Accepting `null` keeps an emptied optional field valid; whether the field may
|
|
15
|
+
* be empty at all stays with the required rules that run in `superRefine`.
|
|
16
|
+
*
|
|
17
|
+
* https://webitel.atlassian.net/browse/WTEL-10326
|
|
18
|
+
*/
|
|
19
|
+
export const clearableNumberSchema = z.number().nullable().optional();
|
package/src/validations/index.ts
CHANGED
|
@@ -133,6 +133,47 @@ describe('queueSchema', () => {
|
|
|
133
133
|
expect(issuePaths(queueSchema.safeParse(queue))).not.toContain('team');
|
|
134
134
|
});
|
|
135
135
|
|
|
136
|
+
/**
|
|
137
|
+
* `wt-input-number` wraps PrimeVue's `InputNumber`, which emits `null` when
|
|
138
|
+
* its input is emptied. An optional number that rejects `null` fails on the
|
|
139
|
+
* base object, so `superRefine` never runs and the field reads as required.
|
|
140
|
+
* https://webitel.atlassian.net/browse/WTEL-10326
|
|
141
|
+
*/
|
|
142
|
+
it.each(
|
|
143
|
+
allQueueTypes,
|
|
144
|
+
)('accepts cleared optional numbers of type %i', (type) => {
|
|
145
|
+
const queue = validQueueFor(type);
|
|
146
|
+
const required = new Set(requiredPathsFor(type));
|
|
147
|
+
const payload = (queue.payload ?? {}) as AnyRecord;
|
|
148
|
+
|
|
149
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
150
|
+
if (typeof value === 'number' && !required.has(`payload.${key}`)) {
|
|
151
|
+
payload[key] = null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (!required.has('priority')) queue.priority = null;
|
|
155
|
+
|
|
156
|
+
expect(issuePaths(queueSchema.safeParse(queue))).toEqual([]);
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
/** A cleared *required* number still fails — with the rule's message, not zod's. */
|
|
160
|
+
it('reports a cleared required number as required', () => {
|
|
161
|
+
const queue = validQueueFor(QueueType.OUTBOUND_IVR_QUEUE);
|
|
162
|
+
set(queue, 'payload.maxAttempts', null);
|
|
163
|
+
|
|
164
|
+
const result = queueSchema.safeParse(queue);
|
|
165
|
+
|
|
166
|
+
expect(issuePaths(result)).toEqual([
|
|
167
|
+
'payload.maxAttempts',
|
|
168
|
+
]);
|
|
169
|
+
expect(result.error?.issues[0]).toMatchObject({
|
|
170
|
+
code: 'custom',
|
|
171
|
+
params: {
|
|
172
|
+
i18nKey: 'required',
|
|
173
|
+
},
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
136
177
|
/**
|
|
137
178
|
* Regle builds `$fields` from state keys, so anything the defaults seed must
|
|
138
179
|
* survive the schema — a key the schema strips has no validation entry, and
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { get } from 'lodash-es';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
|
|
4
|
+
import { clearableNumberSchema } from '../_shared/clearableNumber.validations';
|
|
4
5
|
import { i18nIssue } from '../_shared/i18nIssue';
|
|
5
6
|
import { isFilled } from '../_shared/isFilled';
|
|
6
7
|
import { flexibleLookupSchema } from '../_shared/lookup.validations';
|
|
@@ -30,7 +31,7 @@ export const queueSchemaBase = z.object({
|
|
|
30
31
|
description: z.string().optional(),
|
|
31
32
|
type: z.number(),
|
|
32
33
|
enabled: z.boolean().optional(),
|
|
33
|
-
priority:
|
|
34
|
+
priority: clearableNumberSchema,
|
|
34
35
|
tags: z
|
|
35
36
|
.array(
|
|
36
37
|
z.object({
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
import { clearableNumberSchema } from '../_shared/clearableNumber.validations';
|
|
4
|
+
|
|
3
5
|
import { flexibleLookupSchema } from '../_shared/lookup.validations';
|
|
4
6
|
|
|
5
7
|
/** Answering-machine detection, on the outbound IVR and the two auto-dialers. */
|
|
@@ -10,13 +12,13 @@ export const queueAmdSchema = z.object({
|
|
|
10
12
|
playback: flexibleLookupSchema.optional(),
|
|
11
13
|
allowNotSure: z.boolean().optional(),
|
|
12
14
|
silenceNotSure: z.boolean().optional(),
|
|
13
|
-
maxWordLength:
|
|
14
|
-
maxNumberOfWords:
|
|
15
|
-
betweenWordsSilence:
|
|
16
|
-
minWordLength:
|
|
17
|
-
totalAnalysisTime:
|
|
18
|
-
silenceThreshold:
|
|
19
|
-
afterGreetingSilence:
|
|
20
|
-
greeting:
|
|
21
|
-
initialSilence:
|
|
15
|
+
maxWordLength: clearableNumberSchema,
|
|
16
|
+
maxNumberOfWords: clearableNumberSchema,
|
|
17
|
+
betweenWordsSilence: clearableNumberSchema,
|
|
18
|
+
minWordLength: clearableNumberSchema,
|
|
19
|
+
totalAnalysisTime: clearableNumberSchema,
|
|
20
|
+
silenceThreshold: clearableNumberSchema,
|
|
21
|
+
afterGreetingSilence: clearableNumberSchema,
|
|
22
|
+
greeting: clearableNumberSchema,
|
|
23
|
+
initialSilence: clearableNumberSchema,
|
|
22
24
|
});
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
import { clearableNumberSchema } from '../_shared/clearableNumber.validations';
|
|
4
|
+
|
|
3
5
|
import { queueAmdSchema } from './queueAmd.validations';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -16,15 +18,15 @@ import { queueAmdSchema } from './queueAmd.validations';
|
|
|
16
18
|
*/
|
|
17
19
|
export const queuePayloadSchema = z.object({
|
|
18
20
|
// dialing and retries
|
|
19
|
-
maxAttempts:
|
|
20
|
-
minAttempts:
|
|
21
|
-
originateTimeout:
|
|
22
|
-
waitBetweenRetries:
|
|
21
|
+
maxAttempts: clearableNumberSchema,
|
|
22
|
+
minAttempts: clearableNumberSchema,
|
|
23
|
+
originateTimeout: clearableNumberSchema,
|
|
24
|
+
waitBetweenRetries: clearableNumberSchema,
|
|
23
25
|
waitBetweenRetriesDesc: z.boolean().optional(),
|
|
24
|
-
minDuration:
|
|
25
|
-
maxCalls:
|
|
26
|
-
progressiveCount:
|
|
27
|
-
dialingRate:
|
|
26
|
+
minDuration: clearableNumberSchema,
|
|
27
|
+
maxCalls: clearableNumberSchema,
|
|
28
|
+
progressiveCount: clearableNumberSchema,
|
|
29
|
+
dialingRate: clearableNumberSchema,
|
|
28
30
|
resourceStrategy: z.string().optional(),
|
|
29
31
|
strictCircuit: z.boolean().optional(),
|
|
30
32
|
perNumbers: z.boolean().optional(),
|
|
@@ -32,33 +34,33 @@ export const queuePayloadSchema = z.object({
|
|
|
32
34
|
retryAbandoned: z.boolean().optional(),
|
|
33
35
|
|
|
34
36
|
// predictive dialer only
|
|
35
|
-
maxAgentLine:
|
|
36
|
-
maxAgentLose:
|
|
37
|
-
maxAbandonedRate:
|
|
38
|
-
targetAbandonedRate:
|
|
39
|
-
abandonRateAdjustment:
|
|
40
|
-
loadFactor:
|
|
41
|
-
playbackSilence:
|
|
42
|
-
statisticTime:
|
|
37
|
+
maxAgentLine: clearableNumberSchema,
|
|
38
|
+
maxAgentLose: clearableNumberSchema,
|
|
39
|
+
maxAbandonedRate: clearableNumberSchema,
|
|
40
|
+
targetAbandonedRate: clearableNumberSchema,
|
|
41
|
+
abandonRateAdjustment: clearableNumberSchema,
|
|
42
|
+
loadFactor: clearableNumberSchema,
|
|
43
|
+
playbackSilence: clearableNumberSchema,
|
|
44
|
+
statisticTime: clearableNumberSchema,
|
|
43
45
|
|
|
44
46
|
// waiting and distribution
|
|
45
47
|
timeBaseScore: z.string().optional(),
|
|
46
|
-
maxWaitTime:
|
|
47
|
-
maxWaitingSize:
|
|
48
|
-
discardAbandonedAfter:
|
|
48
|
+
maxWaitTime: clearableNumberSchema,
|
|
49
|
+
maxWaitingSize: clearableNumberSchema,
|
|
50
|
+
discardAbandonedAfter: clearableNumberSchema,
|
|
49
51
|
manualDistribution: z.boolean().optional(),
|
|
50
|
-
minOnlineAgents:
|
|
51
|
-
maxMemberLimit:
|
|
52
|
+
minOnlineAgents: clearableNumberSchema,
|
|
53
|
+
maxMemberLimit: clearableNumberSchema,
|
|
52
54
|
ignoreCalendar: z.boolean().optional(),
|
|
53
55
|
|
|
54
56
|
// sticky agent
|
|
55
|
-
stickyAgentSec:
|
|
57
|
+
stickyAgentSec: clearableNumberSchema,
|
|
56
58
|
stickyIgnoreStatus: z.boolean().optional(),
|
|
57
59
|
|
|
58
60
|
// chat queues only
|
|
59
|
-
maxIdleAgent:
|
|
60
|
-
maxIdleClient:
|
|
61
|
-
maxIdleDialog:
|
|
61
|
+
maxIdleAgent: clearableNumberSchema,
|
|
62
|
+
maxIdleClient: clearableNumberSchema,
|
|
63
|
+
maxIdleDialog: clearableNumberSchema,
|
|
62
64
|
lastMessageTimeout: z.boolean().optional(),
|
|
63
65
|
|
|
64
66
|
// media
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
|
|
3
|
+
import { clearableNumberSchema } from '../_shared/clearableNumber.validations';
|
|
4
|
+
|
|
3
5
|
import { flexibleLookupSchema } from '../_shared/lookup.validations';
|
|
4
6
|
|
|
5
7
|
export const prolongationOptionsSchema = z.object({
|
|
6
8
|
enabled: z.boolean().optional(),
|
|
7
9
|
isTimeoutRetry: z.boolean().optional(),
|
|
8
|
-
prolongationTimeSec:
|
|
9
|
-
repeatsNumber:
|
|
10
|
+
prolongationTimeSec: clearableNumberSchema,
|
|
11
|
+
repeatsNumber: clearableNumberSchema,
|
|
10
12
|
});
|
|
11
13
|
|
|
12
14
|
export const taskProcessingSchema = z.object({
|
|
13
15
|
enabled: z.boolean().optional(),
|
|
14
16
|
formSchema: flexibleLookupSchema.optional(),
|
|
15
|
-
sec:
|
|
16
|
-
renewalSec:
|
|
17
|
+
sec: clearableNumberSchema,
|
|
18
|
+
renewalSec: clearableNumberSchema,
|
|
17
19
|
// `.prefault`, not `.default`: zod 4's `.default({})` does not recurse, so
|
|
18
20
|
// the nested keys would be missing and Regle would build no `$fields` for
|
|
19
21
|
// them — the prolongation block would lose its validation silently.
|