@coventia/softphone 0.3.0 → 0.4.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/dist/{call-CaPDWVk3.d.cts → call-C6YpT6uR.d.cts} +64 -1
- package/dist/{call-CaPDWVk3.d.ts → call-C6YpT6uR.d.ts} +64 -1
- package/dist/chunk-5E5OEXS2.js +14 -0
- package/dist/chunk-5E5OEXS2.js.map +1 -0
- package/dist/element/index.d.ts +56 -0
- package/dist/element/index.js +1064 -488
- package/dist/element/index.js.map +1 -1
- package/dist/{engine-CU2rEo3g.d.cts → engine-CDdaSojx.d.cts} +1 -1
- package/dist/{engine-BgBsIcEa.d.ts → engine-DPft99Wj.d.ts} +1 -1
- package/dist/index.cjs +97 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -6
- package/dist/index.d.ts +16 -6
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.cts +2 -2
- package/dist/react/index.d.ts +2 -2
- package/dist/{softphone-dZMkW8V1.d.cts → softphone-CY5d2WWY.d.cts} +3 -1
- package/dist/{softphone-DEt0TtQw.d.ts → softphone-DXgmTyrX.d.ts} +3 -1
- package/dist/softphone.css +254 -23
- package/dist/{sources-M3GYMS6V.js → sources-ONYQW733.js} +76 -8
- package/dist/sources-ONYQW733.js.map +1 -0
- package/dist/testing/index.d.cts +2 -2
- package/dist/testing/index.d.ts +2 -2
- package/dist/ui/index.cjs +578 -18
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +2 -2
- package/dist/ui/index.d.ts +2 -2
- package/dist/ui/index.js +573 -18
- package/dist/ui/index.js.map +1 -1
- package/dist/zadarma/index.d.cts +2 -2
- package/dist/zadarma/index.d.ts +2 -2
- package/package.json +1 -1
- package/dist/sources-M3GYMS6V.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as CallOptions, b as CallDirection, H as HangupReason, i as HoldOriginator,
|
|
1
|
+
import { e as CallOptions, b as CallDirection, H as HangupReason, i as HoldOriginator, w as SoftphoneState, s as SoftphoneError } from './call-C6YpT6uR.cjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The `CallEngine` seam — INTERNAL, not exported from src/index.ts.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { e as CallOptions, b as CallDirection, H as HangupReason, i as HoldOriginator,
|
|
1
|
+
import { e as CallOptions, b as CallDirection, H as HangupReason, i as HoldOriginator, w as SoftphoneState, s as SoftphoneError } from './call-C6YpT6uR.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The `CallEngine` seam — INTERNAL, not exported from src/index.ts.
|
package/dist/index.cjs
CHANGED
|
@@ -110,9 +110,9 @@ function createRequest(config, method) {
|
|
|
110
110
|
});
|
|
111
111
|
const body = await res.json().catch(() => null);
|
|
112
112
|
const message = body?.message ?? `${path} \u2014 HTTP ${res.status}`;
|
|
113
|
-
if (!res.ok) throw new ApiError(res.status, message);
|
|
113
|
+
if (!res.ok) throw new ApiError(res.status, message, body);
|
|
114
114
|
if (body?.success === false) {
|
|
115
|
-
throw new ApiError(res.status, message);
|
|
115
|
+
throw new ApiError(res.status, message, body);
|
|
116
116
|
}
|
|
117
117
|
return body;
|
|
118
118
|
}
|
|
@@ -138,15 +138,32 @@ var init_api = __esm({
|
|
|
138
138
|
init_token_cache();
|
|
139
139
|
ApiError = class extends Error {
|
|
140
140
|
status;
|
|
141
|
-
|
|
141
|
+
body;
|
|
142
|
+
constructor(status, message, body = null) {
|
|
142
143
|
super(message);
|
|
143
144
|
this.name = "ApiError";
|
|
144
145
|
this.status = status;
|
|
146
|
+
this.body = body;
|
|
145
147
|
}
|
|
146
148
|
};
|
|
147
149
|
}
|
|
148
150
|
});
|
|
149
151
|
|
|
152
|
+
// src/core/outbound-numbers.ts
|
|
153
|
+
function isOutboundNumberRefused(value) {
|
|
154
|
+
const refusal = value?.refusal;
|
|
155
|
+
return value instanceof Error && !!refusal && (refusal.reason === "platform" || refusal.reason === "user") && typeof refusal.retryAfterSeconds === "number";
|
|
156
|
+
}
|
|
157
|
+
function outboundNumberRefused(refusal) {
|
|
158
|
+
const error = new Error(`Outbound number change refused (${refusal.reason}); retry in ${refusal.retryAfterSeconds}s`);
|
|
159
|
+
error.name = "OutboundNumberRefused";
|
|
160
|
+
return Object.assign(error, { refusal });
|
|
161
|
+
}
|
|
162
|
+
var init_outbound_numbers = __esm({
|
|
163
|
+
"src/core/outbound-numbers.ts"() {
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
150
167
|
// src/coventia/sources.ts
|
|
151
168
|
var sources_exports = {};
|
|
152
169
|
__export(sources_exports, {
|
|
@@ -228,6 +245,8 @@ function coventiaSources(config) {
|
|
|
228
245
|
// row's `called_did` is the OTHER party (already `number` above); showing it again as "DID"
|
|
229
246
|
// would just repeat the row under a wrong label.
|
|
230
247
|
...toDirection(row.direction) === "inbound" && row.called_did ? { did: row.called_did } : {},
|
|
248
|
+
// And the other way round: which of the org's numbers an outbound call showed.
|
|
249
|
+
...toDirection(row.direction) === "outbound" && row.from_number ? { from: row.from_number } : {},
|
|
231
250
|
recorded,
|
|
232
251
|
handledBy,
|
|
233
252
|
// The detail page's one enrichment fetch — signed recording URLs, plus this SAME chain with
|
|
@@ -345,10 +364,10 @@ function coventiaSources(config) {
|
|
|
345
364
|
return { catalogue, orgDefault: body.orgDefault ?? null, mine: body.user ?? null, effective };
|
|
346
365
|
};
|
|
347
366
|
const CACHE_PREFIX = "coventia-softphone:ringtones:";
|
|
348
|
-
const cacheKey = async () => {
|
|
367
|
+
const cacheKey = async (prefix = CACHE_PREFIX) => {
|
|
349
368
|
try {
|
|
350
369
|
const { identity } = await config.tokenSource.getToken();
|
|
351
|
-
return `${
|
|
370
|
+
return `${prefix}${fileBase}|${config.organizationId ?? "-"}|${identity}`;
|
|
352
371
|
} catch {
|
|
353
372
|
return null;
|
|
354
373
|
}
|
|
@@ -381,6 +400,68 @@ function coventiaSources(config) {
|
|
|
381
400
|
),
|
|
382
401
|
cached: recall
|
|
383
402
|
};
|
|
403
|
+
const KINDS = /* @__PURE__ */ new Set(["landline", "mobile", "commercial", "other"]);
|
|
404
|
+
const STATES = /* @__PURE__ */ new Set(["applied", "pending", "failed", "unassigned"]);
|
|
405
|
+
const toOutboundSettings = (body) => {
|
|
406
|
+
const numbers = (body.numbers ?? []).map((n) => ({
|
|
407
|
+
id: n.id,
|
|
408
|
+
number: n.number,
|
|
409
|
+
label: n.label ?? null,
|
|
410
|
+
kind: KINDS.has(n.kind ?? "") ? n.kind : "other"
|
|
411
|
+
}));
|
|
412
|
+
const known = (id) => id && numbers.some((n) => n.id === id) ? id : null;
|
|
413
|
+
return {
|
|
414
|
+
numbers,
|
|
415
|
+
orgDefault: body.orgDefault ?? null,
|
|
416
|
+
mine: known(body.mine),
|
|
417
|
+
// Defensive: a malformed answer naming a number that is not in the list reads as the org default.
|
|
418
|
+
effective: known(body.effective) ?? known(body.orgDefault),
|
|
419
|
+
extension: body.extension ?? null,
|
|
420
|
+
state: STATES.has(body.state ?? "") ? body.state : "applied",
|
|
421
|
+
changeAvailableInSeconds: Math.max(0, Math.ceil(Number(body.changeAvailableInSeconds) || 0))
|
|
422
|
+
};
|
|
423
|
+
};
|
|
424
|
+
const OUTBOUND_PREFIX = "coventia-softphone:outbound-number:";
|
|
425
|
+
const rememberOutbound = async (settings) => {
|
|
426
|
+
const key = await cacheKey(OUTBOUND_PREFIX);
|
|
427
|
+
try {
|
|
428
|
+
if (key) globalThis.localStorage?.setItem(key, JSON.stringify(settings));
|
|
429
|
+
} catch {
|
|
430
|
+
}
|
|
431
|
+
return settings;
|
|
432
|
+
};
|
|
433
|
+
const recallOutbound = async () => {
|
|
434
|
+
const key = await cacheKey(OUTBOUND_PREFIX);
|
|
435
|
+
try {
|
|
436
|
+
const raw = key ? globalThis.localStorage?.getItem(key) : null;
|
|
437
|
+
const s = raw ? JSON.parse(raw) : null;
|
|
438
|
+
const ok = s && Array.isArray(s.numbers) && s.numbers.every((n) => typeof n?.id === "string" && typeof n.number === "string") && (s.effective === null || s.numbers.some((n) => n.id === s.effective));
|
|
439
|
+
return ok ? { ...s, changeAvailableInSeconds: 0 } : null;
|
|
440
|
+
} catch {
|
|
441
|
+
return null;
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
const outboundNumbers = {
|
|
445
|
+
get: async (signal) => rememberOutbound(toOutboundSettings(await get(`${base}/outbound-numbers`, org, signal))),
|
|
446
|
+
// `null` = back to the org default: the empty id is dropped from the query, which the backend reads that way.
|
|
447
|
+
setMine: async (id) => {
|
|
448
|
+
try {
|
|
449
|
+
return rememberOutbound(
|
|
450
|
+
toOutboundSettings(await post(`${base}/outbound-numbers/user`, { ...org, did_id: id ?? "" }))
|
|
451
|
+
);
|
|
452
|
+
} catch (error) {
|
|
453
|
+
const body = error instanceof ApiError ? error.body : null;
|
|
454
|
+
if (error instanceof ApiError && error.status === 429 && body?.code === "rate_limited") {
|
|
455
|
+
throw outboundNumberRefused({
|
|
456
|
+
reason: body.reason === "user" ? "user" : "platform",
|
|
457
|
+
retryAfterSeconds: Math.max(1, Math.ceil(Number(body.retryAfterSeconds) || 1))
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
throw error;
|
|
461
|
+
}
|
|
462
|
+
},
|
|
463
|
+
cached: recallOutbound
|
|
464
|
+
};
|
|
384
465
|
const contacts = config.contacts ?? coventiaContacts;
|
|
385
466
|
const resolve = config.resolveContact ?? (config.contacts ? resolverFromContacts(config.contacts) : coventiaResolve);
|
|
386
467
|
const history = withNameResolution(rawHistory, resolve);
|
|
@@ -393,7 +474,8 @@ function coventiaSources(config) {
|
|
|
393
474
|
listAgents: coventiaListAgents,
|
|
394
475
|
transferOutcomes,
|
|
395
476
|
presence,
|
|
396
|
-
ringtones
|
|
477
|
+
ringtones,
|
|
478
|
+
outboundNumbers
|
|
397
479
|
};
|
|
398
480
|
}
|
|
399
481
|
var toContact, toDirection, otherParty, isMissed, toOutcome, toDate, toTransferOutcome, toPresenceState, toPresenceEntry, toWebSocketUrl;
|
|
@@ -401,6 +483,7 @@ var init_sources2 = __esm({
|
|
|
401
483
|
"src/coventia/sources.ts"() {
|
|
402
484
|
init_sources();
|
|
403
485
|
init_api();
|
|
486
|
+
init_outbound_numbers();
|
|
404
487
|
toContact = (row) => ({
|
|
405
488
|
id: row.wa_id,
|
|
406
489
|
name: row.name,
|
|
@@ -2062,6 +2145,11 @@ function coventiaBackend(config, tokenSource, fallbackBaseUrl) {
|
|
|
2062
2145
|
get: async (signal) => (await load()).ringtones.get(signal),
|
|
2063
2146
|
setMine: async (id) => (await load()).ringtones.setMine(id),
|
|
2064
2147
|
cached: async () => (await load()).ringtones.cached?.() ?? null
|
|
2148
|
+
},
|
|
2149
|
+
outboundNumbers: {
|
|
2150
|
+
get: async (signal) => (await load()).outboundNumbers.get(signal),
|
|
2151
|
+
setMine: async (id) => (await load()).outboundNumbers.setMine(id),
|
|
2152
|
+
cached: async () => (await load()).outboundNumbers.cached?.() ?? null
|
|
2065
2153
|
}
|
|
2066
2154
|
};
|
|
2067
2155
|
}
|
|
@@ -2784,7 +2872,8 @@ function isCallEngine(value) {
|
|
|
2784
2872
|
|
|
2785
2873
|
// src/index.ts
|
|
2786
2874
|
init_errors();
|
|
2787
|
-
|
|
2875
|
+
init_outbound_numbers();
|
|
2876
|
+
var VERSION = "0.4.0";
|
|
2788
2877
|
|
|
2789
2878
|
exports.CALL_TRANSITIONS = CALL_TRANSITIONS;
|
|
2790
2879
|
exports.CallEvent = CallEvent;
|
|
@@ -2795,6 +2884,7 @@ exports.canTransition = canTransition;
|
|
|
2795
2884
|
exports.createSoftphone = createSoftphone;
|
|
2796
2885
|
exports.isBrowser = isBrowser;
|
|
2797
2886
|
exports.isFatal = isFatal;
|
|
2887
|
+
exports.isOutboundNumberRefused = isOutboundNumberRefused;
|
|
2798
2888
|
exports.isTerminal = isTerminal;
|
|
2799
2889
|
exports.isWebRtcSupported = isWebRtcSupported;
|
|
2800
2890
|
//# sourceMappingURL=index.cjs.map
|