@labacacia/nps-sdk 1.0.0-alpha.4 → 1.0.0-alpha.5
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/CHANGELOG.cn.md +20 -0
- package/CHANGELOG.md +20 -0
- package/README.cn.md +10 -3
- package/README.md +10 -3
- package/dist/core/status-codes.d.ts +1 -0
- package/dist/core/status-codes.d.ts.map +1 -1
- package/dist/core/status-codes.js +1 -0
- package/dist/core/status-codes.js.map +1 -1
- package/dist/ndp/dns-txt.d.ts +35 -0
- package/dist/ndp/dns-txt.d.ts.map +1 -0
- package/dist/ndp/dns-txt.js +67 -0
- package/dist/ndp/dns-txt.js.map +1 -0
- package/dist/ndp/index.d.ts +1 -0
- package/dist/ndp/index.d.ts.map +1 -1
- package/dist/ndp/index.js +1 -0
- package/dist/ndp/index.js.map +1 -1
- package/dist/ndp/ndp-registry.d.ts +2 -0
- package/dist/ndp/ndp-registry.d.ts.map +1 -1
- package/dist/ndp/ndp-registry.js +25 -0
- package/dist/ndp/ndp-registry.js.map +1 -1
- package/dist/nip/assurance-level.d.ts +5 -0
- package/dist/nip/assurance-level.d.ts.map +1 -1
- package/dist/nip/assurance-level.js +7 -2
- package/dist/nip/assurance-level.js.map +1 -1
- package/dist/nip/error-codes.d.ts +2 -0
- package/dist/nip/error-codes.d.ts.map +1 -1
- package/dist/nip/error-codes.js +2 -0
- package/dist/nip/error-codes.js.map +1 -1
- package/dist/nop/client.js.map +1 -1
- package/dist/nwp/client.js.map +1 -1
- package/dist/nwp/error-codes.d.ts +42 -0
- package/dist/nwp/error-codes.d.ts.map +1 -0
- package/dist/nwp/error-codes.js +53 -0
- package/dist/nwp/error-codes.js.map +1 -0
- package/dist/nwp/index.d.ts +1 -0
- package/dist/nwp/index.d.ts.map +1 -1
- package/dist/nwp/index.js +1 -0
- package/dist/nwp/index.js.map +1 -1
- package/doc/nps-sdk.nip.cn.md +30 -0
- package/doc/nps-sdk.nip.md +30 -0
- package/doc/nps-sdk.nwp.cn.md +71 -0
- package/doc/nps-sdk.nwp.md +71 -0
- package/package.json +1 -1
- package/src/core/status-codes.ts +1 -0
- package/src/ndp/dns-txt.ts +86 -0
- package/src/ndp/index.ts +1 -0
- package/src/ndp/ndp-registry.ts +34 -0
- package/src/nip/assurance-level.ts +6 -1
- package/src/nip/error-codes.ts +4 -2
- package/src/nop/client.ts +1 -1
- package/src/nwp/client.ts +4 -4
- package/src/nwp/error-codes.ts +62 -0
- package/src/nwp/index.ts +1 -0
- package/tests/ndp.test.ts +106 -0
package/tests/ndp.test.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { describe, expect, it } from "vitest";
|
|
|
5
5
|
import { AnnounceFrame, ResolveFrame, GraphFrame } from "../src/ndp/frames.js";
|
|
6
6
|
import { InMemoryNdpRegistry } from "../src/ndp/ndp-registry.js";
|
|
7
7
|
import { NdpAnnounceValidator, NdpAnnounceResult } from "../src/ndp/validator.js";
|
|
8
|
+
import { parseNpsTxtRecord, extractHostFromTarget, type DnsTxtLookup } from "../src/ndp/dns-txt.js";
|
|
8
9
|
import { NipIdentity } from "../src/nip/identity.js";
|
|
9
10
|
import { createFullRegistry } from "../src/setup.js";
|
|
10
11
|
import { NpsFrameCodec } from "../src/core/index.js";
|
|
@@ -269,3 +270,108 @@ describe("NdpAnnounceValidator", () => {
|
|
|
269
270
|
expect(v.knownPublicKeys.size).toBe(1);
|
|
270
271
|
});
|
|
271
272
|
});
|
|
273
|
+
|
|
274
|
+
// ── DnsTxtResolution ──────────────────────────────────────────────────────────
|
|
275
|
+
|
|
276
|
+
describe("DnsTxtResolution", () => {
|
|
277
|
+
// ── parseNpsTxtRecord ───────────────────────────────────────────────────────
|
|
278
|
+
|
|
279
|
+
it("parseNpsTxtRecord - valid full record", () => {
|
|
280
|
+
const parts = ["v=nps1 type=memory port=17434 nid=urn:nps:node:api.example.com:products fp=sha256:a3f9"];
|
|
281
|
+
const result = parseNpsTxtRecord(parts, "api.example.com");
|
|
282
|
+
expect(result).toBeDefined();
|
|
283
|
+
expect(result?.host).toBe("api.example.com");
|
|
284
|
+
expect(result?.port).toBe(17434);
|
|
285
|
+
expect(result?.ttl).toBe(300);
|
|
286
|
+
expect(result?.certFingerprint).toBe("sha256:a3f9");
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
it("parseNpsTxtRecord - missing v returns undefined", () => {
|
|
290
|
+
const parts = ["type=memory port=17434 nid=urn:nps:node:api.example.com:products"];
|
|
291
|
+
expect(parseNpsTxtRecord(parts, "api.example.com")).toBeUndefined();
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
it("parseNpsTxtRecord - wrong v returns undefined", () => {
|
|
295
|
+
const parts = ["v=nps2 nid=urn:nps:node:api.example.com:products"];
|
|
296
|
+
expect(parseNpsTxtRecord(parts, "api.example.com")).toBeUndefined();
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
it("parseNpsTxtRecord - missing nid returns undefined", () => {
|
|
300
|
+
const parts = ["v=nps1 type=memory port=17434"];
|
|
301
|
+
expect(parseNpsTxtRecord(parts, "api.example.com")).toBeUndefined();
|
|
302
|
+
});
|
|
303
|
+
|
|
304
|
+
it("parseNpsTxtRecord - default port", () => {
|
|
305
|
+
const parts = ["v=nps1 nid=urn:nps:node:api.example.com:products"];
|
|
306
|
+
const result = parseNpsTxtRecord(parts, "api.example.com");
|
|
307
|
+
expect(result).toBeDefined();
|
|
308
|
+
expect(result?.port).toBe(17433);
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
it("parseNpsTxtRecord - with fingerprint", () => {
|
|
312
|
+
const parts = ["v=nps1 nid=urn:nps:node:api.example.com:products fp=sha256:deadbeef"];
|
|
313
|
+
const result = parseNpsTxtRecord(parts, "api.example.com");
|
|
314
|
+
expect(result?.certFingerprint).toBe("sha256:deadbeef");
|
|
315
|
+
});
|
|
316
|
+
|
|
317
|
+
// ── resolveWithDns ──────────────────────────────────────────────────────────
|
|
318
|
+
|
|
319
|
+
it("resolveWithDns - uses registry first (dns not called)", async () => {
|
|
320
|
+
const reg = new InMemoryNdpRegistry();
|
|
321
|
+
reg.announce(makeAnnounce("urn:nps:node:example.com:data", 300));
|
|
322
|
+
|
|
323
|
+
let dnsCalled = false;
|
|
324
|
+
const mockDns: DnsTxtLookup = {
|
|
325
|
+
resolveTxt: async (_hostname: string) => {
|
|
326
|
+
dnsCalled = true;
|
|
327
|
+
return [];
|
|
328
|
+
},
|
|
329
|
+
};
|
|
330
|
+
|
|
331
|
+
const result = await reg.resolveWithDns("nwp://example.com/data", mockDns);
|
|
332
|
+
expect(result).toBeDefined();
|
|
333
|
+
expect(result?.host).toBe("example.com");
|
|
334
|
+
expect(dnsCalled).toBe(false);
|
|
335
|
+
});
|
|
336
|
+
|
|
337
|
+
it("resolveWithDns - falls back to dns when registry empty", async () => {
|
|
338
|
+
const reg = new InMemoryNdpRegistry();
|
|
339
|
+
|
|
340
|
+
const mockDns: DnsTxtLookup = {
|
|
341
|
+
resolveTxt: async (hostname: string) => {
|
|
342
|
+
expect(hostname).toBe("_nps-node.api.example.com");
|
|
343
|
+
return [["v=nps1 nid=urn:nps:node:api.example.com:products port=17434"]];
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
|
|
347
|
+
const result = await reg.resolveWithDns("nwp://api.example.com/products", mockDns);
|
|
348
|
+
expect(result).toBeDefined();
|
|
349
|
+
expect(result?.host).toBe("api.example.com");
|
|
350
|
+
expect(result?.port).toBe(17434);
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
it("resolveWithDns - invalid txt returns undefined", async () => {
|
|
354
|
+
const reg = new InMemoryNdpRegistry();
|
|
355
|
+
|
|
356
|
+
const mockDns: DnsTxtLookup = {
|
|
357
|
+
resolveTxt: async (_hostname: string) => {
|
|
358
|
+
// Missing v=nps1 and nid — invalid record
|
|
359
|
+
return [["type=memory port=17434"]];
|
|
360
|
+
},
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const result = await reg.resolveWithDns("nwp://api.example.com/products", mockDns);
|
|
364
|
+
expect(result).toBeUndefined();
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
it("resolveWithDns - empty records returns undefined", async () => {
|
|
368
|
+
const reg = new InMemoryNdpRegistry();
|
|
369
|
+
|
|
370
|
+
const mockDns: DnsTxtLookup = {
|
|
371
|
+
resolveTxt: async (_hostname: string) => [],
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
const result = await reg.resolveWithDns("nwp://api.example.com/products", mockDns);
|
|
375
|
+
expect(result).toBeUndefined();
|
|
376
|
+
});
|
|
377
|
+
});
|