@dszp/netsapiens-lib 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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":"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"}
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: {
@@ -77,8 +77,9 @@ export interface DomainInventory {
77
77
  export interface ExtensionItem {
78
78
  /**
79
79
  * `ext:<user>` — the stable identity a consumer records a decision against. When `user` is blank
80
- * the key falls back to `ext:~<hash>` (see {@link listDomainInventory}), so two nameless records
81
- * never collide onto one decision.
80
+ * the key falls back to `ext:~<hash>` of the remaining fields (see {@link listDomainInventory}),
81
+ * which keeps two differently-named nameless records apart and deliberately merges two whose
82
+ * fields are identical.
82
83
  */
83
84
  key: string;
84
85
  ext: string;
@@ -122,6 +123,9 @@ export interface DomainInventoryDetail {
122
123
  e911Addresses: AddressItem[];
123
124
  smsNumbers: SmsItem[];
124
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;
125
129
  /**
126
130
  * The items behind every count. Pure. Fields are copied by name from an allowlist; no record passes
127
131
  * through, so a device's MAC or SIP password cannot reach a consumer by accident.
@@ -132,15 +136,21 @@ export interface DomainInventoryDetail {
132
136
  * `addr:a-1`, `sms:13175550100`. NetSapiens will hand back a record whose id is blank, and a key of
133
137
  * `addr:` shared by two records is worse than no key: a consumer recording an acceptance against it
134
138
  * accepts both. So a blank id falls back to `<kind>:~<hash>`, an FNV-1a over whatever else names the
135
- * record — an address by its name, street line and city; an extension by scope, service code, name
136
- * and position; a number or SMS number by its position alone, because two blank numbers are
137
- * indistinguishable from each other by anything but where they sat in the list. Position makes those
138
- * keys stable for one snapshot, not across a re-fetch that reorders the array; a blank id is a
139
- * provisioning fault to fix, and the fallback only keeps two of them apart until it is.
139
+ * record — an address by its name, street line and city; an extension by scope, service code and
140
+ * name; a number or SMS number by the (blank) number itself. No seed carries the array index, so a
141
+ * re-fetch that reorders the list returns the same keys. Two blank records that agree on every
142
+ * remaining field therefore land on ONE key rather than two: a number with no number is not a
143
+ * countable thing, and one derived row is more honest than two that shuffle. A blank id is a
144
+ * provisioning fault to fix; the fallback only keeps the distinguishable ones apart until it is.
140
145
  */
141
146
  export declare function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail;
142
147
  /** The counts, as a fold over {@link listDomainInventory} so the two can never disagree. */
143
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;
144
154
  /**
145
155
  * The items a `counts` path selects — the same vocabulary of dotted paths `countDomainInventory`
146
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":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,8DAA8D;QAC9D,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,kEAAkE;QAClE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACtC,sGAAsG;QACtG,aAAa,EAAE,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;QACtD,oFAAoF;QACpF,aAAa,EAAE,MAAM,CAAC;QACtB,6FAA6F;QAC7F,YAAY,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,8FAA8F;IAC9F,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;IACtE,wFAAwF;IACxF,oBAAoB,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,0CAA0C;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,wFAAwF;IACxF,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CAC7D;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;OAKG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,+EAA+E;IAC/E,IAAI,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;IACvB,kDAAkD;IAClD,KAAK,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;IACpB,gFAAgF;IAChF,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mFAAmF;IACnF,SAAS,EAAE,OAAO,CAAC;CACpB;AACD,MAAM,WAAW,UAAU;IAAG,GAAG,EAAE,MAAM,CAAkE;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,GAAG,UAAU,CAAA;CAAE;AACxJ,MAAM,WAAW,WAAW;IAAG,GAAG,EAAE,MAAM,CAAyE;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE;AACnI,MAAM,WAAW,OAAO;IAAG,GAAG,EAAE,MAAM,CAA6D;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE;AACpH,MAAM,MAAM,aAAa,GAAG,aAAa,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC;AAE/E,MAAM,WAAW,qBAAqB;IACpC,+CAA+C;IAC/C,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,qCAAqC;IACrC,WAAW,EAAE,aAAa,EAAE,CAAC;IAC7B,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,aAAa,EAAE,WAAW,EAAE,CAAC;IAC7B,UAAU,EAAE,OAAO,EAAE,CAAC;CACvB;AAKD,eAAO,MAAM,GAAG,GAAI,GAAG,OAAO,KAAG,MAAgF,CAAC;AAiClH,mFAAmF;AACnF,wBAAgB,YAAY,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAE/C;AA8CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,qBAAqB,CA6C7E;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe,CAExE;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,qBAAqB,GAAG,eAAe,CA0B9E;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,qBAAqB,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,GAAG,SAAS,CAmBjG;AAED,8GAA8G;AAC9G,wBAAgB,SAAS,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAQrD"}
package/dist/inventory.js CHANGED
Binary file
@@ -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":"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"}
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.0",
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,
@@ -180,12 +180,12 @@ ok(sysDev.devices.total === 0, 'a system user device is not counted');
180
180
 
181
181
  const [n0, n1] = d.dids;
182
182
  ok(n0!.key.startsWith('did:~'), '[blank] a blank number falls back to did:~<hash>');
183
- ok(n0!.key !== n1!.key, '[blank] two blank numbers are told apart by position, since nothing else differs');
183
+ ok(n0!.key === n1!.key, '[blank] two blank numbers share one derived key: nothing distinguishes them');
184
184
  ok(n0!.key === again.dids[0]!.key, '[blank] and that key is stable across two calls');
185
185
 
186
186
  const [s0, s1] = d.smsNumbers;
187
187
  ok(s0!.key.startsWith('sms:~'), '[blank] a blank SMS number falls back to sms:~<hash>');
188
- ok(s0!.key !== s1!.key, '[blank] two blank SMS numbers get different keys');
188
+ ok(s0!.key === s1!.key, '[blank] and two blank SMS numbers do the same');
189
189
 
190
190
  const x = d.extensions[0]!;
191
191
  ok(x.key.startsWith('ext:~'), '[blank] a blank user falls back to ext:~<hash>');
@@ -194,5 +194,20 @@ ok(sysDev.devices.total === 0, 'a system user device is not counted');
194
194
  ok(x.key === again.extensions[0]!.key, '[blank] the extension key is stable across two calls');
195
195
  }
196
196
 
197
+ // ── a derived key does not depend on where the record sat in the array ───────────────────────────────
198
+ {
199
+ const numbers = [
200
+ { phonenumber: '' },
201
+ { phonenumber: '13175550100' },
202
+ { phonenumber: '' , 'dial-rule-application': 'to-user' },
203
+ ];
204
+ const forward = listDomainInventory({ meta: { domain: 'order.example' }, phonenumbers: numbers } as Snapshot);
205
+ const reversed = listDomainInventory({ meta: { domain: 'order.example' }, phonenumbers: [...numbers].reverse() } as Snapshot);
206
+ const derived = (d: ReturnType<typeof listDomainInventory>) =>
207
+ d.dids.map((n) => n.key).filter((k) => k.startsWith('did:~')).sort().join(',');
208
+ ok(derived(forward) !== '', '[order] the fixture really does produce derived keys');
209
+ ok(derived(forward) === derived(reversed), '[order] reversing the phonenumbers array leaves the did:~ keys unchanged');
210
+ }
211
+
197
212
  console.log(`\n${pass} passed, ${fail} failed`);
198
213
  if (fail) process.exit(1);
package/src/inventory.ts CHANGED
@@ -69,8 +69,9 @@ export interface DomainInventory {
69
69
  export interface ExtensionItem {
70
70
  /**
71
71
  * `ext:<user>` — the stable identity a consumer records a decision against. When `user` is blank
72
- * the key falls back to `ext:~<hash>` (see {@link listDomainInventory}), so two nameless records
73
- * never collide onto one decision.
72
+ * the key falls back to `ext:~<hash>` of the remaining fields (see {@link listDomainInventory}),
73
+ * which keeps two differently-named nameless records apart and deliberately merges two whose
74
+ * fields are identical.
74
75
  */
75
76
  key: string;
76
77
  ext: string;
@@ -109,7 +110,7 @@ export interface DomainInventoryDetail {
109
110
  /** NANP toll-free area codes, 800 through 888. A number outside this set is counted local. */
110
111
  const TOLL_FREE = new Set(['800', '833', '844', '855', '866', '877', '888']);
111
112
 
112
- 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());
113
114
  const bump = (into: Record<string, number>, key: string): void => { into[key] = (into[key] ?? 0) + 1; };
114
115
 
115
116
  /**
@@ -131,13 +132,19 @@ function hash32(s: string): string {
131
132
  * identity field would otherwise hand every nameless record of that kind the same key, and a
132
133
  * consumer keying decisions by it would accept one record and believe it had accepted all of them.
133
134
  * The `~` is what tells a reader the key is derived rather than the system's own id.
135
+ *
136
+ * The seed is the record's OWN fields and nothing else — never its position in the array. A key that
137
+ * depended on position would change under a re-fetch that reordered the list, orphaning every
138
+ * decision a consumer had recorded against it. The price is that two blank records whose remaining
139
+ * fields are identical collapse onto ONE key, and that is the right trade: a number with no number
140
+ * is not a countable thing, and one derived row is more honest than two that shuffle.
134
141
  */
135
142
  function identityKey(kind: string, id: string, seed: string): string {
136
143
  return id ? `${kind}:${id}` : `${kind}:~${hash32(seed)}`;
137
144
  }
138
145
 
139
146
  /** Is this user one of NetSapiens' internal routing objects rather than a seat? */
140
- function isSystemUser(user: Rec): boolean {
147
+ export function isSystemUser(user: Rec): boolean {
141
148
  return str(user['service-code']).toLowerCase().startsWith('system-');
142
149
  }
143
150
 
@@ -158,7 +165,7 @@ function aorLocal(device: Rec): string {
158
165
  return at === -1 ? a : a.slice(0, at);
159
166
  }
160
167
 
161
- function extensionItem(u: Rec, devices: Rec[], index: number): ExtensionItem {
168
+ function extensionItem(u: Rec, devices: Rec[]): ExtensionItem {
162
169
  const ext = str(u.user);
163
170
  // The Teams test is `<ext>t`, so a blank ext would read every device whose aor local part is a
164
171
  // bare `t` as a connector. No extension number, no Teams claim.
@@ -169,7 +176,7 @@ function extensionItem(u: Rec, devices: Rec[], index: number): ExtensionItem {
169
176
  const scope = str(u['user-scope']);
170
177
  const serviceCode = str(u['service-code']);
171
178
  return {
172
- key: identityKey('ext', ext, `${scope}${serviceCode}${name}${index}`),
179
+ key: identityKey('ext', ext, `${scope}\u0000${serviceCode}\u0000${name}`),
173
180
  ext,
174
181
  name,
175
182
  site: str(u.site),
@@ -195,11 +202,12 @@ function extensionItem(u: Rec, devices: Rec[], index: number): ExtensionItem {
195
202
  * `addr:a-1`, `sms:13175550100`. NetSapiens will hand back a record whose id is blank, and a key of
196
203
  * `addr:` shared by two records is worse than no key: a consumer recording an acceptance against it
197
204
  * accepts both. So a blank id falls back to `<kind>:~<hash>`, an FNV-1a over whatever else names the
198
- * record — an address by its name, street line and city; an extension by scope, service code, name
199
- * and position; a number or SMS number by its position alone, because two blank numbers are
200
- * indistinguishable from each other by anything but where they sat in the list. Position makes those
201
- * keys stable for one snapshot, not across a re-fetch that reorders the array; a blank id is a
202
- * provisioning fault to fix, and the fallback only keeps two of them apart until it is.
205
+ * record — an address by its name, street line and city; an extension by scope, service code and
206
+ * name; a number or SMS number by the (blank) number itself. No seed carries the array index, so a
207
+ * re-fetch that reorders the list returns the same keys. Two blank records that agree on every
208
+ * remaining field therefore land on ONE key rather than two: a number with no number is not a
209
+ * countable thing, and one derived row is more honest than two that shuffle. A blank id is a
210
+ * provisioning fault to fix; the fallback only keeps the distinguishable ones apart until it is.
203
211
  */
204
212
  export function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail {
205
213
  const users: Rec[] = Array.isArray(snapshot.users) ? snapshot.users : [];
@@ -213,17 +221,19 @@ export function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail {
213
221
  for (let i = 0; i < users.length; i++) {
214
222
  const u = users[i]!;
215
223
  const ext = str(u.user);
216
- // A blank `user` is looked up too, rather than handed an empty device list: NetSapiens files a
217
- // nameless user's devices under `''`, and dropping them reads as a clean match on a domain that
218
- // has handsets nobody can see. Two blank users would share that list and overcount a visible
219
- // drift the operator investigates, which is the failure worth having.
220
- const item = extensionItem(u, devicesByUser[ext] ?? [], i);
224
+ // A blank `user` is looked up too, rather than handed an empty device list. This library's own
225
+ // `fetchDomainSnapshot` never files anything under `''` it skips a blank extension before the
226
+ // device read (see `nsClient.ts`) so this lookup can only hit in a snapshot built elsewhere,
227
+ // from a backup or a fixture. Dropping it would read as a clean match on a domain that has
228
+ // handsets nobody can see; two blank users sharing one list overcount instead, which is a
229
+ // visible drift an operator investigates, and that is the failure worth having.
230
+ const item = extensionItem(u, devicesByUser[ext] ?? []);
221
231
  (isSystemUser(u) ? systemUsers : extensions).push(item);
222
232
  }
223
- const dids: NumberItem[] = phonenumbers.map((p, i) => {
233
+ const dids: NumberItem[] = phonenumbers.map((p) => {
224
234
  const number = str(p.phonenumber);
225
235
  const kind: 'local' | 'tollFree' = isTollFree(number) ? 'tollFree' : 'local';
226
- return { key: identityKey('did', number, `${JSON.stringify({ number, kind })} ${i}`), number, kind };
236
+ return { key: identityKey('did', number, JSON.stringify({ number, kind })), number, kind };
227
237
  });
228
238
  const e911Addresses: AddressItem[] = addresses.map((a, i) => {
229
239
  const id = str(a['emergency-address-id']);
@@ -239,16 +249,23 @@ export function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail {
239
249
  label: label || id || `(address ${i + 1})`,
240
250
  };
241
251
  });
242
- const smsNumbers: SmsItem[] = smsnumbers.map((s, i) => {
252
+ const smsNumbers: SmsItem[] = smsnumbers.map((s) => {
243
253
  const number = str(s.number);
244
- return { key: identityKey('sms', number, `${JSON.stringify({ number })} ${i}`), number };
254
+ return { key: identityKey('sms', number, JSON.stringify({ number })), number };
245
255
  });
246
256
  return { extensions, systemUsers, dids, e911Addresses, smsNumbers };
247
257
  }
248
258
 
249
259
  /** The counts, as a fold over {@link listDomainInventory} so the two can never disagree. */
250
260
  export function countDomainInventory(snapshot: Snapshot): DomainInventory {
251
- 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 {
252
269
  const inv: DomainInventory = {
253
270
  extensions: { total: 0, byScope: {}, byServiceCode: {}, byDeviceCount: { '0': 0, '1': 0, '2': 0, '3+': 0 }, withAnyDevice: 0, withNoDevice: 0 },
254
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 } : {}),