@dszp/netsapiens-lib 0.3.1 → 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/README.md CHANGED
@@ -61,17 +61,21 @@ Two composites are provided because they're multi-read and worth getting right o
61
61
  | `listDomains(client)` | `/domains` → `{domain, description, locked}[]` |
62
62
  | `fetchDomainSnapshot(client, domain, opts?)` | `/domains/{d}` plus, in parallel, `timeframes`, `users`, `callqueues`, `phonenumbers`, `autoattendants` — then per-user `answerrules`. Individual reads fail **soft** (a missing collection yields `[]`, not a thrown snapshot). |
63
63
 
64
- The snapshot is the routing subset — what `resolveFlow()` needs. It is not a full domain export. Three
64
+ The snapshot is the routing subset — what `resolveFlow()` needs. It is not a full domain export. Four
65
65
  options pull in more, each off by default because each costs an extra read: `includeAddresses` (E911
66
- address records), `includeSmsNumbers` (SMS-enabled numbers), and `includeDevices` (per-extension device
67
- records — one `/devices` read per real extension, so it is the expensive one on a domain with many seats).
68
- All three exist for `countDomainInventory()` below; a caller that only resolves call flows never needs them.
66
+ address records), `includeSmsNumbers` (the domain-level SMS-enabled number list), `includeDevices`
67
+ (per-extension device records — one `/devices` read per real extension, so it is the expensive one on a
68
+ domain with many seats), and `includeUserSmsNumbers` (per-extension SMS numbers into
69
+ `snapshot.smsNumbersByUser` — same one-read-per-extension cost, needed because the domain-level list
70
+ doesn't say which user a number belongs to). All four exist for `countDomainInventory()` below; a caller
71
+ that only resolves call flows never needs them.
69
72
 
70
73
  A per-extension devices read that fails with anything other than 404 does not abort the snapshot — the
71
74
  extension stays in `users` with no entry in `devicesByUser`, and its number is recorded in
72
75
  `snapshot.deviceReadFailures` instead. `deviceReadFailures` is set whenever `includeDevices` was asked
73
76
  for (an empty array when nothing failed) and absent otherwise, so a device-count consumer can tell a
74
77
  genuine zero from a read that never completed rather than silently undercounting.
78
+ `includeUserSmsNumbers` fails the same way into `snapshot.smsReadFailures`.
75
79
 
76
80
  ### Counting a domain: `countDomainInventory`
77
81
 
@@ -157,6 +161,18 @@ const premium = itemsFor(detail, 'extensions.byServiceCode.premium') ?? [];
157
161
  premium.map(itemLabel); // e.g. ["101 — Jane Doe, North", "102"]
158
162
  ```
159
163
 
164
+ A domain often serves several billing accounts or physical sites at once, and a consumer reconciling
165
+ against one of them needs to know which inventory items are actually its own. `attributeDomainInventory(snapshot)`
166
+ answers that: it's pure (no account knowledge, just the snapshot) and labels every extension, number,
167
+ address and SMS number either `own-site` (the item's own site matches), `via-user:<ext>` /
168
+ `via-users:<exts>` (it's reachable only through another item that has a site), or an
169
+ `unattributed:<reason>` — `no-site`, `routed-to:<x>`, `shared-across:<sites>`, `unreferenced`, or
170
+ `sms-user-unknown` when a domain-level SMS number can't be matched to a user because the snapshot was
171
+ never fetched with `includeUserSmsNumbers`. Filter `listDomainInventory(snapshot)`'s items by that
172
+ attribution to scope a domain down to one site, then run `countInventoryDetail(detail)` over what's left
173
+ to get counts that agree with what you kept, rather than recomputing `countDomainInventory` against the
174
+ whole domain and hoping the numbers happen to match.
175
+
160
176
  ### Read/write split by charter
161
177
 
162
178
  `NsClient` exposes **`get()` and nothing else**, and `verify()` only ever issues `GET /jwt`. That is a
@@ -0,0 +1,11 @@
1
+ import type { Snapshot } from './model.js';
2
+ export interface ItemAttribution {
3
+ /** The site this item belongs to; `null` when it cannot be placed. */
4
+ site: string | null;
5
+ /** `own-site` | `via-user:<ext>` | `via-users:<ext,ext>` | `unattributed:<reason>`. */
6
+ how: string;
7
+ }
8
+ export interface DomainAttribution {
9
+ items: Record<string, ItemAttribution>;
10
+ }
11
+ export declare function attributeDomainInventory(snapshot: Snapshot): DomainAttribution;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAkCA,OAAO,KAAK,EAAO,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uFAAuF;IACvF,GAAG,EAAE,MAAM,CAAC;CACb;AACD,MAAM,WAAW,iBAAiB;IAAG,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAAE;AAI7E,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,GAAG,iBAAiB,CA0D9E"}
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Which SITE each inventory item belongs to, and how that was decided. Pure: feed it the same
3
+ * `Snapshot` `listDomainInventory` takes, get one verdict per item key.
4
+ *
5
+ * ## Why a library concern
6
+ *
7
+ * A NetSapiens domain can be billed in pieces — one account per site, or one account for most of
8
+ * it and another for one branch — and the phone system already knows most of what is needed to
9
+ * split it: a user carries `site`, a number carries its destination user, an SMS number is enabled
10
+ * on a user, an address is referenced by users. What it does NOT know is who pays; that stays with
11
+ * the consumer. This module answers "which site", never "which account".
12
+ *
13
+ * ## The rules
14
+ *
15
+ * - An extension: its own `site` (`own-site`), or `unattributed:no-site` when blank.
16
+ * - A number: the site of its `dial-rule-translation-destination-user` when that names a REAL
17
+ * extension (`via-user:<ext>`), whatever the application — `to-user`, `to-single-device`. When it
18
+ * names a system user (a queue, an attendant, a time-of-day router are users too) the reason is
19
+ * `routed-to:<that user's service-code>`; when it names nobody, `routed-to:<application>`; a real
20
+ * user with no site is `no-site`.
21
+ * - An address: the one site every REAL extension referencing it sits on (`via-users:<exts>`);
22
+ * `shared-across:<sites>` when they sit on more than one; `unreferenced` when none does;
23
+ * `no-site` when the referencing users have no site.
24
+ * - An SMS number: the site of the user whose per-user list carries it (`via-user:<ext>`), or
25
+ * `sms-user-unknown` when no per-user list does — including when the per-user read was never
26
+ * made. Never guessed from the domain-level list, which does not say.
27
+ *
28
+ * ## Keys are joined by index
29
+ *
30
+ * `listDomainInventory` maps each source array 1:1 and in order, and this module relies on that to
31
+ * put an item's KEY (which may be a derived `~hash`) beside its RECORD's routing fields. That
32
+ * invariant is this library's own, and this is the one place allowed to lean on it.
33
+ */
34
+ import { isSystemUser, listDomainInventory, str } from './inventory.js';
35
+ const none = (reason) => ({ site: null, how: `unattributed:${reason}` });
36
+ export function attributeDomainInventory(snapshot) {
37
+ const users = Array.isArray(snapshot.users) ? snapshot.users : [];
38
+ const phonenumbers = Array.isArray(snapshot.phonenumbers) ? snapshot.phonenumbers : [];
39
+ const addresses = Array.isArray(snapshot.addresses) ? snapshot.addresses : [];
40
+ const smsnumbers = Array.isArray(snapshot.smsnumbers) ? snapshot.smsnumbers : [];
41
+ const byUser = snapshot.smsNumbersByUser;
42
+ const d = listDomainInventory(snapshot);
43
+ const items = {};
44
+ const userByExt = new Map();
45
+ for (const u of users) {
46
+ const ext = str(u.user);
47
+ if (ext && !userByExt.has(ext))
48
+ userByExt.set(ext, u);
49
+ }
50
+ // Extensions: the detail already carries `site`, so no record is needed here.
51
+ for (const x of d.extensions)
52
+ items[x.key] = x.site ? { site: x.site, how: 'own-site' } : none('no-site');
53
+ // Numbers, by index against `phonenumbers`.
54
+ for (let i = 0; i < d.dids.length; i++) {
55
+ const key = d.dids[i].key, p = phonenumbers[i] ?? {};
56
+ const app = str(p['dial-rule-application']) || 'unknown';
57
+ const dest = str(p['dial-rule-translation-destination-user']);
58
+ const u = dest ? userByExt.get(dest) : undefined;
59
+ if (!u) {
60
+ items[key] = none(`routed-to:${app}`);
61
+ continue;
62
+ }
63
+ if (isSystemUser(u)) {
64
+ items[key] = none(`routed-to:${str(u['service-code'])}`);
65
+ continue;
66
+ }
67
+ const site = str(u.site);
68
+ items[key] = site ? { site, how: `via-user:${dest}` } : none('no-site');
69
+ }
70
+ // Addresses, by index against `addresses`; referenced by REAL extensions only.
71
+ const refs = new Map();
72
+ for (const u of users) {
73
+ if (isSystemUser(u))
74
+ continue;
75
+ const id = str(u['emergency-address-id']);
76
+ if (!id)
77
+ continue;
78
+ const list = refs.get(id) ?? [];
79
+ list.push(u);
80
+ refs.set(id, list);
81
+ }
82
+ for (let i = 0; i < d.e911Addresses.length; i++) {
83
+ const key = d.e911Addresses[i].key, id = str((addresses[i] ?? {})['emergency-address-id']);
84
+ const who = id ? refs.get(id) ?? [] : [];
85
+ if (!who.length) {
86
+ items[key] = none('unreferenced');
87
+ continue;
88
+ }
89
+ const sites = [...new Set(who.map((u) => str(u.site)).filter(Boolean))].sort();
90
+ if (sites.length === 0)
91
+ items[key] = none('no-site');
92
+ else if (sites.length === 1)
93
+ items[key] = { site: sites[0], how: `via-users:${who.map((u) => str(u.user)).filter(Boolean).sort().join(',')}` };
94
+ else
95
+ items[key] = none(`shared-across:${sites.join(',')}`);
96
+ }
97
+ // SMS numbers, by index against `smsnumbers`, joined to a user through the per-user lists.
98
+ const extBySms = new Map();
99
+ if (byUser)
100
+ for (const [ext, list] of Object.entries(byUser))
101
+ for (const s of Array.isArray(list) ? list : []) {
102
+ const n = str(s.number);
103
+ if (n && !extBySms.has(n))
104
+ extBySms.set(n, ext);
105
+ }
106
+ for (let i = 0; i < d.smsNumbers.length; i++) {
107
+ const key = d.smsNumbers[i].key, n = str((smsnumbers[i] ?? {}).number);
108
+ const ext = n ? extBySms.get(n) : undefined;
109
+ const u = ext ? userByExt.get(ext) : undefined;
110
+ if (!u) {
111
+ items[key] = none('sms-user-unknown');
112
+ continue;
113
+ }
114
+ const site = str(u.site);
115
+ items[key] = site ? { site, how: `via-user:${ext}` } : none('no-site');
116
+ }
117
+ return { items };
118
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribution.js","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAWxE,MAAM,IAAI,GAAG,CAAC,MAAc,EAAmB,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,MAAM,EAAE,EAAE,CAAC,CAAC;AAElG,MAAM,UAAU,wBAAwB,CAAC,QAAkB;IACzD,MAAM,KAAK,GAAU,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACzE,MAAM,YAAY,GAAU,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9F,MAAM,SAAS,GAAU,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IACrF,MAAM,UAAU,GAAU,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;IACxF,MAAM,MAAM,GAAG,QAAQ,CAAC,gBAAgB,CAAC;IACzC,MAAM,CAAC,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,KAAK,GAAoC,EAAE,CAAC;IAElD,MAAM,SAAS,GAAG,IAAI,GAAG,EAAe,CAAC;IACzC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QAAC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAAC,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAAC,CAAC;IAE1G,8EAA8E;IAC9E,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAE1G,4CAA4C;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,GAAG,EAAE,CAAC,GAAG,YAAY,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtD,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,IAAI,SAAS,CAAC;QACzD,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,wCAAwC,CAAC,CAAC,CAAC;QAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,IAAI,CAAC,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC5D,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC5F,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC1E,CAAC;IAED,+EAA+E;IAC/E,MAAM,IAAI,GAAG,IAAI,GAAG,EAAiB,CAAC;IACtC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,IAAI,YAAY,CAAC,CAAC,CAAC;YAAE,SAAS;QAC9B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE;YAAE,SAAS;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;QAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACpE,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAChD,MAAM,GAAG,GAAG,CAAC,CAAC,aAAa,CAAC,CAAC,CAAE,CAAC,GAAG,EAAE,EAAE,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;QAC5F,MAAM,GAAG,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QACjE,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/E,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC;aAChD,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAE,EAAE,GAAG,EAAE,aAAa,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;;YAC3I,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,iBAAiB,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7D,CAAC;IAED,2FAA2F;IAC3F,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAC;IAC3C,IAAI,MAAM;QAAE,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC;YAAE,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;gBAAC,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;oBAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAAC,CAAC;IAC5L,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACxE,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAC/C,IAAI,CAAC,CAAC,EAAE,CAAC;YAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC,CAAC;YAAC,SAAS;QAAC,CAAC;QAC5D,MAAM,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QACzB,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,YAAY,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzE,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC"}
package/dist/index.d.ts CHANGED
@@ -16,7 +16,8 @@ export { THEMES, DEFAULT_LIGHT_THEME, DEFAULT_DARK_THEME, NODE_LIGHT, NODE_DARK,
16
16
  export { renderGalleryHtml, renderFlowCards, renderFlowCard, mermaidBootstrap, flowAnchorId, type GalleryOptions, type CardOptions, } from './html.js';
17
17
  export { resolveSvgSize, rasterizerScript } from './raster.js';
18
18
  export { NsClient, NsApiError, assertBareServer, fetchDomainSnapshot, listDomains, asArray, type NsClientConfig, type FetchSnapshotOptions } from './nsClient.js';
19
- export { countDomainInventory, listDomainInventory, itemsFor, itemLabel, type DomainInventory, type DomainInventoryDetail, type ExtensionItem, type NumberItem, type AddressItem, type SmsItem, type InventoryItem } from './inventory.js';
19
+ export { countDomainInventory, countInventoryDetail, listDomainInventory, itemsFor, itemLabel, type DomainInventory, type DomainInventoryDetail, type ExtensionItem, type NumberItem, type AddressItem, type SmsItem, type InventoryItem } from './inventory.js';
20
+ export { attributeDomainInventory, type DomainAttribution, type ItemAttribution } from './attribution.js';
20
21
  export { NsWriteClient, type NsWriteClientConfig } from './nsWriteClient.js';
21
22
  export { supportsSynchronous, SYNCHRONOUS_OPERATIONS, type SynchronousMethod, type SynchronousOperation, } from './nsSynchronous.js';
22
23
  export { ensureNsDevice, generateSipPassword, SIP_PW_FIELD, type NsDeviceWriter, type EnsureNsDeviceOptions, type EnsureNsDeviceResult, } from './nsDevice.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -15,7 +15,8 @@ export { THEMES, DEFAULT_LIGHT_THEME, DEFAULT_DARK_THEME, NODE_LIGHT, NODE_DARK,
15
15
  export { renderGalleryHtml, renderFlowCards, renderFlowCard, mermaidBootstrap, flowAnchorId, } from './html.js';
16
16
  export { resolveSvgSize, rasterizerScript } from './raster.js';
17
17
  export { NsClient, NsApiError, assertBareServer, fetchDomainSnapshot, listDomains, asArray } from './nsClient.js';
18
- export { countDomainInventory, listDomainInventory, itemsFor, itemLabel } from './inventory.js';
18
+ export { countDomainInventory, countInventoryDetail, listDomainInventory, itemsFor, itemLabel } from './inventory.js';
19
+ export { attributeDomainInventory } from './attribution.js';
19
20
  export { NsWriteClient } from './nsWriteClient.js';
20
21
  export { supportsSynchronous, SYNCHRONOUS_OPERATIONS, } from './nsSynchronous.js';
21
22
  export { ensureNsDevice, generateSipPassword, SIP_PW_FIELD, } from './nsDevice.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAuC,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,MAAM,EACN,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,GAKV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,GAGb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,EAAkD,MAAM,eAAe,CAAC;AAClK,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAA6I,MAAM,gBAAgB,CAAC;AAC3O,OAAO,EAAE,aAAa,EAA4B,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GAGvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,GAIb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAiD,MAAM,mBAAmB,CAAC;AAC7G,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAUlB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,QAAQ,EACR,kBAAkB,GAOnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAwB,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,YAAY,GAIb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,SAAS,EACT,GAAG,GAIJ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GAOpB,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAkB,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAuC,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,MAAM,EACN,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,GAKV,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,GAGb,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,WAAW,EAAE,OAAO,EAAkD,MAAM,eAAe,CAAC;AAClK,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAA6I,MAAM,gBAAgB,CAAC;AACjQ,OAAO,EAAE,wBAAwB,EAAgD,MAAM,kBAAkB,CAAC;AAC1G,OAAO,EAAE,aAAa,EAA4B,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EACL,mBAAmB,EACnB,sBAAsB,GAGvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,GAIb,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAiD,MAAM,mBAAmB,CAAC;AAC7G,OAAO,EACL,qBAAqB,EACrB,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,oBAAoB,EACpB,iBAAiB,EACjB,iBAAiB,EACjB,iBAAiB,GAUlB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,QAAQ,EACR,kBAAkB,GAOnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAwB,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,YAAY,GAIb,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,SAAS,EACT,GAAG,GAIJ,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,GAOpB,MAAM,kBAAkB,CAAC"}
@@ -24,7 +24,7 @@
24
24
  * attendants, queues and time-of-day routers as users, and counting them as seats would overstate
25
25
  * every domain that has any. They are counted separately, as information, and never compared.
26
26
  */
27
- import type { Snapshot } from './model.js';
27
+ import type { Rec, Snapshot } from './model.js';
28
28
  export interface DomainInventory {
29
29
  /** Real seats: users whose `service-code` is empty or non-`system-*`. */
30
30
  extensions: {
@@ -123,6 +123,9 @@ export interface DomainInventoryDetail {
123
123
  e911Addresses: AddressItem[];
124
124
  smsNumbers: SmsItem[];
125
125
  }
126
+ export declare const str: (v: unknown) => string;
127
+ /** Is this user one of NetSapiens' internal routing objects rather than a seat? */
128
+ export declare function isSystemUser(user: Rec): boolean;
126
129
  /**
127
130
  * The items behind every count. Pure. Fields are copied by name from an allowlist; no record passes
128
131
  * through, so a device's MAC or SIP password cannot reach a consumer by accident.
@@ -143,6 +146,11 @@ export interface DomainInventoryDetail {
143
146
  export declare function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail;
144
147
  /** The counts, as a fold over {@link listDomainInventory} so the two can never disagree. */
145
148
  export declare function countDomainInventory(snapshot: Snapshot): DomainInventory;
149
+ /**
150
+ * Count an item list. Exposed separately so a consumer that has FILTERED the lists — to one site, to
151
+ * one billing account — gets counts that agree with what it kept, rather than re-counting the snapshot.
152
+ */
153
+ export declare function countInventoryDetail(d: DomainInventoryDetail): DomainInventory;
146
154
  /**
147
155
  * The items a `counts` path selects — the same vocabulary of dotted paths `countDomainInventory`
148
156
  * answers numbers for. `undefined` means that dimension has no item list (devices, system users, or a
@@ -1 +1 @@
1
- {"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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"}
package/dist/inventory.js CHANGED
@@ -1,6 +1,6 @@
1
1
  /** NANP toll-free area codes, 800 through 888. A number outside this set is counted local. */
2
2
  const TOLL_FREE = new Set(['800', '833', '844', '855', '866', '877', '888']);
3
- const str = (v) => (typeof v === 'string' ? v.trim() : v == null ? '' : String(v).trim());
3
+ export const str = (v) => (typeof v === 'string' ? v.trim() : v == null ? '' : String(v).trim());
4
4
  const bump = (into, key) => { into[key] = (into[key] ?? 0) + 1; };
5
5
  /**
6
6
  * FNV-1a over a string, as eight lowercase hex digits. Synchronous and dependency-free on purpose:
@@ -31,7 +31,7 @@ function identityKey(kind, id, seed) {
31
31
  return id ? `${kind}:${id}` : `${kind}:~${hash32(seed)}`;
32
32
  }
33
33
  /** Is this user one of NetSapiens' internal routing objects rather than a seat? */
34
- function isSystemUser(user) {
34
+ export function isSystemUser(user) {
35
35
  return str(user['service-code']).toLowerCase().startsWith('system-');
36
36
  }
37
37
  /**
@@ -139,7 +139,13 @@ export function listDomainInventory(snapshot) {
139
139
  }
140
140
  /** The counts, as a fold over {@link listDomainInventory} so the two can never disagree. */
141
141
  export function countDomainInventory(snapshot) {
142
- const d = listDomainInventory(snapshot);
142
+ return countInventoryDetail(listDomainInventory(snapshot));
143
+ }
144
+ /**
145
+ * Count an item list. Exposed separately so a consumer that has FILTERED the lists — to one site, to
146
+ * one billing account — gets counts that agree with what it kept, rather than re-counting the snapshot.
147
+ */
148
+ export function countInventoryDetail(d) {
143
149
  const inv = {
144
150
  extensions: { total: 0, byScope: {}, byServiceCode: {}, byDeviceCount: { '0': 0, '1': 0, '2': 0, '3+': 0 }, withAnyDevice: 0, withNoDevice: 0 },
145
151
  systemUsers: { total: d.systemUsers.length, byServiceCode: {} },
@@ -1 +1 @@
1
- {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"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"}
package/dist/model.d.ts CHANGED
@@ -69,6 +69,14 @@ export interface Snapshot {
69
69
  * that returns the list. Present only when the fetch asked for them.
70
70
  */
71
71
  smsnumbers?: Rec[];
72
+ /**
73
+ * SMS-enabled numbers PER USER — GET /domains/{d}/users/{ext}/smsnumbers, one call per real
74
+ * extension, present only when `includeUserSmsNumbers` was asked for. The domain-level list
75
+ * (`smsnumbers`) does not say which user a number is enabled on; this does.
76
+ */
77
+ smsNumbersByUser?: Record<string, Rec[]>;
78
+ /** Extensions whose per-user SMS read failed with something other than 404 — same contract as `deviceReadFailures`. */
79
+ smsReadFailures?: string[];
72
80
  autoattendants?: Rec[];
73
81
  dialrulesByPlan?: Record<string, Rec[]>;
74
82
  answerrulesByUser?: Record<string, Rec[]>;
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,QAAQ,GAChB,KAAK,GACL,WAAW,GACX,MAAM,GACN,SAAS,GACT,OAAO,GACP,QAAQ,GACR,WAAW,GACX,QAAQ,GACR,WAAW,GACX,UAAU,GACV,OAAO,GACP,QAAQ,GACR,SAAS,CAAC;AAEd,MAAM,MAAM,QAAQ,GAChB,OAAO,GACP,MAAM,GACN,QAAQ,GACR,UAAU,GACV,MAAM,GACN,OAAO,GACP,KAAK,GACL,UAAU,GACV,UAAU,GACV,MAAM,GACN,KAAK,CAAC;AAEV,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,0BAA0B;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,8DAA8D;IAC9D,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oGAAoG;IACpG,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,sGAAsG;IACtG,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,QAAQ,CAAC;IACf,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACrD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,uFAAuF;IACvF,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAQD,MAAM,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAEtC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,GAAG,CAAC;IACV,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,YAAY,CAAC,EAAE,GAAG,EAAE,CAAC;IACrB;;;OAGG;IACH,SAAS,CAAC,EAAE,GAAG,EAAE,CAAC;IAClB;;;;OAIG;IACH,UAAU,CAAC,EAAE,GAAG,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,GAAG,EAAE,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IACxC,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC1C;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACvC,sBAAsB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAC/C;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAAC;CAClB"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
@@ -100,6 +100,12 @@ export interface FetchSnapshotOptions {
100
100
  * auto attendants and queues, and they hold no seat.
101
101
  */
102
102
  includeDevices?: boolean;
103
+ /**
104
+ * Also read each REAL extension's SMS-enabled numbers into `smsNumbersByUser`. One call per
105
+ * extension, like `includeDevices`, and for the same reason: the domain-level list does not say
106
+ * which user a number belongs to, and a consumer splitting a domain by site needs to know.
107
+ */
108
+ includeUserSmsNumbers?: boolean;
103
109
  }
104
110
  /**
105
111
  * Read a live domain into the `Snapshot` shape the resolver consumes. Routing subset only:
@@ -1 +1 @@
1
- {"version":3,"file":"nsClient.d.ts","sourceRoot":"","sources":["../src/nsClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,UAAW,SAAQ,KAAK;aAGjB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;aACZ,IAAI,EAAE,OAAO;IAC7B,gGAAgG;aAChF,MAAM,CAAC,EAAE,MAAM;gBAL/B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO;IAC7B,gGAAgG;IAChF,MAAM,CAAC,EAAE,MAAM,YAAA;CAKlC;AAED,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED,qBAAa,QAAQ;;gBAKP,GAAG,EAAE,cAAc;IAMzB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CA8B1F;AAED,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,CAI3C;AAgBD;iFACiF;AACjF,wBAAsB,WAAW,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,CAAC,CASzH;AAED,MAAM,WAAW,oBAAoB;IACnC,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,4GAA4G;IAC5G,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,QAAQ,CAAC,CA+H9H"}
1
+ {"version":3,"file":"nsClient.d.ts","sourceRoot":"","sources":["../src/nsClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,qBAAa,UAAW,SAAQ,KAAK;aAGjB,MAAM,EAAE,MAAM;aACd,IAAI,EAAE,MAAM;aACZ,IAAI,EAAE,OAAO;IAC7B,gGAAgG;aAChF,MAAM,CAAC,EAAE,MAAM;gBAL/B,OAAO,EAAE,MAAM,EACC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,OAAO;IAC7B,gGAAgG;IAChF,MAAM,CAAC,EAAE,MAAM,YAAA;CAKlC;AAED,MAAM,WAAW,cAAc;IAC7B,qFAAqF;IACrF,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAED;;;;;;;;;;;GAWG;AACH;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAYvD;AAED,qBAAa,QAAQ;;gBAKP,GAAG,EAAE,cAAc;IAMzB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CA8B1F;AAED,mGAAmG;AACnG,wBAAgB,OAAO,CAAC,GAAG,EAAE,OAAO,GAAG,GAAG,EAAE,CAI3C;AAgBD;iFACiF;AACjF,wBAAsB,WAAW,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,EAAE,CAAC,CASzH;AAED,MAAM,WAAW,oBAAoB;IACnC,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,4GAA4G;IAC5G,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iGAAiG;IACjG,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B;;;;;OAKG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;;OAIG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,oBAAyB,GAAG,OAAO,CAAC,QAAQ,CAAC,CAyJ9H"}
package/dist/nsClient.js CHANGED
@@ -207,6 +207,31 @@ export async function fetchDomainSnapshot(client, domain, opts = {}) {
207
207
  if (devs.length)
208
208
  devicesByUser[ext] = devs;
209
209
  });
210
+ // SORTED before it leaves. These fill under `mapLimit`, so the order is whichever read failed first —
211
+ // a list that reshuffles between two reads of the same broken domain reads as data that changed, and a
212
+ // consumer prints this straight at an operator.
213
+ deviceReadFailures.sort();
214
+ }
215
+ // Per-user SMS numbers, same shape and reason as devices above: the domain-level list (see
216
+ // includeSmsNumbers) does not say which user a number belongs to.
217
+ let smsNumbersByUser;
218
+ let smsReadFailures;
219
+ if (opts.includeUserSmsNumbers) {
220
+ smsNumbersByUser = {};
221
+ smsReadFailures = [];
222
+ const seats = users.filter((u) => !String(u['service-code'] ?? '').trim().toLowerCase().startsWith('system-'));
223
+ await mapLimit(seats, conc, async (u) => {
224
+ const ext = String(u.user ?? '');
225
+ if (!ext)
226
+ return;
227
+ const list = await soft(`${base}/users/${enc(ext)}/smsnumbers`).catch(() => {
228
+ smsReadFailures.push(ext);
229
+ return [];
230
+ });
231
+ if (list.length)
232
+ smsNumbersByUser[ext] = list;
233
+ });
234
+ smsReadFailures.sort(); // same reason as deviceReadFailures above
210
235
  }
211
236
  const answerrulesByUser = {};
212
237
  await mapLimit(users, conc, async (u) => {
@@ -267,6 +292,8 @@ export async function fetchDomainSnapshot(client, domain, opts = {}) {
267
292
  ...(smsnumbers ? { smsnumbers } : {}),
268
293
  ...(devicesByUser ? { devicesByUser } : {}),
269
294
  ...(deviceReadFailures ? { deviceReadFailures } : {}),
295
+ ...(smsNumbersByUser ? { smsNumbersByUser } : {}),
296
+ ...(smsReadFailures ? { smsReadFailures } : {}),
270
297
  ...(attendantDetailsByUser && Object.keys(attendantDetailsByUser).length ? { attendantDetailsByUser } : {}),
271
298
  ...(attendantDialrulesByExt && Object.keys(attendantDialrulesByExt).length ? { attendantDialrulesByExt } : {}),
272
299
  ...(dialrulesByPlan ? { dialrulesByPlan } : {}),
@@ -1 +1 @@
1
- {"version":3,"file":"nsClient.js","sourceRoot":"","sources":["../src/nsClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,MAAM,OAAO,UAAW,SAAQ,KAAK;IAGjB;IACA;IACA;IAEA;IANlB,YACE,OAAe,EACC,MAAc,EACd,IAAY,EACZ,IAAa;IAC7B,gGAAgG;IAChF,MAAe;QAE/B,KAAK,CAAC,OAAO,CAAC,CAAC;QANC,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAQ;QACZ,SAAI,GAAJ,IAAI,CAAS;QAEb,WAAM,GAAN,MAAM,CAAS;QAG/B,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAWD;;;;;;;;;;;GAWG;AACH;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC1D,IAAI,CAAM,CAAC;IACX,IAAI,CAAC;QACH,CAAC,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,sCAAsC,CAAC,CAAC;IACtF,CAAC;IACD,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC,QAAQ,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,sBAAsB,MAAM,yFAAyF,CAAC,CAAC;IACzI,CAAC;IACD,OAAO,CAAC,CAAC,IAAI,CAAC;AAChB,CAAC;AAED,MAAM,OAAO,QAAQ;IACV,QAAQ,CAAS;IACjB,MAAM,CAAS;IACf,UAAU,CAAe;IAElC,YAAY,GAAmB;QAC7B,IAAI,CAAC,QAAQ,GAAG,WAAW,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;QACpE,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;QACxB,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC,SAAS,IAAI,KAAK,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,GAAG,CAAc,IAAY,EAAE,KAAuC;QAC1E,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;QAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;YAAE,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;QAErF,8FAA8F;QAC9F,+FAA+F;QAC/F,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC;QAChC,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,EAAE;YACxC,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;SAChF,CAAC,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,MAAM,GAAY,IAAI,CAAC;QAC3B,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC;gBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC5B,CAAC;YAAC,MAAM,CAAC;gBACP,gDAAgD;YAClD,CAAC;QACH,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,0FAA0F;YAC1F,8FAA8F;YAC9F,yEAAyE;YACzE,MAAM,MAAM,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACvH,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,iDAAiD,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5I,MAAM,IAAI,UAAU,CAAC,OAAO,IAAI,MAAM,GAAG,CAAC,MAAM,GAAG,IAAI,KAAK,MAAM,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAClG,CAAC;QACD,OAAO,MAAW,CAAC;IACrB,CAAC;CACF;AAED,mGAAmG;AACnG,MAAM,UAAU,OAAO,CAAC,GAAY;IAClC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAAE,OAAO,GAAY,CAAC;IAC5C,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,CAAC,GAAU,CAAC,CAAC;IACxD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,6FAA6F;AAC7F,KAAK,UAAU,QAAQ,CAAI,KAAU,EAAE,KAAa,EAAE,EAA6C;IACjG,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,IAAI,EAAE;QAC/E,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,CAAC,EAAE,CAAC;YAChB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,CAAE,EAAE,GAAG,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,GAAG,GAAG,kBAAkB,CAAC;AAE/B;iFACiF;AACjF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAgB;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IACnD,OAAO,IAAI;SACR,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;QAC9B,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7D,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAC7B,CAAC;AAyCD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,MAAgB,EAAE,MAAc,EAAE,OAA6B,EAAE;IACzG,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,YAAY,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;IACvC,MAAM,IAAI,GAAG,KAAK,EAAE,CAAS,EAAkB,EAAE;QAC/C,IAAI,CAAC;YACH,OAAO,OAAO,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,GAAG,YAAY,UAAU,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;gBAAE,OAAO,EAAE,CAAC;YAC/D,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;IACnE,MAAM,CAAC,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,SAAS,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC7G,IAAI,CAAC,GAAG,IAAI,aAAa,CAAC;QAC1B,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC;QACrB,IAAI,CAAC,GAAG,IAAI,aAAa,CAAC;QAC1B,IAAI,CAAC,GAAG,IAAI,eAAe,CAAC;QAC5B,IAAI,CAAC,GAAG,IAAI,iBAAiB,CAAC;QAC9B,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,YAAY,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QAC9E,mGAAmG;QACnG,qGAAqG;QACrG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;KACxF,CAAC,CAAC;IAEH,mGAAmG;IACnG,mEAAmE;IACnE,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,IAAI,iBAAoD,CAAC;QACzD,IAAI,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,wCAAwC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC/H,iBAAiB,GAAG,EAAE,CAAC;YACvB,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;gBACtC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;gBAChF,IAAI,KAAK,CAAC,MAAM;oBAAE,iBAAkB,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC;YAClD,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO;YACL,IAAI,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc;YAChG,GAAG,CAAC,iBAAiB,CAAC,CAAC,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnD,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtC,CAAC;IACJ,CAAC;IAED,qGAAqG;IACrG,qEAAqE;IACrE,IAAI,aAAgD,CAAC;IACrD,IAAI,kBAAwC,CAAC;IAC7C,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;QACxB,aAAa,GAAG,EAAE,CAAC;QACnB,kBAAkB,GAAG,EAAE,CAAC;QACxB,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;QAC/G,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;YACjC,IAAI,CAAC,GAAG;gBAAE,OAAO;YACjB,8FAA8F;YAC9F,6FAA6F;YAC7F,2DAA2D;YAC3D,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,UAAU,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBACtE,kBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC9B,OAAO,EAAE,CAAC;YACZ,CAAC,CAAC,CAAC;YACH,IAAI,IAAI,CAAC,MAAM;gBAAE,aAAc,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;QAC9C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,iBAAiB,GAA0B,EAAE,CAAC;IACpD,MAAM,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,UAAU,GAAG,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAClF,IAAI,KAAK,CAAC,MAAM;YAAE,iBAAiB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,MAAM,aAAa,GAA0B,EAAE,CAAC;IAChD,MAAM,QAAQ,CAAC,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QACtC,IAAI,CAAC,GAAG;YAAE,OAAO;QACjB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,eAAe,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;QAChF,IAAI,GAAG,CAAC,MAAM;YAAE,aAAa,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,gGAAgG;IAChG,iGAAiG;IACjG,gGAAgG;IAChG,iHAAiH;IACjH,IAAI,sBAAyD,CAAC;IAC9D,IAAI,uBAA0D,CAAC;IAC/D,IAAI,IAAI,CAAC,qBAAqB,IAAI,IAAI,EAAE,CAAC;QACvC,MAAM,IAAI,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QACxJ,sBAAsB,GAAG,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,IAAI,IAAI;YAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,wCAAwC;QACpG,MAAM,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;YACrC,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,UAAU,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,mBAAmB,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC9G,IAAI,MAAM;gBAAE,sBAAuB,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC,CAAC,CAAC;QACH,uBAAuB,GAAG,EAAE,CAAC;QAC7B,MAAM,QAAQ,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YACvE,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,IAAI,cAAc,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,CAAC;YAChG,IAAI,EAAE,CAAC,MAAM;gBAAE,uBAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,IAAI,eAAkD,CAAC;IACvD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC1B,eAAe,GAAG,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC,GAAG,IAAI,cAAc,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC;IAC3G,CAAC;IAED,OAAO;QACL,IAAI,EAAE,EAAE,MAAM,EAAE;QAChB,MAAM,EAAE,SAAS;QACjB,UAAU;QACV,KAAK;QACL,UAAU;QACV,YAAY;QACZ,cAAc;QACd,iBAAiB;QACjB,aAAa;QACb,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,sBAAsB,IAAI,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,sBAAsB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3G,GAAG,CAAC,uBAAuB,IAAI,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9G,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAChD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"nsClient.js","sourceRoot":"","sources":["../src/nsClient.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dszp/netsapiens-lib",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Portable, Node-free NetSapiens toolkit: split read/write API clients, JWT (ns_t) validation, and a snapshot -> FlowGraph -> Mermaid call-flow resolver/renderer. Runs unchanged in a Cloudflare Worker, Node, or the browser.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -59,7 +59,7 @@
59
59
  "//prepublishOnly": "Publish-only build with sourcemaps OFF. The `files` globs exclude dist/**/*.map on purpose (they point at src/, which does not ship), but tsc still emits a //# sourceMappingURL pointer into every .js/.d.ts -- so consumers' devtools 404 chasing maps that were never published. Dropping the pointer at publish time is what the exclusion always meant. A normal `pnpm build` keeps maps for link: consumers.",
60
60
  "prepublishOnly": "tsc -p tsconfig.json --sourceMap false --declarationMap false",
61
61
  "//test": "The offline suite — green on a fresh clone with no credentials and no fixtures. test:ns is NOT included: it needs a domain snapshot that (correctly) isn't in the repo.",
62
- "test": "pnpm run test:jwt && pnpm run test:principal && pnpm run test:resolver && pnpm run test:raster && pnpm run test:nswrite && pnpm run test:nssync && pnpm run test:eligibility && pnpm run test:nsauth && pnpm test:nssubs && pnpm test:nsdevice && pnpm run test:inventory",
62
+ "test": "pnpm run test:jwt && pnpm run test:principal && pnpm run test:resolver && pnpm run test:raster && pnpm run test:nswrite && pnpm run test:nssync && pnpm run test:eligibility && pnpm run test:nsauth && pnpm test:nssubs && pnpm test:nsdevice && pnpm run test:inventory && pnpm run test:attribution",
63
63
  "test:jwt": "tsx src/jwt.selftest.ts",
64
64
  "test:ns": "tsx src/nsClient.selftest.ts",
65
65
  "test:nswrite": "tsx src/nsWriteClient.selftest.ts",
@@ -71,7 +71,8 @@
71
71
  "test:eligibility": "tsx src/eligibility.selftest.ts",
72
72
  "test:nssubs": "tsx src/nsSubscriptions.selftest.ts",
73
73
  "test:nsdevice": "tsx src/nsDevice.selftest.ts",
74
- "test:inventory": "tsx src/inventory.selftest.ts"
74
+ "test:inventory": "tsx src/inventory.selftest.ts",
75
+ "test:attribution": "tsx src/attribution.selftest.ts"
75
76
  },
76
77
  "devDependencies": {
77
78
  "tsx": "^4.22.4",
@@ -0,0 +1,70 @@
1
+ /** Offline test for item→site attribution. pnpm test:attribution */
2
+ import { attributeDomainInventory } from './attribution.js';
3
+ import { listDomainInventory } from './inventory.js';
4
+ import type { Snapshot } from './model.js';
5
+
6
+ let pass = 0, fail = 0;
7
+ const ok = (c: boolean, m: string) => { c ? pass++ : fail++; console.log(`${c ? 'PASS' : 'FAIL'} ${m}`); };
8
+
9
+ const snap: Snapshot = {
10
+ meta: { domain: 'acme.example' },
11
+ users: [
12
+ { user: '100', site: 'North', 'service-code': '', 'emergency-address-id': 'a-1' },
13
+ { user: '101', site: 'South', 'service-code': '', 'emergency-address-id': 'a-1' },
14
+ { user: '102', site: 'South', 'service-code': '', 'emergency-address-id': 'a-2' },
15
+ { user: '103', site: '', 'service-code': '' }, // no site
16
+ { user: '701', site: 'North', 'service-code': 'system-queue' }, // a queue is a user too
17
+ ],
18
+ phonenumbers: [
19
+ { phonenumber: '13175550100', 'dial-rule-application': 'to-user', 'dial-rule-translation-destination-user': '100' },
20
+ { phonenumber: '13175550101', 'dial-rule-application': 'to-user', 'dial-rule-translation-destination-user': '701' },
21
+ { phonenumber: '13175550102', 'dial-rule-application': 'to-connection', 'dial-rule-translation-destination-user': '' },
22
+ { phonenumber: '13175550103', 'dial-rule-application': 'to-user', 'dial-rule-translation-destination-user': '103' },
23
+ { phonenumber: '13175550104', 'dial-rule-application': 'to-user', 'dial-rule-translation-destination-user': '999' },
24
+ ],
25
+ addresses: [
26
+ { 'emergency-address-id': 'a-1', 'address-name': 'Shared' },
27
+ { 'emergency-address-id': 'a-2', 'address-name': 'South only' },
28
+ { 'emergency-address-id': 'a-3', 'address-name': 'Nobody' },
29
+ ],
30
+ smsnumbers: [{ number: '13175550100' }, { number: '13175550102' }, { number: '13175550199' }],
31
+ smsNumbersByUser: { '100': [{ number: '13175550100' }], '103': [{ number: '13175550102' }] },
32
+ };
33
+
34
+ const a = attributeDomainInventory(snap).items;
35
+ const d = listDomainInventory(snap);
36
+ const allKeys = [...d.extensions, ...d.dids, ...d.e911Addresses, ...d.smsNumbers].map((i) => i.key);
37
+ ok(allKeys.every((k) => k in a), 'every extension, number, address and SMS number has an attribution');
38
+ ok(Object.keys(a).length === allKeys.length, 'and nothing else does (system users are not items)');
39
+
40
+ ok(a['ext:100']!.site === 'North' && a['ext:100']!.how === 'own-site', 'an extension is attributed to its own site');
41
+ ok(a['ext:103']!.site === null && a['ext:103']!.how === 'unattributed:no-site', 'an extension with a blank site is unattributed:no-site');
42
+
43
+ ok(a['did:13175550100']!.site === 'North' && a['did:13175550100']!.how === 'via-user:100', 'a number routed to a user inherits that user\'s site');
44
+ ok(a['did:13175550101']!.site === null && a['did:13175550101']!.how === 'unattributed:routed-to:system-queue', 'a number routed to a queue names the queue\'s service code');
45
+ ok(a['did:13175550102']!.site === null && a['did:13175550102']!.how === 'unattributed:routed-to:to-connection', 'a number routed to a connection names the application');
46
+ ok(a['did:13175550103']!.site === null && a['did:13175550103']!.how === 'unattributed:no-site', 'a number routed to a site-less user is no-site, not routed-to');
47
+ ok(a['did:13175550104']!.site === null && a['did:13175550104']!.how === 'unattributed:routed-to:to-user', 'a number whose destination user does not exist falls back to the application name');
48
+
49
+ ok(a['addr:a-1']!.site === null && a['addr:a-1']!.how === 'unattributed:shared-across:North,South', 'an address referenced from two sites is shared, sites sorted');
50
+ ok(a['addr:a-2']!.site === 'South' && a['addr:a-2']!.how === 'via-users:102', 'an address referenced from one site follows it and names the users');
51
+ ok(a['addr:a-3']!.site === null && a['addr:a-3']!.how === 'unattributed:unreferenced', 'an address nobody references is unreferenced');
52
+
53
+ ok(a['sms:13175550100']!.site === 'North' && a['sms:13175550100']!.how === 'via-user:100', 'an SMS number follows the user it is enabled on');
54
+ ok(a['sms:13175550102']!.site === null && a['sms:13175550102']!.how === 'unattributed:no-site', 'an SMS number on a site-less user is no-site');
55
+ ok(a['sms:13175550199']!.site === null && a['sms:13175550199']!.how === 'unattributed:sms-user-unknown', 'an SMS number no per-user list claims is sms-user-unknown');
56
+
57
+ // Without the per-user read at all, every SMS number is unknown — never guessed.
58
+ const noUser = attributeDomainInventory({ ...snap, smsNumbersByUser: undefined }).items;
59
+ ok(noUser['sms:13175550100']!.how === 'unattributed:sms-user-unknown', 'with no per-user SMS read, SMS numbers are sms-user-unknown');
60
+
61
+ // The address rule reads REAL extensions only: a queue referencing an address must not place it.
62
+ const queueAddr = attributeDomainInventory({ ...snap, users: [{ user: '701', site: 'North', 'service-code': 'system-queue', 'emergency-address-id': 'a-3' }], addresses: [{ 'emergency-address-id': 'a-3' }] }).items;
63
+ ok(queueAddr['addr:a-3']!.how === 'unattributed:unreferenced', 'a system user referencing an address does not attribute it');
64
+
65
+ // A number routed to a system user by an application other than to-user still names the service code.
66
+ const devRoute = attributeDomainInventory({ ...snap, phonenumbers: [{ phonenumber: '13175550105', 'dial-rule-application': 'to-single-device', 'dial-rule-translation-destination-user': '101' }] }).items;
67
+ ok(devRoute['did:13175550105']!.site === 'South' && devRoute['did:13175550105']!.how === 'via-user:101', 'to-single-device to a real user inherits the site like to-user');
68
+
69
+ console.log(`\n${pass} passed, ${fail} failed`);
70
+ if (fail) process.exit(1);
@@ -0,0 +1,105 @@
1
+ /**
2
+ * Which SITE each inventory item belongs to, and how that was decided. Pure: feed it the same
3
+ * `Snapshot` `listDomainInventory` takes, get one verdict per item key.
4
+ *
5
+ * ## Why a library concern
6
+ *
7
+ * A NetSapiens domain can be billed in pieces — one account per site, or one account for most of
8
+ * it and another for one branch — and the phone system already knows most of what is needed to
9
+ * split it: a user carries `site`, a number carries its destination user, an SMS number is enabled
10
+ * on a user, an address is referenced by users. What it does NOT know is who pays; that stays with
11
+ * the consumer. This module answers "which site", never "which account".
12
+ *
13
+ * ## The rules
14
+ *
15
+ * - An extension: its own `site` (`own-site`), or `unattributed:no-site` when blank.
16
+ * - A number: the site of its `dial-rule-translation-destination-user` when that names a REAL
17
+ * extension (`via-user:<ext>`), whatever the application — `to-user`, `to-single-device`. When it
18
+ * names a system user (a queue, an attendant, a time-of-day router are users too) the reason is
19
+ * `routed-to:<that user's service-code>`; when it names nobody, `routed-to:<application>`; a real
20
+ * user with no site is `no-site`.
21
+ * - An address: the one site every REAL extension referencing it sits on (`via-users:<exts>`);
22
+ * `shared-across:<sites>` when they sit on more than one; `unreferenced` when none does;
23
+ * `no-site` when the referencing users have no site.
24
+ * - An SMS number: the site of the user whose per-user list carries it (`via-user:<ext>`), or
25
+ * `sms-user-unknown` when no per-user list does — including when the per-user read was never
26
+ * made. Never guessed from the domain-level list, which does not say.
27
+ *
28
+ * ## Keys are joined by index
29
+ *
30
+ * `listDomainInventory` maps each source array 1:1 and in order, and this module relies on that to
31
+ * put an item's KEY (which may be a derived `~hash`) beside its RECORD's routing fields. That
32
+ * invariant is this library's own, and this is the one place allowed to lean on it.
33
+ */
34
+ import { isSystemUser, listDomainInventory, str } from './inventory.js';
35
+ import type { Rec, Snapshot } from './model.js';
36
+
37
+ export interface ItemAttribution {
38
+ /** The site this item belongs to; `null` when it cannot be placed. */
39
+ site: string | null;
40
+ /** `own-site` | `via-user:<ext>` | `via-users:<ext,ext>` | `unattributed:<reason>`. */
41
+ how: string;
42
+ }
43
+ export interface DomainAttribution { items: Record<string, ItemAttribution> }
44
+
45
+ const none = (reason: string): ItemAttribution => ({ site: null, how: `unattributed:${reason}` });
46
+
47
+ export function attributeDomainInventory(snapshot: Snapshot): DomainAttribution {
48
+ const users: Rec[] = Array.isArray(snapshot.users) ? snapshot.users : [];
49
+ const phonenumbers: Rec[] = Array.isArray(snapshot.phonenumbers) ? snapshot.phonenumbers : [];
50
+ const addresses: Rec[] = Array.isArray(snapshot.addresses) ? snapshot.addresses : [];
51
+ const smsnumbers: Rec[] = Array.isArray(snapshot.smsnumbers) ? snapshot.smsnumbers : [];
52
+ const byUser = snapshot.smsNumbersByUser;
53
+ const d = listDomainInventory(snapshot);
54
+ const items: Record<string, ItemAttribution> = {};
55
+
56
+ const userByExt = new Map<string, Rec>();
57
+ for (const u of users) { const ext = str(u.user); if (ext && !userByExt.has(ext)) userByExt.set(ext, u); }
58
+
59
+ // Extensions: the detail already carries `site`, so no record is needed here.
60
+ for (const x of d.extensions) items[x.key] = x.site ? { site: x.site, how: 'own-site' } : none('no-site');
61
+
62
+ // Numbers, by index against `phonenumbers`.
63
+ for (let i = 0; i < d.dids.length; i++) {
64
+ const key = d.dids[i]!.key, p = phonenumbers[i] ?? {};
65
+ const app = str(p['dial-rule-application']) || 'unknown';
66
+ const dest = str(p['dial-rule-translation-destination-user']);
67
+ const u = dest ? userByExt.get(dest) : undefined;
68
+ if (!u) { items[key] = none(`routed-to:${app}`); continue; }
69
+ if (isSystemUser(u)) { items[key] = none(`routed-to:${str(u['service-code'])}`); continue; }
70
+ const site = str(u.site);
71
+ items[key] = site ? { site, how: `via-user:${dest}` } : none('no-site');
72
+ }
73
+
74
+ // Addresses, by index against `addresses`; referenced by REAL extensions only.
75
+ const refs = new Map<string, Rec[]>();
76
+ for (const u of users) {
77
+ if (isSystemUser(u)) continue;
78
+ const id = str(u['emergency-address-id']);
79
+ if (!id) continue;
80
+ const list = refs.get(id) ?? []; list.push(u); refs.set(id, list);
81
+ }
82
+ for (let i = 0; i < d.e911Addresses.length; i++) {
83
+ const key = d.e911Addresses[i]!.key, id = str((addresses[i] ?? {})['emergency-address-id']);
84
+ const who = id ? refs.get(id) ?? [] : [];
85
+ if (!who.length) { items[key] = none('unreferenced'); continue; }
86
+ const sites = [...new Set(who.map((u) => str(u.site)).filter(Boolean))].sort();
87
+ if (sites.length === 0) items[key] = none('no-site');
88
+ else if (sites.length === 1) items[key] = { site: sites[0]!, how: `via-users:${who.map((u) => str(u.user)).filter(Boolean).sort().join(',')}` };
89
+ else items[key] = none(`shared-across:${sites.join(',')}`);
90
+ }
91
+
92
+ // SMS numbers, by index against `smsnumbers`, joined to a user through the per-user lists.
93
+ const extBySms = new Map<string, string>();
94
+ if (byUser) for (const [ext, list] of Object.entries(byUser)) for (const s of Array.isArray(list) ? list : []) { const n = str(s.number); if (n && !extBySms.has(n)) extBySms.set(n, ext); }
95
+ for (let i = 0; i < d.smsNumbers.length; i++) {
96
+ const key = d.smsNumbers[i]!.key, n = str((smsnumbers[i] ?? {}).number);
97
+ const ext = n ? extBySms.get(n) : undefined;
98
+ const u = ext ? userByExt.get(ext) : undefined;
99
+ if (!u) { items[key] = none('sms-user-unknown'); continue; }
100
+ const site = str(u.site);
101
+ items[key] = site ? { site, how: `via-user:${ext}` } : none('no-site');
102
+ }
103
+
104
+ return { items };
105
+ }
package/src/index.ts CHANGED
@@ -37,7 +37,8 @@ export {
37
37
  } from './html.js';
38
38
  export { resolveSvgSize, rasterizerScript } from './raster.js';
39
39
  export { NsClient, NsApiError, assertBareServer, fetchDomainSnapshot, listDomains, asArray, type NsClientConfig, type FetchSnapshotOptions } from './nsClient.js';
40
- export { countDomainInventory, listDomainInventory, itemsFor, itemLabel, type DomainInventory, type DomainInventoryDetail, type ExtensionItem, type NumberItem, type AddressItem, type SmsItem, type InventoryItem } from './inventory.js';
40
+ export { countDomainInventory, countInventoryDetail, listDomainInventory, itemsFor, itemLabel, type DomainInventory, type DomainInventoryDetail, type ExtensionItem, type NumberItem, type AddressItem, type SmsItem, type InventoryItem } from './inventory.js';
41
+ export { attributeDomainInventory, type DomainAttribution, type ItemAttribution } from './attribution.js';
41
42
  export { NsWriteClient, type NsWriteClientConfig } from './nsWriteClient.js';
42
43
  export {
43
44
  supportsSynchronous,
package/src/inventory.ts CHANGED
@@ -110,7 +110,7 @@ export interface DomainInventoryDetail {
110
110
  /** NANP toll-free area codes, 800 through 888. A number outside this set is counted local. */
111
111
  const TOLL_FREE = new Set(['800', '833', '844', '855', '866', '877', '888']);
112
112
 
113
- const str = (v: unknown): string => (typeof v === 'string' ? v.trim() : v == null ? '' : String(v).trim());
113
+ export const str = (v: unknown): string => (typeof v === 'string' ? v.trim() : v == null ? '' : String(v).trim());
114
114
  const bump = (into: Record<string, number>, key: string): void => { into[key] = (into[key] ?? 0) + 1; };
115
115
 
116
116
  /**
@@ -144,7 +144,7 @@ function identityKey(kind: string, id: string, seed: string): string {
144
144
  }
145
145
 
146
146
  /** Is this user one of NetSapiens' internal routing objects rather than a seat? */
147
- function isSystemUser(user: Rec): boolean {
147
+ export function isSystemUser(user: Rec): boolean {
148
148
  return str(user['service-code']).toLowerCase().startsWith('system-');
149
149
  }
150
150
 
@@ -258,7 +258,14 @@ export function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail {
258
258
 
259
259
  /** The counts, as a fold over {@link listDomainInventory} so the two can never disagree. */
260
260
  export function countDomainInventory(snapshot: Snapshot): DomainInventory {
261
- const d = listDomainInventory(snapshot);
261
+ return countInventoryDetail(listDomainInventory(snapshot));
262
+ }
263
+
264
+ /**
265
+ * Count an item list. Exposed separately so a consumer that has FILTERED the lists — to one site, to
266
+ * one billing account — gets counts that agree with what it kept, rather than re-counting the snapshot.
267
+ */
268
+ export function countInventoryDetail(d: DomainInventoryDetail): DomainInventory {
262
269
  const inv: DomainInventory = {
263
270
  extensions: { total: 0, byScope: {}, byServiceCode: {}, byDeviceCount: { '0': 0, '1': 0, '2': 0, '3+': 0 }, withAnyDevice: 0, withNoDevice: 0 },
264
271
  systemUsers: { total: d.systemUsers.length, byServiceCode: {} },
package/src/model.ts CHANGED
@@ -102,6 +102,14 @@ export interface Snapshot {
102
102
  * that returns the list. Present only when the fetch asked for them.
103
103
  */
104
104
  smsnumbers?: Rec[];
105
+ /**
106
+ * SMS-enabled numbers PER USER — GET /domains/{d}/users/{ext}/smsnumbers, one call per real
107
+ * extension, present only when `includeUserSmsNumbers` was asked for. The domain-level list
108
+ * (`smsnumbers`) does not say which user a number is enabled on; this does.
109
+ */
110
+ smsNumbersByUser?: Record<string, Rec[]>;
111
+ /** Extensions whose per-user SMS read failed with something other than 404 — same contract as `deviceReadFailures`. */
112
+ smsReadFailures?: string[];
105
113
  autoattendants?: Rec[];
106
114
  dialrulesByPlan?: Record<string, Rec[]>;
107
115
  answerrulesByUser?: Record<string, Rec[]>;
@@ -168,6 +168,52 @@ const ok = (c: boolean, msg: string) => {
168
168
  ok(noDevicesSnap.deviceReadFailures === undefined, 'without includeDevices, deviceReadFailures is absent entirely');
169
169
  }
170
170
 
171
+ // -- per-user SMS numbers: one call per REAL extension, opt-in, failures named like device reads --
172
+ {
173
+ const seen: string[] = [];
174
+ const client = { get: async (p: string) => {
175
+ seen.push(p);
176
+ if (p.endsWith('/users')) return [{ user: '100', 'service-code': '' }, { user: '101', 'service-code': '' }, { user: '700', 'service-code': 'system-aa' }];
177
+ if (p.endsWith('/users/100/smsnumbers')) return [{ number: '13175550100' }];
178
+ if (p.endsWith('/users/101/smsnumbers')) throw new NsApiError('GET .../smsnumbers → 500', 500, p, null);
179
+ if (/\/domains\/[^/]+$/.test(p)) return [{ domain: 'acme.example' }];
180
+ return [];
181
+ } } as unknown as NsClient;
182
+ const snap = await fetchDomainSnapshot(client, 'acme.example', { includeAttendantMenus: false, includeUserSmsNumbers: true });
183
+ ok(JSON.stringify(snap.smsNumbersByUser) === JSON.stringify({ '100': [{ number: '13175550100' }] }), 'per-user SMS numbers are filed under the extension');
184
+ ok(JSON.stringify(snap.smsReadFailures) === JSON.stringify(['101']), 'a failed per-user SMS read is named');
185
+ ok(!seen.some((p) => p.endsWith('/users/700/smsnumbers')), 'system users are not read');
186
+ const plain = await fetchDomainSnapshot(client, 'acme.example', { includeAttendantMenus: false });
187
+ ok(plain.smsNumbersByUser === undefined && plain.smsReadFailures === undefined, 'without the option neither field is present');
188
+
189
+ // PRESENT AND EMPTY when every read answered — the same contract deviceReadFailures has, and the
190
+ // distinction a consumer needs: absent means nobody asked, empty means nothing failed. An absent
191
+ // field read as "nothing failed" would be a page claiming a clean read it never performed.
192
+ const allOk = { get: async (p: string) => {
193
+ if (p.endsWith('/users')) return [{ user: '100', 'service-code': '' }];
194
+ if (p.endsWith('/users/100/smsnumbers')) return [{ number: '13175550100' }];
195
+ if (/\/domains\/[^/]+$/.test(p)) return [{ domain: 'acme.example' }];
196
+ return [];
197
+ } } as unknown as NsClient;
198
+ const clean = await fetchDomainSnapshot(allOk, 'acme.example', { includeAttendantMenus: false, includeUserSmsNumbers: true });
199
+ ok(Array.isArray(clean.smsReadFailures) && clean.smsReadFailures.length === 0,
200
+ 'no failures - smsReadFailures is an empty array, not absent');
201
+
202
+ // SORTED, not in completion order. These fill under mapLimit, so the fixture makes the FIRST-sorting
203
+ // extension answer last; an unsorted list would come back ['101','100'] and the panel that prints it
204
+ // would reshuffle between two reads of the same broken domain.
205
+ const twoFails = { get: async (p: string) => {
206
+ if (p.endsWith('/users')) return [{ user: '100', 'service-code': '' }, { user: '101', 'service-code': '' }];
207
+ if (p.endsWith('/users/100/smsnumbers')) { await new Promise((r) => setTimeout(r, 10)); throw new NsApiError('GET .../smsnumbers → 500', 500, p, null); }
208
+ if (p.endsWith('/users/101/smsnumbers')) throw new NsApiError('GET .../smsnumbers → 500', 500, p, null);
209
+ if (/\/domains\/[^/]+$/.test(p)) return [{ domain: 'acme.example' }];
210
+ return [];
211
+ } } as unknown as NsClient;
212
+ const sorted = await fetchDomainSnapshot(twoFails, 'acme.example', { includeAttendantMenus: false, includeUserSmsNumbers: true });
213
+ ok(JSON.stringify(sorted.smsReadFailures) === JSON.stringify(['100', '101']),
214
+ 'two failures come back sorted, whichever order they completed in');
215
+ }
216
+
171
217
  console.log(`\n${pass} passed, ${fail} failed`);
172
218
  process.exit(fail ? 1 : 0);
173
219
  })();
package/src/nsClient.ts CHANGED
@@ -183,6 +183,12 @@ export interface FetchSnapshotOptions {
183
183
  * auto attendants and queues, and they hold no seat.
184
184
  */
185
185
  includeDevices?: boolean;
186
+ /**
187
+ * Also read each REAL extension's SMS-enabled numbers into `smsNumbersByUser`. One call per
188
+ * extension, like `includeDevices`, and for the same reason: the domain-level list does not say
189
+ * which user a number belongs to, and a consumer splitting a domain by site needs to know.
190
+ */
191
+ includeUserSmsNumbers?: boolean;
186
192
  }
187
193
 
188
194
  /**
@@ -258,6 +264,30 @@ export async function fetchDomainSnapshot(client: NsClient, domain: string, opts
258
264
  });
259
265
  if (devs.length) devicesByUser![ext] = devs;
260
266
  });
267
+ // SORTED before it leaves. These fill under `mapLimit`, so the order is whichever read failed first —
268
+ // a list that reshuffles between two reads of the same broken domain reads as data that changed, and a
269
+ // consumer prints this straight at an operator.
270
+ deviceReadFailures.sort();
271
+ }
272
+
273
+ // Per-user SMS numbers, same shape and reason as devices above: the domain-level list (see
274
+ // includeSmsNumbers) does not say which user a number belongs to.
275
+ let smsNumbersByUser: Record<string, Rec[]> | undefined;
276
+ let smsReadFailures: string[] | undefined;
277
+ if (opts.includeUserSmsNumbers) {
278
+ smsNumbersByUser = {};
279
+ smsReadFailures = [];
280
+ const seats = users.filter((u) => !String(u['service-code'] ?? '').trim().toLowerCase().startsWith('system-'));
281
+ await mapLimit(seats, conc, async (u) => {
282
+ const ext = String(u.user ?? '');
283
+ if (!ext) return;
284
+ const list = await soft(`${base}/users/${enc(ext)}/smsnumbers`).catch(() => {
285
+ smsReadFailures!.push(ext);
286
+ return [];
287
+ });
288
+ if (list.length) smsNumbersByUser![ext] = list;
289
+ });
290
+ smsReadFailures.sort(); // same reason as deviceReadFailures above
261
291
  }
262
292
 
263
293
  const answerrulesByUser: Record<string, Rec[]> = {};
@@ -316,6 +346,8 @@ export async function fetchDomainSnapshot(client: NsClient, domain: string, opts
316
346
  ...(smsnumbers ? { smsnumbers } : {}),
317
347
  ...(devicesByUser ? { devicesByUser } : {}),
318
348
  ...(deviceReadFailures ? { deviceReadFailures } : {}),
349
+ ...(smsNumbersByUser ? { smsNumbersByUser } : {}),
350
+ ...(smsReadFailures ? { smsReadFailures } : {}),
319
351
  ...(attendantDetailsByUser && Object.keys(attendantDetailsByUser).length ? { attendantDetailsByUser } : {}),
320
352
  ...(attendantDialrulesByExt && Object.keys(attendantDialrulesByExt).length ? { attendantDialrulesByExt } : {}),
321
353
  ...(dialrulesByPlan ? { dialrulesByPlan } : {}),