@dszp/netsapiens-lib 0.8.0 → 0.9.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
@@ -63,7 +63,10 @@ Two composites are provided because they're multi-read and worth getting right o
63
63
 
64
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` (the domain-level SMS-enabled number list), `includeDevices`
66
+ address records **and** emergency endpoints — two reads under one flag, because the endpoint is what the
67
+ carrier bills for and the address is the location it dispatches to, and counting one without the other
68
+ is how a domain gets billed for the wrong thing), `includeSmsNumbers` (the domain-level SMS-enabled
69
+ number list), `includeDevices`
67
70
  (per-extension device records — one `/devices` read per real extension, so it is the expensive one on a
68
71
  domain with many seats), and `includeUserSmsNumbers` (per-extension SMS numbers into
69
72
  `snapshot.smsNumbersByUser` — same one-read-per-extension cost, needed because the domain-level list
@@ -95,7 +98,13 @@ VoIP operator actually sells on:
95
98
  it is a connector, not a handset. See [Device suffixes](#device-suffixes).
96
99
  - `dids` — phone numbers: `total` / `tollFree` / `local`, all three **excluding fax lines**, plus
97
100
  `fax` and `all` (everything, `total + fax === all`). See [Fax lines](#fax-lines).
98
- - `e911Addresses`, `smsNumbers`record counts.
101
+ - `e911Addresses` — E911 **address** records: dispatchable locations, information only.
102
+ - `e911Endpoints` — provisioned Emergency **Endpoints**: a callback number, a caller name, a billing
103
+ address and a vendor. This is the unit the E911 carrier routes on and bills per. See
104
+ [E911](#e911-endpoints-bill-addresses-locate).
105
+ - `e911Legacy` — distinct legacy emergency numbers on a domain that has no endpoint records. Comparable
106
+ with `e911Endpoints` and never overlapping it.
107
+ - `smsNumbers` — record count.
99
108
  - `devices` — `total` and `byModel`, real extensions only (a system user's device is not a seat).
100
109
 
101
110
  Every leaf is a number, on purpose: a caller reconciling this against a billing system addresses a
@@ -183,6 +192,8 @@ never appear, though names and sites now do (that's the point of a list). Each i
183
192
  | `extensions`, `systemUsers` | `ext:<user>` |
184
193
  | `dids` | `did:<phonenumber>` |
185
194
  | `e911Addresses` | `addr:<emergency-address-id>` |
195
+ | `e911Endpoints` | `e911:<callback digits>` |
196
+ | `e911Legacy` | `e911legacy:<digits>` |
186
197
  | `smsNumbers` | `sms:<number>` |
187
198
 
188
199
  A number carries `fax` (see [Fax lines](#fax-lines)) and `destination` — where it routes, in words
@@ -210,6 +221,8 @@ no separate lookup table:
210
221
  | `dids.fax` | fax lines |
211
222
  | `dids.all` | every phone number, fax lines included |
212
223
  | `e911Addresses` | E911 addresses |
224
+ | `e911Endpoints` | Emergency endpoints |
225
+ | `e911Legacy` | Legacy emergency numbers |
213
226
  | `smsNumbers` | SMS numbers |
214
227
 
215
228
  `devices.*` and `systemUsers.*` paths return `undefined` — not `[]` — because there is no item list for
@@ -235,16 +248,57 @@ address and SMS number either `own-site` (the item's own site matches), `via-use
235
248
  never fetched with `includeUserSmsNumbers`.
236
249
 
237
250
  Each verdict carries **`sites: string[]`** as well as `site`. They agree wherever there is one site,
238
- and only an **E911 address** can carry more than one: an address is a fact about a place, and users on
239
- four sites can all reference it, so `sites` names every one of them while `site` stays `null`. A
240
- consumer splitting a domain between billing accounts should read `sites` placing such an address on
241
- exactly one account leaves every other referencing account's E911 line short.
251
+ and only the three E911 kinds an **address**, an **endpoint**, a **legacy number** can carry more
252
+ than one: each is a fact about a place, and users on four sites can all reference it, so `sites` names
253
+ every one of them while `site` stays `null`. A consumer splitting a domain between billing accounts
254
+ should read `sites` — placing such an item on exactly one account leaves every other referencing
255
+ account's E911 line short.
256
+
257
+ Attribution reads two E911 **inheritances** into a blank field before it decides anything: a user with a
258
+ blank `emergency-address-id` is placed as referencing the domain's default address, and one with a blank
259
+ `caller-id-number-emergency` as referencing that address's endpoint. Reading the raw records instead
260
+ would call a domain's busiest address unreferenced — but both fallbacks are **this library's inference,
261
+ not confirmed platform behaviour**, and the same state can be read as an E911 gap. They fail closed
262
+ (nothing to inherit leaves the user referencing nothing), they move placement rather than counts, and
263
+ the ⚠️ on `EmergencyModel` sets out exactly what is known and what is assumed.
242
264
 
243
265
  Filter `listDomainInventory(snapshot)`'s items by that
244
266
  attribution to scope a domain down to one site, then run `countInventoryDetail(detail)` over what's left
245
267
  to get counts that agree with what you kept, rather than recomputing `countDomainInventory` against the
246
268
  whole domain and hoping the numbers happen to match.
247
269
 
270
+ ### E911: endpoints bill, addresses locate
271
+
272
+ Three things wear the E911 name in NetSapiens, and only one of them is billable.
273
+
274
+ An **Emergency Endpoint** (`GET /domains/{d}/addresses/endpoints`) is a callback number, a caller name,
275
+ a billing address and a vendor. It is what the carrier routes a 911 call on and what it charges for, and
276
+ it is counted as `e911Endpoints`. ⚠️ An endpoint record holds its callback NUMBER in the
277
+ `emergency-address-id` field — the same field name an address record uses for its own `a-…` id.
278
+
279
+ An **Emergency Address** is a dispatchable location forwarded to responders. Several can sit under one
280
+ endpoint, and nobody bills them; `e911Addresses` stays, as information.
281
+
282
+ A **legacy emergency number** has no API object at all. On a domain still on the pre-endpoint model every
283
+ user carries an empty `emergency-address-id` and a `caller-id-number-emergency` set to one of a handful
284
+ of DIDs, and the carrier bills per one of those DIDs. `e911Legacy` counts the distinct ones, excluding
285
+ any that is also an endpoint callback so a half-migrated domain is not billed twice for one place.
286
+
287
+ Users, devices and sites point at an endpoint through their Emergency Caller ID matching its callback
288
+ number, compared as digits (`emergencyDigits` collapses `1NXXNXXXXXX` to ten and reads the `[*]`
289
+ wildcard as "not set"). `resolveEmergency(snapshot)` is the one place the domain-default fallbacks are
290
+ applied, and both the counter and `attributeDomainInventory` read it, so the count and the placement
291
+ cannot disagree about who references what. **Read its ⚠️ before relying on the placement**: that a blank
292
+ field falls back to the domain default at all, and that the default address's callback is reachable by
293
+ matching `address-name` against an endpoint, are two assumptions this library makes rather than two
294
+ things the platform documents. Both fail closed.
295
+
296
+ `e911Legacy` needs the endpoint list to have been read, because it is kept apart from `e911Endpoints` by
297
+ excluding numbers that are already endpoint callbacks. **It is 0 whenever `snapshot.addressEndpoints` is
298
+ `undefined`** — the fetch never asked — since a count derived from the users alone would report a
299
+ fully-migrated domain's every emergency caller ID as a billable line. An empty ARRAY is the other fact,
300
+ "asked, and there are none", and that one does support a count.
301
+
248
302
  ### Read/write split by charter
249
303
 
250
304
  `NsClient` exposes **`get()` and nothing else**, and `verify()` only ever issues `GET /jwt`. That is a
@@ -1 +1 @@
1
- {"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAO,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,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,CA8D9E"}
1
+ {"version":3,"file":"attribution.d.ts","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"AAsDA,OAAO,KAAK,EAAO,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEhD,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB;;;;;;;OAOG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,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,CAuF9E"}
@@ -24,17 +24,34 @@
24
24
  * when there is exactly one and `null` otherwise, so a consumer that can only hold one still reads
25
25
  * the unambiguous case correctly. `unreferenced` when no real extension names it; `no-site` when the
26
26
  * ones that do have no site.
27
+ * - An E911 ENDPOINT: the same rule, over the users whose Emergency Caller ID equals its callback.
28
+ * An endpoint is a fact about a place too — it is the thing the carrier bills for one — so it can
29
+ * sit on several sites for the same reason an address can.
30
+ * - A LEGACY emergency number: the same rule again, over the users the number was derived from.
27
31
  * - An SMS number: the site of the user whose per-user list carries it (`via-user:<ext>`), or
28
32
  * `sms-user-unknown` when no per-user list does — including when the per-user read was never
29
33
  * made. Never guessed from the domain-level list, which does not say.
30
34
  *
35
+ * ## A blank E911 field is READ AS the domain default — an inference, not a platform fact
36
+ *
37
+ * A user with a blank `emergency-address-id` is placed here as referencing the domain's default
38
+ * address, and one with a blank `caller-id-number-emergency` as referencing that address's endpoint.
39
+ * Reading the records literally instead would call a domain's busiest address unreferenced, so the
40
+ * fallback is the better of the two readings — but it is a reading. **It has not been confirmed against
41
+ * live platform behaviour**, and the same state can be read as an E911 gap; see the ⚠️ on
42
+ * `EmergencyModel` in `inventory.ts` for the two assumptions and how each fails closed. What they move
43
+ * is placement, not counts — on a split domain, which accounts are told they need an E911 line.
44
+ *
45
+ * Both are resolved by `resolveEmergency` in `inventory.ts`, the same call the counter makes, so the
46
+ * count and the placement cannot disagree about who references what.
47
+ *
31
48
  * ## Keys are joined by index
32
49
  *
33
50
  * `listDomainInventory` maps each source array 1:1 and in order, and this module relies on that to
34
51
  * put an item's KEY (which may be a derived `~hash`) beside its RECORD's routing fields. That
35
52
  * invariant is this library's own, and this is the one place allowed to lean on it.
36
53
  */
37
- import { isSystemUser, listDomainInventory, str, usersByExt } from './inventory.js';
54
+ import { isSystemUser, legacyEmergencyNumber, listDomainInventory, resolveEmergency, str, usersByExt } from './inventory.js';
38
55
  const none = (reason) => ({ site: null, sites: [], how: `unattributed:${reason}` });
39
56
  export function attributeDomainInventory(snapshot) {
40
57
  const users = Array.isArray(snapshot.users) ? snapshot.users : [];
@@ -67,36 +84,56 @@ export function attributeDomainInventory(snapshot) {
67
84
  }
68
85
  items[key] = one(site, `via-user:${dest}`);
69
86
  }
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
- }
87
+ /**
88
+ * The verdict for a PLACE — an address, an endpoint, a legacy number — from the real extensions that
89
+ * reference it. One function because the three differ only in how "reference" is decided, and three
90
+ * copies of the multi-site rule would be three chances to disagree about it.
91
+ *
92
+ * SEVERAL SITES IS AN ANSWER, not a failure. The referencing users name every place the thing is
93
+ * used, and a consumer billing per site needs all of them; `site` still answers only the unambiguous
94
+ * case, which is what keeps a one-site consumer correct without reading `sites`.
95
+ */
96
+ const place = (who) => {
97
+ if (!who.length)
98
+ return none('unreferenced');
89
99
  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
- continue;
93
- }
94
- // SEVERAL SITES IS AN ANSWER, not a failure. The referencing users name every place this address
95
- // is used, and a consumer billing per site needs all of them; `site` still answers only the
96
- // unambiguous case, which is what keeps a one-site consumer correct without reading `sites`.
100
+ if (sites.length === 0)
101
+ return none('no-site');
97
102
  const how = `via-users:${who.map((u) => str(u.user)).filter(Boolean).sort().join(',')}`;
98
- items[key] = sites.length === 1 ? one(sites[0], how) : { site: null, sites, how };
103
+ return sites.length === 1 ? one(sites[0], how) : { site: null, sites, how };
104
+ };
105
+ /** Group the REAL extensions by whatever they reference; a blank answer references nothing. */
106
+ const referencedBy = (of) => {
107
+ const refs = new Map();
108
+ for (const u of users) {
109
+ if (isSystemUser(u))
110
+ continue;
111
+ const id = of(u);
112
+ if (!id)
113
+ continue;
114
+ const list = refs.get(id) ?? [];
115
+ list.push(u);
116
+ refs.set(id, list);
117
+ }
118
+ return refs;
119
+ };
120
+ // The two inheritances (see the module doc), resolved once and shared with the counter's own reading
121
+ // of them — `listDomainInventory` above derived the legacy list from this same rule.
122
+ const em = resolveEmergency(snapshot);
123
+ // Addresses, by index against `addresses`. A user with a blank id references the DOMAIN DEFAULT.
124
+ const addrRefs = referencedBy((u) => em.addressIdFor(u));
125
+ for (let i = 0; i < d.e911Addresses.length; i++) {
126
+ const key = d.e911Addresses[i].key, id = str((addresses[i] ?? {})['emergency-address-id']);
127
+ items[key] = place(id ? addrRefs.get(id) ?? [] : []);
99
128
  }
129
+ // Endpoints and legacy numbers carry their own identity on the item (`callback` / `number`), so
130
+ // neither needs the index join the other lists use — nothing here depends on list order.
131
+ const cbRefs = referencedBy((u) => em.callbackFor(u));
132
+ for (const e of d.e911Endpoints)
133
+ items[e.key] = place(e.callback ? cbRefs.get(e.callback) ?? [] : []);
134
+ const legacyRefs = referencedBy((u) => legacyEmergencyNumber(u, em));
135
+ for (const l of d.e911Legacy)
136
+ items[l.key] = place(legacyRefs.get(l.number) ?? []);
100
137
  // SMS numbers, by index against `smsnumbers`, joined to a user through the per-user lists.
101
138
  const extBySms = new Map();
102
139
  if (byUser)
@@ -1 +1 @@
1
- {"version":3,"file":"attribution.js","sourceRoot":"","sources":["../src/attribution.ts"],"names":[],"mappings":"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"}
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,7 @@ 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, countInventoryDetail, listDomainInventory, itemsFor, itemLabel, destinationOf, usersByExt, DEFAULT_DEVICE_SUFFIXES, type DeviceSuffixLegend, type DomainInventory, type DomainInventoryDetail, type InventoryOptions, type ExtensionItem, type NumberItem, type AddressItem, type SmsItem, type InventoryItem } from './inventory.js';
19
+ export { countDomainInventory, countInventoryDetail, listDomainInventory, itemsFor, itemLabel, destinationOf, emergencyDigits, legacyEmergencyNumber, resolveEmergency, usersByExt, DEFAULT_DEVICE_SUFFIXES, type DeviceSuffixLegend, type DomainInventory, type DomainInventoryDetail, type EmergencyModel, type InventoryOptions, type ExtensionItem, type NumberItem, type AddressItem, type EndpointItem, type LegacyE911Item, type SmsItem, type InventoryItem } from './inventory.js';
20
20
  export { attributeDomainInventory, type DomainAttribution, type ItemAttribution } from './attribution.js';
21
21
  export { NsWriteClient, type NsWriteClientConfig } from './nsWriteClient.js';
22
22
  export { supportsSynchronous, SYNCHRONOUS_OPERATIONS, type SynchronousMethod, type SynchronousOperation, } from './nsSynchronous.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,KAAK,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EACL,MAAM,EACN,mBAAmB,EACnB,kBAAkB,EAClB,UAAU,EACV,SAAS,EACT,UAAU,EACV,SAAS,EACT,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,SAAS,EACd,KAAK,WAAW,GACjB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,WAAW,GACjB,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,EAAE,KAAK,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAClK,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,uBAAuB,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,KAAK,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,gBAAgB,CAAC;AACrW,OAAO,EAAE,wBAAwB,EAAE,KAAK,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAC1G,OAAO,EAAE,aAAa,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,cAAc,EACd,mBAAmB,EACnB,YAAY,EACZ,KAAK,cAAc,EACnB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,GAC1B,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAE,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,EACjB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,uBAAuB,EAC5B,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,GAC9B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,MAAM,EACN,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,QAAQ,EACR,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,YAAY,GAClB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,KAAK,eAAe,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1F,OAAO,EACL,WAAW,EACX,aAAa,EACb,eAAe,EACf,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,QAAQ,EACb,KAAK,KAAK,GACX,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,WAAW,EACX,SAAS,EACT,GAAG,EACH,KAAK,UAAU,EACf,KAAK,MAAM,EACX,KAAK,eAAe,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,mBAAmB,EACnB,KAAK,YAAY,EACjB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,WAAW,EAChB,KAAK,QAAQ,EACb,KAAK,UAAU,GAChB,MAAM,kBAAkB,CAAC"}
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,7 @@ 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, countInventoryDetail, listDomainInventory, itemsFor, itemLabel, destinationOf, usersByExt, DEFAULT_DEVICE_SUFFIXES } from './inventory.js';
18
+ export { countDomainInventory, countInventoryDetail, listDomainInventory, itemsFor, itemLabel, destinationOf, emergencyDigits, legacyEmergencyNumber, resolveEmergency, usersByExt, DEFAULT_DEVICE_SUFFIXES } from './inventory.js';
19
19
  export { attributeDomainInventory } from './attribution.js';
20
20
  export { NsWriteClient } from './nsWriteClient.js';
21
21
  export { supportsSynchronous, SYNCHRONOUS_OPERATIONS, } from './nsSynchronous.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,oBAAoB,EAAE,mBAAmB,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,uBAAuB,EAA6L,MAAM,gBAAgB,CAAC;AACrW,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"}
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,EAAE,aAAa,EAAE,eAAe,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,UAAU,EAAE,uBAAuB,EAA0P,MAAM,gBAAgB,CAAC;AAC5d,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"}
@@ -38,6 +38,35 @@
38
38
  * case-insensitively, and on nothing else — not the `dial-rule-description`, which is a portal-written
39
39
  * note an operator can edit. **With no hosts supplied nothing is a fax line**, because a library that
40
40
  * hardcoded one deployment's fax server would be wrong everywhere else.
41
+ *
42
+ * ## E911: the ENDPOINT is the billable unit, the address is a location
43
+ *
44
+ * An **Emergency Endpoint** is a callback number, a caller name, a billing address and a vendor. It is
45
+ * what the E911 carrier routes on and what it bills per, and it is counted as `e911Endpoints`. An
46
+ * **Emergency Address** is a dispatchable location forwarded to responders; several of them can sit
47
+ * under one endpoint, and nobody bills them. `e911Addresses` stays, as information.
48
+ *
49
+ * Users, devices and sites point at an endpoint through their Emergency Caller ID
50
+ * (`caller-id-number-emergency`) matching the endpoint's callback number. This library then INFERS two
51
+ * fallbacks for a blank field — a blank `emergency-address-id` reads as the domain default address, and
52
+ * a blank caller ID reads as that address's endpoint. **Neither is a measured platform behaviour**; see
53
+ * the ⚠️ on {@link EmergencyModel} for what is known and what is assumed. They live in
54
+ * {@link resolveEmergency} alone, so the counter and `attribution.ts` cannot disagree about them, and
55
+ * they fail closed: nothing to inherit leaves a user referencing nothing rather than referencing a
56
+ * guess.
57
+ *
58
+ * ## Legacy emergency numbers, which have no API object at all
59
+ *
60
+ * A domain still on the legacy provisioning model has no endpoint records. Every one of its users
61
+ * carries an EMPTY `emergency-address-id` and a `caller-id-number-emergency` set to one of a handful of
62
+ * DIDs — and the carrier bills per one of those DIDs, exactly as it bills per endpoint on the new
63
+ * model. `e911Legacy` is therefore the count of DISTINCT such numbers, and a rulebook can count the two
64
+ * dimensions together so one retail E911 line pays for either model.
65
+ *
66
+ * A number that IS an endpoint callback is excluded, because a half-migrated domain that counted it in
67
+ * both dimensions would bill the same place twice. That exclusion is also the precondition: with no
68
+ * endpoint list read there is nothing to exclude against, so `e911Legacy` is 0 whenever
69
+ * `snapshot.addressEndpoints` is `undefined` rather than an array. See {@link DomainInventory.e911Legacy}.
41
70
  */
42
71
  import type { Rec, Snapshot } from './model.js';
43
72
  export interface DomainInventory {
@@ -88,8 +117,25 @@ export interface DomainInventory {
88
117
  fax: number;
89
118
  all: number;
90
119
  };
91
- /** E911 address records on the domain. */
120
+ /**
121
+ * E911 address records on the domain — dispatchable LOCATIONS, and information only. The billable
122
+ * unit is {@link DomainInventory.e911Endpoints}; see the module doc.
123
+ */
92
124
  e911Addresses: number;
125
+ /** Provisioned Emergency Endpoints — the unit the E911 carrier bills per. */
126
+ e911Endpoints: number;
127
+ /**
128
+ * Distinct legacy emergency numbers — the pre-endpoint model, which has no API object of its own.
129
+ * Comparable with {@link DomainInventory.e911Endpoints}, and never overlapping it **provided the
130
+ * snapshot carries an endpoint list**: the two are kept apart by excluding numbers that are already
131
+ * endpoint callbacks, which needs the endpoints to have been read.
132
+ *
133
+ * So this is **0 whenever `snapshot.addressEndpoints` is `undefined`** — the fetch never asked, and a
134
+ * count derived from the users alone would report a fully-migrated domain's every emergency caller ID
135
+ * as a line to bill for. An empty ARRAY is the other fact — asked, and the domain has none — and that
136
+ * one does support a count. Fetch with `includeAddresses: true` (see `fetchDomainSnapshot`).
137
+ */
138
+ e911Legacy: number;
93
139
  /** SMS-enabled numbers on the domain. */
94
140
  smsNumbers: number;
95
141
  /** Devices belonging to real extensions only — a system user's device is not a seat. */
@@ -173,11 +219,43 @@ export interface AddressItem {
173
219
  key: string;
174
220
  label: string;
175
221
  }
222
+ /**
223
+ * One provisioned Emergency Endpoint — the thing the E911 carrier bills per.
224
+ *
225
+ * An allowlist like every other item: the callback, the caller name, and the billing address reduced to
226
+ * the ONE line {@link AddressItem} already exposes. The endpoint record also carries a geolocation XML
227
+ * and a public IP, and neither belongs in front of a billing operator.
228
+ */
229
+ export interface EndpointItem {
230
+ /** `e911:<callback>` — the digits, so a device's 11-digit form and the record's 10-digit form are one
231
+ * key. `e911:~<hash>` when the record names no callback at all. */
232
+ key: string;
233
+ /** The callback number, digits only ({@link emergencyDigits}); `''` when the record has none. */
234
+ callback: string;
235
+ /** `caller-name` — who the carrier announces; `''` when blank. */
236
+ callerName: string;
237
+ /** Street and city, one line — no more of the billing address than the address list already shows. */
238
+ billingAddress: string;
239
+ /** How many users the RECORD says are configured on it (`count-users-configured`), 0 when it says nothing. */
240
+ users: number;
241
+ }
242
+ /**
243
+ * One legacy emergency number: a `caller-id-number-emergency` in use on a domain that has no endpoint
244
+ * records for it. Derived from the users, because the legacy model has no object of its own to read.
245
+ */
246
+ export interface LegacyE911Item {
247
+ /** `e911legacy:<digits>`. Never a hash fallback — a blank number is not one of these. */
248
+ key: string;
249
+ /** The number, digits only ({@link emergencyDigits}). */
250
+ number: string;
251
+ /** How many real extensions reference it — counted here, not read off a record. */
252
+ users: number;
253
+ }
176
254
  export interface SmsItem {
177
255
  key: string;
178
256
  number: string;
179
257
  }
180
- export type InventoryItem = ExtensionItem | NumberItem | AddressItem | SmsItem;
258
+ export type InventoryItem = ExtensionItem | NumberItem | AddressItem | EndpointItem | LegacyE911Item | SmsItem;
181
259
  export interface DomainInventoryDetail {
182
260
  /** Real seats only, same rule as the count. */
183
261
  extensions: ExtensionItem[];
@@ -185,6 +263,8 @@ export interface DomainInventoryDetail {
185
263
  systemUsers: ExtensionItem[];
186
264
  dids: NumberItem[];
187
265
  e911Addresses: AddressItem[];
266
+ e911Endpoints: EndpointItem[];
267
+ e911Legacy: LegacyE911Item[];
188
268
  smsNumbers: SmsItem[];
189
269
  }
190
270
  /** A device-name suffix legend: `suffix → { label, teams? }`. See {@link InventoryOptions.deviceSuffixes}. */
@@ -229,12 +309,79 @@ export interface InventoryOptions {
229
309
  export declare const str: (v: unknown) => string;
230
310
  /** Is this user one of NetSapiens' internal routing objects rather than a seat? */
231
311
  export declare function isSystemUser(user: Rec): boolean;
312
+ /**
313
+ * An Emergency Caller ID reduced to what two records can be compared on: its digits, with an 11-digit
314
+ * `1NXXNXXXXXX` collapsed to its 10-digit form so a device's spelling matches an endpoint's.
315
+ *
316
+ * `''` for "not set", which the API says three ways: empty, absent, and the `[*]` wildcard the portal
317
+ * renders as "Select a Caller ID for 911 calls". Treating `[*]` as a value would give every unset
318
+ * device on a domain one shared fake endpoint.
319
+ */
320
+ export declare function emergencyDigits(v: unknown): string;
232
321
  /**
233
322
  * One record per non-blank `user`, first one wins. The same rule `attribution.ts` needs to join a
234
323
  * number's `dial-rule-translation-destination-user` (or an SMS number, or an address) back to the
235
324
  * user it belongs to — extracted here so there is exactly one copy of it in the library.
236
325
  */
237
326
  export declare function usersByExt(users: Rec[]): Map<string, Rec>;
327
+ /**
328
+ * How a domain's E911 records join up, and the two INHERITANCES this library reads into a blank field.
329
+ *
330
+ * Both the counter and `attribution.ts` need to answer "which endpoint does this user reference?" and
331
+ * "which address?". Resolved in one place so the count and the site attribution cannot disagree about
332
+ * who references what.
333
+ *
334
+ * ⚠️ **Both inheritances are this library's inference, not a measured platform behaviour.** Two
335
+ * separate assumptions sit under them, and a consumer relying on the placement should know which:
336
+ *
337
+ * 1. **That a blank field falls back to the domain default at all.** A user with a blank
338
+ * `caller-id-number-emergency` is read here as referencing the default address's endpoint, and one
339
+ * with a blank `emergency-address-id` as referencing the default address. That is a plausible
340
+ * reading of a record the portal badges "Domain Default" — but it has not been confirmed against a
341
+ * live 911 call, and the same state can be read as an E911 GAP rather than an inheritance.
342
+ * 2. **That the default address's callback is joined by `address-name`.** An address record carries no
343
+ * callback field of its own (checked against a live domain and 34 captured snapshots), so the only
344
+ * thing tying the domain default to an endpoint is that the endpoint names the same address. Every
345
+ * captured domain carrying both agreed on that name.
346
+ *
347
+ * Both fail CLOSED. No default address, no endpoint naming it, or a name that does not match, and
348
+ * `defaultCallback` is `''` — the users who would have inherited it reference nothing and are left
349
+ * unattributed, rather than being attached to a guess. The COUNTS are unaffected either way
350
+ * (`e911Endpoints` is a record count, and a user with both fields blank is correctly not legacy); what
351
+ * these assumptions move is PLACEMENT, which on a split domain decides which accounts are told they
352
+ * need an E911 line.
353
+ */
354
+ export interface EmergencyModel {
355
+ /** The `emergency-address-id` of the record marked `domain_default`; `''` when the domain has none. */
356
+ defaultAddressId: string;
357
+ /** The callback of the endpoint bound to the DEFAULT address, digits only; `''` when there is none. */
358
+ defaultCallback: string;
359
+ /** Every provisioned endpoint's callback, digits only — the "is this number already an endpoint?" test. */
360
+ endpointCallbacks: Set<string>;
361
+ /** Which address a user references: their own field, the domain default when it is blank. */
362
+ addressIdFor: (user: Rec) => string;
363
+ /** The callback a user SETS: their own field, else any of their devices'; `''` when neither does. */
364
+ setCallbackFor: (user: Rec) => string;
365
+ /** Which endpoint a user references: {@link EmergencyModel.setCallbackFor}, else the domain default's. */
366
+ callbackFor: (user: Rec) => string;
367
+ }
368
+ export declare function resolveEmergency(snapshot: Snapshot): EmergencyModel;
369
+ /**
370
+ * Is this user on the LEGACY emergency model — a caller ID set by hand, with no address record behind
371
+ * it and no endpoint provisioned for the number?
372
+ *
373
+ * All three clauses matter. A blank `emergency-address-id` alone is not legacy: a user with BOTH fields
374
+ * blank inherits the domain default address, which is the new model working as designed. And a number
375
+ * that IS an endpoint callback is the new model too — counting it here as well would bill a
376
+ * half-migrated domain twice for one place.
377
+ *
378
+ * ⚠️ **The `em` must come from a snapshot whose endpoints were READ.** The third clause tests against
379
+ * `em.endpointCallbacks`, which is empty both when the domain has no endpoints and when nobody asked
380
+ * for them — so on a snapshot fetched without `includeAddresses` this answers "legacy" for every user
381
+ * on a fully-migrated domain. {@link listDomainInventory} refuses to derive the list at all in that
382
+ * state; a caller using this predicate directly has to make the same check.
383
+ */
384
+ export declare function legacyEmergencyNumber(user: Rec, em: EmergencyModel): string;
238
385
  /**
239
386
  * Where a phone number routes, in words a person reads at a glance — not the raw NetSapiens dial
240
387
  * rule fields. Pure; looks the destination user up in `userByExt` ({@link usersByExt}) so it can
@@ -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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"}