@labacacia/nps-sdk 1.0.0-alpha.6 → 1.0.0-alpha.7

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.
Files changed (365) hide show
  1. package/CHANGELOG.cn.md +115 -0
  2. package/CHANGELOG.md +124 -0
  3. package/README.cn.md +3 -1
  4. package/README.md +3 -1
  5. package/dist/core/anchor-cache.d.ts +42 -0
  6. package/dist/core/anchor-cache.d.ts.map +1 -0
  7. package/dist/core/anchor-cache.js +104 -0
  8. package/dist/core/anchor-cache.js.map +1 -0
  9. package/dist/core/cache.d.ts +14 -0
  10. package/dist/core/cache.d.ts.map +1 -0
  11. package/dist/core/cache.js +80 -0
  12. package/dist/core/cache.js.map +1 -0
  13. package/dist/core/canonical-json.d.ts +12 -0
  14. package/dist/core/canonical-json.d.ts.map +1 -0
  15. package/dist/core/canonical-json.js +44 -0
  16. package/dist/core/canonical-json.js.map +1 -0
  17. package/dist/core/codec.d.ts +32 -0
  18. package/dist/core/codec.d.ts.map +1 -0
  19. package/dist/core/codec.js +119 -0
  20. package/dist/core/codec.js.map +1 -0
  21. package/dist/core/codecs/index.d.ts +4 -0
  22. package/dist/core/codecs/index.d.ts.map +1 -0
  23. package/{src/core/codecs/index.ts → dist/core/codecs/index.js} +1 -0
  24. package/dist/core/codecs/index.js.map +1 -0
  25. package/dist/core/codecs/ncp-codec.d.ts +39 -0
  26. package/dist/core/codecs/ncp-codec.d.ts.map +1 -0
  27. package/dist/core/codecs/ncp-codec.js +93 -0
  28. package/dist/core/codecs/ncp-codec.js.map +1 -0
  29. package/dist/core/codecs/tier1-json-codec.d.ts +10 -0
  30. package/dist/core/codecs/tier1-json-codec.d.ts.map +1 -0
  31. package/{src/core/codecs/tier1-json-codec.ts → dist/core/codecs/tier1-json-codec.js} +11 -16
  32. package/dist/core/codecs/tier1-json-codec.js.map +1 -0
  33. package/dist/core/codecs/tier2-msgpack-codec.d.ts +10 -0
  34. package/dist/core/codecs/tier2-msgpack-codec.d.ts.map +1 -0
  35. package/{src/core/codecs/tier2-msgpack-codec.ts → dist/core/codecs/tier2-msgpack-codec.js} +10 -14
  36. package/dist/core/codecs/tier2-msgpack-codec.js.map +1 -0
  37. package/dist/core/crypto-provider.d.ts +31 -0
  38. package/dist/core/crypto-provider.d.ts.map +1 -0
  39. package/dist/core/crypto-provider.js +10 -0
  40. package/dist/core/crypto-provider.js.map +1 -0
  41. package/dist/core/exceptions.d.ts +27 -0
  42. package/dist/core/exceptions.d.ts.map +1 -0
  43. package/dist/core/exceptions.js +52 -0
  44. package/dist/core/exceptions.js.map +1 -0
  45. package/dist/core/frame-header.d.ts +87 -0
  46. package/dist/core/frame-header.d.ts.map +1 -0
  47. package/dist/core/frame-header.js +185 -0
  48. package/dist/core/frame-header.js.map +1 -0
  49. package/dist/core/frame-registry.d.ts +35 -0
  50. package/dist/core/frame-registry.d.ts.map +1 -0
  51. package/dist/core/frame-registry.js +63 -0
  52. package/dist/core/frame-registry.js.map +1 -0
  53. package/dist/core/frames.d.ts +81 -0
  54. package/dist/core/frames.d.ts.map +1 -0
  55. package/dist/core/frames.js +154 -0
  56. package/dist/core/frames.js.map +1 -0
  57. package/dist/core/index.d.ts +11 -0
  58. package/dist/core/index.d.ts.map +1 -0
  59. package/{src/core/index.ts → dist/core/index.js} +3 -23
  60. package/dist/core/index.js.map +1 -0
  61. package/dist/core/registry.d.ts +11 -0
  62. package/dist/core/registry.d.ts.map +1 -0
  63. package/dist/core/registry.js +17 -0
  64. package/dist/core/registry.js.map +1 -0
  65. package/dist/core/status-codes.d.ts +29 -0
  66. package/dist/core/status-codes.d.ts.map +1 -0
  67. package/dist/core/status-codes.js +39 -0
  68. package/dist/core/status-codes.js.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.d.ts.map +1 -0
  71. package/{src/index.ts → dist/index.js} +1 -1
  72. package/dist/index.js.map +1 -0
  73. package/dist/ncp/frames/anchor-frame.d.ts +29 -0
  74. package/dist/ncp/frames/anchor-frame.d.ts.map +1 -0
  75. package/dist/ncp/frames/anchor-frame.js +54 -0
  76. package/dist/ncp/frames/anchor-frame.js.map +1 -0
  77. package/dist/ncp/frames/caps-frame.d.ts +29 -0
  78. package/dist/ncp/frames/caps-frame.d.ts.map +1 -0
  79. package/dist/ncp/frames/caps-frame.js +29 -0
  80. package/dist/ncp/frames/caps-frame.js.map +1 -0
  81. package/dist/ncp/frames/diff-frame.d.ts +32 -0
  82. package/dist/ncp/frames/diff-frame.d.ts.map +1 -0
  83. package/dist/ncp/frames/diff-frame.js +37 -0
  84. package/dist/ncp/frames/diff-frame.js.map +1 -0
  85. package/dist/ncp/frames/error-frame.d.ts +16 -0
  86. package/dist/ncp/frames/error-frame.d.ts.map +1 -0
  87. package/dist/ncp/frames/error-frame.js +13 -0
  88. package/dist/ncp/frames/error-frame.js.map +1 -0
  89. package/dist/ncp/frames/hello-frame.d.ts +21 -0
  90. package/dist/ncp/frames/hello-frame.d.ts.map +1 -0
  91. package/dist/ncp/frames/hello-frame.js +25 -0
  92. package/dist/ncp/frames/hello-frame.js.map +1 -0
  93. package/dist/ncp/frames/stream-frame.d.ts +16 -0
  94. package/dist/ncp/frames/stream-frame.d.ts.map +1 -0
  95. package/dist/ncp/frames/stream-frame.js +18 -0
  96. package/dist/ncp/frames/stream-frame.js.map +1 -0
  97. package/dist/ncp/frames.d.ts +94 -0
  98. package/dist/ncp/frames.d.ts.map +1 -0
  99. package/dist/ncp/frames.js +192 -0
  100. package/dist/ncp/frames.js.map +1 -0
  101. package/dist/ncp/handshake.d.ts +30 -0
  102. package/dist/ncp/handshake.d.ts.map +1 -0
  103. package/dist/ncp/handshake.js +80 -0
  104. package/dist/ncp/handshake.js.map +1 -0
  105. package/dist/ncp/index.d.ts +12 -0
  106. package/dist/ncp/index.d.ts.map +1 -0
  107. package/{src/ncp/index.ts → dist/ncp/index.js} +1 -0
  108. package/dist/ncp/index.js.map +1 -0
  109. package/dist/ncp/ncp-error-codes.d.ts +23 -0
  110. package/dist/ncp/ncp-error-codes.d.ts.map +1 -0
  111. package/dist/ncp/ncp-error-codes.js +34 -0
  112. package/dist/ncp/ncp-error-codes.js.map +1 -0
  113. package/dist/ncp/ncp-patch-format.d.ts +7 -0
  114. package/dist/ncp/ncp-patch-format.d.ts.map +1 -0
  115. package/dist/ncp/ncp-patch-format.js +13 -0
  116. package/dist/ncp/ncp-patch-format.js.map +1 -0
  117. package/dist/ncp/preamble.d.ts +47 -0
  118. package/dist/ncp/preamble.d.ts.map +1 -0
  119. package/dist/ncp/preamble.js +74 -0
  120. package/dist/ncp/preamble.js.map +1 -0
  121. package/dist/ncp/registry.d.ts +3 -0
  122. package/dist/ncp/registry.d.ts.map +1 -0
  123. package/dist/ncp/registry.js +13 -0
  124. package/dist/ncp/registry.js.map +1 -0
  125. package/dist/ncp/stream-manager.d.ts +57 -0
  126. package/dist/ncp/stream-manager.d.ts.map +1 -0
  127. package/dist/ncp/stream-manager.js +163 -0
  128. package/dist/ncp/stream-manager.js.map +1 -0
  129. package/dist/ndp/dns-txt.d.ts +35 -0
  130. package/dist/ndp/dns-txt.d.ts.map +1 -0
  131. package/dist/ndp/dns-txt.js +67 -0
  132. package/dist/ndp/dns-txt.js.map +1 -0
  133. package/dist/ndp/frames.d.ts +56 -0
  134. package/dist/ndp/frames.d.ts.map +1 -0
  135. package/dist/ndp/frames.js +87 -0
  136. package/dist/ndp/frames.js.map +1 -0
  137. package/dist/ndp/index.d.ts +6 -0
  138. package/dist/ndp/index.d.ts.map +1 -0
  139. package/{src/ndp/index.ts → dist/ndp/index.js} +1 -1
  140. package/dist/ndp/index.js.map +1 -0
  141. package/dist/ndp/ndp-registry.d.ts +13 -0
  142. package/dist/ndp/ndp-registry.d.ts.map +1 -0
  143. package/dist/ndp/ndp-registry.js +104 -0
  144. package/dist/ndp/ndp-registry.js.map +1 -0
  145. package/dist/ndp/registry.d.ts +3 -0
  146. package/dist/ndp/registry.d.ts.map +1 -0
  147. package/dist/ndp/registry.js +10 -0
  148. package/dist/ndp/registry.js.map +1 -0
  149. package/dist/ndp/validator.d.ts +18 -0
  150. package/dist/ndp/validator.d.ts.map +1 -0
  151. package/dist/ndp/validator.js +48 -0
  152. package/dist/ndp/validator.js.map +1 -0
  153. package/dist/nip/acme/client.d.ts +31 -0
  154. package/dist/nip/acme/client.d.ts.map +1 -0
  155. package/dist/nip/acme/client.js +136 -0
  156. package/dist/nip/acme/client.js.map +1 -0
  157. package/dist/nip/acme/index.d.ts +6 -0
  158. package/dist/nip/acme/index.d.ts.map +1 -0
  159. package/{src/nip/acme/index.ts → dist/nip/acme/index.js} +1 -1
  160. package/dist/nip/acme/index.js.map +1 -0
  161. package/dist/nip/acme/jws.d.ts +31 -0
  162. package/dist/nip/acme/jws.d.ts.map +1 -0
  163. package/dist/nip/acme/jws.js +76 -0
  164. package/dist/nip/acme/jws.js.map +1 -0
  165. package/dist/nip/acme/messages.d.ts +71 -0
  166. package/dist/nip/acme/messages.d.ts.map +1 -0
  167. package/dist/nip/acme/messages.js +4 -0
  168. package/dist/nip/acme/messages.js.map +1 -0
  169. package/dist/nip/acme/server.d.ts +41 -0
  170. package/dist/nip/acme/server.d.ts.map +1 -0
  171. package/dist/nip/acme/server.js +458 -0
  172. package/dist/nip/acme/server.js.map +1 -0
  173. package/dist/nip/acme/wire.d.ts +19 -0
  174. package/dist/nip/acme/wire.d.ts.map +1 -0
  175. package/dist/nip/acme/wire.js +21 -0
  176. package/dist/nip/acme/wire.js.map +1 -0
  177. package/dist/nip/assurance-level.d.ts +19 -0
  178. package/dist/nip/assurance-level.d.ts.map +1 -0
  179. package/dist/nip/assurance-level.js +38 -0
  180. package/dist/nip/assurance-level.js.map +1 -0
  181. package/dist/nip/cert-format.d.ts +5 -0
  182. package/dist/nip/cert-format.d.ts.map +1 -0
  183. package/dist/nip/cert-format.js +6 -0
  184. package/dist/nip/cert-format.js.map +1 -0
  185. package/dist/nip/error-codes.d.ts +25 -0
  186. package/dist/nip/error-codes.d.ts.map +1 -0
  187. package/{src/nip/error-codes.ts → dist/nip/error-codes.js} +19 -25
  188. package/dist/nip/error-codes.js.map +1 -0
  189. package/dist/nip/frames.d.ts +53 -0
  190. package/dist/nip/frames.d.ts.map +1 -0
  191. package/dist/nip/frames.js +106 -0
  192. package/dist/nip/frames.js.map +1 -0
  193. package/dist/nip/identity.d.ts +18 -0
  194. package/dist/nip/identity.d.ts.map +1 -0
  195. package/dist/nip/identity.js +94 -0
  196. package/dist/nip/identity.js.map +1 -0
  197. package/dist/nip/index.d.ts +11 -0
  198. package/dist/nip/index.d.ts.map +1 -0
  199. package/{src/nip/index.ts → dist/nip/index.js} +3 -2
  200. package/dist/nip/index.js.map +1 -0
  201. package/dist/nip/registry.d.ts +3 -0
  202. package/dist/nip/registry.d.ts.map +1 -0
  203. package/dist/nip/registry.js +10 -0
  204. package/dist/nip/registry.js.map +1 -0
  205. package/dist/nip/reputation-client.d.ts +116 -0
  206. package/dist/nip/reputation-client.d.ts.map +1 -0
  207. package/dist/nip/reputation-client.js +261 -0
  208. package/dist/nip/reputation-client.js.map +1 -0
  209. package/dist/nip/verifier.d.ts +23 -0
  210. package/dist/nip/verifier.d.ts.map +1 -0
  211. package/dist/nip/verifier.js +90 -0
  212. package/dist/nip/verifier.js.map +1 -0
  213. package/dist/nip/x509/builder.d.ts +35 -0
  214. package/dist/nip/x509/builder.d.ts.map +1 -0
  215. package/dist/nip/x509/builder.js +59 -0
  216. package/dist/nip/x509/builder.js.map +1 -0
  217. package/dist/nip/x509/index.d.ts +4 -0
  218. package/dist/nip/x509/index.d.ts.map +1 -0
  219. package/{src/nip/x509/index.ts → dist/nip/x509/index.js} +1 -1
  220. package/dist/nip/x509/index.js.map +1 -0
  221. package/dist/nip/x509/oids.d.ts +16 -0
  222. package/dist/nip/x509/oids.d.ts.map +1 -0
  223. package/{src/nip/x509/oids.ts → dist/nip/x509/oids.js} +5 -10
  224. package/dist/nip/x509/oids.js.map +1 -0
  225. package/dist/nip/x509/verifier.d.ts +26 -0
  226. package/dist/nip/x509/verifier.d.ts.map +1 -0
  227. package/dist/nip/x509/verifier.js +171 -0
  228. package/dist/nip/x509/verifier.js.map +1 -0
  229. package/dist/nop/client.d.ts +34 -0
  230. package/dist/nop/client.d.ts.map +1 -0
  231. package/dist/nop/client.js +90 -0
  232. package/dist/nop/client.js.map +1 -0
  233. package/dist/nop/frames.d.ts +65 -0
  234. package/dist/nop/frames.d.ts.map +1 -0
  235. package/dist/nop/frames.js +148 -0
  236. package/dist/nop/frames.js.map +1 -0
  237. package/dist/nop/index.d.ts +5 -0
  238. package/dist/nop/index.d.ts.map +1 -0
  239. package/{src/nop/index.ts → dist/nop/index.js} +1 -1
  240. package/dist/nop/index.js.map +1 -0
  241. package/dist/nop/models.d.ts +58 -0
  242. package/dist/nop/models.d.ts.map +1 -0
  243. package/dist/nop/models.js +50 -0
  244. package/dist/nop/models.js.map +1 -0
  245. package/dist/nop/nop-types.d.ts +136 -0
  246. package/dist/nop/nop-types.d.ts.map +1 -0
  247. package/dist/nop/nop-types.js +44 -0
  248. package/dist/nop/nop-types.js.map +1 -0
  249. package/dist/nop/registry.d.ts +3 -0
  250. package/dist/nop/registry.d.ts.map +1 -0
  251. package/dist/nop/registry.js +11 -0
  252. package/dist/nop/registry.js.map +1 -0
  253. package/dist/nwp/anchor-client.d.ts +109 -0
  254. package/dist/nwp/anchor-client.d.ts.map +1 -0
  255. package/dist/nwp/anchor-client.js +279 -0
  256. package/dist/nwp/anchor-client.js.map +1 -0
  257. package/dist/nwp/client.d.ts +22 -0
  258. package/dist/nwp/client.d.ts.map +1 -0
  259. package/dist/nwp/client.js +101 -0
  260. package/dist/nwp/client.js.map +1 -0
  261. package/dist/nwp/frames.d.ts +46 -0
  262. package/dist/nwp/frames.d.ts.map +1 -0
  263. package/dist/nwp/frames.js +81 -0
  264. package/dist/nwp/frames.js.map +1 -0
  265. package/dist/nwp/index.d.ts +5 -0
  266. package/dist/nwp/index.d.ts.map +1 -0
  267. package/{src/nwp/index.ts → dist/nwp/index.js} +2 -1
  268. package/dist/nwp/index.js.map +1 -0
  269. package/dist/nwp/registry.d.ts +3 -0
  270. package/dist/nwp/registry.d.ts.map +1 -0
  271. package/dist/nwp/registry.js +9 -0
  272. package/dist/nwp/registry.js.map +1 -0
  273. package/dist/setup.d.ts +10 -0
  274. package/dist/setup.d.ts.map +1 -0
  275. package/{src/setup.ts → dist/setup.js} +13 -16
  276. package/dist/setup.js.map +1 -0
  277. package/package.json +12 -1
  278. package/CONTRIBUTING.cn.md +0 -35
  279. package/CONTRIBUTING.md +0 -35
  280. package/nip-ca-server/Dockerfile +0 -27
  281. package/nip-ca-server/README.md +0 -45
  282. package/nip-ca-server/db/001_init.sql +0 -25
  283. package/nip-ca-server/docker-compose.yml +0 -29
  284. package/nip-ca-server/package.json +0 -23
  285. package/nip-ca-server/src/ca.ts +0 -155
  286. package/nip-ca-server/src/db.ts +0 -104
  287. package/nip-ca-server/src/index.ts +0 -157
  288. package/nip-ca-server/tsconfig.json +0 -13
  289. package/src/core/anchor-cache.ts +0 -129
  290. package/src/core/cache.ts +0 -93
  291. package/src/core/canonical-json.ts +0 -50
  292. package/src/core/codec.ts +0 -158
  293. package/src/core/codecs/ncp-codec.ts +0 -170
  294. package/src/core/crypto-provider.ts +0 -47
  295. package/src/core/exceptions.ts +0 -57
  296. package/src/core/frame-header.ts +0 -282
  297. package/src/core/frame-registry.ts +0 -91
  298. package/src/core/frames.ts +0 -184
  299. package/src/core/registry.ts +0 -28
  300. package/src/core/status-codes.ts +0 -47
  301. package/src/ncp/frames/anchor-frame.ts +0 -87
  302. package/src/ncp/frames/caps-frame.ts +0 -59
  303. package/src/ncp/frames/diff-frame.ts +0 -69
  304. package/src/ncp/frames/error-frame.ts +0 -26
  305. package/src/ncp/frames/hello-frame.ts +0 -50
  306. package/src/ncp/frames/stream-frame.ts +0 -35
  307. package/src/ncp/frames.ts +0 -251
  308. package/src/ncp/handshake.ts +0 -95
  309. package/src/ncp/ncp-error-codes.ts +0 -36
  310. package/src/ncp/ncp-patch-format.ts +0 -16
  311. package/src/ncp/preamble.ts +0 -79
  312. package/src/ncp/registry.ts +0 -15
  313. package/src/ncp/stream-manager.ts +0 -212
  314. package/src/ndp/dns-txt.ts +0 -86
  315. package/src/ndp/frames.ts +0 -124
  316. package/src/ndp/ndp-registry.ts +0 -116
  317. package/src/ndp/registry.ts +0 -12
  318. package/src/ndp/validator.ts +0 -64
  319. package/src/nip/acme/client.ts +0 -185
  320. package/src/nip/acme/jws.ts +0 -109
  321. package/src/nip/acme/messages.ts +0 -85
  322. package/src/nip/acme/server.ts +0 -480
  323. package/src/nip/acme/wire.ts +0 -24
  324. package/src/nip/assurance-level.ts +0 -40
  325. package/src/nip/cert-format.ts +0 -9
  326. package/src/nip/frames.ts +0 -138
  327. package/src/nip/identity.ts +0 -113
  328. package/src/nip/registry.ts +0 -12
  329. package/src/nip/verifier.ts +0 -122
  330. package/src/nip/x509/builder.ts +0 -91
  331. package/src/nip/x509/verifier.ts +0 -214
  332. package/src/nop/client.ts +0 -103
  333. package/src/nop/frames.ts +0 -181
  334. package/src/nop/models.ts +0 -79
  335. package/src/nop/nop-types.ts +0 -208
  336. package/src/nop/registry.ts +0 -13
  337. package/src/nwp/client.ts +0 -114
  338. package/src/nwp/frames.ts +0 -116
  339. package/src/nwp/registry.ts +0 -11
  340. package/tests/_rfc0002-keys.ts +0 -57
  341. package/tests/core/anchor-cache.test.ts +0 -242
  342. package/tests/core/codec.test.ts +0 -205
  343. package/tests/core/frame-registry.test.ts +0 -46
  344. package/tests/core.test.ts +0 -327
  345. package/tests/ncp/diff-binary-bitset.test.ts +0 -107
  346. package/tests/ncp/e2e-enc-reject.test.ts +0 -93
  347. package/tests/ncp/err-error-frame.test.ts +0 -152
  348. package/tests/ncp/frames.test.ts +0 -359
  349. package/tests/ncp/framing.test.ts +0 -233
  350. package/tests/ncp/hello-frame.test.ts +0 -122
  351. package/tests/ncp/inline-anchor.test.ts +0 -88
  352. package/tests/ncp/preamble.test.ts +0 -93
  353. package/tests/ncp/security.test.ts +0 -184
  354. package/tests/ncp/stream-window.test.ts +0 -167
  355. package/tests/ncp/stream.test.ts +0 -242
  356. package/tests/ncp/version-negotiation.test.ts +0 -123
  357. package/tests/ndp.test.ts +0 -377
  358. package/tests/nip-acme-agent01.test.ts +0 -192
  359. package/tests/nip-x509.test.ts +0 -280
  360. package/tests/nip.test.ts +0 -184
  361. package/tests/nop.test.ts +0 -344
  362. package/tests/nwp.test.ts +0 -237
  363. package/tsconfig.json +0 -20
  364. package/tsup.config.ts +0 -20
  365. package/vitest.config.ts +0 -10
@@ -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
- });