@opencxh/domain 1.128.0 → 1.131.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/entities/activity/index.d.ts +1 -0
- package/dist/entities/activity/timestamp.d.ts +15 -0
- package/dist/entities/company/index.d.ts +1 -0
- package/dist/entities/company/types.d.ts +50 -0
- package/dist/entities/contact/types.d.ts +29 -0
- package/dist/entities/contact-source/index.d.ts +1 -0
- package/dist/entities/contact-source/types.d.ts +56 -0
- package/dist/entities/interaction/types.d.ts +15 -0
- package/dist/entities/memory/item.d.ts +36 -1
- package/dist/entities/memory/query.d.ts +42 -0
- package/dist/entities/organization/types.d.ts +7 -0
- package/dist/entities/playbook/trigger-vars.d.ts +6 -0
- package/dist/index.cjs +7 -7
- package/dist/index.d.ts +3 -0
- package/dist/index.js +452 -239
- package/dist/platform/ai-tools.d.ts +19 -0
- package/dist/platform/communication.d.ts +15 -9
- package/dist/platform/scope.d.ts +25 -0
- package/dist/platform/services.d.ts +18 -1
- package/dist/text/endpoint.d.ts +104 -0
- package/dist/text/endpoint.test.d.ts +1 -0
- package/dist/text/region.test.d.ts +1 -0
- package/package.json +8 -4
|
@@ -19,6 +19,25 @@ export interface AiTool {
|
|
|
19
19
|
description: string;
|
|
20
20
|
parameters: AiToolParameterSchema;
|
|
21
21
|
}
|
|
22
|
+
/**
|
|
23
|
+
* One entry in the tool catalog: what is available in this organisation right now.
|
|
24
|
+
*
|
|
25
|
+
* Lives in domain because three places already had their own copy (the AI server's
|
|
26
|
+
* registry and two of its client hooks) and the contact-source register needs a fourth —
|
|
27
|
+
* the catalog is what an organisation picks an external contact source from.
|
|
28
|
+
*/
|
|
29
|
+
export interface ToolCatalogEntry {
|
|
30
|
+
name: string;
|
|
31
|
+
description: string;
|
|
32
|
+
/** "mcp" for external MCP tools, otherwise the owning app name. */
|
|
33
|
+
source: string;
|
|
34
|
+
/** JSON-Schema of the tool's arguments — drives the playbook builder's param form. */
|
|
35
|
+
parameters: AiToolParameterSchema;
|
|
36
|
+
/** read | write as the tool declares it; absent = unknown. */
|
|
37
|
+
access?: "read" | "write";
|
|
38
|
+
/** internal | outward as the tool declares it; absent = outward. */
|
|
39
|
+
effect?: "internal" | "outward";
|
|
40
|
+
}
|
|
22
41
|
/** A model's request to call a tool. */
|
|
23
42
|
export interface AiToolCall {
|
|
24
43
|
id: string;
|
|
@@ -44,6 +44,12 @@ export interface CommsAccount<T = any> {
|
|
|
44
44
|
userId: string;
|
|
45
45
|
config: T;
|
|
46
46
|
status: 'registered' | 'unregistered' | 'error';
|
|
47
|
+
/**
|
|
48
|
+
* The channel this registration serves. Set by the transport provider from
|
|
49
|
+
* its registration config; this is what binds an outgoing intent on a
|
|
50
|
+
* channel to the right account when several are registered at once.
|
|
51
|
+
*/
|
|
52
|
+
channelId?: string;
|
|
47
53
|
}
|
|
48
54
|
export interface ITransportProvider {
|
|
49
55
|
readonly id: string;
|
|
@@ -79,19 +85,19 @@ export declare enum CommunicationScheme {
|
|
|
79
85
|
CALENDAR = "calendar"
|
|
80
86
|
}
|
|
81
87
|
/**
|
|
82
|
-
* Account selector for `transport: session` intents.
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
88
|
-
*
|
|
89
|
-
*
|
|
88
|
+
* Account selector for `transport: session` intents. Narrows the registered
|
|
89
|
+
* `CommsAccount`s down to the one that should service this intent.
|
|
90
|
+
*
|
|
91
|
+
* `protocol` is the filter axis rather than a provider id because the two id
|
|
92
|
+
* spaces don't line up: `channel.providerId` is the *server* provider (e.g.
|
|
93
|
+
* eylo-voip) while `account.providerId` is the *transport* provider (e.g.
|
|
94
|
+
* sip-provider). Which of the remaining candidates is picked is decided by the
|
|
95
|
+
* binding on the account itself (`CommsAccount.channelId`) — `accountId` is
|
|
96
|
+
* only a static pin for providers that have no per-channel binding.
|
|
90
97
|
*/
|
|
91
98
|
export interface AccountSelector {
|
|
92
99
|
protocol: string;
|
|
93
100
|
accountId?: string;
|
|
94
|
-
matcherId?: string;
|
|
95
101
|
}
|
|
96
102
|
/**
|
|
97
103
|
* Routing-hint voor de frontend en de comm-server: hoe wordt deze intent
|
package/dist/platform/scope.d.ts
CHANGED
|
@@ -21,6 +21,31 @@ export interface ScopeAuth {
|
|
|
21
21
|
* onbekend, en dat wordt daar als "versmallen" gelezen: de veilige kant.
|
|
22
22
|
*/
|
|
23
23
|
ownerScope?: OwnerScope;
|
|
24
|
+
/**
|
|
25
|
+
* De **dossiersleutels** waaronder deze resource valt: de canonieke sleutels waarmee andere
|
|
26
|
+
* apps hem in één geïndexeerde `$in` terugvinden.
|
|
27
|
+
*
|
|
28
|
+
* Dit is de ene conventie waarmee verbanden in dit platform worden uitgedrukt. Deze
|
|
29
|
+
* datastore kan niet joinen en niet recursief traverseren, dus een edge-*tabel* zou van
|
|
30
|
+
* elke vraag een keten van `$in`-hops met een groeiende idlijst maken. In plaats daarvan
|
|
31
|
+
* draagt elke contextdragende rij zijn eigen sleutels, platgeslagen op **schrijfmoment**:
|
|
32
|
+
* `Interaction.partyKeys` doet dat al, `Contact.keys`/`Company.keys` ook, en de
|
|
33
|
+
* geheugenlaag stempelt ze via dit veld op zijn items (`MemoryItem.keys`).
|
|
34
|
+
*
|
|
35
|
+
* Het vocabulaire is dat van `endpointKey`: `mailto:`, `tel:`, `domain:`, plus de
|
|
36
|
+
* vastgelegde `contact:<id>` / `company:<id>` / `interaction:<id>`. Twee rollen, één
|
|
37
|
+
* vorm — *identiteit* ("dit ben ik", `Contact.keys`) en *verwijzing* ("hier hoor ik bij",
|
|
38
|
+
* `partyKeys`).
|
|
39
|
+
*
|
|
40
|
+
* **Klein houden.** Dit is de set van de rij zelf, niet zijn hele omgeving: een company
|
|
41
|
+
* geeft zijn eigen sleutels en domeinen, níet die van tweehonderd medewerkers. Die
|
|
42
|
+
* fan-out hoort bij een expliciete zoekvraag (`keySetForCompany`), niet bij elke
|
|
43
|
+
* autorisatie — deze call zit op het hete pad van elke geheugen-schrijfactie.
|
|
44
|
+
*
|
|
45
|
+
* Afwezig = onbekend, en dat wordt gelezen als "alleen het subject zelf": minder
|
|
46
|
+
* vindbaar, nooit ruimer. Dezelfde richting als {@link ScopeAuth.ownerScope}.
|
|
47
|
+
*/
|
|
48
|
+
keys?: string[];
|
|
24
49
|
}
|
|
25
50
|
/** GET /provider/scope/describe response: the scopeKey prefixes an app owns. */
|
|
26
51
|
export interface ScopeDescribe {
|
|
@@ -36,7 +36,24 @@ export type ServiceHandlerMetadata<P = any, T = any, R = any> = {
|
|
|
36
36
|
appId: string;
|
|
37
37
|
fn: ServiceHandlerFn<P, T, R>;
|
|
38
38
|
};
|
|
39
|
-
|
|
39
|
+
/**
|
|
40
|
+
* `T` defaults to `unknown` because most handlers only care about `params`.
|
|
41
|
+
* Spelling it `never` instead makes the handler unassignable to
|
|
42
|
+
* {@link ServiceHandlerFn} (whose `payload` is `any`), which is a confusing error
|
|
43
|
+
* for a service that simply takes no payload.
|
|
44
|
+
*/
|
|
45
|
+
export type ServiceCallOptions<P, T = unknown> = {
|
|
40
46
|
params?: P;
|
|
41
47
|
payload?: T;
|
|
48
|
+
/**
|
|
49
|
+
* Restrict this call to these provider apps.
|
|
50
|
+
*
|
|
51
|
+
* Without it the only participation filter is "is the app installed for this org",
|
|
52
|
+
* which is all-or-nothing and the same switch that controls the app's routes and
|
|
53
|
+
* settings pages. A caller that has a per-source preference (which address books may
|
|
54
|
+
* be searched) needs to narrow one call without uninstalling anything.
|
|
55
|
+
*
|
|
56
|
+
* Absent means every enabled handler, which is the previous behaviour.
|
|
57
|
+
*/
|
|
58
|
+
appIds?: string[];
|
|
42
59
|
};
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One normalisation for communication endpoints — phone numbers, e-mail addresses
|
|
3
|
+
* and the lookup keys built from them.
|
|
4
|
+
*
|
|
5
|
+
* Before this module there were five copies of `resource.replace(/[\s()-]/g, "")`
|
|
6
|
+
* spread over eylo-voip, microsoft and three comms services, plus a sixth variant
|
|
7
|
+
* with `+31` hardcoded. None of them turned a national number into an international
|
|
8
|
+
* one, so `0882112121` never matched `+31882112121`. Every lookup key in the platform
|
|
9
|
+
* has to be produced here, or the write side and the read side drift apart and the
|
|
10
|
+
* index is worthless.
|
|
11
|
+
*
|
|
12
|
+
* Deliberately dependency-free: `libphonenumber-js` is ~145 kB for a rule we express
|
|
13
|
+
* in a table. The honest cost is that we cannot validate per-country number *plans*,
|
|
14
|
+
* only plausible lengths — so we reject implausible input instead of forcing it, and
|
|
15
|
+
* callers keep the raw value for display.
|
|
16
|
+
*/
|
|
17
|
+
/** A dialling plan entry: enough to normalise, not enough to validate a number plan. */
|
|
18
|
+
export interface PhoneRegion {
|
|
19
|
+
/** E.164 country calling code, without `+`. */
|
|
20
|
+
callingCode: string;
|
|
21
|
+
/** Prefix used when dialling domestically (dropped when going international). */
|
|
22
|
+
trunkPrefix?: string;
|
|
23
|
+
/** Plausible length of the national significant number, excluding the trunk prefix. */
|
|
24
|
+
nsnMin: number;
|
|
25
|
+
nsnMax: number;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The regions we serve. Adding one is a table entry, not code — but do add it: a
|
|
29
|
+
* missing region means every national number from that country resolves to `null`.
|
|
30
|
+
*/
|
|
31
|
+
export declare const PHONE_REGIONS: Record<string, PhoneRegion>;
|
|
32
|
+
/** Fallback when no organisation region is configured. */
|
|
33
|
+
export declare const DEFAULT_PHONE_REGION = "NL";
|
|
34
|
+
/**
|
|
35
|
+
* True when a value looks like an e-mail address rather than a SIP-style phone URI.
|
|
36
|
+
*
|
|
37
|
+
* Both contain an `@`, so presence of one proves nothing: `0653928801@demo1.eylo.tel` is a
|
|
38
|
+
* phone number. The local part decides — digits and phone punctuation mean a number.
|
|
39
|
+
*/
|
|
40
|
+
export declare function looksLikeEmail(value: string | undefined | null): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Turn any written form of a phone number into `+<callingCode><nsn>`, or `null` when
|
|
43
|
+
* it cannot be resolved without guessing.
|
|
44
|
+
*
|
|
45
|
+
* | input | output |
|
|
46
|
+
* |---|---|
|
|
47
|
+
* | `+31 88 211 2121` | `+31882112121` |
|
|
48
|
+
* | `0031882112121` | `+31882112121` |
|
|
49
|
+
* | `088 211 2121` (region NL) | `+31882112121` |
|
|
50
|
+
* | `882112121` | `null` — ambiguous, we do not guess |
|
|
51
|
+
*
|
|
52
|
+
* Resolution order for the region: an explicit `+` or `00` wins, then `defaultRegion`
|
|
53
|
+
* (the organisation setting, or the region of the channel the call came in on).
|
|
54
|
+
*/
|
|
55
|
+
export declare function toE164(raw: string | undefined | null, defaultRegion?: string): string | null;
|
|
56
|
+
/**
|
|
57
|
+
* The last 8-9 digits of a number, notation-independent: `+31882112121`,
|
|
58
|
+
* `0882112121` and `088 211 2121` all share `882112121`.
|
|
59
|
+
*
|
|
60
|
+
* Use it to ORDER candidates for a human. Never to link automatically — short
|
|
61
|
+
* suffixes collide across borders and direct-dial ranges make it worse.
|
|
62
|
+
*/
|
|
63
|
+
export declare function phoneSuffix(raw: string | undefined | null, length?: number): string | null;
|
|
64
|
+
/**
|
|
65
|
+
* Lowercase, trim and drop a `+tag` sub-address, so `Naam+factuur@Bedrijf.NL`
|
|
66
|
+
* matches `naam@bedrijf.nl`.
|
|
67
|
+
*/
|
|
68
|
+
export declare function normalizeEmail(raw: string | undefined | null): string | null;
|
|
69
|
+
/** The domain part of an e-mail address, already normalised. */
|
|
70
|
+
export declare function emailDomain(raw: string | undefined | null): string | null;
|
|
71
|
+
/**
|
|
72
|
+
* The registrable part of a host: `mail.bedrijf.nl` → `bedrijf.nl`,
|
|
73
|
+
* `mail.bedrijf.co.uk` → `bedrijf.co.uk`. A subdomain belongs to the same company.
|
|
74
|
+
*
|
|
75
|
+
* This is a short list, not the public suffix list — a dependency-free approximation
|
|
76
|
+
* that is right for the regions we serve and degrades to "one label too many", never
|
|
77
|
+
* to a public suffix on its own.
|
|
78
|
+
*/
|
|
79
|
+
export declare function registrableDomain(host: string | undefined | null): string | null;
|
|
80
|
+
/**
|
|
81
|
+
* Free-mail and consumer domains. A company row with `gmail.com` in `domains` would
|
|
82
|
+
* map EVERY private customer onto itself — not an edge case but the first time
|
|
83
|
+
* somebody saves a Gmail address on a company.
|
|
84
|
+
*/
|
|
85
|
+
export declare const PUBLIC_EMAIL_DOMAINS: Set<string>;
|
|
86
|
+
/** True when a domain is consumer mail and must never identify a company. */
|
|
87
|
+
export declare function isPublicEmailDomain(domain: string | undefined | null): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Does normalising this scheme need a phone region?
|
|
90
|
+
*
|
|
91
|
+
* Worth asking before resolving one: the region lives on the organisation, so fetching it
|
|
92
|
+
* is a cross-app round trip, while an e-mail address has no region at all. A mail-only
|
|
93
|
+
* lookup that resolves the region anyway pays for four internal RPCs it never uses.
|
|
94
|
+
*/
|
|
95
|
+
export declare function needsPhoneRegion(scheme: string | undefined | null): boolean;
|
|
96
|
+
/**
|
|
97
|
+
* The canonical, indexable lookup key for an endpoint: `tel:+31882112121`,
|
|
98
|
+
* `mailto:naam@bedrijf.nl`. Returns `null` when the resource cannot be normalised —
|
|
99
|
+
* an un-normalisable value must never reach a key array, or the index lies.
|
|
100
|
+
*
|
|
101
|
+
* `scheme` is the lowercase `CommunicationScheme` value; this module deliberately does
|
|
102
|
+
* not import that enum so it stays usable from the write path of any app.
|
|
103
|
+
*/
|
|
104
|
+
export declare function endpointKey(scheme: string | undefined | null, resource: string | undefined | null, defaultRegion?: string): string | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opencxh/domain",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.131.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -10,14 +10,18 @@
|
|
|
10
10
|
],
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "vite build",
|
|
13
|
-
"typecheck": "tsc --noEmit"
|
|
13
|
+
"typecheck": "tsc --noEmit",
|
|
14
|
+
"test": "vitest",
|
|
15
|
+
"test:run": "vitest run",
|
|
16
|
+
"test:watch": "vitest --watch"
|
|
14
17
|
},
|
|
15
18
|
"peerDependencies": {
|
|
16
19
|
"rxjs": "^7.8.2"
|
|
17
20
|
},
|
|
18
21
|
"devDependencies": {
|
|
19
|
-
"typescript": "
|
|
22
|
+
"typescript": "6.0.3",
|
|
20
23
|
"vite": "7.1.7",
|
|
21
|
-
"vite-plugin-dts": "^
|
|
24
|
+
"vite-plugin-dts": "^5.0.3",
|
|
25
|
+
"vitest": "^4.0.18"
|
|
22
26
|
}
|
|
23
27
|
}
|