@wirebench/engine 2.2.0 → 3.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/README.md +134 -1
  2. package/dist/account/schema.d.ts +34 -0
  3. package/dist/account/schema.js +29 -0
  4. package/dist/assert/callback.d.ts +76 -0
  5. package/dist/assert/callback.js +320 -0
  6. package/dist/assert/capture-source.d.ts +50 -0
  7. package/dist/assert/capture-source.js +89 -0
  8. package/dist/assert/check.d.ts +8 -0
  9. package/dist/assert/check.js +18 -0
  10. package/dist/assert/header.d.ts +5 -0
  11. package/dist/assert/header.js +48 -0
  12. package/dist/assert/index.d.ts +2 -2
  13. package/dist/assert/index.js +12 -0
  14. package/dist/assert/match.d.ts +6 -0
  15. package/dist/assert/match.js +13 -4
  16. package/dist/assert/model.d.ts +110 -3
  17. package/dist/assert/model.js +16 -1
  18. package/dist/assert/schema.d.ts +194 -1
  19. package/dist/assert/schema.js +154 -12
  20. package/dist/assert/status-names.d.ts +9 -0
  21. package/dist/assert/status-names.js +27 -0
  22. package/dist/assert/status.d.ts +4 -1
  23. package/dist/assert/status.js +27 -3
  24. package/dist/asyncapi/browser.d.ts +7 -0
  25. package/dist/asyncapi/browser.js +6 -0
  26. package/dist/asyncapi/frame-check-worker-host.d.ts +44 -0
  27. package/dist/asyncapi/frame-check-worker-host.js +175 -0
  28. package/dist/asyncapi/frame-check-worker.d.ts +12 -0
  29. package/dist/asyncapi/frame-check-worker.js +25 -0
  30. package/dist/asyncapi/frame-check.d.ts +25 -0
  31. package/dist/asyncapi/frame-check.js +78 -0
  32. package/dist/asyncapi/import.d.ts +25 -0
  33. package/dist/asyncapi/import.js +34 -0
  34. package/dist/asyncapi/map.d.ts +40 -0
  35. package/dist/asyncapi/map.js +230 -0
  36. package/dist/asyncapi/model.d.ts +84 -0
  37. package/dist/asyncapi/model.js +7 -0
  38. package/dist/asyncapi/normalise-2.d.ts +13 -0
  39. package/dist/asyncapi/normalise-2.js +113 -0
  40. package/dist/asyncapi/normalise-3.d.ts +14 -0
  41. package/dist/asyncapi/normalise-3.js +133 -0
  42. package/dist/asyncapi/parse.d.ts +31 -0
  43. package/dist/asyncapi/parse.js +85 -0
  44. package/dist/asyncapi/read.d.ts +35 -0
  45. package/dist/asyncapi/read.js +186 -0
  46. package/dist/asyncapi/security.d.ts +14 -0
  47. package/dist/asyncapi/security.js +55 -0
  48. package/dist/asyncapi/update.d.ts +53 -0
  49. package/dist/asyncapi/update.js +220 -0
  50. package/dist/errors.d.ts +16 -0
  51. package/dist/errors.js +22 -0
  52. package/dist/grpc/events.d.ts +22 -0
  53. package/dist/grpc/events.js +1 -0
  54. package/dist/grpc/expand.d.ts +1 -1
  55. package/dist/grpc/expand.js +15 -5
  56. package/dist/grpc/files.d.ts +271 -0
  57. package/dist/grpc/files.js +62 -0
  58. package/dist/grpc/model.d.ts +11 -1
  59. package/dist/grpc/module.d.ts +2 -0
  60. package/dist/grpc/module.js +13 -0
  61. package/dist/grpc/run.d.ts +73 -0
  62. package/dist/grpc/run.js +407 -0
  63. package/dist/grpc/script-types.d.ts +8 -0
  64. package/dist/grpc/script-types.js +149 -0
  65. package/dist/grpc/scripting.d.ts +34 -0
  66. package/dist/grpc/scripting.js +147 -0
  67. package/dist/grpc/send-input.d.ts +46 -0
  68. package/dist/grpc/send-input.js +42 -0
  69. package/dist/grpc/send.d.ts +2 -2
  70. package/dist/grpc/status.d.ts +9 -2
  71. package/dist/grpc/status.js +11 -24
  72. package/dist/grpc/storage.d.ts +9 -0
  73. package/dist/grpc/storage.js +167 -0
  74. package/dist/{rest/auth.d.ts → http/auth/apply-auth.d.ts} +4 -4
  75. package/dist/{rest/auth.js → http/auth/apply-auth.js} +1 -1
  76. package/dist/http/auth/apply.d.ts +1 -1
  77. package/dist/{rest → http/auth}/oauth2.d.ts +2 -2
  78. package/dist/{rest → http/auth}/oauth2.js +1 -1
  79. package/dist/http/auth/send-auth.d.ts +57 -0
  80. package/dist/http/auth/send-auth.js +7 -0
  81. package/dist/http/client.js +150 -8
  82. package/dist/http/cookies.d.ts +79 -0
  83. package/dist/http/cookies.js +81 -0
  84. package/dist/http/curl.d.ts +4 -14
  85. package/dist/http/curl.js +4 -154
  86. package/dist/http/decompress.d.ts +7 -0
  87. package/dist/http/decompress.js +23 -1
  88. package/dist/http/document-fetch.d.ts +42 -0
  89. package/dist/http/document-fetch.js +207 -0
  90. package/dist/http/entries.d.ts +27 -0
  91. package/dist/http/entries.js +16 -0
  92. package/dist/http/escape.d.ts +18 -0
  93. package/dist/http/escape.js +30 -0
  94. package/dist/http/fetch-document.d.ts +28 -0
  95. package/dist/{wsdl/fetch.js → http/fetch-document.js} +8 -16
  96. package/dist/http/media-type.d.ts +9 -0
  97. package/dist/http/media-type.js +12 -0
  98. package/dist/http/transcript-cap.d.ts +26 -0
  99. package/dist/http/transcript-cap.js +36 -0
  100. package/dist/http/types.d.ts +59 -0
  101. package/dist/http/webhook-signature.d.ts +81 -0
  102. package/dist/http/webhook-signature.js +227 -0
  103. package/dist/import-detect.d.ts +2 -2
  104. package/dist/import-detect.js +10 -1
  105. package/dist/index.d.ts +207 -55
  106. package/dist/index.js +129 -32
  107. package/dist/json/cursor.d.ts +2 -0
  108. package/dist/json/cursor.js +1 -0
  109. package/dist/json/pointer-range.d.ts +18 -0
  110. package/dist/json/pointer-range.js +157 -0
  111. package/dist/json/schema/model.d.ts +59 -0
  112. package/dist/json/schema/model.js +8 -0
  113. package/dist/json/schema/parse-text.d.ts +16 -0
  114. package/dist/json/schema/parse-text.js +37 -0
  115. package/dist/{rest/openapi → json/schema}/refs.d.ts +2 -2
  116. package/dist/{rest/openapi → json/schema}/refs.js +3 -3
  117. package/dist/{rest/openapi → json/schema}/sample.d.ts +4 -0
  118. package/dist/{rest/openapi → json/schema}/sample.js +2 -2
  119. package/dist/json/schema/source.d.ts +21 -0
  120. package/dist/json/schema/source.js +8 -0
  121. package/dist/json/schema-validate.d.ts +49 -0
  122. package/dist/json/schema-validate.js +557 -0
  123. package/dist/{wss/keystore → keystore}/index.js +1 -1
  124. package/dist/{wss/keystore → keystore}/pem.js +1 -1
  125. package/dist/{wss/keystore → keystore}/pkcs12.js +1 -1
  126. package/dist/project/attachments-cache.d.ts +3 -1
  127. package/dist/{wsdl → project}/cache-naming.js +1 -1
  128. package/dist/project/endpoints.d.ts +18 -8
  129. package/dist/project/endpoints.js +21 -6
  130. package/dist/project/environments.d.ts +7 -5
  131. package/dist/project/history.d.ts +105 -9
  132. package/dist/project/history.js +195 -23
  133. package/dist/project/inherit.d.ts +7 -0
  134. package/dist/project/inherit.js +9 -0
  135. package/dist/project/keystores.d.ts +1 -1
  136. package/dist/project/load-helpers.d.ts +89 -0
  137. package/dist/project/load-helpers.js +177 -0
  138. package/dist/project/load.d.ts +30 -4
  139. package/dist/project/load.js +168 -545
  140. package/dist/project/managed-files.d.ts +36 -0
  141. package/dist/project/managed-files.js +97 -0
  142. package/dist/project/migrate.d.ts +2 -2
  143. package/dist/project/migrate.js +2 -2
  144. package/dist/project/model.d.ts +92 -14
  145. package/dist/project/model.js +50 -4
  146. package/dist/project/paths.d.ts +10 -1
  147. package/dist/project/paths.js +10 -1
  148. package/dist/project/preferences.d.ts +11 -2
  149. package/dist/project/preferences.js +5 -1
  150. package/dist/project/properties.d.ts +31 -17
  151. package/dist/project/properties.js +89 -70
  152. package/dist/project/request-location.d.ts +20 -0
  153. package/dist/project/request-location.js +62 -0
  154. package/dist/project/save.d.ts +12 -2
  155. package/dist/project/save.js +186 -141
  156. package/dist/project/schema-parts.d.ts +337 -0
  157. package/dist/project/schema-parts.js +248 -0
  158. package/dist/project/schema.d.ts +72 -928
  159. package/dist/project/schema.js +17 -466
  160. package/dist/project/sequence-guards.d.ts +43 -0
  161. package/dist/project/sequence-guards.js +109 -0
  162. package/dist/project/serialize-helpers.d.ts +60 -0
  163. package/dist/project/serialize-helpers.js +108 -0
  164. package/dist/project/serialize.d.ts +7 -8
  165. package/dist/project/serialize.js +34 -293
  166. package/dist/protocol/features.d.ts +51 -0
  167. package/dist/protocol/features.js +64 -0
  168. package/dist/protocol/index.d.ts +7 -0
  169. package/dist/protocol/index.js +4 -0
  170. package/dist/protocol/module.d.ts +247 -0
  171. package/dist/protocol/module.js +48 -0
  172. package/dist/protocol/registry.d.ts +42 -0
  173. package/dist/protocol/registry.js +47 -0
  174. package/dist/protocols.d.ts +77 -0
  175. package/dist/protocols.js +40 -0
  176. package/dist/redact/index.d.ts +12 -1
  177. package/dist/redact/index.js +55 -7
  178. package/dist/redact/literal.d.ts +10 -0
  179. package/dist/redact/literal.js +110 -12
  180. package/dist/rest/body.d.ts +2 -10
  181. package/dist/rest/body.js +3 -25
  182. package/dist/rest/browser.d.ts +4 -0
  183. package/dist/rest/browser.js +5 -0
  184. package/dist/rest/contract-check-worker-host.d.ts +36 -0
  185. package/dist/rest/contract-check-worker-host.js +158 -0
  186. package/dist/rest/contract-check-worker.d.ts +7 -0
  187. package/dist/rest/contract-check-worker.js +28 -0
  188. package/dist/rest/contract-check.d.ts +43 -0
  189. package/dist/rest/contract-check.js +217 -0
  190. package/dist/rest/cookie-jar.d.ts +62 -0
  191. package/dist/rest/cookie-jar.js +262 -0
  192. package/dist/rest/cookies.d.ts +6 -22
  193. package/dist/rest/cookies.js +6 -42
  194. package/dist/rest/curl.js +5 -1
  195. package/dist/rest/events.d.ts +12 -0
  196. package/dist/rest/events.js +1 -0
  197. package/dist/rest/expand.d.ts +6 -1
  198. package/dist/rest/expand.js +29 -11
  199. package/dist/rest/files.d.ts +439 -0
  200. package/dist/rest/files.js +107 -0
  201. package/dist/rest/json-form.d.ts +97 -0
  202. package/dist/rest/json-form.js +396 -0
  203. package/dist/rest/model.d.ts +35 -24
  204. package/dist/rest/model.js +6 -9
  205. package/dist/rest/module.d.ts +2 -0
  206. package/dist/rest/module.js +13 -0
  207. package/dist/rest/openapi/cache.d.ts +7 -2
  208. package/dist/rest/openapi/cache.js +2 -2
  209. package/dist/rest/openapi/import.d.ts +11 -16
  210. package/dist/rest/openapi/import.js +6 -2
  211. package/dist/rest/openapi/map.d.ts +38 -1
  212. package/dist/rest/openapi/map.js +151 -41
  213. package/dist/rest/openapi/match.d.ts +20 -0
  214. package/dist/rest/openapi/match.js +117 -0
  215. package/dist/rest/openapi/model.d.ts +33 -45
  216. package/dist/rest/openapi/parse.d.ts +3 -12
  217. package/dist/rest/openapi/parse.js +138 -67
  218. package/dist/rest/openapi/responses.d.ts +23 -0
  219. package/dist/rest/openapi/responses.js +59 -0
  220. package/dist/rest/openapi/runtime-expression.d.ts +69 -0
  221. package/dist/rest/openapi/runtime-expression.js +213 -0
  222. package/dist/rest/openapi/update.d.ts +116 -0
  223. package/dist/rest/openapi/update.js +456 -0
  224. package/dist/rest/postman/map.d.ts +1 -0
  225. package/dist/rest/postman/map.js +66 -4
  226. package/dist/rest/postman/model.d.ts +9 -0
  227. package/dist/rest/postman/parse.js +33 -10
  228. package/dist/rest/response.d.ts +2 -23
  229. package/dist/rest/response.js +3 -75
  230. package/dist/rest/run.d.ts +56 -0
  231. package/dist/rest/run.js +395 -0
  232. package/dist/rest/script-types.d.ts +7 -0
  233. package/dist/rest/script-types.js +83 -0
  234. package/dist/rest/scripting.d.ts +38 -0
  235. package/dist/rest/scripting.js +282 -0
  236. package/dist/rest/send-input.d.ts +54 -0
  237. package/dist/rest/send-input.js +73 -0
  238. package/dist/rest/send.d.ts +77 -4
  239. package/dist/rest/send.js +128 -7
  240. package/dist/rest/sse-transcript.d.ts +25 -0
  241. package/dist/rest/sse-transcript.js +95 -0
  242. package/dist/rest/sse.d.ts +43 -0
  243. package/dist/rest/sse.js +195 -0
  244. package/dist/rest/storage.d.ts +26 -0
  245. package/dist/rest/storage.js +262 -0
  246. package/dist/rest/url.d.ts +10 -4
  247. package/dist/rest/url.js +38 -5
  248. package/dist/run/baseline-update.d.ts +35 -0
  249. package/dist/run/baseline-update.js +97 -0
  250. package/dist/run/baseline.d.ts +42 -0
  251. package/dist/run/baseline.js +93 -0
  252. package/dist/run/context.d.ts +86 -0
  253. package/dist/run/context.js +31 -0
  254. package/dist/run/current-values.d.ts +32 -0
  255. package/dist/run/current-values.js +43 -0
  256. package/dist/run/event-queue.d.ts +14 -0
  257. package/dist/run/event-queue.js +46 -0
  258. package/dist/run/exchange.d.ts +62 -0
  259. package/dist/run/exchange.js +65 -0
  260. package/dist/run/host.d.ts +89 -0
  261. package/dist/run/host.js +1 -0
  262. package/dist/run/index.d.ts +20 -7
  263. package/dist/run/index.js +12 -4
  264. package/dist/run/oauth2-token.d.ts +42 -0
  265. package/dist/run/oauth2-token.js +92 -0
  266. package/dist/run/open.d.ts +12 -0
  267. package/dist/run/open.js +16 -0
  268. package/dist/run/run.d.ts +124 -4
  269. package/dist/run/run.js +293 -134
  270. package/dist/run/scope.d.ts +11 -0
  271. package/dist/run/scope.js +26 -0
  272. package/dist/run/script-support.d.ts +53 -0
  273. package/dist/run/script-support.js +68 -0
  274. package/dist/run/secret-needs.d.ts +11 -4
  275. package/dist/run/secret-needs.js +48 -96
  276. package/dist/run/select.d.ts +34 -25
  277. package/dist/run/select.js +45 -54
  278. package/dist/run/send-helpers.d.ts +93 -0
  279. package/dist/run/send-helpers.js +255 -0
  280. package/dist/run/tree.d.ts +50 -0
  281. package/dist/run/tree.js +54 -0
  282. package/dist/script/api/postman.d.ts +10 -0
  283. package/dist/script/api/postman.js +264 -0
  284. package/dist/script/api/prelude.d.ts +20 -0
  285. package/dist/script/api/prelude.js +215 -0
  286. package/dist/script/apply.d.ts +44 -0
  287. package/dist/script/apply.js +120 -0
  288. package/dist/script/check/host.d.ts +41 -0
  289. package/dist/script/check/host.js +143 -0
  290. package/dist/script/check/service.d.ts +52 -0
  291. package/dist/script/check/service.js +195 -0
  292. package/dist/script/check/worker.d.ts +1 -0
  293. package/dist/script/check/worker.js +40 -0
  294. package/dist/script/index.d.ts +16 -0
  295. package/dist/script/index.js +10 -0
  296. package/dist/script/lookup.d.ts +10 -0
  297. package/dist/script/lookup.js +23 -0
  298. package/dist/script/model.d.ts +82 -0
  299. package/dist/script/model.js +18 -0
  300. package/dist/script/props.d.ts +8 -0
  301. package/dist/script/props.js +28 -0
  302. package/dist/script/request-scripts.d.ts +83 -0
  303. package/dist/script/request-scripts.js +160 -0
  304. package/dist/script/run.d.ts +47 -0
  305. package/dist/script/run.js +146 -0
  306. package/dist/script/sandbox/execute.d.ts +26 -0
  307. package/dist/script/sandbox/execute.js +212 -0
  308. package/dist/script/sandbox/host-api.d.ts +27 -0
  309. package/dist/script/sandbox/host-api.js +101 -0
  310. package/dist/script/sandbox/host.d.ts +18 -0
  311. package/dist/script/sandbox/host.js +172 -0
  312. package/dist/script/sandbox/model.d.ts +69 -0
  313. package/dist/script/sandbox/model.js +24 -0
  314. package/dist/script/sandbox/worker.d.ts +1 -0
  315. package/dist/script/sandbox/worker.js +20 -0
  316. package/dist/script/send.d.ts +27 -0
  317. package/dist/script/send.js +76 -0
  318. package/dist/script/strip.d.ts +5 -0
  319. package/dist/script/strip.js +43 -0
  320. package/dist/script/types/api.d.ts +38 -0
  321. package/dist/script/types/api.js +113 -0
  322. package/dist/script/types/json-schema.d.ts +26 -0
  323. package/dist/script/types/json-schema.js +206 -0
  324. package/dist/secrets/env-names.d.ts +9 -1
  325. package/dist/secrets/env-names.js +17 -1
  326. package/dist/secrets/resolve.d.ts +44 -4
  327. package/dist/secrets/resolve.js +58 -1
  328. package/dist/secrets/scan/apply.d.ts +36 -0
  329. package/dist/secrets/scan/apply.js +194 -0
  330. package/dist/secrets/scan/rules.d.ts +32 -0
  331. package/dist/secrets/scan/rules.js +346 -0
  332. package/dist/secrets/scan/scan.d.ts +6 -0
  333. package/dist/secrets/scan/scan.js +57 -0
  334. package/dist/secrets/scan/walk.d.ts +70 -0
  335. package/dist/secrets/scan/walk.js +156 -0
  336. package/dist/secrets/secret-refs.d.ts +8 -0
  337. package/dist/secrets/secret-refs.js +25 -0
  338. package/dist/secrets/secret-token.d.ts +17 -0
  339. package/dist/secrets/secret-token.js +25 -0
  340. package/dist/sequence/file.d.ts +169 -0
  341. package/dist/sequence/file.js +237 -0
  342. package/dist/sequence/index.d.ts +7 -0
  343. package/dist/sequence/index.js +5 -0
  344. package/dist/sequence/load.d.ts +32 -0
  345. package/dist/sequence/load.js +56 -0
  346. package/dist/sequence/model.d.ts +115 -0
  347. package/dist/sequence/model.js +53 -0
  348. package/dist/sequence/run.d.ts +131 -0
  349. package/dist/sequence/run.js +191 -0
  350. package/dist/sequence/transfer.d.ts +24 -0
  351. package/dist/sequence/transfer.js +75 -0
  352. package/dist/server-api/audit.d.ts +455 -0
  353. package/dist/server-api/audit.js +186 -0
  354. package/dist/server-api/ci-tokens.d.ts +50 -0
  355. package/dist/server-api/ci-tokens.js +35 -0
  356. package/dist/server-api/hooks.d.ts +337 -0
  357. package/dist/server-api/hooks.js +152 -0
  358. package/dist/server-api/identity.d.ts +210 -0
  359. package/dist/server-api/identity.js +115 -0
  360. package/dist/server-api/licensing.d.ts +80 -0
  361. package/dist/server-api/licensing.js +53 -0
  362. package/dist/server-api/live.d.ts +132 -0
  363. package/dist/server-api/live.js +102 -0
  364. package/dist/server-api/meta.d.ts +31 -0
  365. package/dist/server-api/meta.js +21 -0
  366. package/dist/server-api/sync.d.ts +179 -0
  367. package/dist/server-api/sync.js +124 -0
  368. package/dist/server-api/teams.d.ts +306 -0
  369. package/dist/server-api/teams.js +113 -0
  370. package/dist/snapshot/diff.d.ts +30 -0
  371. package/dist/snapshot/diff.js +75 -0
  372. package/dist/snapshot/format.d.ts +17 -0
  373. package/dist/snapshot/format.js +40 -0
  374. package/dist/snapshot/golden-file.d.ts +45 -0
  375. package/dist/snapshot/golden-file.js +173 -0
  376. package/dist/snapshot/ignore.d.ts +14 -0
  377. package/dist/snapshot/ignore.js +79 -0
  378. package/dist/snapshot/index.d.ts +9 -0
  379. package/dist/snapshot/index.js +9 -0
  380. package/dist/snapshot/json-diff.d.ts +3 -0
  381. package/dist/snapshot/json-diff.js +93 -0
  382. package/dist/snapshot/xml-diff.d.ts +10 -0
  383. package/dist/snapshot/xml-diff.js +194 -0
  384. package/dist/soap/auth.d.ts +26 -0
  385. package/dist/soap/auth.js +54 -0
  386. package/dist/soap/curl.d.ts +20 -0
  387. package/dist/soap/curl.js +161 -0
  388. package/dist/soap/expand.d.ts +24 -0
  389. package/dist/soap/expand.js +95 -0
  390. package/dist/soap/files.d.ts +384 -0
  391. package/dist/soap/files.js +114 -0
  392. package/dist/soap/form-request.d.ts +13 -0
  393. package/dist/soap/form-request.js +2 -2
  394. package/dist/soap/generate.d.ts +12 -0
  395. package/dist/{generate.js → soap/generate.js} +4 -4
  396. package/dist/{import.d.ts → soap/import.d.ts} +4 -4
  397. package/dist/{import.js → soap/import.js} +13 -13
  398. package/dist/soap/json-operation.d.ts +35 -0
  399. package/dist/soap/json-operation.js +225 -0
  400. package/dist/soap/legacy-project/env-refs.d.ts +19 -0
  401. package/dist/soap/legacy-project/env-refs.js +105 -0
  402. package/dist/soap/legacy-project/map.d.ts +2 -2
  403. package/dist/soap/legacy-project/map.js +6 -0
  404. package/dist/soap/mime/multipart.d.ts +2 -2
  405. package/dist/soap/mime/multipart.js +2 -5
  406. package/dist/soap/mime/send-pipeline.d.ts +1 -1
  407. package/dist/soap/mime/send-pipeline.js +1 -1
  408. package/dist/soap/mime/types.d.ts +1 -3
  409. package/dist/soap/module.d.ts +2 -0
  410. package/dist/soap/module.js +13 -0
  411. package/dist/soap/namespace-scope.js +1 -1
  412. package/dist/soap/operations.d.ts +12 -0
  413. package/dist/{operations.js → soap/operations.js} +4 -4
  414. package/dist/soap/run.d.ts +70 -0
  415. package/dist/soap/run.js +549 -0
  416. package/dist/soap/script-types.d.ts +65 -0
  417. package/dist/soap/script-types.js +379 -0
  418. package/dist/soap/scripting.d.ts +45 -0
  419. package/dist/soap/scripting.js +221 -0
  420. package/dist/soap/send-input.d.ts +61 -0
  421. package/dist/{send-options.js → soap/send-input.js} +5 -109
  422. package/dist/{send.d.ts → soap/send.d.ts} +1 -1
  423. package/dist/{send.js → soap/send.js} +28 -12
  424. package/dist/soap/storage.d.ts +9 -0
  425. package/dist/soap/storage.js +237 -0
  426. package/dist/soap/transforms.d.ts +3 -12
  427. package/dist/soap/transforms.js +3 -14
  428. package/dist/{types.d.ts → soap/types.d.ts} +34 -84
  429. package/dist/sync/git-cli.d.ts +202 -0
  430. package/dist/sync/git-cli.js +684 -0
  431. package/dist/sync/three-way-merge.d.ts +41 -0
  432. package/dist/sync/three-way-merge.js +85 -0
  433. package/dist/sync/tree-paths.d.ts +34 -0
  434. package/dist/sync/tree-paths.js +131 -0
  435. package/dist/team-secrets/envelope.d.ts +10 -0
  436. package/dist/team-secrets/envelope.js +121 -0
  437. package/dist/team-secrets/errors.d.ts +26 -0
  438. package/dist/team-secrets/errors.js +27 -0
  439. package/dist/team-secrets/index.d.ts +14 -0
  440. package/dist/team-secrets/index.js +8 -0
  441. package/dist/team-secrets/keys.d.ts +52 -0
  442. package/dist/team-secrets/keys.js +158 -0
  443. package/dist/team-secrets/log.d.ts +48 -0
  444. package/dist/team-secrets/log.js +175 -0
  445. package/dist/team-secrets/resolve-conflict.d.ts +7 -0
  446. package/dist/team-secrets/resolve-conflict.js +14 -0
  447. package/dist/team-secrets/schema.d.ts +97 -0
  448. package/dist/team-secrets/schema.js +157 -0
  449. package/dist/team-secrets/sign.d.ts +24 -0
  450. package/dist/team-secrets/sign.js +71 -0
  451. package/dist/team-secrets/vault.d.ts +49 -0
  452. package/dist/team-secrets/vault.js +148 -0
  453. package/dist/validate/wsi/run-message.d.ts +2 -2
  454. package/dist/validate/wsi/run-message.js +1 -1
  455. package/dist/validate/wsi/run-wsdl.d.ts +2 -2
  456. package/dist/validate/wsi/run-wsdl.js +1 -1
  457. package/dist/validate/wsi/types.d.ts +1 -1
  458. package/dist/webhooks/model.d.ts +138 -0
  459. package/dist/webhooks/model.js +150 -0
  460. package/dist/workspace/commit-message.d.ts +1 -1
  461. package/dist/workspace/commit-message.js +6 -1
  462. package/dist/workspace/environments.d.ts +11 -4
  463. package/dist/workspace/environments.js +12 -0
  464. package/dist/workspace/index.d.ts +3 -3
  465. package/dist/workspace/index.js +2 -2
  466. package/dist/workspace/paths.d.ts +5 -2
  467. package/dist/workspace/paths.js +5 -2
  468. package/dist/workspace/schema.d.ts +7 -3
  469. package/dist/workspace/schema.js +24 -3
  470. package/dist/workspace/share.d.ts +30 -11
  471. package/dist/workspace/share.js +32 -6
  472. package/dist/ws/call.d.ts +1 -1
  473. package/dist/ws/call.js +2 -2
  474. package/dist/ws/connect.d.ts +60 -0
  475. package/dist/ws/connect.js +131 -0
  476. package/dist/ws/events.d.ts +17 -0
  477. package/dist/ws/events.js +1 -0
  478. package/dist/ws/expand.d.ts +1 -1
  479. package/dist/ws/expand.js +1 -1
  480. package/dist/ws/files.d.ts +284 -0
  481. package/dist/ws/files.js +71 -0
  482. package/dist/ws/history-entry.d.ts +44 -0
  483. package/dist/ws/history-entry.js +93 -0
  484. package/dist/ws/model.d.ts +44 -3
  485. package/dist/ws/model.js +3 -0
  486. package/dist/ws/module.d.ts +2 -0
  487. package/dist/ws/module.js +11 -0
  488. package/dist/ws/run.d.ts +63 -0
  489. package/dist/ws/run.js +470 -0
  490. package/dist/ws/session.d.ts +18 -0
  491. package/dist/ws/session.js +52 -25
  492. package/dist/ws/storage.d.ts +9 -0
  493. package/dist/ws/storage.js +176 -0
  494. package/dist/ws/transcript.d.ts +3 -4
  495. package/dist/ws/transcript.js +26 -17
  496. package/dist/ws/url.d.ts +1 -1
  497. package/dist/wsdl/cache.js +1 -1
  498. package/dist/wsdl/docs-generator.d.ts +3 -3
  499. package/dist/wsdl/docs-generator.js +1 -1
  500. package/dist/wsdl/export-definition.js +1 -1
  501. package/dist/wsdl/qname.d.ts +2 -5
  502. package/dist/wsdl/resolver.d.ts +4 -11
  503. package/dist/wsdl/resolver.js +3 -3
  504. package/dist/wsdl/update-definition.d.ts +5 -5
  505. package/dist/wsdl/update-definition.js +6 -6
  506. package/dist/wss/apply.js +1 -1
  507. package/dist/{project/wss-configs.d.ts → wss/configs.d.ts} +2 -2
  508. package/dist/{project/wss-configs.js → wss/configs.js} +2 -2
  509. package/dist/wss/incoming/decrypt.d.ts +1 -1
  510. package/dist/wss/incoming/index.js +1 -1
  511. package/dist/wss/incoming/verify.d.ts +1 -1
  512. package/dist/wss/incoming/verify.js +1 -1
  513. package/dist/wss/key-identifiers.js +1 -1
  514. package/dist/wss/model.d.ts +1 -1
  515. package/dist/wss/outgoing/encryption.d.ts +1 -1
  516. package/dist/wss/outgoing/signature.d.ts +1 -1
  517. package/dist/xml/decode.d.ts +15 -0
  518. package/dist/xml/decode.js +22 -0
  519. package/dist/xml/entitize.d.ts +17 -0
  520. package/dist/xml/entitize.js +19 -0
  521. package/dist/xml/index.d.ts +1 -1
  522. package/dist/xml/index.js +1 -1
  523. package/dist/xml/locate.d.ts +39 -0
  524. package/dist/xml/locate.js +117 -0
  525. package/dist/xml/qname.d.ts +12 -0
  526. package/dist/xml/qname.js +8 -0
  527. package/dist/xpath/evaluate-async.d.ts +19 -0
  528. package/dist/xpath/evaluate-async.js +31 -11
  529. package/dist/xpath/evaluate.d.ts +1 -1
  530. package/dist/xpath/namespaces.js +1 -1
  531. package/dist/xpath/worker.d.ts +11 -5
  532. package/dist/xpath/worker.js +24 -7
  533. package/dist/xsd/form-model.d.ts +19 -2
  534. package/dist/xsd/form-model.js +14 -2
  535. package/dist/xsd/json-bridge.d.ts +152 -0
  536. package/dist/xsd/json-bridge.js +1213 -0
  537. package/dist/xsd/locate.d.ts +2 -30
  538. package/dist/xsd/locate.js +1 -109
  539. package/dist/xsd/xml-scan.d.ts +2 -0
  540. package/dist/xsd/xml-scan.js +1 -1
  541. package/dist/xsd/xml-writer.d.ts +2 -0
  542. package/dist/xsd/xml-writer.js +4 -0
  543. package/package.json +12 -1
  544. package/dist/generate.d.ts +0 -12
  545. package/dist/operations.d.ts +0 -12
  546. package/dist/run/effective-auth.d.ts +0 -10
  547. package/dist/run/effective-auth.js +0 -19
  548. package/dist/run/prepare.d.ts +0 -43
  549. package/dist/run/prepare.js +0 -280
  550. package/dist/send-options.d.ts +0 -141
  551. package/dist/wsdl/fetch.d.ts +0 -13
  552. /package/dist/{soap → http}/charset.d.ts +0 -0
  553. /package/dist/{soap → http}/charset.js +0 -0
  554. /package/dist/{wsdl → http}/ref-policy.d.ts +0 -0
  555. /package/dist/{wsdl → http}/ref-policy.js +0 -0
  556. /package/dist/{wss/keystore → keystore}/certificate.d.ts +0 -0
  557. /package/dist/{wss/keystore → keystore}/certificate.js +0 -0
  558. /package/dist/{wss/keystore → keystore}/index.d.ts +0 -0
  559. /package/dist/{wss/keystore → keystore}/model.d.ts +0 -0
  560. /package/dist/{wss/keystore → keystore}/model.js +0 -0
  561. /package/dist/{wss/keystore → keystore}/pem.d.ts +0 -0
  562. /package/dist/{wss/keystore → keystore}/pkcs12.d.ts +0 -0
  563. /package/dist/{wsdl → project}/cache-naming.d.ts +0 -0
  564. /package/dist/{types.js → soap/types.js} +0 -0
  565. /package/dist/{soap → xml}/prefixes.d.ts +0 -0
  566. /package/dist/{soap → xml}/prefixes.js +0 -0
@@ -0,0 +1,63 @@
1
+ /**
2
+ * WebSocket's run facet (spec §3.3). A run selects every request its contract still has. A send
3
+ * resolves the request and refuses one with a reference nothing resolves, connects (its TLS
4
+ * identity, the proxy, its credentials with an OAuth2 token), then opens the session (spec §3.4).
5
+ * A host that opens it interactive drives the session with push and close; a run sends the saved
6
+ * messages in order, waits for a reply after the last one, then closes, all within the run timeout
7
+ * (spec §5.2).
8
+ */
9
+ import type { AssertionSubject } from '../assert/model.js';
10
+ import type { AuthConfig, Project } from '../project/model.js';
11
+ import type { Preferences } from '../project/preferences.js';
12
+ import type { ProtocolRun } from '../protocol/module.js';
13
+ import type { RunContext } from '../run/context.js';
14
+ import type { Resolved } from '../run/send-helpers.js';
15
+ import type { WsCallInput } from './expand.js';
16
+ import type { WsApi, WsExchange, WsFolder, WsRequestDef, WsRequestSettings } from './model.js';
17
+ /** One saved WebSocket request selected for a run. */
18
+ export interface WsSelected {
19
+ readonly kind: 'websocket';
20
+ readonly path: string;
21
+ readonly group: string;
22
+ readonly api: WsApi;
23
+ readonly chain: readonly WsFolder[];
24
+ readonly request: WsRequestDef;
25
+ }
26
+ /** The same chain for a WebSocket request: request, its folders inside-out, the API. */
27
+ export declare function wsEffectiveAuth(selected: WsSelected): AuthConfig;
28
+ /**
29
+ * The WebSocket item for `requestId`, built as a run builds it, and found even when its contract no
30
+ * longer has it (`orphaned`), which a run skips and a person may still open. Undefined when no
31
+ * WebSocket request has that id.
32
+ */
33
+ export declare function wsItemFor(project: Project, requestId: string): WsSelected | undefined;
34
+ /**
35
+ * The effective `WsRequestSettings` a request sends with, request settings resolved against
36
+ * project/preference defaults.
37
+ *
38
+ * A `WsApi` carries no settings of its own to inherit from (unlike a gRPC or REST API), so this
39
+ * ladder is shorter than `toGrpcSendInput`'s: only `handshakeTimeoutMs` has a project/preference
40
+ * fallback (mirroring gRPC's `timeoutMs`, sourced from `project.settings.defaultTimeoutMs` and then
41
+ * `preferences.http.socketTimeoutMs`); `trustInvalid`, `sslKeystoreRef`, `bindAddress` and
42
+ * `maxMessageBytes` are the request's own or absent. A host that lends no preferences gets the
43
+ * defaults, as gRPC's does.
44
+ */
45
+ export declare function effectiveWsSettings(request: WsRequestDef, project: Project, preferences: Preferences | undefined): WsRequestSettings;
46
+ /**
47
+ * A WebSocket request resolved for its send (spec §3.4): the server URL through the environment's override for the
48
+ * API (the slot a REST base URL uses), the settings ladder, and one expansion pass over the server
49
+ * URL, the request's URL, query, headers and subprotocols and the API's headers, nothing connected.
50
+ * The run timeout, when given, is the handshake timeout. A reference nothing resolves is reported in
51
+ * `unresolved`, not thrown: the send refuses it, a preview shows it.
52
+ *
53
+ * @throws WirebenchError `secret-missing`
54
+ */
55
+ export declare function resolveWs(selected: WsSelected, context: RunContext): Promise<Resolved<WsCallInput>>;
56
+ /**
57
+ * A session as assertions see it: the handshake's status and response headers, and every text the
58
+ * server sent, in order, as a JSON array — a JSON message as its value, any other as its text. A
59
+ * refused handshake has no status, so it reads as 0.
60
+ */
61
+ export declare function wsSubject(exchange: WsExchange): AssertionSubject;
62
+ /** WebSocket's run facet. */
63
+ export declare const wsRun: ProtocolRun<WsSelected>;
package/dist/ws/run.js ADDED
@@ -0,0 +1,470 @@
1
+ import { HttpError, WsError } from '../errors.js';
2
+ import { resolveAuthChain } from '../http/auth/apply-auth.js';
3
+ import { DEFAULT_PREFERENCES } from '../project/preferences.js';
4
+ import { expand } from '../project/properties.js';
5
+ import { scopesFor } from '../run/context.js';
6
+ import { exchangeController } from '../run/exchange.js';
7
+ import { authFor, baseUrlFor, keystoreNeeds, originOf, tlsFor, unresolvedError, withSecrets, } from '../run/send-helpers.js';
8
+ import { ORPHANED_STEP_REASON, findInTree, walkTree } from '../run/tree.js';
9
+ import { secretNeedsOfAuth } from '../secrets/env-names.js';
10
+ import { toWsSessionOptions } from './call.js';
11
+ import { expandWsInput, expandWsMessage } from './expand.js';
12
+ import { assertCloseCode, HANDSHAKE_TIMEOUT_ERROR, openWsSession } from './session.js';
13
+ import { resolveWsUrl } from './url.js';
14
+ /** The same chain for a WebSocket request: request, its folders inside-out, the API. */
15
+ export function wsEffectiveAuth(selected) {
16
+ const { api, chain, request } = selected;
17
+ return resolveAuthChain([request.auth, ...[...chain].reverse().map((folder) => folder.auth), api.auth]);
18
+ }
19
+ /**
20
+ * The WebSocket item for `requestId`, built as a run builds it, and found even when its contract no
21
+ * longer has it (`orphaned`), which a run skips and a person may still open. Undefined when no
22
+ * WebSocket request has that id.
23
+ */
24
+ export function wsItemFor(project, requestId) {
25
+ const candidates = [];
26
+ for (const api of project.wsApis) {
27
+ walkTree(api, [], api.name, `apis/${api.slug}/requests`, (request, chain, group) => request.id === requestId
28
+ ? { kind: 'websocket', path: `${group}/${request.name}`, group, api, chain, request }
29
+ : undefined, candidates);
30
+ }
31
+ return candidates[0]?.item;
32
+ }
33
+ /**
34
+ * The effective `WsRequestSettings` a request sends with, request settings resolved against
35
+ * project/preference defaults.
36
+ *
37
+ * A `WsApi` carries no settings of its own to inherit from (unlike a gRPC or REST API), so this
38
+ * ladder is shorter than `toGrpcSendInput`'s: only `handshakeTimeoutMs` has a project/preference
39
+ * fallback (mirroring gRPC's `timeoutMs`, sourced from `project.settings.defaultTimeoutMs` and then
40
+ * `preferences.http.socketTimeoutMs`); `trustInvalid`, `sslKeystoreRef`, `bindAddress` and
41
+ * `maxMessageBytes` are the request's own or absent. A host that lends no preferences gets the
42
+ * defaults, as gRPC's does.
43
+ */
44
+ export function effectiveWsSettings(request, project, preferences) {
45
+ const handshakeTimeoutMs = request.settings.handshakeTimeoutMs ??
46
+ project.settings.defaultTimeoutMs ??
47
+ (preferences ?? DEFAULT_PREFERENCES).http.socketTimeoutMs;
48
+ return {
49
+ ...request.settings,
50
+ handshakeTimeoutMs,
51
+ };
52
+ }
53
+ /**
54
+ * A WebSocket request resolved for its send (spec §3.4): the server URL through the environment's override for the
55
+ * API (the slot a REST base URL uses), the settings ladder, and one expansion pass over the server
56
+ * URL, the request's URL, query, headers and subprotocols and the API's headers, nothing connected.
57
+ * The run timeout, when given, is the handshake timeout. A reference nothing resolves is reported in
58
+ * `unresolved`, not thrown: the send refuses it, a preview shows it.
59
+ *
60
+ * @throws WirebenchError `secret-missing`
61
+ */
62
+ export async function resolveWs(selected, context) {
63
+ const { api, request } = selected;
64
+ const scopes = scopesFor(context);
65
+ const settings = effectiveWsSettings(request, context.project, context.host.preferences);
66
+ const unexpanded = {
67
+ serverUrl: baseUrlFor(context, { slug: api.slug, baseUrl: api.url }),
68
+ request: {
69
+ url: request.url,
70
+ query: request.query,
71
+ headers: request.headers,
72
+ subprotocols: request.subprotocols,
73
+ settings: context.timeoutMs !== undefined ? { ...settings, handshakeTimeoutMs: context.timeoutMs } : settings,
74
+ },
75
+ apiHeaders: api.headers,
76
+ };
77
+ const withTokens = await withSecrets(unexpanded, scopes, context.host.getSecret, context.secretPlaceholders);
78
+ // `expandWsInput` leaves the server URL alone; it is expanded here, first, as the app does.
79
+ const server = expand(unexpanded.serverUrl, withTokens);
80
+ const { input, unresolved } = expandWsInput(unexpanded, withTokens);
81
+ return { input: { ...input, serverUrl: server.text }, unresolved: [...server.unresolved, ...unresolved] };
82
+ }
83
+ /** The URL a resolved call dials, before any API key travels in its query. */
84
+ function dialledUrl(input) {
85
+ try {
86
+ return resolveWsUrl(input.serverUrl, input.request.url, input.request.query);
87
+ }
88
+ catch {
89
+ return `${input.serverUrl}${input.request.url}`;
90
+ }
91
+ }
92
+ /** What a call that failed before it dialled was about to send: its URL and its enabled header rows. */
93
+ function attemptedOf(input) {
94
+ return {
95
+ url: dialledUrl(input),
96
+ method: 'GET',
97
+ headers: Object.fromEntries([...input.apiHeaders, ...input.request.headers].filter((row) => row.enabled).map((row) => [row.name, row.value])),
98
+ };
99
+ }
100
+ /**
101
+ * The request's TLS identity and trust decision, the proxy chosen for the URL's `http(s)` form, and
102
+ * the chain's credentials (an OAuth2 token included), over a resolved call, as the options the
103
+ * session opens with.
104
+ *
105
+ * @throws WirebenchError `secret-missing` | `auth-grant-unsupported` | `keystore-missing` |
106
+ * `ws-auth-unsupported` | `ws-bad-url`
107
+ */
108
+ async function connectWs(selected, context, input, signal) {
109
+ const { settings } = selected.request;
110
+ const tls = await tlsFor(context, settings.sslKeystoreRef, settings.trustInvalid === true);
111
+ const proxy = await context.host.proxyFor?.(dialledUrl(input).replace(/^ws/, 'http'));
112
+ const auth = await authFor(wsEffectiveAuth(selected), selected.path, context, tls);
113
+ return toWsSessionOptions(input, {
114
+ ...(auth !== undefined ? { auth } : {}),
115
+ ...(tls !== undefined ? { tls } : {}),
116
+ ...(proxy !== undefined ? { proxy } : {}),
117
+ signal,
118
+ });
119
+ }
120
+ /** True when `text` is strictly valid base64, the empty string included: the app's own check. */
121
+ function isValidBase64(text) {
122
+ return text.length % 4 === 0 && /^[A-Za-z0-9+/]*={0,2}$/.test(text);
123
+ }
124
+ /**
125
+ * The saved messages a run sends, in order: text expanded with the request's escaping, binary from
126
+ * its base64. Expanded before the session dials, so a reference nothing resolves refuses the send.
127
+ *
128
+ * @throws WsError `ws-bad-binary` for a binary message that is not valid base64
129
+ */
130
+ async function savedPayloads(selected, context) {
131
+ const { messages, settings } = selected.request;
132
+ const texts = messages.filter((message) => message.format === 'text').map((message) => message.content);
133
+ const scopes = await withSecrets(texts, scopesFor(context), context.host.getSecret);
134
+ const unresolved = [];
135
+ const payloads = messages.map((message) => {
136
+ if (message.format === 'binary') {
137
+ // `Buffer.from` drops what is not base64 and would send what is left: refuse it instead.
138
+ if (!isValidBase64(message.content)) {
139
+ throw new WsError('ws-bad-binary', `The saved message "${message.name}" is not valid base64.`, {
140
+ details: { path: selected.path, message: message.name },
141
+ });
142
+ }
143
+ return new Uint8Array(Buffer.from(message.content, 'base64'));
144
+ }
145
+ const expanded = expandWsMessage(message.content, scopes, { escape: settings.escapeProperties === true });
146
+ unresolved.push(...expanded.unresolved);
147
+ return expanded.text;
148
+ });
149
+ return { payloads, unresolved };
150
+ }
151
+ /** A pushed message as it goes on the wire, a text expanded against the request's scopes when asked. */
152
+ async function pushedPayload(selected, context, message) {
153
+ if ('base64' in message)
154
+ return new Uint8Array(Buffer.from(message.base64, 'base64'));
155
+ if (message.expand !== true)
156
+ return message.text;
157
+ const scopes = await withSecrets(message.text, message.scopes ?? scopesFor(context), context.host.getSecret);
158
+ const expanded = expandWsMessage(message.text, scopes, {
159
+ escape: selected.request.settings.escapeProperties === true,
160
+ });
161
+ if (expanded.unresolved.length > 0) {
162
+ throw unresolvedError('ws-unresolved-properties', selected.path, expanded.unresolved);
163
+ }
164
+ return expanded.text;
165
+ }
166
+ function sessionClosed(closing, settled) {
167
+ return new WsError('ws-session-closed', 'The connection is closed', { details: { closing, settled } });
168
+ }
169
+ function wsSessionState() {
170
+ let resolveOpen;
171
+ let rejectOpen;
172
+ const open = new Promise((resolve, reject) => {
173
+ resolveOpen = resolve;
174
+ rejectOpen = reject;
175
+ });
176
+ // Observed here: a session that never opens and has nothing waiting rejects it unread.
177
+ open.catch(() => undefined);
178
+ let isOpen = false;
179
+ let tail = Promise.resolve();
180
+ let closing = false;
181
+ let done = false;
182
+ const enqueue = (step) => {
183
+ const result = tail.then(step);
184
+ tail = result.catch(() => undefined);
185
+ return result;
186
+ };
187
+ return {
188
+ send(prepare) {
189
+ if (closing || done)
190
+ return Promise.reject(sessionClosed(closing, done));
191
+ // Expanded at once; only the write waits its turn.
192
+ const payload = prepare();
193
+ payload.catch(() => undefined);
194
+ return enqueue(async () => {
195
+ const data = await payload;
196
+ return (await open).send(data);
197
+ });
198
+ },
199
+ close(code, reason) {
200
+ if (closing || done)
201
+ return;
202
+ if (code !== undefined)
203
+ assertCloseCode(code);
204
+ closing = true;
205
+ void enqueue(async () => (await open).close(code, reason)).catch(() => undefined);
206
+ },
207
+ opened(handle) {
208
+ isOpen = true;
209
+ resolveOpen(handle);
210
+ },
211
+ settled() {
212
+ done = true;
213
+ if (!isOpen)
214
+ rejectOpen(sessionClosed(closing, true));
215
+ },
216
+ };
217
+ }
218
+ /**
219
+ * Why a run's session never opened: `timeout` when the server did not answer the handshake in time,
220
+ * the HTTP layer's code; `ws-handshake-refused` for a refusal or a server that cannot be reached.
221
+ */
222
+ function handshakeFailure(handshake) {
223
+ if (handshake.error?.startsWith(HANDSHAKE_TIMEOUT_ERROR) === true) {
224
+ return new HttpError('timeout', 'The request timed out.', { details: { url: handshake.url } });
225
+ }
226
+ return new WsError('ws-handshake-refused', handshake.error ?? 'The server refused the WebSocket handshake.', {
227
+ details: { url: handshake.url },
228
+ });
229
+ }
230
+ /** How long a run waits for the server to answer its close before letting the connection go. */
231
+ const RUN_CLOSE_GRACE_MS = 500;
232
+ function replyWatch(saved) {
233
+ let sent = 0;
234
+ let hasReplied = false;
235
+ let resolve;
236
+ const replied = new Promise((done) => {
237
+ resolve = done;
238
+ });
239
+ return {
240
+ replied,
241
+ get hasReplied() {
242
+ return hasReplied;
243
+ },
244
+ frame(frame) {
245
+ if (frame.opcode !== 'text' && frame.opcode !== 'binary')
246
+ return;
247
+ if (frame.direction === 'sent') {
248
+ sent += 1;
249
+ }
250
+ else if (sent >= saved && !hasReplied) {
251
+ hasReplied = true;
252
+ resolve();
253
+ }
254
+ },
255
+ };
256
+ }
257
+ /** The handshake's response head, as `raw` keeps it: status line and headers. */
258
+ function responseHead(handshake) {
259
+ if (handshake.status === undefined)
260
+ return '';
261
+ const lines = [
262
+ `HTTP/1.1 ${handshake.status} ${handshake.statusText ?? ''}`.trimEnd(),
263
+ ...Object.entries(handshake.responseHeaders ?? {}).map(([name, value]) => `${name}: ${value}`),
264
+ ];
265
+ return `${lines.join('\r\n')}\r\n\r\n`;
266
+ }
267
+ /** A received text as assertions read it: its JSON value when it is JSON, else the text itself. */
268
+ function messageValue(text) {
269
+ try {
270
+ return JSON.parse(text);
271
+ }
272
+ catch {
273
+ return text;
274
+ }
275
+ }
276
+ /**
277
+ * A session as assertions see it: the handshake's status and response headers, and every text the
278
+ * server sent, in order, as a JSON array — a JSON message as its value, any other as its text. A
279
+ * refused handshake has no status, so it reads as 0.
280
+ */
281
+ export function wsSubject(exchange) {
282
+ const received = exchange.frames
283
+ .filter((frame) => frame.direction === 'received' && frame.opcode === 'text')
284
+ .map((frame) => messageValue(frame.text ?? ''));
285
+ return {
286
+ protocol: 'websocket',
287
+ status: exchange.handshake.status ?? 0,
288
+ durationMs: exchange.durationMs,
289
+ bodyText: JSON.stringify(received),
290
+ bodyKind: 'json',
291
+ headers: Object.entries(exchange.handshake.responseHeaders ?? {}),
292
+ };
293
+ }
294
+ /**
295
+ * One WebSocket request as a run or a host sends it (spec §3.4): resolve, connect, open. A failure
296
+ * is told to the host with its stage and what was attempted: a reference nothing resolves in the
297
+ * prepare stage. A cancel before the handshake fails the send, with `aborted`; a cancel after it
298
+ * ends the session, which settles with what it recorded. Otherwise an interactive session's outcome
299
+ * is a result, a refused handshake included, which the host shows; a run's session that never opened
300
+ * fails, with `ws-handshake-refused` or `timeout`, so a dead endpoint never passes a run. A run's
301
+ * session closes with 1000 once a reply comes after its last saved message; one the run timeout
302
+ * closes first fails with `timeout`, never a pass, and a server that never answers that close is let
303
+ * go after a short grace. A host's own send that is not interactive closes after its last message.
304
+ */
305
+ async function sendWsItem(selected, context, controller, state, interactive, run) {
306
+ let startedAt = Date.now();
307
+ // Never masks the send's own error: a row that cannot be built, or a host that throws, is dropped.
308
+ const failed = (stage, error, attempted, input, transcript) => {
309
+ try {
310
+ context.host.events?.onFailed?.(selected, {
311
+ stage,
312
+ error,
313
+ startedAt,
314
+ durationMs: Date.now() - startedAt,
315
+ ...(attempted !== undefined ? { attempted, input } : {}),
316
+ ...(transcript !== undefined ? { exchange: transcript } : {}),
317
+ });
318
+ }
319
+ catch {
320
+ // Deliberately ignored — see above.
321
+ }
322
+ };
323
+ let watch;
324
+ let deadline;
325
+ try {
326
+ let input;
327
+ let options;
328
+ try {
329
+ const resolved = await resolveWs(selected, context);
330
+ input = resolved.input;
331
+ if (resolved.unresolved.length > 0) {
332
+ throw unresolvedError('ws-unresolved-properties', selected.path, resolved.unresolved);
333
+ }
334
+ if (!interactive) {
335
+ const saved = await savedPayloads(selected, context);
336
+ if (saved.unresolved.length > 0) {
337
+ throw unresolvedError('ws-unresolved-properties', selected.path, saved.unresolved);
338
+ }
339
+ for (const payload of saved.payloads)
340
+ void state.send(() => Promise.resolve(payload)).catch(() => undefined);
341
+ if (run) {
342
+ watch = replyWatch(saved.payloads.length);
343
+ void watch.replied.then(() => state.close(1000));
344
+ }
345
+ else {
346
+ state.close(1000);
347
+ }
348
+ }
349
+ const connected = await connectWs(selected, context, input, controller.signal);
350
+ options = run ? { ...connected, closeGraceMs: RUN_CLOSE_GRACE_MS } : connected;
351
+ }
352
+ catch (error) {
353
+ failed('prepare', error, input === undefined ? undefined : attemptedOf(input), input);
354
+ throw error;
355
+ }
356
+ const sentAttempt = { url: options.url, method: 'GET', headers: options.headers ?? {} };
357
+ // The send stage's own clock: a send-stage failure never counts resolve or the token.
358
+ startedAt = Date.now();
359
+ let opened = false;
360
+ let timedOut = false;
361
+ let exchange;
362
+ try {
363
+ // The run timeout bounds the whole session; it is also the handshake's, so either ends it. The
364
+ // settings ladder always gives one.
365
+ if (watch !== undefined && options.handshakeTimeoutMs !== undefined) {
366
+ deadline = setTimeout(() => {
367
+ timedOut = true;
368
+ state.close(1000);
369
+ }, options.handshakeTimeoutMs);
370
+ }
371
+ const session = openWsSession(options, {
372
+ onHandshake: (handshake) => {
373
+ opened = true;
374
+ controller.queue.push({ protocol: 'websocket', kind: 'handshake', handshake });
375
+ if (handshake.status === 101) {
376
+ try {
377
+ context.host.events?.onExchange?.(selected, handshake);
378
+ }
379
+ catch {
380
+ // A host that cannot log the handshake does not end the session.
381
+ }
382
+ }
383
+ // After this hook returns: `session` is assigned by then, and the socket is open.
384
+ queueMicrotask(() => state.opened(session));
385
+ },
386
+ onFrame: (frame) => {
387
+ watch?.frame(frame);
388
+ controller.queue.push({ protocol: 'websocket', kind: 'frame', frame });
389
+ },
390
+ onClosed: () => controller.queue.push({ protocol: 'websocket', kind: 'closed' }),
391
+ });
392
+ exchange = await session.done;
393
+ // A run's session cancelled before its reply is cut short, never a pass, as any other protocol's
394
+ // cancelled step is. Any other session settles with its transcript once it has opened.
395
+ if (controller.signal.aborted && (!opened || (run && watch?.hasReplied !== true))) {
396
+ throw new HttpError('aborted', 'The request was aborted.');
397
+ }
398
+ // A host shows a refused handshake from the transcript; a run has nothing to assert on, so it fails.
399
+ if (!opened && !interactive)
400
+ throw handshakeFailure(exchange.handshake);
401
+ if (timedOut && watch?.hasReplied === false) {
402
+ throw new HttpError('timeout', 'The request timed out.', { details: { url: exchange.url } });
403
+ }
404
+ }
405
+ catch (error) {
406
+ // A session that settled before failing (cancelled before it opened) keeps its transcript.
407
+ failed('send', error, sentAttempt, input, exchange);
408
+ throw error;
409
+ }
410
+ return {
411
+ subject: wsSubject(exchange),
412
+ raw: {
413
+ rawRequest: new TextEncoder().encode(exchange.handshake.rawRequestHead ?? ''),
414
+ rawResponse: new TextEncoder().encode(responseHead(exchange.handshake)),
415
+ },
416
+ exchange: { kind: 'websocket', ws: exchange },
417
+ ...originOf(exchange.url),
418
+ };
419
+ }
420
+ finally {
421
+ clearTimeout(deadline);
422
+ state.settled();
423
+ }
424
+ }
425
+ /** WebSocket's run facet. */
426
+ export const wsRun = {
427
+ groups(project) {
428
+ return project.wsApis.map((api) => {
429
+ const candidates = [];
430
+ walkTree(api, [], api.name, `apis/${api.slug}/requests`, (request, chain, group) => request.orphaned === true
431
+ ? undefined
432
+ : { kind: 'websocket', path: `${group}/${request.name}`, group, api, chain, request }, candidates);
433
+ return { order: api.order, name: api.name, candidates };
434
+ });
435
+ },
436
+ whyNotRunnable(project, requestId) {
437
+ for (const api of project.wsApis) {
438
+ const request = findInTree(api, requestId);
439
+ if (request !== undefined) {
440
+ return request.orphaned === true ? ORPHANED_STEP_REASON : undefined;
441
+ }
442
+ }
443
+ return undefined;
444
+ },
445
+ open(selected, scope, host, options) {
446
+ const controller = exchangeController('websocket', options);
447
+ const context = { ...scope.context, host, signal: controller.signal };
448
+ const state = wsSessionState();
449
+ // A WebSocket has no half-close: ending the sending side ends the session.
450
+ const streaming = {
451
+ push: (message) => state.send(() => pushedPayload(selected, context, message)),
452
+ halfClose: () => state.close(),
453
+ close: (code, reason) => state.close(code, reason),
454
+ };
455
+ return controller.handle(() => sendWsItem(selected, context, controller, state, options.interactive, options.run === true), options.interactive ? streaming : undefined);
456
+ },
457
+ resolve(selected, scope, host) {
458
+ return resolveWs(selected, { ...scope.context, host });
459
+ },
460
+ scriptTypes() {
461
+ // No scripting facet: a run refuses a scripted request with `script-unsupported` before asking.
462
+ return Promise.resolve({ generated: '' });
463
+ },
464
+ secretNeeds(selected, project) {
465
+ return [
466
+ ...secretNeedsOfAuth(wsEffectiveAuth(selected)),
467
+ ...keystoreNeeds(project, selected.request.settings.sslKeystoreRef),
468
+ ];
469
+ },
470
+ };
@@ -1,6 +1,11 @@
1
1
  import type { ProxyOptions, TlsOptions } from '../http/types.js';
2
2
  import { type TlsSocketLike } from '../http/tls.js';
3
3
  import type { WsExchange, WsFrame, WsHandshake } from './model.js';
4
+ /**
5
+ * How a handshake that timed out begins its `error`: the one failure a caller tells apart from a
6
+ * refusal (the run facet fails a run's send with `timeout` for it). Not part of the public surface.
7
+ */
8
+ export declare const HANDSHAKE_TIMEOUT_ERROR = "The server did not answer the handshake within";
4
9
  /** Options for {@link openWsSession}. */
5
10
  export interface WsSessionOptions {
6
11
  readonly url: string;
@@ -14,6 +19,11 @@ export interface WsSessionOptions {
14
19
  readonly handshakeTimeoutMs?: number;
15
20
  /** Default unlimited. A larger received message ends the session from this side. */
16
21
  readonly maxMessageBytes?: number;
22
+ /**
23
+ * Default unlimited. How long a close from this side, or a cancel while it closes, waits for the
24
+ * server's answer before the connection is torn down and the session settles with 1006.
25
+ */
26
+ readonly closeGraceMs?: number;
17
27
  readonly signal?: AbortSignal;
18
28
  }
19
29
  /** Hooks {@link openWsSession} calls as the session runs, in addition to `done`. */
@@ -32,6 +42,13 @@ export interface WsSessionHandle {
32
42
  /** Never rejects. */
33
43
  readonly done: Promise<WsExchange>;
34
44
  }
45
+ /**
46
+ * RFC 6455 §7.4, as the WHATWG API enforces it: 1000, or the 3000–4999 range. Exported for the run
47
+ * facet, which refuses a bad code when it is asked to close rather than when the close goes out.
48
+ *
49
+ * @throws WsError `ws-bad-close`
50
+ */
51
+ export declare function assertCloseCode(code: number): void;
35
52
  /**
36
53
  * True when `message` (an `undici:client:sendHeaders` payload) is this session's own WebSocket
37
54
  * upgrade request. Matched by origin and path *and* required to carry `Sec-WebSocket-Key`
@@ -45,6 +62,7 @@ export declare function isUpgradeHeadFor(message: unknown, httpOrigin: string, p
45
62
  headers: string;
46
63
  socket?: TlsSocketLike & {
47
64
  encrypted?: boolean;
65
+ destroy?: () => void;
48
66
  };
49
67
  };
50
68
  export declare function openWsSession(options: WsSessionOptions, hooks?: WsSessionHooks): WsSessionHandle;