@opencxh/domain 1.18.0 → 1.18.1
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/entities/channel/types.d.ts +4 -2
- package/dist/index.cjs +1 -1
- package/dist/index.js +54 -110
- package/dist/platform/capabilities.d.ts +34 -46
- package/dist/platform/communication.d.ts +54 -14
- package/dist/platform/provider.d.ts +12 -0
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IntentCapability, Uri } from '../../platform/communication';
|
|
2
2
|
export interface Channel {
|
|
3
3
|
id: string;
|
|
4
4
|
organizationId: string;
|
|
@@ -12,7 +12,9 @@ export interface Channel {
|
|
|
12
12
|
ownerId: string;
|
|
13
13
|
externalIds?: string[];
|
|
14
14
|
settings: Record<string, any>;
|
|
15
|
-
|
|
15
|
+
disabledIntents?: string[];
|
|
16
|
+
intentOverrides?: Record<string, Partial<IntentCapability>>;
|
|
17
|
+
extraIntents?: IntentCapability[];
|
|
16
18
|
enabled: boolean;
|
|
17
19
|
verified: boolean;
|
|
18
20
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var l=(t=>(t.MAILTO="mailto",t.SIP="sip",t.TEL="tel",t.WEBHOOK="webhook",t.USERNAME="username",t.ID="id",t.CUSTOM="custom",t.URL="url",t.TELEGRAM="telegram",t.WHATSAPP="whatsapp",t.VIBER="viber",t.SMS="sms",t.FAX="fax",t.TEAMS="teams",t))(l||{});function a(t){if(t.endpoints&&t.endpoints.length>0)return t.endpoints;const e=[];return t.phone&&e.push({scheme:l.TEL,resource:t.phone,primary:!0}),t.email&&e.push({scheme:l.MAILTO,resource:t.email,primary:!t.phone}),e}const p=t=>!!t.assignedUserId||!!t.assignedInboxId,d=t=>t.status==="closed",g=t=>({urgent:10,high:5,normal:2,low:1})[t.priority]||0,c=(t,e=30)=>t.title?.length<=e?t.title:`${t.title.substring(0,e)}...`;function f(t,e){const r=new Set(t.disabledIntents??[]),i=t.intentOverrides??{},n=e.intents.filter(s=>!r.has(s.intent)).map(s=>I(s,i[s.intent]));if(!t.extraIntents||t.extraIntents.length===0)return n;const o=new Set(n.map(s=>s.intent));for(const s of t.extraIntents)o.has(s.intent)||(n.push(s),o.add(s.intent));return n}function I(t,e){return e?{intent:e.intent??t.intent,targetSchemes:e.targetSchemes??t.targetSchemes,transport:e.transport??t.transport}:t}function h(t,e){const r=[];for(const i of t){if(!i.enabled)continue;const n=e[i.providerId];if(n)for(const o of f(i,n))r.push({channel:i,description:n,capability:o})}return r}function y(t,e){return e.filter(r=>r.capability.intent===t)}function u(t,e){return e.filter(r=>r.capability.targetSchemes.includes(t))}function T(t,e){return u(t.scheme,e)}function b(t,e,r){const i=[];for(const n of t)for(const o of r)o.capability.intent===e&&o.capability.targetSchemes.includes(n.scheme)&&i.push({channelIntent:o,endpoint:n});return i}exports.CommunicationScheme=l;exports.buildChannelIntents=h;exports.filterByEndpoint=T;exports.filterByIntent=y;exports.filterByTargetScheme=u;exports.getContactEndpoints=a;exports.getShortTitle=c;exports.getUrgencyScore=g;exports.isAssigned=p;exports.isClosed=d;exports.matchContactToIntents=b;exports.resolveChannelIntents=f;
|
package/dist/index.js
CHANGED
|
@@ -1,125 +1,69 @@
|
|
|
1
|
-
var
|
|
2
|
-
function
|
|
3
|
-
if (
|
|
4
|
-
return
|
|
5
|
-
const
|
|
6
|
-
return
|
|
1
|
+
var f = /* @__PURE__ */ ((t) => (t.MAILTO = "mailto", t.SIP = "sip", t.TEL = "tel", t.WEBHOOK = "webhook", t.USERNAME = "username", t.ID = "id", t.CUSTOM = "custom", t.URL = "url", t.TELEGRAM = "telegram", t.WHATSAPP = "whatsapp", t.VIBER = "viber", t.SMS = "sms", t.FAX = "fax", t.TEAMS = "teams", t))(f || {});
|
|
2
|
+
function a(t) {
|
|
3
|
+
if (t.endpoints && t.endpoints.length > 0)
|
|
4
|
+
return t.endpoints;
|
|
5
|
+
const e = [];
|
|
6
|
+
return t.phone && e.push({ scheme: f.TEL, resource: t.phone, primary: !0 }), t.email && e.push({ scheme: f.MAILTO, resource: t.email, primary: !t.phone }), e;
|
|
7
7
|
}
|
|
8
|
-
const
|
|
8
|
+
const d = (t) => !!t.assignedUserId || !!t.assignedInboxId, g = (t) => t.status === "closed", I = (t) => ({
|
|
9
9
|
urgent: 10,
|
|
10
10
|
high: 5,
|
|
11
11
|
normal: 2,
|
|
12
12
|
low: 1
|
|
13
|
-
})[
|
|
14
|
-
|
|
15
|
-
[
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
[o.TEAMS]: ["call", "message", "video"],
|
|
22
|
-
[o.FAX]: ["message"]
|
|
23
|
-
}, u = {
|
|
24
|
-
call: "transport",
|
|
25
|
-
video: "transport",
|
|
26
|
-
message: "transport",
|
|
27
|
-
mail: "compose"
|
|
28
|
-
}, p = ["call", "mail", "message", "video"];
|
|
29
|
-
function a(e, s) {
|
|
30
|
-
if (!e.supportedSchemes.includes(s)) return [];
|
|
31
|
-
const n = e.capabilities.filter(
|
|
32
|
-
(t) => t.scheme === s && t.value === !0 && p.includes(t.key)
|
|
33
|
-
);
|
|
34
|
-
return n.length > 0 ? n.map((t) => t.key) : d[s] ?? [];
|
|
35
|
-
}
|
|
36
|
-
function f(e) {
|
|
37
|
-
const s = /* @__PURE__ */ new Set();
|
|
38
|
-
for (const n of e.supportedSchemes)
|
|
39
|
-
for (const t of a(e, n)) s.add(t);
|
|
40
|
-
return Array.from(s);
|
|
41
|
-
}
|
|
42
|
-
function h(e, s, n) {
|
|
43
|
-
return e.capabilities.find(
|
|
44
|
-
(r) => r.scheme === s && r.key === n && r.value === !0
|
|
45
|
-
)?.dispatch ?? u[n];
|
|
13
|
+
})[t.priority] || 0, c = (t, e = 30) => t.title?.length <= e ? t.title : `${t.title.substring(0, e)}...`;
|
|
14
|
+
function l(t, e) {
|
|
15
|
+
const r = new Set(t.disabledIntents ?? []), i = t.intentOverrides ?? {}, n = e.intents.filter((s) => !r.has(s.intent)).map((s) => u(s, i[s.intent]));
|
|
16
|
+
if (!t.extraIntents || t.extraIntents.length === 0) return n;
|
|
17
|
+
const o = new Set(n.map((s) => s.intent));
|
|
18
|
+
for (const s of t.extraIntents)
|
|
19
|
+
o.has(s.intent) || (n.push(s), o.add(s.intent));
|
|
20
|
+
return n;
|
|
46
21
|
}
|
|
47
|
-
function
|
|
48
|
-
return
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
22
|
+
function u(t, e) {
|
|
23
|
+
return e ? {
|
|
24
|
+
intent: e.intent ?? t.intent,
|
|
25
|
+
targetSchemes: e.targetSchemes ?? t.targetSchemes,
|
|
26
|
+
transport: e.transport ?? t.transport
|
|
27
|
+
} : t;
|
|
53
28
|
}
|
|
54
|
-
function
|
|
55
|
-
const
|
|
56
|
-
for (const
|
|
57
|
-
if (!
|
|
58
|
-
const
|
|
59
|
-
if (
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
if (!i.value || !p.includes(i.key)) continue;
|
|
63
|
-
const c = i.scheme, l = i.key;
|
|
64
|
-
n.push({
|
|
65
|
-
channel: t,
|
|
66
|
-
description: r,
|
|
67
|
-
scheme: c,
|
|
68
|
-
intent: l,
|
|
69
|
-
dispatch: i.dispatch ?? u[l]
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
continue;
|
|
73
|
-
}
|
|
74
|
-
for (const i of r.supportedSchemes) {
|
|
75
|
-
const c = a(r, i);
|
|
76
|
-
for (const l of c)
|
|
77
|
-
n.push({
|
|
78
|
-
channel: t,
|
|
79
|
-
description: r,
|
|
80
|
-
scheme: i,
|
|
81
|
-
intent: l,
|
|
82
|
-
dispatch: h(r, i, l)
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
29
|
+
function h(t, e) {
|
|
30
|
+
const r = [];
|
|
31
|
+
for (const i of t) {
|
|
32
|
+
if (!i.enabled) continue;
|
|
33
|
+
const n = e[i.providerId];
|
|
34
|
+
if (n)
|
|
35
|
+
for (const o of l(i, n))
|
|
36
|
+
r.push({ channel: i, description: n, capability: o });
|
|
86
37
|
}
|
|
87
|
-
return
|
|
38
|
+
return r;
|
|
88
39
|
}
|
|
89
|
-
function y(
|
|
90
|
-
return
|
|
40
|
+
function y(t, e) {
|
|
41
|
+
return e.filter((r) => r.capability.intent === t);
|
|
91
42
|
}
|
|
92
|
-
function
|
|
93
|
-
return
|
|
43
|
+
function p(t, e) {
|
|
44
|
+
return e.filter((r) => r.capability.targetSchemes.includes(t));
|
|
94
45
|
}
|
|
95
|
-
function
|
|
96
|
-
|
|
97
|
-
for (const r of e)
|
|
98
|
-
for (const i of n)
|
|
99
|
-
i.description.supportedSchemes.includes(r.scheme) && a(i.description, r.scheme).includes(s) && t.push({ capability: i, endpoint: r });
|
|
100
|
-
return t;
|
|
46
|
+
function b(t, e) {
|
|
47
|
+
return p(t.scheme, e);
|
|
101
48
|
}
|
|
102
|
-
function
|
|
103
|
-
const
|
|
104
|
-
for (const
|
|
105
|
-
for (const
|
|
106
|
-
|
|
107
|
-
return
|
|
49
|
+
function E(t, e, r) {
|
|
50
|
+
const i = [];
|
|
51
|
+
for (const n of t)
|
|
52
|
+
for (const o of r)
|
|
53
|
+
o.capability.intent === e && o.capability.targetSchemes.includes(n.scheme) && i.push({ channelIntent: o, endpoint: n });
|
|
54
|
+
return i;
|
|
108
55
|
}
|
|
109
56
|
export {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
E as
|
|
121
|
-
|
|
122
|
-
S as resolveForContact,
|
|
123
|
-
M as resolveForEndpoint,
|
|
124
|
-
y as resolveForIntent
|
|
57
|
+
f as CommunicationScheme,
|
|
58
|
+
h as buildChannelIntents,
|
|
59
|
+
b as filterByEndpoint,
|
|
60
|
+
y as filterByIntent,
|
|
61
|
+
p as filterByTargetScheme,
|
|
62
|
+
a as getContactEndpoints,
|
|
63
|
+
c as getShortTitle,
|
|
64
|
+
I as getUrgencyScore,
|
|
65
|
+
d as isAssigned,
|
|
66
|
+
g as isClosed,
|
|
67
|
+
E as matchContactToIntents,
|
|
68
|
+
l as resolveChannelIntents
|
|
125
69
|
};
|
|
@@ -1,60 +1,48 @@
|
|
|
1
1
|
import { Channel } from '../entities/channel/types';
|
|
2
2
|
import { ContactEndpoint } from '../entities/contact/types';
|
|
3
|
-
import {
|
|
3
|
+
import { CommunicationScheme, IntentCapability, ProviderDescription, Uri } from './communication';
|
|
4
|
+
/**
|
|
5
|
+
* Reference list of intents that have built-in UI defaults (icons, labels,
|
|
6
|
+
* default composers). Intent itself is an open string — providers may
|
|
7
|
+
* declare anything. Unknown intents render as generic actions.
|
|
8
|
+
*/
|
|
4
9
|
export type CommunicationIntent = "call" | "mail" | "message" | "video";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
export interface ChannelCapability {
|
|
10
|
+
/**
|
|
11
|
+
* A channel's effective intent — the resolved IntentCapability for this
|
|
12
|
+
* specific channel, ready for routing/UI decisions.
|
|
13
|
+
*/
|
|
14
|
+
export interface ChannelIntent {
|
|
11
15
|
channel: Channel;
|
|
12
16
|
description: ProviderDescription;
|
|
13
|
-
|
|
14
|
-
intent: CommunicationIntent;
|
|
15
|
-
dispatch: CommunicationDispatch;
|
|
17
|
+
capability: IntentCapability;
|
|
16
18
|
}
|
|
17
|
-
export interface
|
|
18
|
-
|
|
19
|
+
export interface ChannelIntentMatch {
|
|
20
|
+
channelIntent: ChannelIntent;
|
|
19
21
|
endpoint: ContactEndpoint;
|
|
20
22
|
}
|
|
21
|
-
export interface ChannelCapabilityMatch {
|
|
22
|
-
capability: ChannelCapability;
|
|
23
|
-
endpoint: ContactEndpoint;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Returns which intents a provider offers for a given scheme.
|
|
27
|
-
* Capability rows whose `key` is a known user-intent (`call|mail|message|video`)
|
|
28
|
-
* are treated as explicit declarations; anything else is ignored. Empty
|
|
29
|
-
* declared list falls back to a conventional default per scheme.
|
|
30
|
-
*/
|
|
31
|
-
export declare function intentsForScheme(description: ProviderDescription, scheme: CommunicationScheme): CommunicationIntent[];
|
|
32
|
-
export declare function intentsForProvider(description: ProviderDescription): CommunicationIntent[];
|
|
33
23
|
/**
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
24
|
+
* Pure resolution of a channel's effective intents.
|
|
25
|
+
*
|
|
26
|
+
* Algorithm:
|
|
27
|
+
* 1. Start from `description.intents` (provider defaults)
|
|
28
|
+
* 2. Drop entries whose `intent` is in `channel.disabledIntents`
|
|
29
|
+
* 3. Shallow-merge `channel.intentOverrides[intent]` over the provider default
|
|
30
|
+
* 4. Append `channel.extraIntents` (deduped on `intent`)
|
|
31
|
+
*
|
|
32
|
+
* No fallback heuristics, no scheme-based defaults — provider declares the
|
|
33
|
+
* source of truth, channel patches it.
|
|
37
34
|
*/
|
|
38
|
-
export declare function
|
|
39
|
-
export declare function buildResolvedCapabilities(descriptions: Record<string, ProviderDescription>, _accounts?: CommsAccount[]): ResolvedCapability[];
|
|
35
|
+
export declare function resolveChannelIntents(channel: Channel, description: ProviderDescription): IntentCapability[];
|
|
40
36
|
/**
|
|
41
|
-
* Builds (channel ×
|
|
42
|
-
*
|
|
43
|
-
* Precedence:
|
|
44
|
-
* 1. `channel.capabilities` when present — the precise truth for *this*
|
|
45
|
-
* specific channel (e.g. one Microsoft account exposes only Teams,
|
|
46
|
-
* another only mailto). Each capability row maps directly to one
|
|
47
|
-
* ChannelCapability.
|
|
48
|
-
* 2. Fallback: provider-level `description.capabilities` × `supportedSchemes`
|
|
49
|
-
* — coarse default for backends that don't yet declare per-channel.
|
|
37
|
+
* Builds the full set of (channel × intent) entries across all channels —
|
|
38
|
+
* the source for the starter palette.
|
|
50
39
|
*/
|
|
51
|
-
export declare function
|
|
52
|
-
export declare function
|
|
53
|
-
export declare function
|
|
54
|
-
export declare function
|
|
40
|
+
export declare function buildChannelIntents(channels: Channel[], descriptions: Record<string, ProviderDescription>): ChannelIntent[];
|
|
41
|
+
export declare function filterByIntent(intent: string, items: ChannelIntent[]): ChannelIntent[];
|
|
42
|
+
export declare function filterByTargetScheme(scheme: CommunicationScheme, items: ChannelIntent[]): ChannelIntent[];
|
|
43
|
+
export declare function filterByEndpoint(uri: Uri, items: ChannelIntent[]): ChannelIntent[];
|
|
55
44
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
* how. Drives both contact-detail buttons and contact-named palette rows.
|
|
45
|
+
* Cross-product of contact endpoints × channel intents for one specific
|
|
46
|
+
* intent. One match = one row in the starter palette / contact buttons.
|
|
59
47
|
*/
|
|
60
|
-
export declare function
|
|
48
|
+
export declare function matchContactToIntents(endpoints: ContactEndpoint[], intent: string, items: ChannelIntent[]): ChannelIntentMatch[];
|
|
@@ -41,18 +41,6 @@ export interface ITransportProvider {
|
|
|
41
41
|
handleAction(sessionId: string, actionId: string, ...args: any[]): void;
|
|
42
42
|
}
|
|
43
43
|
export type CommunicationDispatch = "transport" | "compose";
|
|
44
|
-
export interface Capability {
|
|
45
|
-
scheme: string;
|
|
46
|
-
key: string;
|
|
47
|
-
value: boolean;
|
|
48
|
-
/**
|
|
49
|
-
* How this (scheme,intent) is delivered. `transport` goes through
|
|
50
|
-
* ITransportProvider.createSession (live SIP/Teams call). `compose`
|
|
51
|
-
* goes through the server-side compose endpoint with a channelId
|
|
52
|
-
* (mail, async messaging). Defaults to intent: mail=compose, rest=transport.
|
|
53
|
-
*/
|
|
54
|
-
dispatch?: CommunicationDispatch;
|
|
55
|
-
}
|
|
56
44
|
export declare enum CommunicationScheme {
|
|
57
45
|
MAILTO = "mailto",
|
|
58
46
|
SIP = "sip",
|
|
@@ -69,11 +57,63 @@ export declare enum CommunicationScheme {
|
|
|
69
57
|
FAX = "fax",
|
|
70
58
|
TEAMS = "teams"
|
|
71
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Account selector for `transport: session` intents. Tells the frontend
|
|
62
|
+
* which `CommsAccount` should service this intent on this channel.
|
|
63
|
+
* - `protocol` only: pick the first registered account with this protocol
|
|
64
|
+
* (acceptable when there is one UA per provider per tenant)
|
|
65
|
+
* - `accountId` set: pin to a specific account (multi-trunk / multi-tenant)
|
|
66
|
+
*/
|
|
67
|
+
export interface AccountSelector {
|
|
68
|
+
protocol: string;
|
|
69
|
+
accountId?: string;
|
|
70
|
+
}
|
|
71
|
+
export type TransportConfig = {
|
|
72
|
+
kind: "compose";
|
|
73
|
+
/** Optional federated composer resource as "<app>:<resource>". */
|
|
74
|
+
composer?: string;
|
|
75
|
+
/**
|
|
76
|
+
* When true, comms-app `interaction/compose` skips its auto-create
|
|
77
|
+
* and lets the provider own interaction lifecycle (e.g. Teams chat
|
|
78
|
+
* upserts on a chatId externalId).
|
|
79
|
+
*/
|
|
80
|
+
ownsInteraction?: boolean;
|
|
81
|
+
} | {
|
|
82
|
+
kind: "session";
|
|
83
|
+
accountSelector: AccountSelector;
|
|
84
|
+
ui: {
|
|
85
|
+
canvas: `${string}:${string}`;
|
|
86
|
+
actionTray?: `${string}:${string}`;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* One user-facing intent a provider/channel can perform on a target.
|
|
91
|
+
* `intent` is an open string — known values (call/mail/message/video) get
|
|
92
|
+
* default UI/labels; new ones (`schedule`, `transfer`, `record`) render as
|
|
93
|
+
* generic actions until a provider declares specialised UI.
|
|
94
|
+
*/
|
|
95
|
+
export interface IntentCapability {
|
|
96
|
+
intent: string;
|
|
97
|
+
targetSchemes: CommunicationScheme[];
|
|
98
|
+
transport: TransportConfig;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Provider-level feature flag (no routing relevance). Used for things
|
|
102
|
+
* like `call_hold`, `call_forward`, `message_reactions` that providers
|
|
103
|
+
* advertise to feature-detect, but which are not user-pickable intents.
|
|
104
|
+
*/
|
|
105
|
+
export interface ProviderFeature {
|
|
106
|
+
name: string;
|
|
107
|
+
scheme?: CommunicationScheme;
|
|
108
|
+
value: boolean;
|
|
109
|
+
}
|
|
72
110
|
export interface ProviderDescription {
|
|
73
111
|
id?: string;
|
|
74
112
|
displayName: string;
|
|
75
|
-
|
|
76
|
-
|
|
113
|
+
/** User-intents this provider offers by default. Channels inherit. */
|
|
114
|
+
intents: IntentCapability[];
|
|
115
|
+
/** Provider feature flags — separate from routing. */
|
|
116
|
+
features: ProviderFeature[];
|
|
77
117
|
}
|
|
78
118
|
export interface PersonalAuthOption {
|
|
79
119
|
id: string;
|
|
@@ -16,6 +16,18 @@ export interface ComposePayload {
|
|
|
16
16
|
channelUri?: Uri;
|
|
17
17
|
recipientUri: Uri;
|
|
18
18
|
subject?: string;
|
|
19
|
+
/**
|
|
20
|
+
* The user-intent picked in the starter / contact buttons. Lets a
|
|
21
|
+
* provider compose-handler dispatch on intent — e.g. a Microsoft
|
|
22
|
+
* mailbox with intent `message` routes to Teams chat, intent `mail`
|
|
23
|
+
* routes to Outlook send-mail. Open string for forward-compat.
|
|
24
|
+
*/
|
|
25
|
+
intent?: string;
|
|
26
|
+
/**
|
|
27
|
+
* Channel-specific extras — template_id, attachments, location, etc.
|
|
28
|
+
* Provider compose-handlers may read this; defaults ignore it.
|
|
29
|
+
*/
|
|
30
|
+
extra?: Record<string, any>;
|
|
19
31
|
}
|
|
20
32
|
export interface ComposeResponse {
|
|
21
33
|
messageId: string;
|