@labacacia/nps-sdk 1.0.0-alpha.6 → 1.0.0-alpha.8
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 +126 -0
- package/CHANGELOG.md +135 -0
- package/README.cn.md +9 -2
- package/README.md +9 -2
- package/dist/core/anchor-cache.d.ts +42 -0
- package/dist/core/anchor-cache.d.ts.map +1 -0
- package/dist/core/anchor-cache.js +104 -0
- package/dist/core/anchor-cache.js.map +1 -0
- package/dist/core/cache.d.ts +14 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +80 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/canonical-json.d.ts +12 -0
- package/dist/core/canonical-json.d.ts.map +1 -0
- package/dist/core/canonical-json.js +44 -0
- package/dist/core/canonical-json.js.map +1 -0
- package/dist/core/codec.d.ts +32 -0
- package/dist/core/codec.d.ts.map +1 -0
- package/dist/core/codec.js +119 -0
- package/dist/core/codec.js.map +1 -0
- package/dist/core/codecs/index.d.ts +4 -0
- package/dist/core/codecs/index.d.ts.map +1 -0
- package/{src/core/codecs/index.ts → dist/core/codecs/index.js} +1 -0
- package/dist/core/codecs/index.js.map +1 -0
- package/dist/core/codecs/ncp-codec.d.ts +39 -0
- package/dist/core/codecs/ncp-codec.d.ts.map +1 -0
- package/dist/core/codecs/ncp-codec.js +93 -0
- package/dist/core/codecs/ncp-codec.js.map +1 -0
- package/dist/core/codecs/tier1-json-codec.d.ts +10 -0
- package/dist/core/codecs/tier1-json-codec.d.ts.map +1 -0
- package/{src/core/codecs/tier1-json-codec.ts → dist/core/codecs/tier1-json-codec.js} +11 -16
- package/dist/core/codecs/tier1-json-codec.js.map +1 -0
- package/dist/core/codecs/tier2-msgpack-codec.d.ts +10 -0
- package/dist/core/codecs/tier2-msgpack-codec.d.ts.map +1 -0
- package/{src/core/codecs/tier2-msgpack-codec.ts → dist/core/codecs/tier2-msgpack-codec.js} +10 -14
- package/dist/core/codecs/tier2-msgpack-codec.js.map +1 -0
- package/dist/core/crypto-provider.d.ts +31 -0
- package/dist/core/crypto-provider.d.ts.map +1 -0
- package/dist/core/crypto-provider.js +10 -0
- package/dist/core/crypto-provider.js.map +1 -0
- package/dist/core/exceptions.d.ts +27 -0
- package/dist/core/exceptions.d.ts.map +1 -0
- package/dist/core/exceptions.js +52 -0
- package/dist/core/exceptions.js.map +1 -0
- package/dist/core/frame-header.d.ts +87 -0
- package/dist/core/frame-header.d.ts.map +1 -0
- package/dist/core/frame-header.js +185 -0
- package/dist/core/frame-header.js.map +1 -0
- package/dist/core/frame-registry.d.ts +35 -0
- package/dist/core/frame-registry.d.ts.map +1 -0
- package/dist/core/frame-registry.js +63 -0
- package/dist/core/frame-registry.js.map +1 -0
- package/dist/core/frames.d.ts +82 -0
- package/dist/core/frames.d.ts.map +1 -0
- package/dist/core/frames.js +155 -0
- package/dist/core/frames.js.map +1 -0
- package/dist/core/index.d.ts +11 -0
- package/dist/core/index.d.ts.map +1 -0
- package/{src/core/index.ts → dist/core/index.js} +3 -23
- package/dist/core/index.js.map +1 -0
- package/dist/core/registry.d.ts +11 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +17 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/status-codes.d.ts +29 -0
- package/dist/core/status-codes.d.ts.map +1 -0
- package/dist/core/status-codes.js +39 -0
- package/dist/core/status-codes.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/{src/index.ts → dist/index.js} +1 -1
- package/dist/index.js.map +1 -0
- package/dist/ncp/frames/anchor-frame.d.ts +29 -0
- package/dist/ncp/frames/anchor-frame.d.ts.map +1 -0
- package/dist/ncp/frames/anchor-frame.js +54 -0
- package/dist/ncp/frames/anchor-frame.js.map +1 -0
- package/dist/ncp/frames/caps-frame.d.ts +29 -0
- package/dist/ncp/frames/caps-frame.d.ts.map +1 -0
- package/dist/ncp/frames/caps-frame.js +29 -0
- package/dist/ncp/frames/caps-frame.js.map +1 -0
- package/dist/ncp/frames/diff-frame.d.ts +32 -0
- package/dist/ncp/frames/diff-frame.d.ts.map +1 -0
- package/dist/ncp/frames/diff-frame.js +37 -0
- package/dist/ncp/frames/diff-frame.js.map +1 -0
- package/dist/ncp/frames/error-frame.d.ts +16 -0
- package/dist/ncp/frames/error-frame.d.ts.map +1 -0
- package/dist/ncp/frames/error-frame.js +13 -0
- package/dist/ncp/frames/error-frame.js.map +1 -0
- package/dist/ncp/frames/hello-frame.d.ts +21 -0
- package/dist/ncp/frames/hello-frame.d.ts.map +1 -0
- package/dist/ncp/frames/hello-frame.js +25 -0
- package/dist/ncp/frames/hello-frame.js.map +1 -0
- package/dist/ncp/frames/stream-frame.d.ts +16 -0
- package/dist/ncp/frames/stream-frame.d.ts.map +1 -0
- package/dist/ncp/frames/stream-frame.js +18 -0
- package/dist/ncp/frames/stream-frame.js.map +1 -0
- package/dist/ncp/frames.d.ts +94 -0
- package/dist/ncp/frames.d.ts.map +1 -0
- package/dist/ncp/frames.js +192 -0
- package/dist/ncp/frames.js.map +1 -0
- package/dist/ncp/handshake.d.ts +30 -0
- package/dist/ncp/handshake.d.ts.map +1 -0
- package/dist/ncp/handshake.js +80 -0
- package/dist/ncp/handshake.js.map +1 -0
- package/dist/ncp/index.d.ts +12 -0
- package/dist/ncp/index.d.ts.map +1 -0
- package/{src/ncp/index.ts → dist/ncp/index.js} +1 -0
- package/dist/ncp/index.js.map +1 -0
- package/dist/ncp/ncp-error-codes.d.ts +23 -0
- package/dist/ncp/ncp-error-codes.d.ts.map +1 -0
- package/dist/ncp/ncp-error-codes.js +34 -0
- package/dist/ncp/ncp-error-codes.js.map +1 -0
- package/dist/ncp/ncp-patch-format.d.ts +7 -0
- package/dist/ncp/ncp-patch-format.d.ts.map +1 -0
- package/dist/ncp/ncp-patch-format.js +13 -0
- package/dist/ncp/ncp-patch-format.js.map +1 -0
- package/dist/ncp/preamble.d.ts +47 -0
- package/dist/ncp/preamble.d.ts.map +1 -0
- package/dist/ncp/preamble.js +74 -0
- package/dist/ncp/preamble.js.map +1 -0
- package/dist/ncp/registry.d.ts +3 -0
- package/dist/ncp/registry.d.ts.map +1 -0
- package/dist/ncp/registry.js +13 -0
- package/dist/ncp/registry.js.map +1 -0
- package/dist/ncp/stream-manager.d.ts +57 -0
- package/dist/ncp/stream-manager.d.ts.map +1 -0
- package/dist/ncp/stream-manager.js +163 -0
- package/dist/ncp/stream-manager.js.map +1 -0
- 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/frames.d.ts +56 -0
- package/dist/ndp/frames.d.ts.map +1 -0
- package/dist/ndp/frames.js +87 -0
- package/dist/ndp/frames.js.map +1 -0
- package/dist/ndp/index.d.ts +6 -0
- package/dist/ndp/index.d.ts.map +1 -0
- package/{src/ndp/index.ts → dist/ndp/index.js} +1 -1
- package/dist/ndp/index.js.map +1 -0
- package/dist/ndp/ndp-registry.d.ts +13 -0
- package/dist/ndp/ndp-registry.d.ts.map +1 -0
- package/dist/ndp/ndp-registry.js +104 -0
- package/dist/ndp/ndp-registry.js.map +1 -0
- package/dist/ndp/registry.d.ts +3 -0
- package/dist/ndp/registry.d.ts.map +1 -0
- package/dist/ndp/registry.js +10 -0
- package/dist/ndp/registry.js.map +1 -0
- package/dist/ndp/validator.d.ts +18 -0
- package/dist/ndp/validator.d.ts.map +1 -0
- package/dist/ndp/validator.js +48 -0
- package/dist/ndp/validator.js.map +1 -0
- package/dist/nip/acme/client.d.ts +31 -0
- package/dist/nip/acme/client.d.ts.map +1 -0
- package/dist/nip/acme/client.js +136 -0
- package/dist/nip/acme/client.js.map +1 -0
- package/dist/nip/acme/index.d.ts +6 -0
- package/dist/nip/acme/index.d.ts.map +1 -0
- package/{src/nip/acme/index.ts → dist/nip/acme/index.js} +1 -1
- package/dist/nip/acme/index.js.map +1 -0
- package/dist/nip/acme/jws.d.ts +31 -0
- package/dist/nip/acme/jws.d.ts.map +1 -0
- package/dist/nip/acme/jws.js +76 -0
- package/dist/nip/acme/jws.js.map +1 -0
- package/dist/nip/acme/messages.d.ts +71 -0
- package/dist/nip/acme/messages.d.ts.map +1 -0
- package/dist/nip/acme/messages.js +4 -0
- package/dist/nip/acme/messages.js.map +1 -0
- package/dist/nip/acme/server.d.ts +41 -0
- package/dist/nip/acme/server.d.ts.map +1 -0
- package/dist/nip/acme/server.js +458 -0
- package/dist/nip/acme/server.js.map +1 -0
- package/dist/nip/acme/wire.d.ts +19 -0
- package/dist/nip/acme/wire.d.ts.map +1 -0
- package/dist/nip/acme/wire.js +21 -0
- package/dist/nip/acme/wire.js.map +1 -0
- package/dist/nip/assurance-level.d.ts +19 -0
- package/dist/nip/assurance-level.d.ts.map +1 -0
- package/dist/nip/assurance-level.js +38 -0
- package/dist/nip/assurance-level.js.map +1 -0
- package/dist/nip/cert-format.d.ts +5 -0
- package/dist/nip/cert-format.d.ts.map +1 -0
- package/dist/nip/cert-format.js +6 -0
- package/dist/nip/cert-format.js.map +1 -0
- package/dist/nip/error-codes.d.ts +25 -0
- package/dist/nip/error-codes.d.ts.map +1 -0
- package/{src/nip/error-codes.ts → dist/nip/error-codes.js} +19 -25
- package/dist/nip/error-codes.js.map +1 -0
- package/dist/nip/frames.d.ts +53 -0
- package/dist/nip/frames.d.ts.map +1 -0
- package/dist/nip/frames.js +106 -0
- package/dist/nip/frames.js.map +1 -0
- package/dist/nip/identity.d.ts +18 -0
- package/dist/nip/identity.d.ts.map +1 -0
- package/dist/nip/identity.js +94 -0
- package/dist/nip/identity.js.map +1 -0
- package/dist/nip/index.d.ts +11 -0
- package/dist/nip/index.d.ts.map +1 -0
- package/{src/nip/index.ts → dist/nip/index.js} +3 -2
- package/dist/nip/index.js.map +1 -0
- package/dist/nip/registry.d.ts +3 -0
- package/dist/nip/registry.d.ts.map +1 -0
- package/dist/nip/registry.js +10 -0
- package/dist/nip/registry.js.map +1 -0
- package/dist/nip/reputation-client.d.ts +116 -0
- package/dist/nip/reputation-client.d.ts.map +1 -0
- package/dist/nip/reputation-client.js +261 -0
- package/dist/nip/reputation-client.js.map +1 -0
- package/dist/nip/verifier.d.ts +23 -0
- package/dist/nip/verifier.d.ts.map +1 -0
- package/dist/nip/verifier.js +90 -0
- package/dist/nip/verifier.js.map +1 -0
- package/dist/nip/x509/builder.d.ts +35 -0
- package/dist/nip/x509/builder.d.ts.map +1 -0
- package/dist/nip/x509/builder.js +59 -0
- package/dist/nip/x509/builder.js.map +1 -0
- package/dist/nip/x509/index.d.ts +4 -0
- package/dist/nip/x509/index.d.ts.map +1 -0
- package/{src/nip/x509/index.ts → dist/nip/x509/index.js} +1 -1
- package/dist/nip/x509/index.js.map +1 -0
- package/dist/nip/x509/oids.d.ts +16 -0
- package/dist/nip/x509/oids.d.ts.map +1 -0
- package/{src/nip/x509/oids.ts → dist/nip/x509/oids.js} +5 -10
- package/dist/nip/x509/oids.js.map +1 -0
- package/dist/nip/x509/verifier.d.ts +26 -0
- package/dist/nip/x509/verifier.d.ts.map +1 -0
- package/dist/nip/x509/verifier.js +171 -0
- package/dist/nip/x509/verifier.js.map +1 -0
- package/dist/nop/client.d.ts +34 -0
- package/dist/nop/client.d.ts.map +1 -0
- package/dist/nop/client.js +90 -0
- package/dist/nop/client.js.map +1 -0
- package/dist/nop/frames.d.ts +65 -0
- package/dist/nop/frames.d.ts.map +1 -0
- package/dist/nop/frames.js +148 -0
- package/dist/nop/frames.js.map +1 -0
- package/dist/nop/index.d.ts +5 -0
- package/dist/nop/index.d.ts.map +1 -0
- package/{src/nop/index.ts → dist/nop/index.js} +1 -1
- package/dist/nop/index.js.map +1 -0
- package/dist/nop/models.d.ts +58 -0
- package/dist/nop/models.d.ts.map +1 -0
- package/dist/nop/models.js +50 -0
- package/dist/nop/models.js.map +1 -0
- package/dist/nop/nop-types.d.ts +136 -0
- package/dist/nop/nop-types.d.ts.map +1 -0
- package/dist/nop/nop-types.js +44 -0
- package/dist/nop/nop-types.js.map +1 -0
- package/dist/nop/registry.d.ts +3 -0
- package/dist/nop/registry.d.ts.map +1 -0
- package/dist/nop/registry.js +11 -0
- package/dist/nop/registry.js.map +1 -0
- package/dist/nwp/anchor-client.d.ts +109 -0
- package/dist/nwp/anchor-client.d.ts.map +1 -0
- package/dist/nwp/anchor-client.js +279 -0
- package/dist/nwp/anchor-client.js.map +1 -0
- package/dist/nwp/client.d.ts +28 -0
- package/dist/nwp/client.d.ts.map +1 -0
- package/dist/nwp/client.js +142 -0
- package/dist/nwp/client.js.map +1 -0
- package/dist/nwp/frames.d.ts +107 -0
- package/dist/nwp/frames.d.ts.map +1 -0
- package/dist/nwp/frames.js +198 -0
- package/dist/nwp/frames.js.map +1 -0
- package/dist/nwp/index.d.ts +6 -0
- package/dist/nwp/index.d.ts.map +1 -0
- package/{src/nwp/index.ts → dist/nwp/index.js} +3 -1
- package/dist/nwp/index.js.map +1 -0
- package/dist/nwp/manifest.d.ts +69 -0
- package/dist/nwp/manifest.d.ts.map +1 -0
- package/dist/nwp/manifest.js +4 -0
- package/dist/nwp/manifest.js.map +1 -0
- package/dist/nwp/registry.d.ts +3 -0
- package/dist/nwp/registry.d.ts.map +1 -0
- package/dist/nwp/registry.js +10 -0
- package/dist/nwp/registry.js.map +1 -0
- package/dist/setup.d.ts +10 -0
- package/dist/setup.d.ts.map +1 -0
- package/{src/setup.ts → dist/setup.js} +13 -16
- package/dist/setup.js.map +1 -0
- package/package.json +12 -1
- package/CONTRIBUTING.cn.md +0 -35
- package/CONTRIBUTING.md +0 -35
- package/nip-ca-server/Dockerfile +0 -27
- package/nip-ca-server/README.md +0 -45
- package/nip-ca-server/db/001_init.sql +0 -25
- package/nip-ca-server/docker-compose.yml +0 -29
- package/nip-ca-server/package.json +0 -23
- package/nip-ca-server/src/ca.ts +0 -155
- package/nip-ca-server/src/db.ts +0 -104
- package/nip-ca-server/src/index.ts +0 -157
- package/nip-ca-server/tsconfig.json +0 -13
- package/src/core/anchor-cache.ts +0 -129
- package/src/core/cache.ts +0 -93
- package/src/core/canonical-json.ts +0 -50
- package/src/core/codec.ts +0 -158
- package/src/core/codecs/ncp-codec.ts +0 -170
- package/src/core/crypto-provider.ts +0 -47
- package/src/core/exceptions.ts +0 -57
- package/src/core/frame-header.ts +0 -282
- package/src/core/frame-registry.ts +0 -91
- package/src/core/frames.ts +0 -184
- package/src/core/registry.ts +0 -28
- package/src/core/status-codes.ts +0 -47
- package/src/ncp/frames/anchor-frame.ts +0 -87
- package/src/ncp/frames/caps-frame.ts +0 -59
- package/src/ncp/frames/diff-frame.ts +0 -69
- package/src/ncp/frames/error-frame.ts +0 -26
- package/src/ncp/frames/hello-frame.ts +0 -50
- package/src/ncp/frames/stream-frame.ts +0 -35
- package/src/ncp/frames.ts +0 -251
- package/src/ncp/handshake.ts +0 -95
- package/src/ncp/ncp-error-codes.ts +0 -36
- package/src/ncp/ncp-patch-format.ts +0 -16
- package/src/ncp/preamble.ts +0 -79
- package/src/ncp/registry.ts +0 -15
- package/src/ncp/stream-manager.ts +0 -212
- package/src/ndp/dns-txt.ts +0 -86
- package/src/ndp/frames.ts +0 -124
- package/src/ndp/ndp-registry.ts +0 -116
- package/src/ndp/registry.ts +0 -12
- package/src/ndp/validator.ts +0 -64
- package/src/nip/acme/client.ts +0 -185
- package/src/nip/acme/jws.ts +0 -109
- package/src/nip/acme/messages.ts +0 -85
- package/src/nip/acme/server.ts +0 -480
- package/src/nip/acme/wire.ts +0 -24
- package/src/nip/assurance-level.ts +0 -40
- package/src/nip/cert-format.ts +0 -9
- package/src/nip/frames.ts +0 -138
- package/src/nip/identity.ts +0 -113
- package/src/nip/registry.ts +0 -12
- package/src/nip/verifier.ts +0 -122
- package/src/nip/x509/builder.ts +0 -91
- package/src/nip/x509/verifier.ts +0 -214
- package/src/nop/client.ts +0 -103
- package/src/nop/frames.ts +0 -181
- package/src/nop/models.ts +0 -79
- package/src/nop/nop-types.ts +0 -208
- package/src/nop/registry.ts +0 -13
- package/src/nwp/client.ts +0 -114
- package/src/nwp/frames.ts +0 -116
- package/src/nwp/registry.ts +0 -11
- package/tests/_rfc0002-keys.ts +0 -57
- package/tests/core/anchor-cache.test.ts +0 -242
- package/tests/core/codec.test.ts +0 -205
- package/tests/core/frame-registry.test.ts +0 -46
- package/tests/core.test.ts +0 -327
- package/tests/ncp/diff-binary-bitset.test.ts +0 -107
- package/tests/ncp/e2e-enc-reject.test.ts +0 -93
- package/tests/ncp/err-error-frame.test.ts +0 -152
- package/tests/ncp/frames.test.ts +0 -359
- package/tests/ncp/framing.test.ts +0 -233
- package/tests/ncp/hello-frame.test.ts +0 -122
- package/tests/ncp/inline-anchor.test.ts +0 -88
- package/tests/ncp/preamble.test.ts +0 -93
- package/tests/ncp/security.test.ts +0 -184
- package/tests/ncp/stream-window.test.ts +0 -167
- package/tests/ncp/stream.test.ts +0 -242
- package/tests/ncp/version-negotiation.test.ts +0 -123
- package/tests/ndp.test.ts +0 -377
- package/tests/nip-acme-agent01.test.ts +0 -192
- package/tests/nip-x509.test.ts +0 -280
- package/tests/nip.test.ts +0 -184
- package/tests/nop.test.ts +0 -344
- package/tests/nwp.test.ts +0 -237
- package/tsconfig.json +0 -20
- package/tsup.config.ts +0 -20
- package/vitest.config.ts +0 -10
package/tests/ncp/stream.test.ts
DELETED
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// Copyright (c) 2026 LabAcacia / INNO LOTUS PTY LTD
|
|
3
|
-
//
|
|
4
|
-
// NCP Test Cases — StreamFrame + StreamManager
|
|
5
|
-
// Covers: NCP-S-01 to NCP-S-06, NCP-S-12 (UUID format), NCP-S-13 (unknown stream_id)
|
|
6
|
-
// Source: test/ncp_test_cases.md §3.3
|
|
7
|
-
|
|
8
|
-
import { describe, it, expect } from "vitest";
|
|
9
|
-
import { NcpError } from "../../src/core/frame-header.js";
|
|
10
|
-
import { StreamManager } from "../../src/ncp/stream-manager.js";
|
|
11
|
-
import { validateStreamFrame, type StreamFrame } from "../../src/ncp/frames/stream-frame.js";
|
|
12
|
-
|
|
13
|
-
function chunk(
|
|
14
|
-
streamId: string,
|
|
15
|
-
seq: number,
|
|
16
|
-
data: unknown[],
|
|
17
|
-
opts?: { is_last?: boolean; error_code?: string },
|
|
18
|
-
): StreamFrame {
|
|
19
|
-
return {
|
|
20
|
-
frame: "0x03",
|
|
21
|
-
stream_id: streamId,
|
|
22
|
-
seq,
|
|
23
|
-
is_last: opts?.is_last ?? false,
|
|
24
|
-
data,
|
|
25
|
-
error_code: opts?.error_code,
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// ===========================================================================
|
|
30
|
-
// NCP-S-01: Sequential Chunks
|
|
31
|
-
// ===========================================================================
|
|
32
|
-
|
|
33
|
-
describe("NCP-S-01: Sequential Chunks", () => {
|
|
34
|
-
// -----------------------------------------------------------------------
|
|
35
|
-
// Spec: §4.3 — seq 0, 1, 2... with is_last=true on final chunk
|
|
36
|
-
// -----------------------------------------------------------------------
|
|
37
|
-
it("reassembles sequential chunks", () => {
|
|
38
|
-
const mgr = new StreamManager();
|
|
39
|
-
|
|
40
|
-
expect(mgr.receive(chunk("s1", 0, ["A", "B"]))).toBe(false);
|
|
41
|
-
expect(mgr.receive(chunk("s1", 1, ["C", "D"]))).toBe(false);
|
|
42
|
-
expect(mgr.receive(chunk("s1", 2, ["E"], { is_last: true }))).toBe(true);
|
|
43
|
-
|
|
44
|
-
const data = mgr.getData("s1");
|
|
45
|
-
expect(data).toEqual(["A", "B", "C", "D", "E"]);
|
|
46
|
-
});
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
// ===========================================================================
|
|
50
|
-
// NCP-S-02: Out of Order Gap
|
|
51
|
-
// ===========================================================================
|
|
52
|
-
|
|
53
|
-
describe("NCP-S-02: Out of Order Gap", () => {
|
|
54
|
-
// -----------------------------------------------------------------------
|
|
55
|
-
// Spec: §4.3 — Sequence numbers MUST be strictly sequential
|
|
56
|
-
// -----------------------------------------------------------------------
|
|
57
|
-
it("rejects sequence gap", () => {
|
|
58
|
-
const mgr = new StreamManager();
|
|
59
|
-
mgr.receive(chunk("s1", 0, ["A"]));
|
|
60
|
-
|
|
61
|
-
expect(() => mgr.receive(chunk("s1", 2, ["C"]))).toThrow(NcpError);
|
|
62
|
-
try {
|
|
63
|
-
mgr.receive(chunk("s1", 2, ["C"]));
|
|
64
|
-
} catch (e) {
|
|
65
|
-
expect((e as NcpError).code).toBe("NCP-STREAM-SEQ-GAP");
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// ===========================================================================
|
|
71
|
-
// NCP-S-03: Duplicate Sequence
|
|
72
|
-
// ===========================================================================
|
|
73
|
-
|
|
74
|
-
describe("NCP-S-03: Duplicate Sequence", () => {
|
|
75
|
-
// -----------------------------------------------------------------------
|
|
76
|
-
// Spec: §4.3 — Duplicate seq: ignore or error (both acceptable)
|
|
77
|
-
// Our implementation: ignore (idempotent)
|
|
78
|
-
// -----------------------------------------------------------------------
|
|
79
|
-
it("ignores duplicate sequence number", () => {
|
|
80
|
-
const mgr = new StreamManager();
|
|
81
|
-
mgr.receive(chunk("s1", 0, ["A"]));
|
|
82
|
-
const result = mgr.receive(chunk("s1", 0, ["A-dup"])); // duplicate
|
|
83
|
-
expect(result).toBe(false); // ignored
|
|
84
|
-
|
|
85
|
-
mgr.receive(chunk("s1", 1, ["B"], { is_last: true }));
|
|
86
|
-
const data = mgr.getData("s1");
|
|
87
|
-
expect(data).toEqual(["A", "B"]); // no duplicate data
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
// ===========================================================================
|
|
92
|
-
// NCP-S-04: Stream ID Conflict
|
|
93
|
-
// ===========================================================================
|
|
94
|
-
|
|
95
|
-
describe("NCP-S-04: Stream ID Conflict", () => {
|
|
96
|
-
// -----------------------------------------------------------------------
|
|
97
|
-
// Spec: §4.3 — New stream MUST NOT reuse an active stream_id.
|
|
98
|
-
// test_cases.md: spec does not define a dedicated code; implementations
|
|
99
|
-
// SHOULD use NPS-CLIENT-CONFLICT until one is assigned.
|
|
100
|
-
// -----------------------------------------------------------------------
|
|
101
|
-
it("rejects reuse of completed stream_id with NPS-CLIENT-CONFLICT", () => {
|
|
102
|
-
const mgr = new StreamManager();
|
|
103
|
-
mgr.receive(chunk("s1", 0, ["A"], { is_last: true }));
|
|
104
|
-
|
|
105
|
-
// Try to reuse s1 — it's completed
|
|
106
|
-
expect(() => mgr.receive(chunk("s1", 0, ["B"]))).toThrow(NcpError);
|
|
107
|
-
try {
|
|
108
|
-
mgr.receive(chunk("s1", 0, ["B"]));
|
|
109
|
-
} catch (e) {
|
|
110
|
-
expect((e as NcpError).code).toBe("NPS-CLIENT-CONFLICT");
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
// ===========================================================================
|
|
116
|
-
// NCP-S-05: Stream Flooding
|
|
117
|
-
// ===========================================================================
|
|
118
|
-
|
|
119
|
-
describe("NCP-S-05: Stream Flooding", () => {
|
|
120
|
-
// -----------------------------------------------------------------------
|
|
121
|
-
// Spec: §7.3 — Max concurrent streams (default 32)
|
|
122
|
-
// -----------------------------------------------------------------------
|
|
123
|
-
it("rejects opening more than max concurrent streams", () => {
|
|
124
|
-
const mgr = new StreamManager({ maxConcurrent: 3 });
|
|
125
|
-
|
|
126
|
-
mgr.receive(chunk("s1", 0, ["A"]));
|
|
127
|
-
mgr.receive(chunk("s2", 0, ["B"]));
|
|
128
|
-
mgr.receive(chunk("s3", 0, ["C"]));
|
|
129
|
-
|
|
130
|
-
// 4th stream exceeds limit
|
|
131
|
-
expect(() => mgr.receive(chunk("s4", 0, ["D"]))).toThrow(NcpError);
|
|
132
|
-
try {
|
|
133
|
-
mgr.receive(chunk("s4", 0, ["D"]));
|
|
134
|
-
} catch (e) {
|
|
135
|
-
expect((e as NcpError).code).toBe("NCP-STREAM-LIMIT-EXCEEDED");
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
// ===========================================================================
|
|
141
|
-
// NCP-S-06: Early Termination
|
|
142
|
-
// ===========================================================================
|
|
143
|
-
|
|
144
|
-
describe("NCP-S-06: Early Termination", () => {
|
|
145
|
-
// -----------------------------------------------------------------------
|
|
146
|
-
// Spec: §4.3 — error_code terminates stream, is_last forced true
|
|
147
|
-
// -----------------------------------------------------------------------
|
|
148
|
-
it("terminates stream on error_code", () => {
|
|
149
|
-
const mgr = new StreamManager();
|
|
150
|
-
|
|
151
|
-
mgr.receive(chunk("s1", 0, ["A"]));
|
|
152
|
-
mgr.receive(chunk("s1", 1, ["B"]));
|
|
153
|
-
|
|
154
|
-
const done = mgr.receive(
|
|
155
|
-
chunk("s1", 2, [], { error_code: "NCP-STREAM-SEQ-GAP" }),
|
|
156
|
-
);
|
|
157
|
-
expect(done).toBe(true);
|
|
158
|
-
|
|
159
|
-
// Partial data available
|
|
160
|
-
const data = mgr.getData("s1");
|
|
161
|
-
expect(data).toEqual(["A", "B"]);
|
|
162
|
-
|
|
163
|
-
// Error propagated
|
|
164
|
-
expect(mgr.getError("s1")).toBe("NCP-STREAM-SEQ-GAP");
|
|
165
|
-
});
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
// ===========================================================================
|
|
169
|
-
// NCP-S-12: Invalid stream_id format
|
|
170
|
-
// ===========================================================================
|
|
171
|
-
|
|
172
|
-
describe("NCP-S-12: Invalid stream_id format", () => {
|
|
173
|
-
// -----------------------------------------------------------------------
|
|
174
|
-
// Spec: §4.3 stream_id MUST be UUID v4
|
|
175
|
-
// -----------------------------------------------------------------------
|
|
176
|
-
const validV4 = "550e8400-e29b-41d4-a716-446655440000";
|
|
177
|
-
const invalidExamples = [
|
|
178
|
-
"not-a-uuid",
|
|
179
|
-
"550e8400-e29b-41d4-a716-44665544000", // one char short
|
|
180
|
-
"550e8400-e29b-11d4-a716-446655440000", // v1, not v4
|
|
181
|
-
"550e8400-e29b-41d4-c716-446655440000", // wrong variant nibble
|
|
182
|
-
"", // empty
|
|
183
|
-
];
|
|
184
|
-
|
|
185
|
-
it("accepts a valid UUID v4 stream_id", () => {
|
|
186
|
-
expect(() =>
|
|
187
|
-
validateStreamFrame({
|
|
188
|
-
frame: "0x03",
|
|
189
|
-
stream_id: validV4,
|
|
190
|
-
seq: 0,
|
|
191
|
-
is_last: false,
|
|
192
|
-
data: [],
|
|
193
|
-
}),
|
|
194
|
-
).not.toThrow();
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it.each(invalidExamples)(
|
|
198
|
-
"rejects stream_id=%s with NPS-CLIENT-BAD-FRAME",
|
|
199
|
-
(bad) => {
|
|
200
|
-
try {
|
|
201
|
-
validateStreamFrame({
|
|
202
|
-
frame: "0x03",
|
|
203
|
-
stream_id: bad,
|
|
204
|
-
seq: 0,
|
|
205
|
-
is_last: false,
|
|
206
|
-
data: [],
|
|
207
|
-
});
|
|
208
|
-
throw new Error("validateStreamFrame should have thrown");
|
|
209
|
-
} catch (e) {
|
|
210
|
-
expect(e).toBeInstanceOf(NcpError);
|
|
211
|
-
expect((e as NcpError).code).toBe("NPS-CLIENT-BAD-FRAME");
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
);
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
// ===========================================================================
|
|
218
|
-
// NCP-S-13: Unknown stream_id
|
|
219
|
-
// ===========================================================================
|
|
220
|
-
|
|
221
|
-
describe("NCP-S-13: Unknown stream_id", () => {
|
|
222
|
-
// -----------------------------------------------------------------------
|
|
223
|
-
// Spec: §4.3 — a frame for a stream_id that was never opened (seq > 0
|
|
224
|
-
// without a prior seq=0 opener) MUST be rejected with NCP-STREAM-NOT-FOUND.
|
|
225
|
-
// -----------------------------------------------------------------------
|
|
226
|
-
it("rejects seq>0 on a never-opened stream_id", () => {
|
|
227
|
-
const mgr = new StreamManager();
|
|
228
|
-
expect(() => mgr.receive(chunk("never-opened", 5, ["X"]))).toThrow(
|
|
229
|
-
NcpError,
|
|
230
|
-
);
|
|
231
|
-
try {
|
|
232
|
-
mgr.receive(chunk("never-opened", 7, ["Y"]));
|
|
233
|
-
} catch (e) {
|
|
234
|
-
expect((e as NcpError).code).toBe("NCP-STREAM-NOT-FOUND");
|
|
235
|
-
}
|
|
236
|
-
});
|
|
237
|
-
|
|
238
|
-
it("accepts seq=0 on a previously-unseen stream_id (opener)", () => {
|
|
239
|
-
const mgr = new StreamManager();
|
|
240
|
-
expect(mgr.receive(chunk("new-stream", 0, ["first"]))).toBe(false);
|
|
241
|
-
});
|
|
242
|
-
});
|
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
-
// Copyright (c) 2026 LabAcacia / INNO LOTUS PTY LTD
|
|
3
|
-
//
|
|
4
|
-
// NCP Test Cases — NCP-VN-01 through VN-08: Handshake & Version Negotiation
|
|
5
|
-
// Source: test/ncp_test_cases.md §7
|
|
6
|
-
|
|
7
|
-
import { describe, it, expect } from "vitest";
|
|
8
|
-
import { negotiateVersion, negotiateEncoding } from "../../src/ncp/handshake.js";
|
|
9
|
-
|
|
10
|
-
describe("NCP-VN: Handshake & Version Negotiation", () => {
|
|
11
|
-
// -----------------------------------------------------------------------
|
|
12
|
-
// NCP-VN-01: Compatible Versions
|
|
13
|
-
// Client: nps_version=0.4, min_version=0.3. Server: nps_version=0.4
|
|
14
|
-
// Expected: session_version=0.4
|
|
15
|
-
// -----------------------------------------------------------------------
|
|
16
|
-
it("NCP-VN-01: compatible versions — session_version = 0.4", () => {
|
|
17
|
-
const result = negotiateVersion(
|
|
18
|
-
{ nps_version: "0.4", min_version: "0.3" },
|
|
19
|
-
{ nps_version: "0.4" },
|
|
20
|
-
);
|
|
21
|
-
expect(result.compatible).toBe(true);
|
|
22
|
-
expect(result.session_version).toBe("0.4");
|
|
23
|
-
expect(result.error_code).toBeUndefined();
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// -----------------------------------------------------------------------
|
|
27
|
-
// NCP-VN-02: Client Newer (downgrade to Server)
|
|
28
|
-
// Client: nps_version=0.5, min_version=0.3. Server: nps_version=0.4
|
|
29
|
-
// Expected: session_version=0.4 (min of both)
|
|
30
|
-
// -----------------------------------------------------------------------
|
|
31
|
-
it("NCP-VN-02: client newer — session_version = 0.4 (server version)", () => {
|
|
32
|
-
const result = negotiateVersion(
|
|
33
|
-
{ nps_version: "0.5", min_version: "0.3" },
|
|
34
|
-
{ nps_version: "0.4" },
|
|
35
|
-
);
|
|
36
|
-
expect(result.compatible).toBe(true);
|
|
37
|
-
expect(result.session_version).toBe("0.4");
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
// -----------------------------------------------------------------------
|
|
41
|
-
// NCP-VN-03: Client min_version > Server max
|
|
42
|
-
// Client: nps_version=0.5, min_version=0.5. Server: nps_version=0.4
|
|
43
|
-
// Expected: NCP-VERSION-INCOMPATIBLE + connection closed
|
|
44
|
-
// -----------------------------------------------------------------------
|
|
45
|
-
it("NCP-VN-03: client min_version > server version — incompatible", () => {
|
|
46
|
-
const result = negotiateVersion(
|
|
47
|
-
{ nps_version: "0.5", min_version: "0.5" },
|
|
48
|
-
{ nps_version: "0.4" },
|
|
49
|
-
);
|
|
50
|
-
expect(result.compatible).toBe(false);
|
|
51
|
-
expect(result.error_code).toBe("NCP-VERSION-INCOMPATIBLE");
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// -----------------------------------------------------------------------
|
|
55
|
-
// NCP-VN-04: Encoding Intersection (msgpack preferred)
|
|
56
|
-
// Client=[msgpack, json], Server=[msgpack, json] → msgpack
|
|
57
|
-
// -----------------------------------------------------------------------
|
|
58
|
-
it("NCP-VN-04: encoding intersection — msgpack preferred over json", () => {
|
|
59
|
-
const result = negotiateEncoding(["msgpack", "json"], ["msgpack", "json"]);
|
|
60
|
-
expect(result.encoding).toBe("msgpack");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
// -----------------------------------------------------------------------
|
|
64
|
-
// NCP-VN-05: Encoding Intersection (json only)
|
|
65
|
-
// Client=[json], Server=[msgpack, json] → json
|
|
66
|
-
// -----------------------------------------------------------------------
|
|
67
|
-
it("NCP-VN-05: encoding intersection — json when client only supports json", () => {
|
|
68
|
-
const result = negotiateEncoding(["json"], ["msgpack", "json"]);
|
|
69
|
-
expect(result.encoding).toBe("json");
|
|
70
|
-
});
|
|
71
|
-
|
|
72
|
-
// -----------------------------------------------------------------------
|
|
73
|
-
// NCP-VN-06: Empty Encoding Intersection
|
|
74
|
-
// Client=[json], Server=[msgpack] → null (no common encoding).
|
|
75
|
-
// Per spec §2.6, this outcome MUST fail the handshake — the session layer
|
|
76
|
-
// treats encoding=null as fatal and the server returns an ErrorFrame.
|
|
77
|
-
// -----------------------------------------------------------------------
|
|
78
|
-
it("NCP-VN-06: empty encoding intersection returns null AND is a fatal handshake outcome", () => {
|
|
79
|
-
const result = negotiateEncoding(["json"], ["msgpack"]);
|
|
80
|
-
expect(result.encoding).toBeNull();
|
|
81
|
-
|
|
82
|
-
// Session-layer contract: null encoding is a fatal handshake error. The
|
|
83
|
-
// session code (not yet implemented) MUST treat this as unrecoverable.
|
|
84
|
-
// We assert the contract here so a future session impl cannot silently
|
|
85
|
-
// downgrade to an undefined/default encoding.
|
|
86
|
-
const handshakeFailsWhenEncodingIsNull = result.encoding === null;
|
|
87
|
-
expect(handshakeFailsWhenEncodingIsNull).toBe(true);
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// -----------------------------------------------------------------------
|
|
91
|
-
// NCP-VN-07: Server 5s Timeout
|
|
92
|
-
// This is a transport-layer concern; we validate the expected behaviour
|
|
93
|
-
// is documented by checking the spec reference.
|
|
94
|
-
// -----------------------------------------------------------------------
|
|
95
|
-
it("NCP-VN-07: server timeout is a transport concern — client SHOULD disconnect after 5s", () => {
|
|
96
|
-
// No unit-testable function for this; spec §7 states client SHOULD disconnect.
|
|
97
|
-
// Placeholder: assert the documented timeout value.
|
|
98
|
-
const HELLO_TIMEOUT_MS = 5000;
|
|
99
|
-
expect(HELLO_TIMEOUT_MS).toBe(5000);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// -----------------------------------------------------------------------
|
|
103
|
-
// NCP-VN-08: max_frame_payload Negotiation
|
|
104
|
-
// Client=65535, Server=131072 → session = 65535 (min)
|
|
105
|
-
// -----------------------------------------------------------------------
|
|
106
|
-
it("NCP-VN-08: max_frame_payload = min(client, server)", () => {
|
|
107
|
-
const clientMax = 65535;
|
|
108
|
-
const serverMax = 131072;
|
|
109
|
-
const sessionMax = Math.min(clientMax, serverMax);
|
|
110
|
-
expect(sessionMax).toBe(65535);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Extra: min_version absent — falls back to nps_version
|
|
114
|
-
it("NCP-VN-extra: min_version absent — uses nps_version as effective minimum", () => {
|
|
115
|
-
// Client: nps_version=0.4, no min_version. Server: nps_version=0.4 → compatible
|
|
116
|
-
const result = negotiateVersion(
|
|
117
|
-
{ nps_version: "0.4" },
|
|
118
|
-
{ nps_version: "0.4" },
|
|
119
|
-
);
|
|
120
|
-
expect(result.compatible).toBe(true);
|
|
121
|
-
expect(result.session_version).toBe("0.4");
|
|
122
|
-
});
|
|
123
|
-
});
|