@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
@@ -13,14 +13,30 @@ export function containsRedaction(text) {
13
13
  }
14
14
  /** Header names (case-insensitive) whose value is always masked. */
15
15
  const SENSITIVE_HEADERS = new Set(['authorization', 'proxy-authorization', 'cookie', 'set-cookie', 'x-api-key']);
16
- /** Masks the values of sensitive headers in a plain header map, case-insensitively. */
16
+ /** True when a header named `name` (any case) always carries a credential; see {@link redactHeaders}. */
17
+ export function isSensitiveHeaderName(name) {
18
+ return SENSITIVE_HEADERS.has(name.toLowerCase());
19
+ }
20
+ /**
21
+ * The test every header redactor applies: a well-known credential header, or one of `extraHeaders`
22
+ * — the name an API key was configured under, which may be anything (`Ocp-Apim-Subscription-Key`).
23
+ * Both compared case-insensitively.
24
+ */
25
+ function headerIsMasked(name, extraHeaders) {
26
+ const lower = name.toLowerCase();
27
+ return SENSITIVE_HEADERS.has(lower) || (extraHeaders?.some((extra) => extra.toLowerCase() === lower) ?? false);
28
+ }
29
+ /**
30
+ * Masks the values of sensitive headers in a plain header map, case-insensitively. `extraHeaders`
31
+ * names more headers to mask, as `redactUrl`'s `extraParams` does for query parameters.
32
+ */
17
33
  export function redactHeaders(headers, opts) {
18
34
  if (opts?.show) {
19
35
  return { ...headers };
20
36
  }
21
37
  const result = {};
22
38
  for (const [name, value] of Object.entries(headers)) {
23
- result[name] = SENSITIVE_HEADERS.has(name.toLowerCase()) ? REDACTED : value;
39
+ result[name] = headerIsMasked(name, opts?.extraHeaders) ? REDACTED : value;
24
40
  }
25
41
  return result;
26
42
  }
@@ -31,7 +47,7 @@ export function redactHeaders(headers, opts) {
31
47
  */
32
48
  export function redactHeaderPairs(pairs, opts) {
33
49
  const show = opts?.show ?? false;
34
- return pairs.map(([name, value]) => [name, !show && SENSITIVE_HEADERS.has(name.toLowerCase()) ? REDACTED : value]);
50
+ return pairs.map(([name, value]) => [name, !show && headerIsMasked(name, opts?.extraHeaders) ? REDACTED : value]);
35
51
  }
36
52
  /**
37
53
  * Query-parameter names (case-insensitive) whose value is masked wherever a URL is logged, stored
@@ -50,6 +66,10 @@ const SENSITIVE_QUERY_PARAMS = new Set([
50
66
  'signature',
51
67
  'sig',
52
68
  ]);
69
+ /** True when a query parameter named `name` (any case) carries a credential; see {@link redactUrl}. */
70
+ export function isSensitiveQueryParam(name) {
71
+ return SENSITIVE_QUERY_PARAMS.has(name.toLowerCase());
72
+ }
53
73
  /**
54
74
  * Masks the value of every sensitive query parameter in `url`, plus any parameter named in
55
75
  * `extraParams` — which is how the send path masks the exact parameter an API key is configured to
@@ -86,6 +106,31 @@ export function redactUrl(url, opts) {
86
106
  // untouched URL is returned as it came in rather than as the parser would have written it.
87
107
  return changed ? parsed.toString() : url;
88
108
  }
109
+ /**
110
+ * Masks the query of a raw request line (`GET /calc?key=secret HTTP/1.1`) by the same rules as
111
+ * {@link redactUrl}, `extraParams` included. The target is usually origin-form (a path), so it is
112
+ * parsed against a placeholder origin and the origin taken off again. Anything that is not a
113
+ * request line — a response's status line, a header — is returned unchanged.
114
+ */
115
+ function redactRequestLine(line, extraParams) {
116
+ // Split rather than matched with one pattern: `\S*\?\S*` backtracks polynomially on a line of `?`s.
117
+ const parts = line.split(' ');
118
+ if (parts.length !== 3) {
119
+ return line;
120
+ }
121
+ const [method = '', target = '', version = ''] = parts;
122
+ if (method === '' || !target.includes('?') || !/^HTTP\/\d(?:\.\d)?$/.test(version)) {
123
+ return line;
124
+ }
125
+ const originForm = target.startsWith('/');
126
+ const base = 'http://request-line.invalid';
127
+ const url = originForm ? `${base}${target}` : target;
128
+ const redacted = redactUrl(url, { extraParams: extraParams ?? [] });
129
+ if (redacted === url) {
130
+ return line;
131
+ }
132
+ return `${method} ${originForm ? redacted.slice(base.length) : redacted} ${version}`;
133
+ }
89
134
  /**
90
135
  * The redaction pass for a response's attachment list. Nothing in `{index, contentId,
91
136
  * contentType, size, name}` carries a secret today, so this is a copy — it exists as the one
@@ -235,13 +280,12 @@ export function redactStructuredBody(text, contentType, opts) {
235
280
  return text;
236
281
  }
237
282
  /** Masks a single raw `name: value` header line (no terminator), case-insensitively. */
238
- function redactHeaderLine(line) {
283
+ function redactHeaderLine(line, extraHeaders) {
239
284
  const idx = line.indexOf(':');
240
285
  if (idx < 0) {
241
286
  return line;
242
287
  }
243
- const name = line.slice(0, idx).trim().toLowerCase();
244
- if (!SENSITIVE_HEADERS.has(name)) {
288
+ if (!headerIsMasked(line.slice(0, idx).trim(), extraHeaders)) {
245
289
  return line;
246
290
  }
247
291
  return `${line.slice(0, idx + 1)} ${REDACTED}`;
@@ -305,7 +349,11 @@ export function redactRawHttp(input, opts) {
305
349
  // Split keeping the terminators so `\r\n` and `\n` mixes survive the round trip verbatim.
306
350
  const redactedHeaderBlock = headerBlock
307
351
  .split(/(\r\n|\n)/)
308
- .map((part, index) => (index % 2 === 0 ? redactHeaderLine(part) : part))
352
+ .map((part, index) => index === 0
353
+ ? redactRequestLine(part, opts?.extraParams)
354
+ : index % 2 === 0
355
+ ? redactHeaderLine(part, opts?.extraHeaders)
356
+ : part)
309
357
  .join('');
310
358
  // XML first (a `wsse:Password` element), then JSON and form bodies by key. A compressed body is
311
359
  // left alone: its bytes are not the text either pass reads.
@@ -8,5 +8,15 @@
8
8
  /**
9
9
  * Builds a function that replaces every occurrence of `values` — and the base64, percent-, form-,
10
10
  * XML- and JSON-escaped forms of each — with the redaction marker.
11
+ *
12
+ * Every match is found on the original text and overlapping or touching matches are merged before
13
+ * anything is replaced. Masking one needle first would hide the start of another that overlaps it
14
+ * (`token` inside a cut `token-abcdef-12…`), leaving the rest of that one in the output.
11
15
  */
12
16
  export declare function createSecretMasker(values: readonly string[]): (text: string) => string;
17
+ /**
18
+ * Builds the same masker over a base64 run of raw bytes: each value's UTF-8 bytes are masked
19
+ * wherever they sit, whatever the bytes around them are (a binary WebSocket frame carrying JSON,
20
+ * MessagePack or CBOR). A run with nothing to mask comes back as the same string, not a re-encoding.
21
+ */
22
+ export declare function createSecretBytesMasker(values: readonly string[]): (base64: string) => string;
@@ -36,6 +36,10 @@ function encodedForms(value) {
36
36
  /**
37
37
  * Builds a function that replaces every occurrence of `values` — and the base64, percent-, form-,
38
38
  * XML- and JSON-escaped forms of each — with the redaction marker.
39
+ *
40
+ * Every match is found on the original text and overlapping or touching matches are merged before
41
+ * anything is replaced. Masking one needle first would hide the start of another that overlaps it
42
+ * (`token` inside a cut `token-abcdef-12…`), leaving the rest of that one in the output.
39
43
  */
40
44
  export function createSecretMasker(values) {
41
45
  const plain = values.filter((value) => value.length >= MIN_MASKED_LENGTH);
@@ -49,20 +53,114 @@ export function createSecretMasker(values) {
49
53
  }
50
54
  }
51
55
  }
52
- // Longest first: a value that is a prefix of another must not leave the other's tail behind.
53
- const ordered = [...needles].sort((a, b) => b.length - a.length);
54
- return (text) => {
55
- let out = maskBasicCredentials(text, plain);
56
- for (const needle of ordered) {
57
- out = out.split(needle).join(REDACTED_MARKER);
56
+ return (text) => replaceRanges(text, [
57
+ ...basicCredentialRanges(text, plain),
58
+ ...needleRanges(text, needles),
59
+ ...cutPrefixRanges(text, needles),
60
+ ]);
61
+ }
62
+ /** Replaces each run of overlapping or touching ranges with one marker. */
63
+ function replaceRanges(text, ranges) {
64
+ if (ranges.length === 0) {
65
+ return text;
66
+ }
67
+ ranges.sort((a, b) => a.start - b.start);
68
+ let out = '';
69
+ let kept = 0;
70
+ let current = { ...ranges[0] };
71
+ for (const range of ranges.slice(1)) {
72
+ if (range.start <= current.end) {
73
+ current.end = Math.max(current.end, range.end);
58
74
  }
59
- return out;
60
- };
75
+ else {
76
+ out += text.slice(kept, current.start) + REDACTED_MARKER;
77
+ kept = current.end;
78
+ current = { ...range };
79
+ }
80
+ }
81
+ return out + text.slice(kept, current.start) + REDACTED_MARKER + text.slice(current.end);
82
+ }
83
+ /** Every occurrence of every needle, overlapping ones included. */
84
+ function needleRanges(text, needles) {
85
+ const ranges = [];
86
+ for (const needle of needles) {
87
+ for (let at = text.indexOf(needle); at !== -1; at = text.indexOf(needle, at + 1)) {
88
+ ranges.push({ start: at, end: at + needle.length });
89
+ }
90
+ }
91
+ return ranges;
92
+ }
93
+ /** The marker every report cap writes where it cut a value. */
94
+ const CUT_MARKER = '\u2026';
95
+ /**
96
+ * A report cap can cut a value inside a secret, so no whole needle is left to match. Finds the
97
+ * longest needle prefix that ends where a cut was made: just before each `…`, after stepping back
98
+ * over the `\n` of `\n… truncated` and any U+FFFD a byte cap left of a split character.
99
+ */
100
+ function cutPrefixRanges(text, needles) {
101
+ const ranges = [];
102
+ let start = 0;
103
+ for (let at = text.indexOf(CUT_MARKER); at !== -1; at = text.indexOf(CUT_MARKER, at + 1)) {
104
+ let end = at;
105
+ if (end > start && text[end - 1] === '\n') {
106
+ end -= 1;
107
+ }
108
+ while (end > start && text[end - 1] === '\uFFFD') {
109
+ end -= 1;
110
+ }
111
+ const length = cutTailLength(text.slice(start, end), needles);
112
+ if (length > 0) {
113
+ ranges.push({ start: end - length, end });
114
+ }
115
+ start = at + 1;
116
+ }
117
+ return ranges;
118
+ }
119
+ /** The length of the cut `Basic` base64 run, else of the longest proper needle prefix `head` ends with. */
120
+ function cutTailLength(head, needles) {
121
+ // Cut base64 cannot be decoded and checked, and it is a credential either way.
122
+ const basic = /\bBasic\s+([A-Za-z0-9+/=]+)$/.exec(head);
123
+ if (basic) {
124
+ return basic[1].length;
125
+ }
126
+ let longest = 0;
127
+ for (const needle of needles) {
128
+ for (let length = Math.min(needle.length - 1, head.length); length > longest; length -= 1) {
129
+ if (head.endsWith(needle.slice(0, length))) {
130
+ longest = length;
131
+ break;
132
+ }
133
+ }
134
+ }
135
+ return longest;
61
136
  }
62
137
  /** A Basic credential is base64 of `user:password`, so the password never appears literally. */
63
- function maskBasicCredentials(text, values) {
64
- return text.replace(/\bBasic\s+([A-Za-z0-9+/=]{8,})/g, (whole, encoded) => {
138
+ function basicCredentialRanges(text, values) {
139
+ const ranges = [];
140
+ for (const match of text.matchAll(/\bBasic\s+([A-Za-z0-9+/=]{8,})/g)) {
141
+ const encoded = match[1];
65
142
  const decoded = Buffer.from(encoded, 'base64').toString('utf8');
66
- return values.some((value) => decoded.includes(value)) ? `Basic ${REDACTED_MARKER}` : whole;
67
- });
143
+ if (values.some((value) => decoded.includes(value))) {
144
+ const end = match.index + match[0].length;
145
+ ranges.push({ start: end - encoded.length, end });
146
+ }
147
+ }
148
+ return ranges;
149
+ }
150
+ /**
151
+ * Builds the same masker over a base64 run of raw bytes: each value's UTF-8 bytes are masked
152
+ * wherever they sit, whatever the bytes around them are (a binary WebSocket frame carrying JSON,
153
+ * MessagePack or CBOR). A run with nothing to mask comes back as the same string, not a re-encoding.
154
+ */
155
+ export function createSecretBytesMasker(values) {
156
+ if (values.length === 0) {
157
+ return (base64) => base64;
158
+ }
159
+ // Read as latin1 so bytes that are not UTF-8 survive the round trip unchanged.
160
+ const mask = createSecretMasker(values.map((value) => Buffer.from(value, 'utf8').toString('latin1')));
161
+ return (base64) => {
162
+ const text = Buffer.from(base64, 'base64').toString('latin1');
163
+ const masked = mask(text);
164
+ return masked === text ? base64 : Buffer.from(masked, 'latin1').toString('base64');
165
+ };
68
166
  }
@@ -14,7 +14,7 @@ export type FileResolver = (source: AttachmentSource) => Promise<Uint8Array>;
14
14
  export interface EncodeBodyOptions {
15
15
  /** How a `multipart` or `binary` body's files are read. Required for those kinds only. */
16
16
  readonly resolveFile?: FileResolver;
17
- /** Charset for a raw or form body. Default `utf-8`; see `soap/charset.ts` for the labels. */
17
+ /** Charset for a raw or form body. Default `utf-8`; see `http/charset.ts` for the labels. */
18
18
  readonly charset?: string;
19
19
  /** Fixed multipart boundary; a random one is generated otherwise. Tests inject it. */
20
20
  readonly boundary?: string;
@@ -46,15 +46,7 @@ export declare function encodeFormFields(fields: readonly KeyValueEntry[]): stri
46
46
  * @throws WirebenchError `rest-file-unresolved` when a file part or binary body has no resolver
47
47
  */
48
48
  export declare function encodeRestBody(body: RestBody, options?: EncodeBodyOptions): Promise<EncodedBody>;
49
- /**
50
- * XML- or JSON-escapes a value being substituted into a body, for the *escape properties* setting.
51
- *
52
- * Only the characters that would otherwise change the document's structure are touched. A JSON
53
- * body gets JSON string escaping (without the surrounding quotes, since the value is substituted
54
- * inside them); an XML body gets the five predefined entities; anything else is left alone,
55
- * because there is no general escape for `text/plain`.
56
- */
57
- export declare function escapeForLanguage(value: string, language: RawLanguage | 'form'): string;
49
+ export { escapeForLanguage } from '../http/escape.js';
58
50
  /** The language a body's escaping follows, for {@link escapeForLanguage}. */
59
51
  export declare function bodyLanguage(body: RestBody): RawLanguage | 'form' | undefined;
60
52
  /** The media type of an encoded body, without its parameters; `undefined` when it has none. */
package/dist/rest/body.js CHANGED
@@ -8,8 +8,8 @@
8
8
  */
9
9
  import { randomBytes } from 'node:crypto';
10
10
  import { WirebenchError } from '../errors.js';
11
- import { encodeBody } from '../soap/charset.js';
12
- import { mediaTypeOf } from '../soap/mime/multipart.js';
11
+ import { encodeBody } from '../http/charset.js';
12
+ import { mediaTypeOf } from '../http/media-type.js';
13
13
  import { RAW_LANGUAGE_CONTENT_TYPES } from './model.js';
14
14
  const CRLF = '\r\n';
15
15
  /** A fresh multipart boundary: long, random, and unable to occur in base64 or text. */
@@ -143,29 +143,7 @@ export async function encodeRestBody(body, options = {}) {
143
143
  }
144
144
  }
145
145
  }
146
- /**
147
- * XML- or JSON-escapes a value being substituted into a body, for the *escape properties* setting.
148
- *
149
- * Only the characters that would otherwise change the document's structure are touched. A JSON
150
- * body gets JSON string escaping (without the surrounding quotes, since the value is substituted
151
- * inside them); an XML body gets the five predefined entities; anything else is left alone,
152
- * because there is no general escape for `text/plain`.
153
- */
154
- export function escapeForLanguage(value, language) {
155
- if (language === 'json') {
156
- const json = JSON.stringify(value);
157
- return json.slice(1, -1);
158
- }
159
- if (language === 'xml' || language === 'html') {
160
- return value
161
- .replace(/&/g, '&amp;')
162
- .replace(/</g, '&lt;')
163
- .replace(/>/g, '&gt;')
164
- .replace(/"/g, '&quot;')
165
- .replace(/'/g, '&apos;');
166
- }
167
- return value;
168
- }
146
+ export { escapeForLanguage } from '../http/escape.js';
169
147
  /** The language a body's escaping follows, for {@link escapeForLanguage}. */
170
148
  export function bodyLanguage(body) {
171
149
  switch (body.kind) {
@@ -10,3 +10,7 @@
10
10
  */
11
11
  export { composeUrl, encodeValue, joinBase, joinQuery, parseUrlParams, splitQuery, type ComposedUrl, type ComposeUrlOptions, type UrlProblem, } from './url.js';
12
12
  export type { KeyValueEntry } from './model.js';
13
+ export { SECRET_NAME_PATTERN } from '../secrets/secret-token.js';
14
+ export { createSseParser, eventStreamDocument, isEventStream, serializeEventStream, type SseParser, type SseRow, } from './sse.js';
15
+ export { applyJsonFormEdit, buildJsonForm, toWireSchema, type JsonFormEdit, type JsonFormKind, type JsonFormNode, type JsonFormOptions, type JsonFormValueType, } from './json-form.js';
16
+ export type { JsonSchema, JsonValue } from './openapi/model.js';
@@ -9,3 +9,8 @@
9
9
  * sets of escaping rules to keep in step.
10
10
  */
11
11
  export { composeUrl, encodeValue, joinBase, joinQuery, parseUrlParams, splitQuery, } from './url.js';
12
+ // The `${secret:name}` name rule, so the renderer's secret review checks a name typed into it
13
+ // exactly as main's move will — a request's headers, query and body are where those tokens land.
14
+ export { SECRET_NAME_PATTERN } from '../secrets/secret-token.js';
15
+ export { createSseParser, eventStreamDocument, isEventStream, serializeEventStream, } from './sse.js';
16
+ export { applyJsonFormEdit, buildJsonForm, toWireSchema, } from './json-form.js';
@@ -0,0 +1,36 @@
1
+ /**
2
+ * REST response checking off the calling thread.
3
+ *
4
+ * {@link checkRestResponse} is synchronous and a contract's `pattern` is untrusted: its own time
5
+ * budget stops a check between steps, but one regex call that runs away cannot be interrupted from
6
+ * the thread it runs on. So the checks run in a `worker_threads` Worker, one response at a time,
7
+ * each under a hard deadline: a worker that has not answered by then is terminated, the response is
8
+ * reported `not-checked`, and a fresh worker is started for the next one. The caller's thread
9
+ * (Electron's main process) never runs a check itself.
10
+ *
11
+ * The input is posted, not serialised: an OpenAPI schema may be shared or refer to itself, which
12
+ * structured clone carries and JSON cannot. Callers pass only the matched operation's `responses`,
13
+ * so each send copies that much and no more.
14
+ */
15
+ import type { RestContractInput, RestContractResult } from './contract-check.js';
16
+ /** How long one response's check may take, worker round trip included, before the worker is replaced. */
17
+ export declare const DEFAULT_REST_CHECK_DEADLINE_MS = 1000;
18
+ /** How many responses may wait behind the one being checked before new ones are not checked at all. */
19
+ export declare const DEFAULT_REST_CHECK_QUEUE = 16;
20
+ export interface RestContractCheckerOptions {
21
+ /** Milliseconds one response's check may take before the worker is terminated and replaced. */
22
+ readonly deadlineMs?: number;
23
+ /** The worker script; tests substitute one. Defaults to the compiled `contract-check-worker.js`. */
24
+ readonly workerUrl?: URL;
25
+ }
26
+ export interface RestContractChecker {
27
+ /** The response's contract result; `not-checked` on overrun, overflow, failure or after dispose. Never rejects. */
28
+ check(input: RestContractInput): Promise<RestContractResult>;
29
+ /** Terminates the worker; checks still waiting resolve `not-checked`. */
30
+ dispose(): Promise<void>;
31
+ /** Workers started so far (a replaced one counts again). */
32
+ readonly spawned: number;
33
+ /** Whether a worker is currently alive. */
34
+ readonly running: boolean;
35
+ }
36
+ export declare function createRestContractChecker(options?: RestContractCheckerOptions): RestContractChecker;
@@ -0,0 +1,158 @@
1
+ /**
2
+ * REST response checking off the calling thread.
3
+ *
4
+ * {@link checkRestResponse} is synchronous and a contract's `pattern` is untrusted: its own time
5
+ * budget stops a check between steps, but one regex call that runs away cannot be interrupted from
6
+ * the thread it runs on. So the checks run in a `worker_threads` Worker, one response at a time,
7
+ * each under a hard deadline: a worker that has not answered by then is terminated, the response is
8
+ * reported `not-checked`, and a fresh worker is started for the next one. The caller's thread
9
+ * (Electron's main process) never runs a check itself.
10
+ *
11
+ * The input is posted, not serialised: an OpenAPI schema may be shared or refer to itself, which
12
+ * structured clone carries and JSON cannot. Callers pass only the matched operation's `responses`,
13
+ * so each send copies that much and no more.
14
+ */
15
+ import { existsSync } from 'node:fs';
16
+ import { fileURLToPath } from 'node:url';
17
+ import { Worker } from 'node:worker_threads';
18
+ /** How long one response's check may take, worker round trip included, before the worker is replaced. */
19
+ export const DEFAULT_REST_CHECK_DEADLINE_MS = 1_000;
20
+ /** How many responses may wait behind the one being checked before new ones are not checked at all. */
21
+ export const DEFAULT_REST_CHECK_QUEUE = 16;
22
+ /**
23
+ * The compiled worker script: the sibling `.js` when running from `dist`, else — running from `src`
24
+ * under vitest — the package's `dist/rest/contract-check-worker.js`.
25
+ */
26
+ function defaultWorkerUrl() {
27
+ const sibling = new URL('./contract-check-worker.js', import.meta.url);
28
+ if (existsSync(fileURLToPath(sibling))) {
29
+ return sibling;
30
+ }
31
+ const fallback = import.meta.url.replace(/\/src\/rest\/contract-check-worker-host\.ts$/, '/dist/rest/contract-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('contract-check worker not found: build the engine package first');
35
+ }
36
+ return new URL(fallback);
37
+ }
38
+ const notChecked = (reason) => ({ status: 'not-checked', problems: [], notes: [reason] });
39
+ export function createRestContractChecker(options = {}) {
40
+ const deadlineMs = options.deadlineMs ?? DEFAULT_REST_CHECK_DEADLINE_MS;
41
+ let url = options.workerUrl;
42
+ let worker;
43
+ let spawned = 0;
44
+ let disposed = false;
45
+ let nextId = 0;
46
+ let current;
47
+ let timer;
48
+ const queue = [];
49
+ const finish = (result) => {
50
+ const job = current;
51
+ if (job === undefined)
52
+ return;
53
+ current = undefined;
54
+ if (timer !== undefined)
55
+ clearTimeout(timer);
56
+ timer = undefined;
57
+ job.resolve(result);
58
+ pump();
59
+ };
60
+ /** Drops the current worker without waiting for it; its late answer or exit is then ignored. */
61
+ const discard = () => {
62
+ const dead = worker;
63
+ worker = undefined;
64
+ if (dead !== undefined) {
65
+ dead.removeAllListeners();
66
+ // An 'error' after the listeners are gone would otherwise be an uncaught exception.
67
+ dead.on('error', () => undefined);
68
+ void dead.terminate();
69
+ }
70
+ };
71
+ const spawn = () => {
72
+ url ??= defaultWorkerUrl();
73
+ const next = new Worker(url);
74
+ spawned += 1;
75
+ // The checker must never be what keeps the process alive.
76
+ next.unref();
77
+ next.on('message', (answer) => {
78
+ if (current?.id === answer.id)
79
+ finish(answer.result);
80
+ });
81
+ const failed = (why) => {
82
+ if (worker !== next)
83
+ return;
84
+ discard();
85
+ finish(notChecked(why));
86
+ };
87
+ next.on('error', (error) => {
88
+ failed(`the check failed: ${error instanceof Error ? error.message : String(error)}`);
89
+ });
90
+ next.on('exit', () => {
91
+ failed('the check stopped unexpectedly');
92
+ });
93
+ return next;
94
+ };
95
+ function pump() {
96
+ if (current !== undefined || disposed)
97
+ return;
98
+ const job = queue.shift();
99
+ if (job === undefined)
100
+ return;
101
+ current = job;
102
+ try {
103
+ worker ??= spawn();
104
+ worker.postMessage({ id: job.id, input: job.input });
105
+ }
106
+ catch (error) {
107
+ discard();
108
+ finish(notChecked(`the check could not start: ${error instanceof Error ? error.message : String(error)}`));
109
+ return;
110
+ }
111
+ // The deadline starts when this response reaches the worker, not when it was queued, so one
112
+ // stuck check never costs the ones behind it their own.
113
+ timer = setTimeout(() => {
114
+ discard();
115
+ finish(notChecked(`the check took longer than ${String(deadlineMs)} ms`));
116
+ }, deadlineMs);
117
+ timer.unref?.();
118
+ }
119
+ return {
120
+ check(input) {
121
+ if (disposed)
122
+ return Promise.resolve(notChecked('the checker was stopped'));
123
+ if (queue.length >= DEFAULT_REST_CHECK_QUEUE) {
124
+ return Promise.resolve(notChecked('too many responses waiting to be checked'));
125
+ }
126
+ return new Promise((resolve) => {
127
+ nextId += 1;
128
+ queue.push({ id: nextId, input, resolve });
129
+ pump();
130
+ });
131
+ },
132
+ async dispose() {
133
+ if (disposed)
134
+ return;
135
+ disposed = true;
136
+ const dead = worker;
137
+ worker = undefined;
138
+ if (timer !== undefined)
139
+ clearTimeout(timer);
140
+ timer = undefined;
141
+ const waiting = [...(current !== undefined ? [current] : []), ...queue.splice(0)];
142
+ current = undefined;
143
+ for (const job of waiting)
144
+ job.resolve(notChecked('the checker was stopped'));
145
+ if (dead !== undefined) {
146
+ dead.removeAllListeners();
147
+ dead.on('error', () => undefined);
148
+ await dead.terminate();
149
+ }
150
+ },
151
+ get spawned() {
152
+ return spawned;
153
+ },
154
+ get running() {
155
+ return worker !== undefined;
156
+ },
157
+ };
158
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Entry point run inside a `node:worker_threads` Worker by {@link createRestContractChecker}. Each
3
+ * message in is one response (`{ id, input }`, the input carrying only the selected operation's
4
+ * responses) and each message out its result (`{ id, result }`). Responses are checked one at a
5
+ * time, in the order they arrive.
6
+ */
7
+ export {};
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Entry point run inside a `node:worker_threads` Worker by {@link createRestContractChecker}. Each
3
+ * message in is one response (`{ id, input }`, the input carrying only the selected operation's
4
+ * responses) and each message out its result (`{ id, result }`). Responses are checked one at a
5
+ * time, in the order they arrive.
6
+ */
7
+ import { parentPort } from 'node:worker_threads';
8
+ import { checkRestResponse } from './contract-check.js';
9
+ /* v8 ignore start -- runs only inside a real worker thread; covered end to end by
10
+ contract-check-worker.test.ts, which coverage instrumentation does not follow across the thread. */
11
+ if (parentPort !== null) {
12
+ const port = parentPort;
13
+ port.on('message', ({ id, input }) => {
14
+ let result;
15
+ try {
16
+ result = checkRestResponse(input);
17
+ }
18
+ catch (error) {
19
+ result = {
20
+ status: 'not-checked',
21
+ problems: [],
22
+ notes: [error instanceof Error ? error.message : String(error)],
23
+ };
24
+ }
25
+ port.postMessage({ id, result });
26
+ });
27
+ }
28
+ /* v8 ignore stop */
@@ -0,0 +1,43 @@
1
+ import type { OpenApiResponses } from './openapi/model.js';
2
+ import type { RestOperationRef } from './openapi/match.js';
3
+ /** A body bigger than this (UTF-8 bytes) is not parsed or validated: it is reported `skipped`. */
4
+ export declare const MAX_CHECKED_BODY_BYTES = 1048576;
5
+ /** The default time one response's check may take before it gives up as `not-checked`. */
6
+ export declare const DEFAULT_REST_CHECK_BUDGET_MS = 200;
7
+ export declare const MAX_CONTRACT_PROBLEMS = 50;
8
+ export declare const MAX_CONTRACT_MESSAGE_LENGTH = 300;
9
+ /**
10
+ * Schema nodes one check may visit. Generous, since a real response (hundreds of rows of dozens of
11
+ * properties) must be checkable: the worker's deadline is what bounds the time, and this only stops a
12
+ * body the deadline would let through yet is still too big to finish.
13
+ */
14
+ export declare const MAX_REST_CHECK_NODES = 200000;
15
+ export declare const MAX_CONTRACT_PATH_LENGTH = 300;
16
+ export type RestContractStatus = 'ok' | 'violation' | 'unmatched' | 'no-schema' | 'no-contract' | 'skipped' | 'not-checked';
17
+ export interface RestContractProblem {
18
+ readonly path: string;
19
+ readonly keyword: string;
20
+ readonly message: string;
21
+ }
22
+ export interface RestContractResult {
23
+ readonly status: RestContractStatus;
24
+ readonly operation?: RestOperationRef;
25
+ readonly responseKey?: string;
26
+ readonly mediaType?: string;
27
+ readonly problems: readonly RestContractProblem[];
28
+ readonly notes: readonly string[];
29
+ }
30
+ export interface RestContractInput {
31
+ readonly status: number;
32
+ readonly contentType?: string | undefined;
33
+ readonly bodyText: string;
34
+ readonly language: string;
35
+ readonly streamed: boolean;
36
+ readonly operation?: RestOperationRef | undefined;
37
+ readonly responses?: OpenApiResponses | undefined;
38
+ }
39
+ export interface RestContractCheckOptions {
40
+ readonly budgetMs?: number;
41
+ readonly now?: () => number;
42
+ }
43
+ export declare function checkRestResponse(input: RestContractInput, options?: RestContractCheckOptions): RestContractResult;