@dszp/netsapiens-lib 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/inventory.d.ts +9 -7
- package/dist/inventory.d.ts.map +1 -1
- package/dist/inventory.js +0 -0
- package/dist/inventory.js.map +1 -1
- package/package.json +1 -1
- package/src/inventory.selftest.ts +17 -2
- package/src/inventory.ts +28 -18
package/dist/inventory.d.ts
CHANGED
|
@@ -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}),
|
|
81
|
-
*
|
|
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;
|
|
@@ -132,11 +133,12 @@ export interface DomainInventoryDetail {
|
|
|
132
133
|
* `addr:a-1`, `sms:13175550100`. NetSapiens will hand back a record whose id is blank, and a key of
|
|
133
134
|
* `addr:` shared by two records is worse than no key: a consumer recording an acceptance against it
|
|
134
135
|
* 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
|
|
136
|
-
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
*
|
|
136
|
+
* record — an address by its name, street line and city; an extension by scope, service code and
|
|
137
|
+
* name; a number or SMS number by the (blank) number itself. No seed carries the array index, so a
|
|
138
|
+
* re-fetch that reorders the list returns the same keys. Two blank records that agree on every
|
|
139
|
+
* remaining field therefore land on ONE key rather than two: a number with no number is not a
|
|
140
|
+
* countable thing, and one derived row is more honest than two that shuffle. A blank id is a
|
|
141
|
+
* provisioning fault to fix; the fallback only keeps the distinguishable ones apart until it is.
|
|
140
142
|
*/
|
|
141
143
|
export declare function listDomainInventory(snapshot: Snapshot): DomainInventoryDetail;
|
|
142
144
|
/** The counts, as a fold over {@link listDomainInventory} so the two can never disagree. */
|
package/dist/inventory.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAO,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
|
|
1
|
+
{"version":3,"file":"inventory.d.ts","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,KAAK,EAAO,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;AAuFD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,GAAG,qBAAqB,CA6C7E;AAED,4FAA4F;AAC5F,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,GAAG,eAAe,CA2BxE;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
|
package/dist/inventory.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inventory.js","sourceRoot":"","sources":["../src/inventory.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.
|
|
3
|
+
"version": "0.3.1",
|
|
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",
|
|
@@ -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
|
|
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
|
|
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}),
|
|
73
|
-
*
|
|
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;
|
|
@@ -131,6 +132,12 @@ 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)}`;
|
|
@@ -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[]
|
|
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}
|
|
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
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
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
|
|
217
|
-
//
|
|
218
|
-
//
|
|
219
|
-
//
|
|
220
|
-
|
|
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
|
|
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,
|
|
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,9 +249,9 @@ 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
|
|
252
|
+
const smsNumbers: SmsItem[] = smsnumbers.map((s) => {
|
|
243
253
|
const number = str(s.number);
|
|
244
|
-
return { key: identityKey('sms', number,
|
|
254
|
+
return { key: identityKey('sms', number, JSON.stringify({ number })), number };
|
|
245
255
|
});
|
|
246
256
|
return { extensions, systemUsers, dids, e911Addresses, smsNumbers };
|
|
247
257
|
}
|