pi-cursor-sdk 0.1.50 → 0.1.51

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 (276) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +1 -1
  3. package/docs/cursor-live-smoke-checklist.md +4 -4
  4. package/docs/cursor-model-ux-spec.md +5 -5
  5. package/docs/cursor-native-tool-replay.md +2 -2
  6. package/docs/cursor-native-tool-visual-audit.md +1 -1
  7. package/docs/cursor-testing-lessons.md +1 -1
  8. package/package.json +3 -12
  9. package/src/cursor-fallback-models.generated.ts +536 -302
  10. package/src/cursor-provider-errors.ts +29 -0
  11. package/src/cursor-tool-manifest.ts +1 -1
  12. package/node_modules/@connectrpc/connect-node/README.md +0 -141
  13. package/node_modules/@connectrpc/connect-node/dist/cjs/compression.d.ts +0 -15
  14. package/node_modules/@connectrpc/connect-node/dist/cjs/compression.js +0 -89
  15. package/node_modules/@connectrpc/connect-node/dist/cjs/connect-node-adapter.d.ts +0 -42
  16. package/node_modules/@connectrpc/connect-node/dist/cjs/connect-node-adapter.js +0 -61
  17. package/node_modules/@connectrpc/connect-node/dist/cjs/connect-transport.d.ts +0 -100
  18. package/node_modules/@connectrpc/connect-node/dist/cjs/connect-transport.js +0 -25
  19. package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-transport.d.ts +0 -96
  20. package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-transport.js +0 -25
  21. package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-web-transport.d.ts +0 -96
  22. package/node_modules/@connectrpc/connect-node/dist/cjs/grpc-web-transport.js +0 -25
  23. package/node_modules/@connectrpc/connect-node/dist/cjs/http2-session-manager.d.ts +0 -146
  24. package/node_modules/@connectrpc/connect-node/dist/cjs/http2-session-manager.js +0 -536
  25. package/node_modules/@connectrpc/connect-node/dist/cjs/index.d.ts +0 -15
  26. package/node_modules/@connectrpc/connect-node/dist/cjs/index.js +0 -36
  27. package/node_modules/@connectrpc/connect-node/dist/cjs/node-error.d.ts +0 -45
  28. package/node_modules/@connectrpc/connect-node/dist/cjs/node-error.js +0 -154
  29. package/node_modules/@connectrpc/connect-node/dist/cjs/node-headers-polyfill.d.ts +0 -1
  30. package/node_modules/@connectrpc/connect-node/dist/cjs/node-headers-polyfill.js +0 -29
  31. package/node_modules/@connectrpc/connect-node/dist/cjs/node-transport-options.d.ts +0 -89
  32. package/node_modules/@connectrpc/connect-node/dist/cjs/node-transport-options.js +0 -58
  33. package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-client.d.ts +0 -54
  34. package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-client.js +0 -326
  35. package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-handler.d.ts +0 -41
  36. package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-handler.js +0 -234
  37. package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-header.d.ts +0 -19
  38. package/node_modules/@connectrpc/connect-node/dist/cjs/node-universal-header.js +0 -97
  39. package/node_modules/@connectrpc/connect-node/dist/cjs/package.json +0 -1
  40. package/node_modules/@connectrpc/connect-node/dist/esm/compression.d.ts +0 -15
  41. package/node_modules/@connectrpc/connect-node/dist/esm/compression.js +0 -86
  42. package/node_modules/@connectrpc/connect-node/dist/esm/connect-node-adapter.d.ts +0 -42
  43. package/node_modules/@connectrpc/connect-node/dist/esm/connect-node-adapter.js +0 -58
  44. package/node_modules/@connectrpc/connect-node/dist/esm/connect-transport.d.ts +0 -100
  45. package/node_modules/@connectrpc/connect-node/dist/esm/connect-transport.js +0 -22
  46. package/node_modules/@connectrpc/connect-node/dist/esm/grpc-transport.d.ts +0 -96
  47. package/node_modules/@connectrpc/connect-node/dist/esm/grpc-transport.js +0 -22
  48. package/node_modules/@connectrpc/connect-node/dist/esm/grpc-web-transport.d.ts +0 -96
  49. package/node_modules/@connectrpc/connect-node/dist/esm/grpc-web-transport.js +0 -22
  50. package/node_modules/@connectrpc/connect-node/dist/esm/http2-session-manager.d.ts +0 -146
  51. package/node_modules/@connectrpc/connect-node/dist/esm/http2-session-manager.js +0 -532
  52. package/node_modules/@connectrpc/connect-node/dist/esm/index.d.ts +0 -15
  53. package/node_modules/@connectrpc/connect-node/dist/esm/index.js +0 -23
  54. package/node_modules/@connectrpc/connect-node/dist/esm/node-error.d.ts +0 -45
  55. package/node_modules/@connectrpc/connect-node/dist/esm/node-error.js +0 -147
  56. package/node_modules/@connectrpc/connect-node/dist/esm/node-headers-polyfill.d.ts +0 -1
  57. package/node_modules/@connectrpc/connect-node/dist/esm/node-headers-polyfill.js +0 -27
  58. package/node_modules/@connectrpc/connect-node/dist/esm/node-transport-options.d.ts +0 -89
  59. package/node_modules/@connectrpc/connect-node/dist/esm/node-transport-options.js +0 -58
  60. package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-client.d.ts +0 -54
  61. package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-client.js +0 -324
  62. package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-handler.d.ts +0 -41
  63. package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-handler.js +0 -230
  64. package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-header.d.ts +0 -19
  65. package/node_modules/@connectrpc/connect-node/dist/esm/node-universal-header.js +0 -93
  66. package/node_modules/@connectrpc/connect-node/package.json +0 -46
  67. package/node_modules/undici/LICENSE +0 -21
  68. package/node_modules/undici/README.md +0 -741
  69. package/node_modules/undici/docs/docs/api/Agent.md +0 -84
  70. package/node_modules/undici/docs/docs/api/BalancedPool.md +0 -99
  71. package/node_modules/undici/docs/docs/api/CacheStorage.md +0 -30
  72. package/node_modules/undici/docs/docs/api/CacheStore.md +0 -164
  73. package/node_modules/undici/docs/docs/api/Client.md +0 -288
  74. package/node_modules/undici/docs/docs/api/ClientStats.md +0 -27
  75. package/node_modules/undici/docs/docs/api/Connector.md +0 -115
  76. package/node_modules/undici/docs/docs/api/ContentType.md +0 -57
  77. package/node_modules/undici/docs/docs/api/Cookies.md +0 -128
  78. package/node_modules/undici/docs/docs/api/Debug.md +0 -62
  79. package/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +0 -315
  80. package/node_modules/undici/docs/docs/api/Dispatcher.md +0 -1392
  81. package/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +0 -159
  82. package/node_modules/undici/docs/docs/api/Errors.md +0 -49
  83. package/node_modules/undici/docs/docs/api/EventSource.md +0 -45
  84. package/node_modules/undici/docs/docs/api/Fetch.md +0 -60
  85. package/node_modules/undici/docs/docs/api/GlobalInstallation.md +0 -139
  86. package/node_modules/undici/docs/docs/api/H2CClient.md +0 -263
  87. package/node_modules/undici/docs/docs/api/MockAgent.md +0 -603
  88. package/node_modules/undici/docs/docs/api/MockCallHistory.md +0 -197
  89. package/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +0 -43
  90. package/node_modules/undici/docs/docs/api/MockClient.md +0 -81
  91. package/node_modules/undici/docs/docs/api/MockErrors.md +0 -12
  92. package/node_modules/undici/docs/docs/api/MockPool.md +0 -555
  93. package/node_modules/undici/docs/docs/api/Pool.md +0 -84
  94. package/node_modules/undici/docs/docs/api/PoolStats.md +0 -35
  95. package/node_modules/undici/docs/docs/api/ProxyAgent.md +0 -229
  96. package/node_modules/undici/docs/docs/api/RedirectHandler.md +0 -93
  97. package/node_modules/undici/docs/docs/api/RetryAgent.md +0 -50
  98. package/node_modules/undici/docs/docs/api/RetryHandler.md +0 -118
  99. package/node_modules/undici/docs/docs/api/RoundRobinPool.md +0 -145
  100. package/node_modules/undici/docs/docs/api/SnapshotAgent.md +0 -616
  101. package/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +0 -275
  102. package/node_modules/undici/docs/docs/api/Util.md +0 -25
  103. package/node_modules/undici/docs/docs/api/WebSocket.md +0 -141
  104. package/node_modules/undici/docs/docs/api/api-lifecycle.md +0 -91
  105. package/node_modules/undici/docs/docs/best-practices/client-certificate.md +0 -64
  106. package/node_modules/undici/docs/docs/best-practices/crawling.md +0 -58
  107. package/node_modules/undici/docs/docs/best-practices/mocking-request.md +0 -190
  108. package/node_modules/undici/docs/docs/best-practices/proxy.md +0 -127
  109. package/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +0 -224
  110. package/node_modules/undici/docs/docs/best-practices/writing-tests.md +0 -63
  111. package/node_modules/undici/index-fetch.js +0 -65
  112. package/node_modules/undici/index.d.ts +0 -3
  113. package/node_modules/undici/index.js +0 -234
  114. package/node_modules/undici/lib/api/abort-signal.js +0 -59
  115. package/node_modules/undici/lib/api/api-connect.js +0 -110
  116. package/node_modules/undici/lib/api/api-pipeline.js +0 -252
  117. package/node_modules/undici/lib/api/api-request.js +0 -214
  118. package/node_modules/undici/lib/api/api-stream.js +0 -209
  119. package/node_modules/undici/lib/api/api-upgrade.js +0 -111
  120. package/node_modules/undici/lib/api/index.js +0 -7
  121. package/node_modules/undici/lib/api/readable.js +0 -580
  122. package/node_modules/undici/lib/cache/memory-cache-store.js +0 -234
  123. package/node_modules/undici/lib/cache/sqlite-cache-store.js +0 -461
  124. package/node_modules/undici/lib/core/connect.js +0 -153
  125. package/node_modules/undici/lib/core/constants.js +0 -143
  126. package/node_modules/undici/lib/core/diagnostics.js +0 -227
  127. package/node_modules/undici/lib/core/errors.js +0 -477
  128. package/node_modules/undici/lib/core/request.js +0 -453
  129. package/node_modules/undici/lib/core/socks5-client.js +0 -422
  130. package/node_modules/undici/lib/core/socks5-utils.js +0 -212
  131. package/node_modules/undici/lib/core/symbols.js +0 -75
  132. package/node_modules/undici/lib/core/tree.js +0 -160
  133. package/node_modules/undici/lib/core/util.js +0 -992
  134. package/node_modules/undici/lib/dispatcher/agent.js +0 -158
  135. package/node_modules/undici/lib/dispatcher/balanced-pool.js +0 -219
  136. package/node_modules/undici/lib/dispatcher/client-h1.js +0 -1722
  137. package/node_modules/undici/lib/dispatcher/client-h2.js +0 -995
  138. package/node_modules/undici/lib/dispatcher/client.js +0 -664
  139. package/node_modules/undici/lib/dispatcher/dispatcher-base.js +0 -184
  140. package/node_modules/undici/lib/dispatcher/dispatcher.js +0 -48
  141. package/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +0 -146
  142. package/node_modules/undici/lib/dispatcher/fixed-queue.js +0 -135
  143. package/node_modules/undici/lib/dispatcher/h2c-client.js +0 -51
  144. package/node_modules/undici/lib/dispatcher/pool-base.js +0 -214
  145. package/node_modules/undici/lib/dispatcher/pool.js +0 -118
  146. package/node_modules/undici/lib/dispatcher/proxy-agent.js +0 -319
  147. package/node_modules/undici/lib/dispatcher/retry-agent.js +0 -35
  148. package/node_modules/undici/lib/dispatcher/round-robin-pool.js +0 -137
  149. package/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +0 -260
  150. package/node_modules/undici/lib/encoding/index.js +0 -33
  151. package/node_modules/undici/lib/global.js +0 -59
  152. package/node_modules/undici/lib/handler/cache-handler.js +0 -578
  153. package/node_modules/undici/lib/handler/cache-revalidation-handler.js +0 -124
  154. package/node_modules/undici/lib/handler/decorator-handler.js +0 -67
  155. package/node_modules/undici/lib/handler/deduplication-handler.js +0 -460
  156. package/node_modules/undici/lib/handler/redirect-handler.js +0 -238
  157. package/node_modules/undici/lib/handler/retry-handler.js +0 -394
  158. package/node_modules/undici/lib/handler/unwrap-handler.js +0 -106
  159. package/node_modules/undici/lib/handler/wrap-handler.js +0 -105
  160. package/node_modules/undici/lib/interceptor/cache.js +0 -495
  161. package/node_modules/undici/lib/interceptor/decompress.js +0 -259
  162. package/node_modules/undici/lib/interceptor/deduplicate.js +0 -117
  163. package/node_modules/undici/lib/interceptor/dns.js +0 -571
  164. package/node_modules/undici/lib/interceptor/dump.js +0 -112
  165. package/node_modules/undici/lib/interceptor/redirect.js +0 -21
  166. package/node_modules/undici/lib/interceptor/response-error.js +0 -95
  167. package/node_modules/undici/lib/interceptor/retry.js +0 -19
  168. package/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  169. package/node_modules/undici/lib/llhttp/constants.d.ts +0 -195
  170. package/node_modules/undici/lib/llhttp/constants.js +0 -531
  171. package/node_modules/undici/lib/llhttp/llhttp-wasm.js +0 -15
  172. package/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +0 -15
  173. package/node_modules/undici/lib/llhttp/utils.d.ts +0 -2
  174. package/node_modules/undici/lib/llhttp/utils.js +0 -12
  175. package/node_modules/undici/lib/mock/mock-agent.js +0 -232
  176. package/node_modules/undici/lib/mock/mock-call-history.js +0 -248
  177. package/node_modules/undici/lib/mock/mock-client.js +0 -68
  178. package/node_modules/undici/lib/mock/mock-errors.js +0 -29
  179. package/node_modules/undici/lib/mock/mock-interceptor.js +0 -209
  180. package/node_modules/undici/lib/mock/mock-pool.js +0 -68
  181. package/node_modules/undici/lib/mock/mock-symbols.js +0 -32
  182. package/node_modules/undici/lib/mock/mock-utils.js +0 -486
  183. package/node_modules/undici/lib/mock/pending-interceptors-formatter.js +0 -43
  184. package/node_modules/undici/lib/mock/snapshot-agent.js +0 -353
  185. package/node_modules/undici/lib/mock/snapshot-recorder.js +0 -588
  186. package/node_modules/undici/lib/mock/snapshot-utils.js +0 -158
  187. package/node_modules/undici/lib/util/cache.js +0 -414
  188. package/node_modules/undici/lib/util/date.js +0 -653
  189. package/node_modules/undici/lib/util/promise.js +0 -28
  190. package/node_modules/undici/lib/util/runtime-features.js +0 -124
  191. package/node_modules/undici/lib/util/stats.js +0 -32
  192. package/node_modules/undici/lib/util/timers.js +0 -425
  193. package/node_modules/undici/lib/web/cache/cache.js +0 -864
  194. package/node_modules/undici/lib/web/cache/cachestorage.js +0 -152
  195. package/node_modules/undici/lib/web/cache/util.js +0 -45
  196. package/node_modules/undici/lib/web/cookies/constants.js +0 -12
  197. package/node_modules/undici/lib/web/cookies/index.js +0 -199
  198. package/node_modules/undici/lib/web/cookies/parse.js +0 -314
  199. package/node_modules/undici/lib/web/cookies/util.js +0 -282
  200. package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +0 -399
  201. package/node_modules/undici/lib/web/eventsource/eventsource.js +0 -501
  202. package/node_modules/undici/lib/web/eventsource/util.js +0 -29
  203. package/node_modules/undici/lib/web/fetch/LICENSE +0 -21
  204. package/node_modules/undici/lib/web/fetch/body.js +0 -509
  205. package/node_modules/undici/lib/web/fetch/constants.js +0 -131
  206. package/node_modules/undici/lib/web/fetch/data-url.js +0 -596
  207. package/node_modules/undici/lib/web/fetch/formdata-parser.js +0 -586
  208. package/node_modules/undici/lib/web/fetch/formdata.js +0 -259
  209. package/node_modules/undici/lib/web/fetch/global.js +0 -40
  210. package/node_modules/undici/lib/web/fetch/headers.js +0 -719
  211. package/node_modules/undici/lib/web/fetch/index.js +0 -2413
  212. package/node_modules/undici/lib/web/fetch/request.js +0 -1115
  213. package/node_modules/undici/lib/web/fetch/response.js +0 -641
  214. package/node_modules/undici/lib/web/fetch/util.js +0 -1522
  215. package/node_modules/undici/lib/web/infra/index.js +0 -229
  216. package/node_modules/undici/lib/web/subresource-integrity/Readme.md +0 -9
  217. package/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +0 -307
  218. package/node_modules/undici/lib/web/webidl/index.js +0 -1006
  219. package/node_modules/undici/lib/web/websocket/connection.js +0 -329
  220. package/node_modules/undici/lib/web/websocket/constants.js +0 -126
  221. package/node_modules/undici/lib/web/websocket/events.js +0 -331
  222. package/node_modules/undici/lib/web/websocket/frame.js +0 -133
  223. package/node_modules/undici/lib/web/websocket/permessage-deflate.js +0 -100
  224. package/node_modules/undici/lib/web/websocket/receiver.js +0 -507
  225. package/node_modules/undici/lib/web/websocket/sender.js +0 -109
  226. package/node_modules/undici/lib/web/websocket/stream/websocketerror.js +0 -104
  227. package/node_modules/undici/lib/web/websocket/stream/websocketstream.js +0 -498
  228. package/node_modules/undici/lib/web/websocket/util.js +0 -347
  229. package/node_modules/undici/lib/web/websocket/websocket.js +0 -758
  230. package/node_modules/undici/package.json +0 -152
  231. package/node_modules/undici/scripts/strip-comments.js +0 -10
  232. package/node_modules/undici/types/README.md +0 -6
  233. package/node_modules/undici/types/agent.d.ts +0 -32
  234. package/node_modules/undici/types/api.d.ts +0 -43
  235. package/node_modules/undici/types/balanced-pool.d.ts +0 -30
  236. package/node_modules/undici/types/cache-interceptor.d.ts +0 -179
  237. package/node_modules/undici/types/cache.d.ts +0 -36
  238. package/node_modules/undici/types/client-stats.d.ts +0 -15
  239. package/node_modules/undici/types/client.d.ts +0 -139
  240. package/node_modules/undici/types/connector.d.ts +0 -36
  241. package/node_modules/undici/types/content-type.d.ts +0 -21
  242. package/node_modules/undici/types/cookies.d.ts +0 -30
  243. package/node_modules/undici/types/diagnostics-channel.d.ts +0 -74
  244. package/node_modules/undici/types/dispatcher.d.ts +0 -275
  245. package/node_modules/undici/types/env-http-proxy-agent.d.ts +0 -22
  246. package/node_modules/undici/types/errors.d.ts +0 -177
  247. package/node_modules/undici/types/eventsource.d.ts +0 -66
  248. package/node_modules/undici/types/fetch.d.ts +0 -231
  249. package/node_modules/undici/types/formdata.d.ts +0 -114
  250. package/node_modules/undici/types/global-dispatcher.d.ts +0 -9
  251. package/node_modules/undici/types/global-origin.d.ts +0 -7
  252. package/node_modules/undici/types/h2c-client.d.ts +0 -73
  253. package/node_modules/undici/types/handlers.d.ts +0 -14
  254. package/node_modules/undici/types/header.d.ts +0 -160
  255. package/node_modules/undici/types/index.d.ts +0 -91
  256. package/node_modules/undici/types/interceptors.d.ts +0 -80
  257. package/node_modules/undici/types/mock-agent.d.ts +0 -68
  258. package/node_modules/undici/types/mock-call-history.d.ts +0 -111
  259. package/node_modules/undici/types/mock-client.d.ts +0 -27
  260. package/node_modules/undici/types/mock-errors.d.ts +0 -12
  261. package/node_modules/undici/types/mock-interceptor.d.ts +0 -94
  262. package/node_modules/undici/types/mock-pool.d.ts +0 -27
  263. package/node_modules/undici/types/patch.d.ts +0 -29
  264. package/node_modules/undici/types/pool-stats.d.ts +0 -19
  265. package/node_modules/undici/types/pool.d.ts +0 -41
  266. package/node_modules/undici/types/proxy-agent.d.ts +0 -29
  267. package/node_modules/undici/types/readable.d.ts +0 -68
  268. package/node_modules/undici/types/retry-agent.d.ts +0 -8
  269. package/node_modules/undici/types/retry-handler.d.ts +0 -125
  270. package/node_modules/undici/types/round-robin-pool.d.ts +0 -41
  271. package/node_modules/undici/types/snapshot-agent.d.ts +0 -109
  272. package/node_modules/undici/types/socks5-proxy-agent.d.ts +0 -25
  273. package/node_modules/undici/types/util.d.ts +0 -18
  274. package/node_modules/undici/types/utility.d.ts +0 -7
  275. package/node_modules/undici/types/webidl.d.ts +0 -347
  276. package/node_modules/undici/types/websocket.d.ts +0 -188
@@ -1,507 +0,0 @@
1
- 'use strict'
2
-
3
- const { Writable } = require('node:stream')
4
- const assert = require('node:assert')
5
- const { parserStates, opcodes, states, emptyBuffer, sentCloseFrameState } = require('./constants')
6
- const {
7
- isValidStatusCode,
8
- isValidOpcode,
9
- websocketMessageReceived,
10
- utf8Decode,
11
- isControlFrame,
12
- isTextBinaryFrame,
13
- isContinuationFrame
14
- } = require('./util')
15
- const { failWebsocketConnection } = require('./connection')
16
- const { WebsocketFrameSend } = require('./frame')
17
- const { PerMessageDeflate } = require('./permessage-deflate')
18
- const { MessageSizeExceededError } = require('../../core/errors')
19
-
20
- // This code was influenced by ws released under the MIT license.
21
- // Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com>
22
- // Copyright (c) 2013 Arnout Kazemier and contributors
23
- // Copyright (c) 2016 Luigi Pinca and contributors
24
-
25
- class ByteParser extends Writable {
26
- #buffers = []
27
- #fragmentsBytes = 0
28
- #byteOffset = 0
29
- #loop = false
30
-
31
- #state = parserStates.INFO
32
-
33
- #info = {}
34
- #fragments = []
35
-
36
- /** @type {Map<string, PerMessageDeflate>} */
37
- #extensions
38
-
39
- /** @type {import('./websocket').Handler} */
40
- #handler
41
-
42
- /** @type {number} */
43
- #maxFragments
44
-
45
- /** @type {number} */
46
- #maxPayloadSize
47
-
48
- /**
49
- * @param {import('./websocket').Handler} handler
50
- * @param {Map<string, string>|null} extensions
51
- * @param {{ maxFragments?: number, maxPayloadSize?: number }} [options]
52
- */
53
- constructor (handler, extensions, options = {}) {
54
- super()
55
-
56
- this.#handler = handler
57
- this.#extensions = extensions == null ? new Map() : extensions
58
- this.#maxFragments = options.maxFragments ?? 0
59
- this.#maxPayloadSize = options.maxPayloadSize ?? 0
60
-
61
- if (this.#extensions.has('permessage-deflate')) {
62
- this.#extensions.set('permessage-deflate', new PerMessageDeflate(extensions, options))
63
- }
64
- }
65
-
66
- /**
67
- * @param {Buffer} chunk
68
- * @param {() => void} callback
69
- */
70
- _write (chunk, _, callback) {
71
- this.#buffers.push(chunk)
72
- this.#byteOffset += chunk.length
73
- this.#loop = true
74
-
75
- this.run(callback)
76
- }
77
-
78
- #validatePayloadLength () {
79
- if (
80
- this.#maxPayloadSize > 0 &&
81
- !isControlFrame(this.#info.opcode) &&
82
- this.#info.payloadLength + this.#fragmentsBytes > this.#maxPayloadSize
83
- ) {
84
- failWebsocketConnection(this.#handler, 1009, 'Payload size exceeds maximum allowed size')
85
- return false
86
- }
87
-
88
- return true
89
- }
90
-
91
- /**
92
- * Runs whenever a new chunk is received.
93
- * Callback is called whenever there are no more chunks buffering,
94
- * or not enough bytes are buffered to parse.
95
- */
96
- run (callback) {
97
- while (this.#loop) {
98
- if (this.#state === parserStates.INFO) {
99
- // If there aren't enough bytes to parse the payload length, etc.
100
- if (this.#byteOffset < 2) {
101
- return callback()
102
- }
103
-
104
- const buffer = this.consume(2)
105
- const fin = (buffer[0] & 0x80) !== 0
106
- const opcode = buffer[0] & 0x0F
107
- const masked = (buffer[1] & 0x80) === 0x80
108
-
109
- const fragmented = !fin && opcode !== opcodes.CONTINUATION
110
- const payloadLength = buffer[1] & 0x7F
111
-
112
- const rsv1 = buffer[0] & 0x40
113
- const rsv2 = buffer[0] & 0x20
114
- const rsv3 = buffer[0] & 0x10
115
-
116
- if (!isValidOpcode(opcode)) {
117
- failWebsocketConnection(this.#handler, 1002, 'Invalid opcode received')
118
- return callback()
119
- }
120
-
121
- if (masked) {
122
- failWebsocketConnection(this.#handler, 1002, 'Frame cannot be masked')
123
- return callback()
124
- }
125
-
126
- // MUST be 0 unless an extension is negotiated that defines meanings
127
- // for non-zero values. If a nonzero value is received and none of
128
- // the negotiated extensions defines the meaning of such a nonzero
129
- // value, the receiving endpoint MUST _Fail the WebSocket
130
- // Connection_.
131
- // This document allocates the RSV1 bit of the WebSocket header for
132
- // PMCEs and calls the bit the "Per-Message Compressed" bit. On a
133
- // WebSocket connection where a PMCE is in use, this bit indicates
134
- // whether a message is compressed or not.
135
- if (rsv1 !== 0 && !this.#extensions.has('permessage-deflate')) {
136
- failWebsocketConnection(this.#handler, 1002, 'Expected RSV1 to be clear.')
137
- return
138
- }
139
-
140
- if (rsv2 !== 0 || rsv3 !== 0) {
141
- failWebsocketConnection(this.#handler, 1002, 'RSV1, RSV2, RSV3 must be clear')
142
- return
143
- }
144
-
145
- if (fragmented && !isTextBinaryFrame(opcode)) {
146
- // Only text and binary frames can be fragmented
147
- failWebsocketConnection(this.#handler, 1002, 'Invalid frame type was fragmented.')
148
- return
149
- }
150
-
151
- // If we are already parsing a text/binary frame and do not receive either
152
- // a continuation frame or close frame, fail the connection.
153
- if (isTextBinaryFrame(opcode) && this.#fragments.length > 0) {
154
- failWebsocketConnection(this.#handler, 1002, 'Expected continuation frame')
155
- return
156
- }
157
-
158
- if (this.#info.fragmented && fragmented) {
159
- // A fragmented frame can't be fragmented itself
160
- failWebsocketConnection(this.#handler, 1002, 'Fragmented frame exceeded 125 bytes.')
161
- return
162
- }
163
-
164
- // "All control frames MUST have a payload length of 125 bytes or less
165
- // and MUST NOT be fragmented."
166
- if ((payloadLength > 125 || fragmented) && isControlFrame(opcode)) {
167
- failWebsocketConnection(this.#handler, 1002, 'Control frame either too large or fragmented')
168
- return
169
- }
170
-
171
- if (isContinuationFrame(opcode) && this.#fragments.length === 0 && !this.#info.compressed) {
172
- failWebsocketConnection(this.#handler, 1002, 'Unexpected continuation frame')
173
- return
174
- }
175
-
176
- if (payloadLength <= 125) {
177
- this.#info.payloadLength = payloadLength
178
- this.#state = parserStates.READ_DATA
179
-
180
- if (!this.#validatePayloadLength()) {
181
- return
182
- }
183
- } else if (payloadLength === 126) {
184
- this.#state = parserStates.PAYLOADLENGTH_16
185
- } else if (payloadLength === 127) {
186
- this.#state = parserStates.PAYLOADLENGTH_64
187
- }
188
-
189
- if (isTextBinaryFrame(opcode)) {
190
- this.#info.binaryType = opcode
191
- this.#info.compressed = rsv1 !== 0
192
- }
193
-
194
- this.#info.opcode = opcode
195
- this.#info.masked = masked
196
- this.#info.fin = fin
197
- this.#info.fragmented = fragmented
198
- } else if (this.#state === parserStates.PAYLOADLENGTH_16) {
199
- if (this.#byteOffset < 2) {
200
- return callback()
201
- }
202
-
203
- const buffer = this.consume(2)
204
-
205
- this.#info.payloadLength = buffer.readUInt16BE(0)
206
- this.#state = parserStates.READ_DATA
207
-
208
- if (!this.#validatePayloadLength()) {
209
- return
210
- }
211
- } else if (this.#state === parserStates.PAYLOADLENGTH_64) {
212
- if (this.#byteOffset < 8) {
213
- return callback()
214
- }
215
-
216
- const buffer = this.consume(8)
217
- const upper = buffer.readUInt32BE(0)
218
- const lower = buffer.readUInt32BE(4)
219
-
220
- // 2^31 is the maximum bytes an arraybuffer can contain
221
- // on 32-bit systems. Although, on 64-bit systems, this is
222
- // 2^53-1 bytes.
223
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length
224
- // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275
225
- // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e
226
- if (upper !== 0 || lower > 2 ** 31 - 1) {
227
- failWebsocketConnection(this.#handler, 1009, 'Received payload length > 2^31 bytes.')
228
- return
229
- }
230
-
231
- this.#info.payloadLength = lower
232
- this.#state = parserStates.READ_DATA
233
-
234
- if (!this.#validatePayloadLength()) {
235
- return
236
- }
237
- } else if (this.#state === parserStates.READ_DATA) {
238
- if (this.#byteOffset < this.#info.payloadLength) {
239
- return callback()
240
- }
241
-
242
- const body = this.consume(this.#info.payloadLength)
243
-
244
- if (isControlFrame(this.#info.opcode)) {
245
- this.#loop = this.parseControlFrame(body)
246
- this.#state = parserStates.INFO
247
- } else {
248
- if (!this.#info.compressed) {
249
- if (!this.writeFragments(body)) {
250
- return
251
- }
252
-
253
- // If the frame is not fragmented, a message has been received.
254
- // If the frame is fragmented, it will terminate with a fin bit set
255
- // and an opcode of 0 (continuation), therefore we handle that when
256
- // parsing continuation frames, not here.
257
- if (!this.#info.fragmented && this.#info.fin) {
258
- websocketMessageReceived(this.#handler, this.#info.binaryType, this.consumeFragments())
259
- }
260
-
261
- this.#state = parserStates.INFO
262
- } else {
263
- this.#extensions.get('permessage-deflate').decompress(
264
- body,
265
- this.#info.fin,
266
- (error, data) => {
267
- if (error) {
268
- const code = error instanceof MessageSizeExceededError ? 1009 : 1007
269
- failWebsocketConnection(this.#handler, code, error.message)
270
- return
271
- }
272
-
273
- if (!this.writeFragments(data)) {
274
- return
275
- }
276
-
277
- // Check cumulative fragment size
278
- if (this.#maxPayloadSize > 0 && this.#fragmentsBytes > this.#maxPayloadSize) {
279
- failWebsocketConnection(this.#handler, 1009, new MessageSizeExceededError().message)
280
- return
281
- }
282
-
283
- if (!this.#info.fin) {
284
- this.#state = parserStates.INFO
285
- this.#loop = true
286
- this.run(callback)
287
- return
288
- }
289
-
290
- websocketMessageReceived(this.#handler, this.#info.binaryType, this.consumeFragments())
291
-
292
- this.#loop = true
293
- this.#state = parserStates.INFO
294
- this.run(callback)
295
- },
296
- this.#fragmentsBytes
297
- )
298
-
299
- this.#loop = false
300
- break
301
- }
302
- }
303
- }
304
- }
305
- }
306
-
307
- /**
308
- * Take n bytes from the buffered Buffers
309
- * @param {number} n
310
- * @returns {Buffer}
311
- */
312
- consume (n) {
313
- if (n > this.#byteOffset) {
314
- throw new Error('Called consume() before buffers satiated.')
315
- } else if (n === 0) {
316
- return emptyBuffer
317
- }
318
-
319
- this.#byteOffset -= n
320
-
321
- const first = this.#buffers[0]
322
-
323
- if (first.length > n) {
324
- // replace with remaining buffer
325
- this.#buffers[0] = first.subarray(n, first.length)
326
- return first.subarray(0, n)
327
- } else if (first.length === n) {
328
- // prefect match
329
- return this.#buffers.shift()
330
- } else {
331
- let offset = 0
332
- // If Buffer.allocUnsafe is used, extra copies will be made because the offset is non-zero.
333
- const buffer = Buffer.allocUnsafeSlow(n)
334
- while (offset !== n) {
335
- const next = this.#buffers[0]
336
- const length = next.length
337
-
338
- if (length + offset === n) {
339
- buffer.set(this.#buffers.shift(), offset)
340
- break
341
- } else if (length + offset > n) {
342
- buffer.set(next.subarray(0, n - offset), offset)
343
- this.#buffers[0] = next.subarray(n - offset)
344
- break
345
- } else {
346
- buffer.set(this.#buffers.shift(), offset)
347
- offset += length
348
- }
349
- }
350
-
351
- return buffer
352
- }
353
- }
354
-
355
- writeFragments (fragment) {
356
- if (
357
- this.#maxFragments > 0 &&
358
- this.#fragments.length === this.#maxFragments
359
- ) {
360
- failWebsocketConnection(this.#handler, 1008, 'Too many message fragments')
361
- return false
362
- }
363
-
364
- this.#fragmentsBytes += fragment.length
365
- this.#fragments.push(fragment)
366
- return true
367
- }
368
-
369
- consumeFragments () {
370
- const fragments = this.#fragments
371
-
372
- if (fragments.length === 1) {
373
- // single fragment
374
- this.#fragmentsBytes = 0
375
- return fragments.shift()
376
- }
377
-
378
- let offset = 0
379
- // If Buffer.allocUnsafe is used, extra copies will be made because the offset is non-zero.
380
- const output = Buffer.allocUnsafeSlow(this.#fragmentsBytes)
381
-
382
- for (let i = 0; i < fragments.length; ++i) {
383
- const buffer = fragments[i]
384
- output.set(buffer, offset)
385
- offset += buffer.length
386
- }
387
-
388
- this.#fragments = []
389
- this.#fragmentsBytes = 0
390
-
391
- return output
392
- }
393
-
394
- parseCloseBody (data) {
395
- assert(data.length !== 1)
396
-
397
- // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5
398
- /** @type {number|undefined} */
399
- let code
400
-
401
- if (data.length >= 2) {
402
- // _The WebSocket Connection Close Code_ is
403
- // defined as the status code (Section 7.4) contained in the first Close
404
- // control frame received by the application
405
- code = data.readUInt16BE(0)
406
- }
407
-
408
- if (code !== undefined && !isValidStatusCode(code)) {
409
- return { code: 1002, reason: 'Invalid status code', error: true }
410
- }
411
-
412
- // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6
413
- /** @type {Buffer} */
414
- let reason = data.subarray(2)
415
-
416
- // Remove BOM
417
- if (reason[0] === 0xEF && reason[1] === 0xBB && reason[2] === 0xBF) {
418
- reason = reason.subarray(3)
419
- }
420
-
421
- try {
422
- reason = utf8Decode(reason)
423
- } catch {
424
- return { code: 1007, reason: 'Invalid UTF-8', error: true }
425
- }
426
-
427
- return { code, reason, error: false }
428
- }
429
-
430
- /**
431
- * Parses control frames.
432
- * @param {Buffer} body
433
- */
434
- parseControlFrame (body) {
435
- const { opcode, payloadLength } = this.#info
436
-
437
- if (opcode === opcodes.CLOSE) {
438
- if (payloadLength === 1) {
439
- failWebsocketConnection(this.#handler, 1002, 'Received close frame with a 1-byte body.')
440
- return false
441
- }
442
-
443
- this.#info.closeInfo = this.parseCloseBody(body)
444
-
445
- if (this.#info.closeInfo.error) {
446
- const { code, reason } = this.#info.closeInfo
447
-
448
- failWebsocketConnection(this.#handler, code, reason)
449
- return false
450
- }
451
-
452
- // Upon receiving such a frame, the other peer sends a
453
- // Close frame in response, if it hasn't already sent one.
454
- if (!this.#handler.closeState.has(sentCloseFrameState.SENT) && !this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
455
- // If an endpoint receives a Close frame and did not previously send a
456
- // Close frame, the endpoint MUST send a Close frame in response. (When
457
- // sending a Close frame in response, the endpoint typically echos the
458
- // status code it received.)
459
- let body = emptyBuffer
460
- if (this.#info.closeInfo.code) {
461
- body = Buffer.allocUnsafe(2)
462
- body.writeUInt16BE(this.#info.closeInfo.code, 0)
463
- }
464
- const closeFrame = new WebsocketFrameSend(body)
465
-
466
- this.#handler.socket.write(closeFrame.createFrame(opcodes.CLOSE))
467
- this.#handler.closeState.add(sentCloseFrameState.SENT)
468
- }
469
-
470
- // Upon either sending or receiving a Close control frame, it is said
471
- // that _The WebSocket Closing Handshake is Started_ and that the
472
- // WebSocket connection is in the CLOSING state.
473
- this.#handler.readyState = states.CLOSING
474
- this.#handler.closeState.add(sentCloseFrameState.RECEIVED)
475
-
476
- return false
477
- } else if (opcode === opcodes.PING) {
478
- // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in
479
- // response, unless it already received a Close frame.
480
- // A Pong frame sent in response to a Ping frame must have identical
481
- // "Application data"
482
-
483
- if (!this.#handler.closeState.has(sentCloseFrameState.RECEIVED)) {
484
- const frame = new WebsocketFrameSend(body)
485
-
486
- this.#handler.socket.write(frame.createFrame(opcodes.PONG))
487
-
488
- this.#handler.onPing(body)
489
- }
490
- } else if (opcode === opcodes.PONG) {
491
- // A Pong frame MAY be sent unsolicited. This serves as a
492
- // unidirectional heartbeat. A response to an unsolicited Pong frame is
493
- // not expected.
494
- this.#handler.onPong(body)
495
- }
496
-
497
- return true
498
- }
499
-
500
- get closingInfo () {
501
- return this.#info.closeInfo
502
- }
503
- }
504
-
505
- module.exports = {
506
- ByteParser
507
- }
@@ -1,109 +0,0 @@
1
- 'use strict'
2
-
3
- const { WebsocketFrameSend } = require('./frame')
4
- const { opcodes, sendHints } = require('./constants')
5
- const FixedQueue = require('../../dispatcher/fixed-queue')
6
-
7
- /**
8
- * @typedef {object} SendQueueNode
9
- * @property {Promise<void> | null} promise
10
- * @property {((...args: any[]) => any)} callback
11
- * @property {Buffer | null} frame
12
- */
13
-
14
- class SendQueue {
15
- /**
16
- * @type {FixedQueue}
17
- */
18
- #queue = new FixedQueue()
19
-
20
- /**
21
- * @type {boolean}
22
- */
23
- #running = false
24
-
25
- /** @type {import('node:net').Socket} */
26
- #socket
27
-
28
- constructor (socket) {
29
- this.#socket = socket
30
- }
31
-
32
- add (item, cb, hint) {
33
- if (hint !== sendHints.blob) {
34
- if (!this.#running) {
35
- // TODO(@tsctx): support fast-path for string on running
36
- if (hint === sendHints.text) {
37
- // special fast-path for string
38
- const { 0: head, 1: body } = WebsocketFrameSend.createFastTextFrame(item)
39
- this.#socket.cork()
40
- this.#socket.write(head)
41
- this.#socket.write(body, cb)
42
- this.#socket.uncork()
43
- } else {
44
- // direct writing
45
- this.#socket.write(createFrame(item, hint), cb)
46
- }
47
- } else {
48
- /** @type {SendQueueNode} */
49
- const node = {
50
- promise: null,
51
- callback: cb,
52
- frame: createFrame(item, hint)
53
- }
54
- this.#queue.push(node)
55
- }
56
- return
57
- }
58
-
59
- /** @type {SendQueueNode} */
60
- const node = {
61
- promise: item.arrayBuffer().then((ab) => {
62
- node.promise = null
63
- node.frame = createFrame(ab, hint)
64
- }),
65
- callback: cb,
66
- frame: null
67
- }
68
-
69
- this.#queue.push(node)
70
-
71
- if (!this.#running) {
72
- this.#run()
73
- }
74
- }
75
-
76
- async #run () {
77
- this.#running = true
78
- const queue = this.#queue
79
- while (!queue.isEmpty()) {
80
- const node = queue.shift()
81
- // wait pending promise
82
- if (node.promise !== null) {
83
- await node.promise
84
- }
85
- // write
86
- this.#socket.write(node.frame, node.callback)
87
- // cleanup
88
- node.callback = node.frame = null
89
- }
90
- this.#running = false
91
- }
92
- }
93
-
94
- function createFrame (data, hint) {
95
- return new WebsocketFrameSend(toBuffer(data, hint)).createFrame(hint === sendHints.text ? opcodes.TEXT : opcodes.BINARY)
96
- }
97
-
98
- function toBuffer (data, hint) {
99
- switch (hint) {
100
- case sendHints.text:
101
- case sendHints.typedArray:
102
- return new Uint8Array(data.buffer, data.byteOffset, data.byteLength)
103
- case sendHints.arrayBuffer:
104
- case sendHints.blob:
105
- return new Uint8Array(data)
106
- }
107
- }
108
-
109
- module.exports = { SendQueue }