@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
@@ -1,6 +1,14 @@
1
1
  import { z } from 'zod';
2
+ import { GRPC_STATUS_NAMES } from './status-names.js';
3
+ import { CALLBACK_LIMITS } from './model.js';
2
4
  const name = z.string().min(1).optional();
3
- const statusValue = z.union([z.number().int().min(100).max(599), z.string().regex(/^[1-5]xx$/)]);
5
+ const grpcStatusNames = Object.values(GRPC_STATUS_NAMES);
6
+ const statusValue = z.union([
7
+ z.number().int().min(100).max(599),
8
+ z.number().int().min(0).max(16),
9
+ z.string().regex(/^[1-5]xx$/),
10
+ z.enum(grpcStatusNames),
11
+ ]);
4
12
  const statusSchema = z.looseObject({
5
13
  type: z.literal('status'),
6
14
  equals: z.union([statusValue, z.array(statusValue).min(1)]),
@@ -23,24 +31,158 @@ const matchSchema = z.looseObject({
23
31
  });
24
32
  const schemaSchema = z.looseObject({ type: z.literal('schema'), name });
25
33
  const slaSchema = z.looseObject({ type: z.literal('sla'), maxMs: z.number().int().positive(), name });
26
- const assertionSchema = z
27
- .discriminatedUnion('type', [statusSchema, soapFaultSchema, matchSchema, schemaSchema, slaSchema])
28
- .superRefine((value, ctx) => {
29
- if (value.type !== 'match') {
30
- return;
34
+ const headerSchema = z.looseObject({
35
+ type: z.literal('header'),
36
+ header: z.string().min(1),
37
+ equals: z.string().optional(),
38
+ matches: z.string().optional(),
39
+ exists: z.boolean().optional(),
40
+ name,
41
+ });
42
+ function compiles(pattern, path, ctx) {
43
+ try {
44
+ // Compiling is linear in the pattern's length; only matching can run away, and that happens on
45
+ // the evaluation worker (`matchRegexWithTimeout`).
46
+ new RegExp(pattern);
31
47
  }
48
+ catch {
49
+ ctx.addIssue({ code: 'custom', path: [...path], message: 'not a valid regular expression' });
50
+ }
51
+ }
52
+ /** Exactly one of `equals`, `matches` or `exists`, and a `matches:` that compiles. */
53
+ function refineOneCheck(value, ctx) {
32
54
  const given = [value.equals, value.matches, value.exists].filter((v) => v !== undefined).length;
33
55
  if (given !== 1) {
34
56
  ctx.addIssue({ code: 'custom', message: 'exactly one of equals, matches or exists is required' });
35
57
  }
36
58
  if (value.matches !== undefined) {
37
- try {
38
- new RegExp(value.matches);
39
- }
40
- catch {
41
- ctx.addIssue({ code: 'custom', path: ['matches'], message: 'not a valid regular expression' });
42
- }
59
+ compiles(value.matches, ['matches'], ctx);
60
+ }
61
+ }
62
+ /** A `match` or `header` assertion names exactly one check, and a `matches:` must compile. */
63
+ function refineCheck(value, ctx) {
64
+ if (value.type === 'match' || value.type === 'header') {
65
+ refineOneCheck(value, ctx);
66
+ }
67
+ }
68
+ const oneCheck = {
69
+ equals: z.string().optional(),
70
+ matches: z.string().optional(),
71
+ exists: z.boolean().optional(),
72
+ };
73
+ const callbackHeaderSchema = z.looseObject({ name: z.string().min(1), ...oneCheck }).superRefine(refineOneCheck);
74
+ const callbackBodySchema = z
75
+ .looseObject({ language: z.enum(['jsonpath', 'xpath']), path: z.string().min(1), ...oneCheck })
76
+ .superRefine(refineOneCheck);
77
+ const callbackMatchSchema = z
78
+ .looseObject({
79
+ method: z.string().min(1).optional(),
80
+ path: z.string().startsWith('/').optional(),
81
+ pathMatches: z.string().min(1).optional(),
82
+ headers: z.array(callbackHeaderSchema).max(CALLBACK_LIMITS.maxHeaderChecks).optional(),
83
+ body: callbackBodySchema.optional(),
84
+ })
85
+ .superRefine((value, ctx) => {
86
+ if (value.path !== undefined && value.pathMatches !== undefined) {
87
+ ctx.addIssue({ code: 'custom', message: 'at most one of path and pathMatches' });
88
+ }
89
+ if (value.pathMatches !== undefined) {
90
+ compiles(value.pathMatches, ['pathMatches'], ctx);
91
+ }
92
+ });
93
+ const callbackCheckSchema = z
94
+ .looseObject({
95
+ body: callbackBodySchema.optional(),
96
+ header: callbackHeaderSchema.optional(),
97
+ signature: z.literal('verified').optional(),
98
+ })
99
+ .superRefine((value, ctx) => {
100
+ const given = [value.body, value.header, value.signature].filter((v) => v !== undefined).length;
101
+ if (given !== 1) {
102
+ ctx.addIssue({ code: 'custom', message: 'each expect entry is exactly one of body, header or signature' });
43
103
  }
44
104
  });
105
+ /** `type: callback` (spec §2.1): the same shape on a request file and on a sequence step. */
106
+ export const callbackAssertionSchema = z.looseObject({
107
+ type: z.literal('callback'),
108
+ catchUrl: z.string().min(1).max(CALLBACK_LIMITS.maxCatchUrlLength),
109
+ withinMs: z
110
+ .number()
111
+ .int()
112
+ .min(CALLBACK_LIMITS.minWithinMs)
113
+ .max(CALLBACK_LIMITS.maxWithinMs)
114
+ .default(CALLBACK_LIMITS.defaultWithinMs),
115
+ match: callbackMatchSchema.default({}),
116
+ expect: z.array(callbackCheckSchema).max(CALLBACK_LIMITS.maxExpectChecks).default([]),
117
+ name,
118
+ });
119
+ function checkOf(raw) {
120
+ return {
121
+ ...(raw.equals !== undefined ? { equals: raw.equals } : {}),
122
+ ...(raw.matches !== undefined ? { matches: raw.matches } : {}),
123
+ ...(raw.exists !== undefined ? { exists: raw.exists } : {}),
124
+ };
125
+ }
126
+ const toHeader = (raw) => ({
127
+ name: raw.name,
128
+ ...checkOf(raw),
129
+ });
130
+ const toBody = (raw) => ({
131
+ language: raw.language,
132
+ path: raw.path,
133
+ ...checkOf(raw),
134
+ });
135
+ function toCheck(check) {
136
+ if ('body' in check && check.body !== undefined)
137
+ return { body: toBody(check.body) };
138
+ if ('header' in check && check.header !== undefined)
139
+ return { header: toHeader(check.header) };
140
+ return { signature: 'verified' };
141
+ }
142
+ /**
143
+ * Only the fields a callback assertion defines, at every level. `looseObject` keeps unknown keys on
144
+ * the parsed value; dropping them here keeps them from being written back.
145
+ */
146
+ export function toCallbackAssertion(raw) {
147
+ const match = raw.match;
148
+ return {
149
+ type: 'callback',
150
+ catchUrl: raw.catchUrl,
151
+ withinMs: raw.withinMs,
152
+ match: {
153
+ ...(match.method !== undefined ? { method: match.method } : {}),
154
+ ...(match.path !== undefined ? { path: match.path } : {}),
155
+ ...(match.pathMatches !== undefined ? { pathMatches: match.pathMatches } : {}),
156
+ ...(match.headers !== undefined ? { headers: match.headers.map(toHeader) } : {}),
157
+ ...(match.body !== undefined ? { body: toBody(match.body) } : {}),
158
+ },
159
+ expect: raw.expect.map(toCheck),
160
+ ...(raw.name !== undefined ? { name: raw.name } : {}),
161
+ };
162
+ }
163
+ const assertionSchema = z
164
+ .discriminatedUnion('type', [
165
+ statusSchema,
166
+ soapFaultSchema,
167
+ matchSchema,
168
+ schemaSchema,
169
+ slaSchema,
170
+ callbackAssertionSchema,
171
+ ])
172
+ .superRefine(refineCheck);
45
173
  /** The `assertions:` list of a request file. `looseObject` like every project schema; see `project/schema.ts`. */
46
174
  export const assertionsSchema = z.array(assertionSchema);
175
+ /**
176
+ * The `assertions:` list of a sequence step: the request catalogue plus `header`.
177
+ */
178
+ export const stepAssertionsSchema = z.array(z
179
+ .discriminatedUnion('type', [
180
+ statusSchema,
181
+ soapFaultSchema,
182
+ matchSchema,
183
+ schemaSchema,
184
+ slaSchema,
185
+ headerSchema,
186
+ callbackAssertionSchema,
187
+ ])
188
+ .superRefine(refineCheck));
@@ -0,0 +1,9 @@
1
+ /**
2
+ * The status names a request file's `status` assertion may be written with.
3
+ *
4
+ * In `assert/` because the assertion file schema (`schema.ts`) lists them, and core imports no
5
+ * protocol folder (protocol modules spec §7.2). They are gRPC's; `grpc/status.ts` re-exports the
6
+ * table and keeps everything else about a status.
7
+ */
8
+ /** The seventeen status codes. `0` is the only success. */
9
+ export declare const GRPC_STATUS_NAMES: Readonly<Record<number, string>>;
@@ -0,0 +1,27 @@
1
+ /**
2
+ * The status names a request file's `status` assertion may be written with.
3
+ *
4
+ * In `assert/` because the assertion file schema (`schema.ts`) lists them, and core imports no
5
+ * protocol folder (protocol modules spec §7.2). They are gRPC's; `grpc/status.ts` re-exports the
6
+ * table and keeps everything else about a status.
7
+ */
8
+ /** The seventeen status codes. `0` is the only success. */
9
+ export const GRPC_STATUS_NAMES = Object.freeze({
10
+ 0: 'OK',
11
+ 1: 'CANCELLED',
12
+ 2: 'UNKNOWN',
13
+ 3: 'INVALID_ARGUMENT',
14
+ 4: 'DEADLINE_EXCEEDED',
15
+ 5: 'NOT_FOUND',
16
+ 6: 'ALREADY_EXISTS',
17
+ 7: 'PERMISSION_DENIED',
18
+ 8: 'RESOURCE_EXHAUSTED',
19
+ 9: 'FAILED_PRECONDITION',
20
+ 10: 'ABORTED',
21
+ 11: 'OUT_OF_RANGE',
22
+ 12: 'UNIMPLEMENTED',
23
+ 13: 'INTERNAL',
24
+ 14: 'UNAVAILABLE',
25
+ 15: 'DATA_LOSS',
26
+ 16: 'UNAUTHENTICATED',
27
+ });
@@ -1,3 +1,6 @@
1
1
  import type { AssertionResult, AssertionSubject, StatusAssertion } from './model.js';
2
- /** Checks the response status code against one or more expected values or `Nxx` classes. */
2
+ /**
3
+ * Checks the response status against one or more expected values. A subject that carries
4
+ * `statusNames` is compared by exact code or by name; any other by HTTP code or `Nxx` class.
5
+ */
3
6
  export declare function evaluateStatus(subject: AssertionSubject, assertion: StatusAssertion): AssertionResult;
@@ -1,14 +1,38 @@
1
- function holds(expected, status) {
1
+ /** The shape of a status name (`NOT_FOUND`), as opposed to an `Nxx` class. */
2
+ const STATUS_NAME = /^[A-Z][A-Z_]*$/;
3
+ function holdsHttp(expected, status) {
2
4
  return typeof expected === 'number' ? expected === status : Number(expected[0]) === Math.floor(status / 100);
3
5
  }
4
- /** Checks the response status code against one or more expected values or `Nxx` classes. */
6
+ /**
7
+ * Checks the response status against one or more expected values. A subject that carries
8
+ * `statusNames` is compared by exact code or by name; any other by HTTP code or `Nxx` class.
9
+ */
5
10
  export function evaluateStatus(subject, assertion) {
6
11
  const expected = typeof assertion.equals === 'number' || typeof assertion.equals === 'string'
7
12
  ? [assertion.equals]
8
13
  : assertion.equals;
9
14
  const text = expected.join(' or ');
10
15
  const base = { type: 'status', label: assertion.name ?? `status is ${text}` };
11
- return expected.some((value) => holds(value, subject.status))
16
+ const names = subject.statusNames;
17
+ if (names !== undefined) {
18
+ const unknownName = expected.find((value) => typeof value === 'string' && !names.byName.has(value));
19
+ if (unknownName !== undefined) {
20
+ return { ...base, outcome: 'errored', message: `${String(unknownName)} is not a gRPC status name` };
21
+ }
22
+ const matched = expected.some((value) => typeof value === 'number' ? value === subject.status : names.byName.get(value) === subject.status);
23
+ return matched
24
+ ? { ...base, outcome: 'passed' }
25
+ : { ...base, outcome: 'failed', expected: text, actual: names.nameOf(subject.status) };
26
+ }
27
+ const statusName = expected.find((value) => typeof value === 'string' && STATUS_NAME.test(value));
28
+ if (statusName !== undefined) {
29
+ return { ...base, outcome: 'errored', message: `${String(statusName)} is a gRPC status name, not an HTTP one` };
30
+ }
31
+ const notHttp = expected.find((value) => typeof value === 'number' && value < 100);
32
+ if (notHttp !== undefined) {
33
+ return { ...base, outcome: 'errored', message: `${String(notHttp)} is not an HTTP status` };
34
+ }
35
+ return expected.some((value) => holdsHttp(value, subject.status))
12
36
  ? { ...base, outcome: 'passed' }
13
37
  : { ...base, outcome: 'failed', expected: text, actual: String(subject.status) };
14
38
  }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The browser-safe face of `asyncapi/`: the model's types, with no Node dependency, reachable from
3
+ * the renderer as `@wirebench/engine/asyncapi`. Parsing stays engine-side, because the reference
4
+ * policy it resolves under reads the file system.
5
+ */
6
+ export type { AsyncApiChannel, AsyncApiChannelParameter, AsyncApiDocument, AsyncApiMessage, AsyncApiOperation, AsyncApiSecurityScheme, AsyncApiServer, AsyncApiSkip, AsyncApiVersion, } from './model.js';
7
+ export type { AsyncApiImportSummary } from './map.js';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * The browser-safe face of `asyncapi/`: the model's types, with no Node dependency, reachable from
3
+ * the renderer as `@wirebench/engine/asyncapi`. Parsing stays engine-side, because the reference
4
+ * policy it resolves under reads the file system.
5
+ */
6
+ export {};
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Live frame checking off the calling thread.
3
+ *
4
+ * {@link checkFrame} is synchronous and a contract's `pattern` is untrusted: its own time budget
5
+ * stops a check between messages, but one regex call that runs away cannot be interrupted from the
6
+ * thread it runs on. So the checks run in a `worker_threads` Worker, one frame at a time, each under
7
+ * a hard deadline: a worker that has not answered by then is terminated, the frame is reported
8
+ * `not-checked`, and a fresh worker is started for the next frame. The caller's thread (Electron's
9
+ * main process) never runs a check itself.
10
+ */
11
+ import type { WsFrame, WsFrameContract } from '../ws/model.js';
12
+ import { type ChannelMessages } from './frame-check.js';
13
+ /** How long one frame's check may take, worker round trip included, before the worker is replaced. */
14
+ export declare const DEFAULT_FRAME_CHECK_DEADLINE_MS = 1000;
15
+ /** How many frames may wait behind the one being checked before new ones are not checked at all. */
16
+ export declare const DEFAULT_FRAME_CHECK_QUEUE = 1000;
17
+ /** Payload bytes that may wait to be checked; a frame that would pass it is not checked at all. */
18
+ export declare const DEFAULT_FRAME_CHECK_QUEUE_BYTES: number;
19
+ export interface WorkerFrameCheckerOptions {
20
+ /** Milliseconds one frame's check may take before the worker is terminated and replaced. */
21
+ readonly deadlineMs?: number;
22
+ /** The in-check budget passed to {@link checkFrame}; below the deadline, it ends a slow check cleanly. */
23
+ readonly budgetMs?: number;
24
+ /** Frames that may wait behind the one being checked. */
25
+ readonly maxQueued?: number;
26
+ /** Payload bytes that may wait behind the frame being checked. */
27
+ readonly maxQueuedBytes?: number;
28
+ /** The worker script; tests substitute one. Defaults to the compiled `frame-check-worker.js`. */
29
+ readonly workerUrl?: URL;
30
+ }
31
+ export interface WorkerFrameChecker {
32
+ /**
33
+ * The frame's contract result. `undefined` for a frame no contract speaks to (binary, control)
34
+ * and for any frame after {@link dispose}. Never rejects.
35
+ */
36
+ check(frame: WsFrame): Promise<WsFrameContract | undefined>;
37
+ /** Terminates the worker; a check still waiting resolves `not-checked`. */
38
+ dispose(): Promise<void>;
39
+ /** Workers started so far (a replaced one counts again). */
40
+ readonly spawned: number;
41
+ /** Whether a worker is currently alive. */
42
+ readonly running: boolean;
43
+ }
44
+ export declare function createWorkerFrameChecker(messages: ChannelMessages, options?: WorkerFrameCheckerOptions): WorkerFrameChecker;
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Live frame checking off the calling thread.
3
+ *
4
+ * {@link checkFrame} is synchronous and a contract's `pattern` is untrusted: its own time budget
5
+ * stops a check between messages, but one regex call that runs away cannot be interrupted from the
6
+ * thread it runs on. So the checks run in a `worker_threads` Worker, one frame at a time, each under
7
+ * a hard deadline: a worker that has not answered by then is terminated, the frame is reported
8
+ * `not-checked`, and a fresh worker is started for the next frame. The caller's thread (Electron's
9
+ * main process) never runs a check itself.
10
+ */
11
+ import { existsSync } from 'node:fs';
12
+ import { fileURLToPath } from 'node:url';
13
+ import { Worker } from 'node:worker_threads';
14
+ import { MAX_CHECKED_FRAME_BYTES } from './frame-check.js';
15
+ /** How long one frame's check may take, worker round trip included, before the worker is replaced. */
16
+ export const DEFAULT_FRAME_CHECK_DEADLINE_MS = 1_000;
17
+ /** How many frames may wait behind the one being checked before new ones are not checked at all. */
18
+ export const DEFAULT_FRAME_CHECK_QUEUE = 1_000;
19
+ /** Payload bytes that may wait to be checked; a frame that would pass it is not checked at all. */
20
+ export const DEFAULT_FRAME_CHECK_QUEUE_BYTES = 8 * 1024 * 1024;
21
+ /**
22
+ * The compiled worker script: the sibling `.js` when running from `dist`, else — running from `src`
23
+ * under vitest — the package's `dist/asyncapi/frame-check-worker.js`, as `xpath/evaluate-async.ts`
24
+ * resolves its own worker.
25
+ */
26
+ function defaultWorkerUrl() {
27
+ const sibling = new URL('./frame-check-worker.js', import.meta.url);
28
+ if (existsSync(fileURLToPath(sibling))) {
29
+ return sibling;
30
+ }
31
+ const fallback = import.meta.url.replace(/\/src\/asyncapi\/frame-check-worker-host\.ts$/, '/dist/asyncapi/frame-check-worker.js');
32
+ /* v8 ignore next 3 -- only reachable when the engine package has never been built */
33
+ if (fallback === import.meta.url) {
34
+ throw new Error('frame-check worker not found: build the engine package first');
35
+ }
36
+ return new URL(fallback);
37
+ }
38
+ const notChecked = (reason) => ({ status: 'not-checked', reason });
39
+ export function createWorkerFrameChecker(messages, options = {}) {
40
+ const deadlineMs = options.deadlineMs ?? DEFAULT_FRAME_CHECK_DEADLINE_MS;
41
+ const maxQueued = options.maxQueued ?? DEFAULT_FRAME_CHECK_QUEUE;
42
+ const maxQueuedBytes = options.maxQueuedBytes ?? DEFAULT_FRAME_CHECK_QUEUE_BYTES;
43
+ let queuedBytes = 0;
44
+ const data = {
45
+ messages,
46
+ ...(options.budgetMs !== undefined ? { budgetMs: options.budgetMs } : {}),
47
+ };
48
+ let url = options.workerUrl;
49
+ let worker;
50
+ let spawned = 0;
51
+ let disposed = false;
52
+ let nextId = 0;
53
+ let current;
54
+ let timer;
55
+ const queue = [];
56
+ const finish = (contract) => {
57
+ const job = current;
58
+ if (job === undefined)
59
+ return;
60
+ current = undefined;
61
+ if (timer !== undefined)
62
+ clearTimeout(timer);
63
+ timer = undefined;
64
+ job.resolve(contract);
65
+ pump();
66
+ };
67
+ /** Drops the current worker without waiting for it; its late answer or exit is then ignored. */
68
+ const discard = () => {
69
+ const dead = worker;
70
+ worker = undefined;
71
+ if (dead !== undefined) {
72
+ dead.removeAllListeners();
73
+ // An 'error' after the listeners are gone would otherwise be an uncaught exception.
74
+ dead.on('error', () => undefined);
75
+ void dead.terminate();
76
+ }
77
+ };
78
+ const spawn = () => {
79
+ url ??= defaultWorkerUrl();
80
+ const next = new Worker(url, { workerData: data });
81
+ spawned += 1;
82
+ // A session's checker must never be what keeps the process alive.
83
+ next.unref();
84
+ next.on('message', (answer) => {
85
+ if (current?.id === answer.id)
86
+ finish(answer.contract ?? undefined);
87
+ });
88
+ const failed = (why) => {
89
+ if (worker !== next)
90
+ return;
91
+ discard();
92
+ finish(notChecked(why));
93
+ };
94
+ next.on('error', (error) => {
95
+ failed(`the check failed: ${error instanceof Error ? error.message : String(error)}`);
96
+ });
97
+ next.on('exit', () => {
98
+ failed('the check stopped unexpectedly');
99
+ });
100
+ return next;
101
+ };
102
+ function pump() {
103
+ if (current !== undefined || disposed)
104
+ return;
105
+ const job = queue.shift();
106
+ if (job === undefined)
107
+ return;
108
+ queuedBytes -= job.frame.size;
109
+ current = job;
110
+ try {
111
+ worker ??= spawn();
112
+ worker.postMessage({ id: job.id, frame: job.frame });
113
+ }
114
+ catch (error) {
115
+ discard();
116
+ finish(notChecked(`the check could not start: ${error instanceof Error ? error.message : String(error)}`));
117
+ return;
118
+ }
119
+ // The deadline starts when this frame reaches the worker, not when it was queued, so one stuck
120
+ // frame never costs the frames behind it their check.
121
+ timer = setTimeout(() => {
122
+ discard();
123
+ finish(notChecked(`the check took longer than ${String(deadlineMs)} ms`));
124
+ }, deadlineMs);
125
+ timer.unref?.();
126
+ }
127
+ return {
128
+ check(frame) {
129
+ if (disposed || frame.opcode !== 'text' || frame.text === undefined)
130
+ return Promise.resolve(undefined);
131
+ // Answered here, as the worker would: a frame this large is never walked, so it must not wait
132
+ // behind others or count against the queued-bytes bound.
133
+ if (frame.size > MAX_CHECKED_FRAME_BYTES) {
134
+ return Promise.resolve({ status: 'skipped', reason: 'frame too large to check' });
135
+ }
136
+ if (queue.length >= maxQueued)
137
+ return Promise.resolve(notChecked('too many frames waiting to be checked'));
138
+ if (queue.length > 0 && queuedBytes + frame.size > maxQueuedBytes) {
139
+ return Promise.resolve(notChecked('too much data waiting to be checked'));
140
+ }
141
+ return new Promise((resolve) => {
142
+ nextId += 1;
143
+ queue.push({ id: nextId, frame, resolve });
144
+ queuedBytes += frame.size;
145
+ pump();
146
+ });
147
+ },
148
+ async dispose() {
149
+ if (disposed)
150
+ return;
151
+ disposed = true;
152
+ const dead = worker;
153
+ worker = undefined;
154
+ if (timer !== undefined)
155
+ clearTimeout(timer);
156
+ timer = undefined;
157
+ const waiting = [...(current !== undefined ? [current] : []), ...queue.splice(0)];
158
+ queuedBytes = 0;
159
+ current = undefined;
160
+ for (const job of waiting)
161
+ job.resolve(notChecked('the session ended'));
162
+ if (dead !== undefined) {
163
+ dead.removeAllListeners();
164
+ dead.on('error', () => undefined);
165
+ await dead.terminate();
166
+ }
167
+ },
168
+ get spawned() {
169
+ return spawned;
170
+ },
171
+ get running() {
172
+ return worker !== undefined;
173
+ },
174
+ };
175
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Entry point run inside a `node:worker_threads` Worker by {@link createWorkerFrameChecker}. Its
3
+ * `workerData` is the channel's messages and the in-check time budget; each message in is one frame
4
+ * (`{ id, frame }`) and each message out its result (`{ id, contract }`, `null` for a frame no
5
+ * contract speaks to). Frames are checked one at a time, in the order they arrive.
6
+ */
7
+ import { type ChannelMessages } from './frame-check.js';
8
+ /** What the host passes as `workerData`. */
9
+ export interface FrameCheckWorkerData {
10
+ readonly messages: ChannelMessages;
11
+ readonly budgetMs?: number;
12
+ }
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Entry point run inside a `node:worker_threads` Worker by {@link createWorkerFrameChecker}. Its
3
+ * `workerData` is the channel's messages and the in-check time budget; each message in is one frame
4
+ * (`{ id, frame }`) and each message out its result (`{ id, contract }`, `null` for a frame no
5
+ * contract speaks to). Frames are checked one at a time, in the order they arrive.
6
+ */
7
+ import { parentPort, workerData } from 'node:worker_threads';
8
+ import { checkFrame } from './frame-check.js';
9
+ /* v8 ignore start -- runs only inside a real worker thread; covered end to end by
10
+ frame-check-worker.test.ts, which coverage instrumentation does not follow across the thread. */
11
+ if (parentPort !== null) {
12
+ const port = parentPort;
13
+ const data = workerData;
14
+ port.on('message', ({ id, frame }) => {
15
+ let contract;
16
+ try {
17
+ contract = checkFrame(frame, data.messages[frame.direction], data.budgetMs !== undefined ? { budgetMs: data.budgetMs } : {});
18
+ }
19
+ catch (error) {
20
+ contract = { status: 'not-checked', reason: error instanceof Error ? error.message : String(error) };
21
+ }
22
+ port.postMessage({ id, contract: contract ?? null });
23
+ });
24
+ }
25
+ /* v8 ignore stop */
@@ -0,0 +1,25 @@
1
+ import type { WsFrame, WsFrameContract } from '../ws/model.js';
2
+ import type { AsyncApiDocument, AsyncApiMessage } from './model.js';
3
+ /** A text frame bigger than this is not parsed or validated: it is reported `skipped`. */
4
+ export declare const MAX_CHECKED_FRAME_BYTES = 262144;
5
+ /** The default time one frame's check may take before it gives up as `not-checked`. */
6
+ export declare const DEFAULT_FRAME_CHECK_BUDGET_MS = 50;
7
+ export type FrameChecker = (frame: WsFrame) => WsFrameContract | undefined;
8
+ export interface FrameCheckOptions {
9
+ /** Milliseconds one frame's check may take; past it the result is `not-checked`. */
10
+ readonly budgetMs?: number;
11
+ /** The clock, injectable for tests; defaults to `performance.now`. */
12
+ readonly now?: () => number;
13
+ }
14
+ /** The messages a channel declares for each of Wirebench's directions — plain data, serialisable. */
15
+ export interface ChannelMessages {
16
+ readonly sent: readonly AsyncApiMessage[];
17
+ readonly received: readonly AsyncApiMessage[];
18
+ }
19
+ export declare function channelMessages(document: AsyncApiDocument, channel: string): ChannelMessages;
20
+ export declare function createFrameChecker(document: AsyncApiDocument, channel: string, options?: FrameCheckOptions): FrameChecker;
21
+ /**
22
+ * Checks one frame against `messages` (the ones declared for the frame's direction). Returns
23
+ * `undefined` for a frame no contract speaks to (binary and control frames).
24
+ */
25
+ export declare function checkFrame(frame: WsFrame, messages: readonly AsyncApiMessage[], options?: FrameCheckOptions): WsFrameContract | undefined;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Checks each live WebSocket frame against the messages its channel's contract declares for that
3
+ * direction.
4
+ *
5
+ * Everything here is pure and synchronous, and {@link checkFrame} takes and returns plain data, so a
6
+ * caller can run it in a worker. That matters because a contract's `pattern` is untrusted: the
7
+ * validator refuses the regex shapes known to backtrack badly, but that scan is a heuristic, and a
8
+ * single regex call cannot be interrupted from the same thread. The time budget here stops the
9
+ * check between messages and reports `not-checked` — neither a pass nor a failure — and the worker
10
+ * is what bounds a single call that runs away.
11
+ */
12
+ import { validateJsonSchema } from '../json/schema-validate.js';
13
+ /** A text frame bigger than this is not parsed or validated: it is reported `skipped`. */
14
+ export const MAX_CHECKED_FRAME_BYTES = 262_144;
15
+ /** The default time one frame's check may take before it gives up as `not-checked`. */
16
+ export const DEFAULT_FRAME_CHECK_BUDGET_MS = 50;
17
+ export function channelMessages(document, channel) {
18
+ const pick = (direction) => document.operations.filter((o) => o.channel === channel && o.direction === direction).flatMap((o) => o.messages);
19
+ return { sent: pick('sent'), received: pick('received') };
20
+ }
21
+ export function createFrameChecker(document, channel, options) {
22
+ const messages = channelMessages(document, channel);
23
+ return (frame) => checkFrame(frame, messages[frame.direction], options);
24
+ }
25
+ function isJsonContentType(contentType) {
26
+ const base = contentType.split(';')[0].trim().toLowerCase();
27
+ return base === '' || base === 'application/json' || base.endsWith('+json') || base === 'text/json';
28
+ }
29
+ /**
30
+ * Checks one frame against `messages` (the ones declared for the frame's direction). Returns
31
+ * `undefined` for a frame no contract speaks to (binary and control frames).
32
+ */
33
+ export function checkFrame(frame, messages, options) {
34
+ if (frame.opcode !== 'text' || frame.text === undefined)
35
+ return undefined;
36
+ if (frame.size > MAX_CHECKED_FRAME_BYTES)
37
+ return { status: 'skipped', reason: 'frame too large to check' };
38
+ if (messages.length === 0)
39
+ return { status: 'unmatched', reason: `no ${frame.direction} messages in the contract` };
40
+ const json = messages.filter((m) => isJsonContentType(m.contentType));
41
+ if (json.length === 0)
42
+ return { status: 'skipped', reason: 'no JSON message to check against' };
43
+ let value;
44
+ try {
45
+ value = JSON.parse(frame.text);
46
+ }
47
+ catch {
48
+ return { status: 'violation', message: json[0].name, reason: 'not JSON' };
49
+ }
50
+ const now = options?.now ?? (() => performance.now());
51
+ const budgetMs = options?.budgetMs ?? DEFAULT_FRAME_CHECK_BUDGET_MS;
52
+ const start = now();
53
+ let closest;
54
+ // A message whose check stopped on the node or depth cap with nothing wrong found so far: the
55
+ // frame may well be that message, so it is neither the closest violation nor a match.
56
+ let undecided;
57
+ for (const message of json) {
58
+ if (now() - start > budgetMs)
59
+ return { status: 'not-checked', reason: 'time budget exceeded' };
60
+ const problems = message.payload === undefined ? [] : validateJsonSchema(value, message.payload);
61
+ if (problems.length > 0 && problems.every((p) => p.keyword === 'budget')) {
62
+ undecided ??= problems[0].message;
63
+ continue;
64
+ }
65
+ if (problems.length === 0) {
66
+ if (now() - start > budgetMs)
67
+ return { status: 'not-checked', reason: 'time budget exceeded' };
68
+ return { status: 'ok', message: message.name };
69
+ }
70
+ if (closest === undefined || problems.length < closest.problems.length)
71
+ closest = { name: message.name, problems };
72
+ }
73
+ if (now() - start > budgetMs)
74
+ return { status: 'not-checked', reason: 'time budget exceeded' };
75
+ if (undecided !== undefined)
76
+ return { status: 'not-checked', reason: undecided };
77
+ return { status: 'violation', message: closest.name, problems: closest.problems };
78
+ }