@wirebench/engine 2.2.1 → 3.1.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (566) hide show
  1. package/README.md +134 -1
  2. package/dist/account/schema.d.ts +34 -0
  3. package/dist/account/schema.js +29 -0
  4. package/dist/assert/callback.d.ts +76 -0
  5. package/dist/assert/callback.js +320 -0
  6. package/dist/assert/capture-source.d.ts +50 -0
  7. package/dist/assert/capture-source.js +89 -0
  8. package/dist/assert/check.d.ts +8 -0
  9. package/dist/assert/check.js +18 -0
  10. package/dist/assert/header.d.ts +5 -0
  11. package/dist/assert/header.js +48 -0
  12. package/dist/assert/index.d.ts +2 -2
  13. package/dist/assert/index.js +12 -0
  14. package/dist/assert/match.d.ts +6 -0
  15. package/dist/assert/match.js +13 -4
  16. package/dist/assert/model.d.ts +110 -3
  17. package/dist/assert/model.js +16 -1
  18. package/dist/assert/schema.d.ts +194 -1
  19. package/dist/assert/schema.js +154 -12
  20. package/dist/assert/status-names.d.ts +9 -0
  21. package/dist/assert/status-names.js +27 -0
  22. package/dist/assert/status.d.ts +4 -1
  23. package/dist/assert/status.js +27 -3
  24. package/dist/asyncapi/browser.d.ts +7 -0
  25. package/dist/asyncapi/browser.js +6 -0
  26. package/dist/asyncapi/frame-check-worker-host.d.ts +44 -0
  27. package/dist/asyncapi/frame-check-worker-host.js +175 -0
  28. package/dist/asyncapi/frame-check-worker.d.ts +12 -0
  29. package/dist/asyncapi/frame-check-worker.js +25 -0
  30. package/dist/asyncapi/frame-check.d.ts +25 -0
  31. package/dist/asyncapi/frame-check.js +78 -0
  32. package/dist/asyncapi/import.d.ts +25 -0
  33. package/dist/asyncapi/import.js +34 -0
  34. package/dist/asyncapi/map.d.ts +40 -0
  35. package/dist/asyncapi/map.js +230 -0
  36. package/dist/asyncapi/model.d.ts +84 -0
  37. package/dist/asyncapi/model.js +7 -0
  38. package/dist/asyncapi/normalise-2.d.ts +13 -0
  39. package/dist/asyncapi/normalise-2.js +113 -0
  40. package/dist/asyncapi/normalise-3.d.ts +14 -0
  41. package/dist/asyncapi/normalise-3.js +133 -0
  42. package/dist/asyncapi/parse.d.ts +31 -0
  43. package/dist/asyncapi/parse.js +85 -0
  44. package/dist/asyncapi/read.d.ts +35 -0
  45. package/dist/asyncapi/read.js +186 -0
  46. package/dist/asyncapi/security.d.ts +14 -0
  47. package/dist/asyncapi/security.js +55 -0
  48. package/dist/asyncapi/update.d.ts +53 -0
  49. package/dist/asyncapi/update.js +220 -0
  50. package/dist/errors.d.ts +16 -0
  51. package/dist/errors.js +22 -0
  52. package/dist/grpc/events.d.ts +22 -0
  53. package/dist/grpc/events.js +1 -0
  54. package/dist/grpc/expand.d.ts +1 -1
  55. package/dist/grpc/expand.js +15 -5
  56. package/dist/grpc/files.d.ts +271 -0
  57. package/dist/grpc/files.js +62 -0
  58. package/dist/grpc/model.d.ts +11 -1
  59. package/dist/grpc/module.d.ts +2 -0
  60. package/dist/grpc/module.js +13 -0
  61. package/dist/grpc/run.d.ts +73 -0
  62. package/dist/grpc/run.js +407 -0
  63. package/dist/grpc/script-types.d.ts +8 -0
  64. package/dist/grpc/script-types.js +149 -0
  65. package/dist/grpc/scripting.d.ts +34 -0
  66. package/dist/grpc/scripting.js +147 -0
  67. package/dist/grpc/send-input.d.ts +46 -0
  68. package/dist/grpc/send-input.js +42 -0
  69. package/dist/grpc/send.d.ts +2 -2
  70. package/dist/grpc/status.d.ts +9 -2
  71. package/dist/grpc/status.js +11 -24
  72. package/dist/grpc/storage.d.ts +9 -0
  73. package/dist/grpc/storage.js +167 -0
  74. package/dist/{rest/auth.d.ts → http/auth/apply-auth.d.ts} +4 -4
  75. package/dist/{rest/auth.js → http/auth/apply-auth.js} +1 -1
  76. package/dist/http/auth/apply.d.ts +1 -1
  77. package/dist/{rest → http/auth}/oauth2.d.ts +2 -2
  78. package/dist/{rest → http/auth}/oauth2.js +1 -1
  79. package/dist/http/auth/send-auth.d.ts +57 -0
  80. package/dist/http/auth/send-auth.js +7 -0
  81. package/dist/http/client.js +150 -8
  82. package/dist/http/cookies.d.ts +79 -0
  83. package/dist/http/cookies.js +81 -0
  84. package/dist/http/curl.d.ts +4 -14
  85. package/dist/http/curl.js +4 -154
  86. package/dist/http/decompress.d.ts +7 -0
  87. package/dist/http/decompress.js +23 -1
  88. package/dist/http/document-fetch.d.ts +42 -0
  89. package/dist/http/document-fetch.js +207 -0
  90. package/dist/http/entries.d.ts +27 -0
  91. package/dist/http/entries.js +16 -0
  92. package/dist/http/escape.d.ts +18 -0
  93. package/dist/http/escape.js +30 -0
  94. package/dist/http/fetch-document.d.ts +28 -0
  95. package/dist/{wsdl/fetch.js → http/fetch-document.js} +8 -16
  96. package/dist/http/media-type.d.ts +9 -0
  97. package/dist/http/media-type.js +12 -0
  98. package/dist/http/transcript-cap.d.ts +26 -0
  99. package/dist/http/transcript-cap.js +36 -0
  100. package/dist/http/types.d.ts +59 -0
  101. package/dist/http/webhook-signature.d.ts +81 -0
  102. package/dist/http/webhook-signature.js +227 -0
  103. package/dist/import-detect.d.ts +2 -2
  104. package/dist/import-detect.js +10 -1
  105. package/dist/index.d.ts +207 -55
  106. package/dist/index.js +129 -32
  107. package/dist/json/cursor.d.ts +2 -0
  108. package/dist/json/cursor.js +1 -0
  109. package/dist/json/pointer-range.d.ts +18 -0
  110. package/dist/json/pointer-range.js +157 -0
  111. package/dist/json/schema/model.d.ts +59 -0
  112. package/dist/json/schema/model.js +8 -0
  113. package/dist/json/schema/parse-text.d.ts +16 -0
  114. package/dist/json/schema/parse-text.js +37 -0
  115. package/dist/{rest/openapi → json/schema}/refs.d.ts +2 -2
  116. package/dist/{rest/openapi → json/schema}/refs.js +3 -3
  117. package/dist/{rest/openapi → json/schema}/sample.d.ts +4 -0
  118. package/dist/{rest/openapi → json/schema}/sample.js +2 -2
  119. package/dist/json/schema/source.d.ts +21 -0
  120. package/dist/json/schema/source.js +8 -0
  121. package/dist/json/schema-validate.d.ts +49 -0
  122. package/dist/json/schema-validate.js +557 -0
  123. package/dist/{wss/keystore → keystore}/index.js +1 -1
  124. package/dist/{wss/keystore → keystore}/pem.js +1 -1
  125. package/dist/{wss/keystore → keystore}/pkcs12.js +1 -1
  126. package/dist/project/attachments-cache.d.ts +3 -1
  127. package/dist/{wsdl → project}/cache-naming.js +1 -1
  128. package/dist/project/endpoints.d.ts +18 -8
  129. package/dist/project/endpoints.js +21 -6
  130. package/dist/project/environments.d.ts +7 -5
  131. package/dist/project/history.d.ts +105 -9
  132. package/dist/project/history.js +195 -23
  133. package/dist/project/inherit.d.ts +7 -0
  134. package/dist/project/inherit.js +9 -0
  135. package/dist/project/keystores.d.ts +1 -1
  136. package/dist/project/load-helpers.d.ts +89 -0
  137. package/dist/project/load-helpers.js +177 -0
  138. package/dist/project/load.d.ts +30 -4
  139. package/dist/project/load.js +168 -545
  140. package/dist/project/managed-files.d.ts +36 -0
  141. package/dist/project/managed-files.js +97 -0
  142. package/dist/project/migrate.d.ts +2 -2
  143. package/dist/project/migrate.js +2 -2
  144. package/dist/project/model.d.ts +92 -14
  145. package/dist/project/model.js +50 -4
  146. package/dist/project/paths.d.ts +10 -1
  147. package/dist/project/paths.js +10 -1
  148. package/dist/project/preferences.d.ts +11 -2
  149. package/dist/project/preferences.js +5 -1
  150. package/dist/project/properties.d.ts +31 -17
  151. package/dist/project/properties.js +89 -70
  152. package/dist/project/request-location.d.ts +20 -0
  153. package/dist/project/request-location.js +62 -0
  154. package/dist/project/save.d.ts +12 -2
  155. package/dist/project/save.js +186 -141
  156. package/dist/project/schema-parts.d.ts +337 -0
  157. package/dist/project/schema-parts.js +248 -0
  158. package/dist/project/schema.d.ts +72 -928
  159. package/dist/project/schema.js +17 -466
  160. package/dist/project/sequence-guards.d.ts +43 -0
  161. package/dist/project/sequence-guards.js +109 -0
  162. package/dist/project/serialize-helpers.d.ts +60 -0
  163. package/dist/project/serialize-helpers.js +108 -0
  164. package/dist/project/serialize.d.ts +7 -8
  165. package/dist/project/serialize.js +34 -293
  166. package/dist/protocol/features.d.ts +51 -0
  167. package/dist/protocol/features.js +64 -0
  168. package/dist/protocol/index.d.ts +7 -0
  169. package/dist/protocol/index.js +4 -0
  170. package/dist/protocol/module.d.ts +247 -0
  171. package/dist/protocol/module.js +48 -0
  172. package/dist/protocol/registry.d.ts +42 -0
  173. package/dist/protocol/registry.js +47 -0
  174. package/dist/protocols.d.ts +77 -0
  175. package/dist/protocols.js +40 -0
  176. package/dist/redact/index.d.ts +12 -1
  177. package/dist/redact/index.js +55 -7
  178. package/dist/redact/literal.d.ts +10 -0
  179. package/dist/redact/literal.js +110 -12
  180. package/dist/rest/body.d.ts +2 -10
  181. package/dist/rest/body.js +3 -25
  182. package/dist/rest/browser.d.ts +4 -0
  183. package/dist/rest/browser.js +5 -0
  184. package/dist/rest/contract-check-worker-host.d.ts +36 -0
  185. package/dist/rest/contract-check-worker-host.js +158 -0
  186. package/dist/rest/contract-check-worker.d.ts +7 -0
  187. package/dist/rest/contract-check-worker.js +28 -0
  188. package/dist/rest/contract-check.d.ts +43 -0
  189. package/dist/rest/contract-check.js +217 -0
  190. package/dist/rest/cookie-jar.d.ts +62 -0
  191. package/dist/rest/cookie-jar.js +262 -0
  192. package/dist/rest/cookies.d.ts +6 -22
  193. package/dist/rest/cookies.js +6 -42
  194. package/dist/rest/curl.js +5 -1
  195. package/dist/rest/events.d.ts +12 -0
  196. package/dist/rest/events.js +1 -0
  197. package/dist/rest/expand.d.ts +6 -1
  198. package/dist/rest/expand.js +29 -11
  199. package/dist/rest/files.d.ts +439 -0
  200. package/dist/rest/files.js +107 -0
  201. package/dist/rest/json-form.d.ts +97 -0
  202. package/dist/rest/json-form.js +396 -0
  203. package/dist/rest/model.d.ts +35 -24
  204. package/dist/rest/model.js +6 -9
  205. package/dist/rest/module.d.ts +2 -0
  206. package/dist/rest/module.js +13 -0
  207. package/dist/rest/openapi/cache.d.ts +7 -2
  208. package/dist/rest/openapi/cache.js +2 -2
  209. package/dist/rest/openapi/import.d.ts +11 -16
  210. package/dist/rest/openapi/import.js +6 -2
  211. package/dist/rest/openapi/map.d.ts +38 -1
  212. package/dist/rest/openapi/map.js +151 -41
  213. package/dist/rest/openapi/match.d.ts +20 -0
  214. package/dist/rest/openapi/match.js +117 -0
  215. package/dist/rest/openapi/model.d.ts +33 -45
  216. package/dist/rest/openapi/parse.d.ts +3 -12
  217. package/dist/rest/openapi/parse.js +138 -67
  218. package/dist/rest/openapi/responses.d.ts +23 -0
  219. package/dist/rest/openapi/responses.js +59 -0
  220. package/dist/rest/openapi/runtime-expression.d.ts +69 -0
  221. package/dist/rest/openapi/runtime-expression.js +213 -0
  222. package/dist/rest/openapi/update.d.ts +116 -0
  223. package/dist/rest/openapi/update.js +456 -0
  224. package/dist/rest/postman/map.d.ts +1 -0
  225. package/dist/rest/postman/map.js +66 -4
  226. package/dist/rest/postman/model.d.ts +9 -0
  227. package/dist/rest/postman/parse.js +33 -10
  228. package/dist/rest/response.d.ts +2 -23
  229. package/dist/rest/response.js +3 -75
  230. package/dist/rest/run.d.ts +56 -0
  231. package/dist/rest/run.js +395 -0
  232. package/dist/rest/script-types.d.ts +7 -0
  233. package/dist/rest/script-types.js +83 -0
  234. package/dist/rest/scripting.d.ts +38 -0
  235. package/dist/rest/scripting.js +282 -0
  236. package/dist/rest/send-input.d.ts +54 -0
  237. package/dist/rest/send-input.js +73 -0
  238. package/dist/rest/send.d.ts +77 -4
  239. package/dist/rest/send.js +128 -7
  240. package/dist/rest/sse-transcript.d.ts +25 -0
  241. package/dist/rest/sse-transcript.js +95 -0
  242. package/dist/rest/sse.d.ts +43 -0
  243. package/dist/rest/sse.js +195 -0
  244. package/dist/rest/storage.d.ts +26 -0
  245. package/dist/rest/storage.js +262 -0
  246. package/dist/rest/url.d.ts +10 -4
  247. package/dist/rest/url.js +38 -5
  248. package/dist/run/baseline-update.d.ts +35 -0
  249. package/dist/run/baseline-update.js +97 -0
  250. package/dist/run/baseline.d.ts +42 -0
  251. package/dist/run/baseline.js +93 -0
  252. package/dist/run/context.d.ts +86 -0
  253. package/dist/run/context.js +31 -0
  254. package/dist/run/current-values.d.ts +32 -0
  255. package/dist/run/current-values.js +43 -0
  256. package/dist/run/event-queue.d.ts +14 -0
  257. package/dist/run/event-queue.js +46 -0
  258. package/dist/run/exchange.d.ts +62 -0
  259. package/dist/run/exchange.js +65 -0
  260. package/dist/run/host.d.ts +89 -0
  261. package/dist/run/host.js +1 -0
  262. package/dist/run/index.d.ts +20 -7
  263. package/dist/run/index.js +12 -4
  264. package/dist/run/oauth2-token.d.ts +42 -0
  265. package/dist/run/oauth2-token.js +92 -0
  266. package/dist/run/open.d.ts +12 -0
  267. package/dist/run/open.js +16 -0
  268. package/dist/run/run.d.ts +124 -4
  269. package/dist/run/run.js +293 -134
  270. package/dist/run/scope.d.ts +11 -0
  271. package/dist/run/scope.js +26 -0
  272. package/dist/run/script-support.d.ts +53 -0
  273. package/dist/run/script-support.js +68 -0
  274. package/dist/run/secret-needs.d.ts +11 -4
  275. package/dist/run/secret-needs.js +48 -96
  276. package/dist/run/select.d.ts +34 -25
  277. package/dist/run/select.js +45 -54
  278. package/dist/run/send-helpers.d.ts +93 -0
  279. package/dist/run/send-helpers.js +255 -0
  280. package/dist/run/tree.d.ts +50 -0
  281. package/dist/run/tree.js +54 -0
  282. package/dist/script/api/postman.d.ts +10 -0
  283. package/dist/script/api/postman.js +264 -0
  284. package/dist/script/api/prelude.d.ts +20 -0
  285. package/dist/script/api/prelude.js +215 -0
  286. package/dist/script/apply.d.ts +44 -0
  287. package/dist/script/apply.js +120 -0
  288. package/dist/script/check/host.d.ts +41 -0
  289. package/dist/script/check/host.js +143 -0
  290. package/dist/script/check/service.d.ts +52 -0
  291. package/dist/script/check/service.js +195 -0
  292. package/dist/script/check/worker.d.ts +1 -0
  293. package/dist/script/check/worker.js +40 -0
  294. package/dist/script/index.d.ts +16 -0
  295. package/dist/script/index.js +10 -0
  296. package/dist/script/lookup.d.ts +10 -0
  297. package/dist/script/lookup.js +23 -0
  298. package/dist/script/model.d.ts +82 -0
  299. package/dist/script/model.js +18 -0
  300. package/dist/script/props.d.ts +8 -0
  301. package/dist/script/props.js +28 -0
  302. package/dist/script/request-scripts.d.ts +83 -0
  303. package/dist/script/request-scripts.js +160 -0
  304. package/dist/script/run.d.ts +47 -0
  305. package/dist/script/run.js +146 -0
  306. package/dist/script/sandbox/execute.d.ts +26 -0
  307. package/dist/script/sandbox/execute.js +212 -0
  308. package/dist/script/sandbox/host-api.d.ts +27 -0
  309. package/dist/script/sandbox/host-api.js +101 -0
  310. package/dist/script/sandbox/host.d.ts +18 -0
  311. package/dist/script/sandbox/host.js +172 -0
  312. package/dist/script/sandbox/model.d.ts +69 -0
  313. package/dist/script/sandbox/model.js +24 -0
  314. package/dist/script/sandbox/worker.d.ts +1 -0
  315. package/dist/script/sandbox/worker.js +20 -0
  316. package/dist/script/send.d.ts +27 -0
  317. package/dist/script/send.js +76 -0
  318. package/dist/script/strip.d.ts +5 -0
  319. package/dist/script/strip.js +43 -0
  320. package/dist/script/types/api.d.ts +38 -0
  321. package/dist/script/types/api.js +113 -0
  322. package/dist/script/types/json-schema.d.ts +26 -0
  323. package/dist/script/types/json-schema.js +206 -0
  324. package/dist/secrets/env-names.d.ts +9 -1
  325. package/dist/secrets/env-names.js +17 -1
  326. package/dist/secrets/resolve.d.ts +44 -4
  327. package/dist/secrets/resolve.js +58 -1
  328. package/dist/secrets/scan/apply.d.ts +36 -0
  329. package/dist/secrets/scan/apply.js +194 -0
  330. package/dist/secrets/scan/rules.d.ts +32 -0
  331. package/dist/secrets/scan/rules.js +346 -0
  332. package/dist/secrets/scan/scan.d.ts +6 -0
  333. package/dist/secrets/scan/scan.js +57 -0
  334. package/dist/secrets/scan/walk.d.ts +70 -0
  335. package/dist/secrets/scan/walk.js +156 -0
  336. package/dist/secrets/secret-refs.d.ts +8 -0
  337. package/dist/secrets/secret-refs.js +25 -0
  338. package/dist/secrets/secret-token.d.ts +17 -0
  339. package/dist/secrets/secret-token.js +25 -0
  340. package/dist/sequence/file.d.ts +169 -0
  341. package/dist/sequence/file.js +237 -0
  342. package/dist/sequence/index.d.ts +7 -0
  343. package/dist/sequence/index.js +5 -0
  344. package/dist/sequence/load.d.ts +32 -0
  345. package/dist/sequence/load.js +56 -0
  346. package/dist/sequence/model.d.ts +115 -0
  347. package/dist/sequence/model.js +53 -0
  348. package/dist/sequence/run.d.ts +131 -0
  349. package/dist/sequence/run.js +191 -0
  350. package/dist/sequence/transfer.d.ts +24 -0
  351. package/dist/sequence/transfer.js +75 -0
  352. package/dist/server-api/audit.d.ts +455 -0
  353. package/dist/server-api/audit.js +186 -0
  354. package/dist/server-api/ci-tokens.d.ts +50 -0
  355. package/dist/server-api/ci-tokens.js +35 -0
  356. package/dist/server-api/hooks.d.ts +337 -0
  357. package/dist/server-api/hooks.js +152 -0
  358. package/dist/server-api/identity.d.ts +210 -0
  359. package/dist/server-api/identity.js +115 -0
  360. package/dist/server-api/licensing.d.ts +80 -0
  361. package/dist/server-api/licensing.js +53 -0
  362. package/dist/server-api/live.d.ts +132 -0
  363. package/dist/server-api/live.js +102 -0
  364. package/dist/server-api/meta.d.ts +31 -0
  365. package/dist/server-api/meta.js +21 -0
  366. package/dist/server-api/sync.d.ts +179 -0
  367. package/dist/server-api/sync.js +124 -0
  368. package/dist/server-api/teams.d.ts +306 -0
  369. package/dist/server-api/teams.js +113 -0
  370. package/dist/snapshot/diff.d.ts +30 -0
  371. package/dist/snapshot/diff.js +75 -0
  372. package/dist/snapshot/format.d.ts +17 -0
  373. package/dist/snapshot/format.js +40 -0
  374. package/dist/snapshot/golden-file.d.ts +45 -0
  375. package/dist/snapshot/golden-file.js +173 -0
  376. package/dist/snapshot/ignore.d.ts +14 -0
  377. package/dist/snapshot/ignore.js +79 -0
  378. package/dist/snapshot/index.d.ts +9 -0
  379. package/dist/snapshot/index.js +9 -0
  380. package/dist/snapshot/json-diff.d.ts +3 -0
  381. package/dist/snapshot/json-diff.js +93 -0
  382. package/dist/snapshot/xml-diff.d.ts +10 -0
  383. package/dist/snapshot/xml-diff.js +194 -0
  384. package/dist/soap/auth.d.ts +26 -0
  385. package/dist/soap/auth.js +54 -0
  386. package/dist/soap/curl.d.ts +20 -0
  387. package/dist/soap/curl.js +161 -0
  388. package/dist/soap/expand.d.ts +24 -0
  389. package/dist/soap/expand.js +95 -0
  390. package/dist/soap/files.d.ts +384 -0
  391. package/dist/soap/files.js +114 -0
  392. package/dist/soap/form-request.d.ts +13 -0
  393. package/dist/soap/form-request.js +2 -2
  394. package/dist/soap/generate.d.ts +12 -0
  395. package/dist/{generate.js → soap/generate.js} +4 -4
  396. package/dist/{import.d.ts → soap/import.d.ts} +4 -4
  397. package/dist/{import.js → soap/import.js} +13 -13
  398. package/dist/soap/json-operation.d.ts +35 -0
  399. package/dist/soap/json-operation.js +225 -0
  400. package/dist/soap/legacy-project/env-refs.d.ts +19 -0
  401. package/dist/soap/legacy-project/env-refs.js +105 -0
  402. package/dist/soap/legacy-project/map.d.ts +2 -2
  403. package/dist/soap/legacy-project/map.js +6 -0
  404. package/dist/soap/mime/multipart.d.ts +2 -2
  405. package/dist/soap/mime/multipart.js +2 -5
  406. package/dist/soap/mime/send-pipeline.d.ts +1 -1
  407. package/dist/soap/mime/send-pipeline.js +1 -1
  408. package/dist/soap/mime/types.d.ts +1 -3
  409. package/dist/soap/module.d.ts +2 -0
  410. package/dist/soap/module.js +13 -0
  411. package/dist/soap/namespace-scope.js +1 -1
  412. package/dist/soap/operations.d.ts +12 -0
  413. package/dist/{operations.js → soap/operations.js} +4 -4
  414. package/dist/soap/run.d.ts +70 -0
  415. package/dist/soap/run.js +549 -0
  416. package/dist/soap/script-types.d.ts +65 -0
  417. package/dist/soap/script-types.js +379 -0
  418. package/dist/soap/scripting.d.ts +45 -0
  419. package/dist/soap/scripting.js +221 -0
  420. package/dist/soap/send-input.d.ts +61 -0
  421. package/dist/{send-options.js → soap/send-input.js} +5 -109
  422. package/dist/{send.d.ts → soap/send.d.ts} +1 -1
  423. package/dist/{send.js → soap/send.js} +28 -12
  424. package/dist/soap/storage.d.ts +9 -0
  425. package/dist/soap/storage.js +237 -0
  426. package/dist/soap/transforms.d.ts +3 -12
  427. package/dist/soap/transforms.js +3 -14
  428. package/dist/{types.d.ts → soap/types.d.ts} +34 -84
  429. package/dist/sync/git-cli.d.ts +202 -0
  430. package/dist/sync/git-cli.js +684 -0
  431. package/dist/sync/three-way-merge.d.ts +41 -0
  432. package/dist/sync/three-way-merge.js +85 -0
  433. package/dist/sync/tree-paths.d.ts +34 -0
  434. package/dist/sync/tree-paths.js +131 -0
  435. package/dist/team-secrets/envelope.d.ts +10 -0
  436. package/dist/team-secrets/envelope.js +121 -0
  437. package/dist/team-secrets/errors.d.ts +26 -0
  438. package/dist/team-secrets/errors.js +27 -0
  439. package/dist/team-secrets/index.d.ts +14 -0
  440. package/dist/team-secrets/index.js +8 -0
  441. package/dist/team-secrets/keys.d.ts +52 -0
  442. package/dist/team-secrets/keys.js +158 -0
  443. package/dist/team-secrets/log.d.ts +48 -0
  444. package/dist/team-secrets/log.js +175 -0
  445. package/dist/team-secrets/resolve-conflict.d.ts +7 -0
  446. package/dist/team-secrets/resolve-conflict.js +14 -0
  447. package/dist/team-secrets/schema.d.ts +97 -0
  448. package/dist/team-secrets/schema.js +157 -0
  449. package/dist/team-secrets/sign.d.ts +24 -0
  450. package/dist/team-secrets/sign.js +71 -0
  451. package/dist/team-secrets/vault.d.ts +49 -0
  452. package/dist/team-secrets/vault.js +148 -0
  453. package/dist/validate/wsi/run-message.d.ts +2 -2
  454. package/dist/validate/wsi/run-message.js +1 -1
  455. package/dist/validate/wsi/run-wsdl.d.ts +2 -2
  456. package/dist/validate/wsi/run-wsdl.js +1 -1
  457. package/dist/validate/wsi/types.d.ts +1 -1
  458. package/dist/webhooks/model.d.ts +138 -0
  459. package/dist/webhooks/model.js +150 -0
  460. package/dist/workspace/commit-message.d.ts +1 -1
  461. package/dist/workspace/commit-message.js +6 -1
  462. package/dist/workspace/environments.d.ts +11 -4
  463. package/dist/workspace/environments.js +12 -0
  464. package/dist/workspace/index.d.ts +3 -3
  465. package/dist/workspace/index.js +2 -2
  466. package/dist/workspace/paths.d.ts +5 -2
  467. package/dist/workspace/paths.js +5 -2
  468. package/dist/workspace/schema.d.ts +7 -3
  469. package/dist/workspace/schema.js +24 -3
  470. package/dist/workspace/share.d.ts +30 -11
  471. package/dist/workspace/share.js +32 -6
  472. package/dist/ws/call.d.ts +1 -1
  473. package/dist/ws/call.js +2 -2
  474. package/dist/ws/connect.d.ts +60 -0
  475. package/dist/ws/connect.js +131 -0
  476. package/dist/ws/events.d.ts +17 -0
  477. package/dist/ws/events.js +1 -0
  478. package/dist/ws/expand.d.ts +1 -1
  479. package/dist/ws/expand.js +1 -1
  480. package/dist/ws/files.d.ts +284 -0
  481. package/dist/ws/files.js +71 -0
  482. package/dist/ws/history-entry.d.ts +44 -0
  483. package/dist/ws/history-entry.js +93 -0
  484. package/dist/ws/model.d.ts +44 -3
  485. package/dist/ws/model.js +3 -0
  486. package/dist/ws/module.d.ts +2 -0
  487. package/dist/ws/module.js +11 -0
  488. package/dist/ws/run.d.ts +63 -0
  489. package/dist/ws/run.js +470 -0
  490. package/dist/ws/session.d.ts +18 -0
  491. package/dist/ws/session.js +52 -25
  492. package/dist/ws/storage.d.ts +9 -0
  493. package/dist/ws/storage.js +176 -0
  494. package/dist/ws/transcript.d.ts +3 -4
  495. package/dist/ws/transcript.js +26 -17
  496. package/dist/ws/url.d.ts +1 -1
  497. package/dist/wsdl/cache.js +1 -1
  498. package/dist/wsdl/docs-generator.d.ts +3 -3
  499. package/dist/wsdl/docs-generator.js +1 -1
  500. package/dist/wsdl/export-definition.js +1 -1
  501. package/dist/wsdl/qname.d.ts +2 -5
  502. package/dist/wsdl/resolver.d.ts +4 -11
  503. package/dist/wsdl/resolver.js +3 -3
  504. package/dist/wsdl/update-definition.d.ts +5 -5
  505. package/dist/wsdl/update-definition.js +6 -6
  506. package/dist/wss/apply.js +1 -1
  507. package/dist/{project/wss-configs.d.ts → wss/configs.d.ts} +2 -2
  508. package/dist/{project/wss-configs.js → wss/configs.js} +2 -2
  509. package/dist/wss/incoming/decrypt.d.ts +1 -1
  510. package/dist/wss/incoming/index.js +1 -1
  511. package/dist/wss/incoming/verify.d.ts +1 -1
  512. package/dist/wss/incoming/verify.js +1 -1
  513. package/dist/wss/key-identifiers.js +1 -1
  514. package/dist/wss/model.d.ts +1 -1
  515. package/dist/wss/outgoing/encryption.d.ts +1 -1
  516. package/dist/wss/outgoing/signature.d.ts +1 -1
  517. package/dist/xml/decode.d.ts +15 -0
  518. package/dist/xml/decode.js +22 -0
  519. package/dist/xml/entitize.d.ts +17 -0
  520. package/dist/xml/entitize.js +19 -0
  521. package/dist/xml/index.d.ts +1 -1
  522. package/dist/xml/index.js +1 -1
  523. package/dist/xml/locate.d.ts +39 -0
  524. package/dist/xml/locate.js +117 -0
  525. package/dist/xml/qname.d.ts +12 -0
  526. package/dist/xml/qname.js +8 -0
  527. package/dist/xpath/evaluate-async.d.ts +19 -0
  528. package/dist/xpath/evaluate-async.js +31 -11
  529. package/dist/xpath/evaluate.d.ts +1 -1
  530. package/dist/xpath/namespaces.js +1 -1
  531. package/dist/xpath/worker.d.ts +11 -5
  532. package/dist/xpath/worker.js +24 -7
  533. package/dist/xsd/form-model.d.ts +19 -2
  534. package/dist/xsd/form-model.js +14 -2
  535. package/dist/xsd/json-bridge.d.ts +152 -0
  536. package/dist/xsd/json-bridge.js +1213 -0
  537. package/dist/xsd/locate.d.ts +2 -30
  538. package/dist/xsd/locate.js +1 -109
  539. package/dist/xsd/xml-scan.d.ts +2 -0
  540. package/dist/xsd/xml-scan.js +1 -1
  541. package/dist/xsd/xml-writer.d.ts +2 -0
  542. package/dist/xsd/xml-writer.js +4 -0
  543. package/package.json +12 -1
  544. package/dist/generate.d.ts +0 -12
  545. package/dist/operations.d.ts +0 -12
  546. package/dist/run/effective-auth.d.ts +0 -10
  547. package/dist/run/effective-auth.js +0 -19
  548. package/dist/run/prepare.d.ts +0 -43
  549. package/dist/run/prepare.js +0 -280
  550. package/dist/send-options.d.ts +0 -141
  551. package/dist/wsdl/fetch.d.ts +0 -13
  552. /package/dist/{soap → http}/charset.d.ts +0 -0
  553. /package/dist/{soap → http}/charset.js +0 -0
  554. /package/dist/{wsdl → http}/ref-policy.d.ts +0 -0
  555. /package/dist/{wsdl → http}/ref-policy.js +0 -0
  556. /package/dist/{wss/keystore → keystore}/certificate.d.ts +0 -0
  557. /package/dist/{wss/keystore → keystore}/certificate.js +0 -0
  558. /package/dist/{wss/keystore → keystore}/index.d.ts +0 -0
  559. /package/dist/{wss/keystore → keystore}/model.d.ts +0 -0
  560. /package/dist/{wss/keystore → keystore}/model.js +0 -0
  561. /package/dist/{wss/keystore → keystore}/pem.d.ts +0 -0
  562. /package/dist/{wss/keystore → keystore}/pkcs12.d.ts +0 -0
  563. /package/dist/{wsdl → project}/cache-naming.d.ts +0 -0
  564. /package/dist/{types.js → soap/types.js} +0 -0
  565. /package/dist/{soap → xml}/prefixes.d.ts +0 -0
  566. /package/dist/{soap → xml}/prefixes.js +0 -0
@@ -0,0 +1,456 @@
1
+ /**
2
+ * Update Definition for an OpenAPI-imported REST API: a per-operation report of what a new version of
3
+ * the document changes.
4
+ *
5
+ * An operation is identified by its lower-cased method and its path exactly as the document writes
6
+ * it, the same key a request's contract link uses — so a renamed path is a removal plus an addition,
7
+ * never a guess by `operationId`.
8
+ *
9
+ * Schemas arrive `$ref`-resolved, which means shared and even cyclic object graphs, so nothing here
10
+ * serialises them: {@link sameStructure} walks both sides together and remembers the pairs it is
11
+ * already comparing.
12
+ *
13
+ * Applying one follows the AsyncAPI rule: both documents are re-mapped with the importer's own
14
+ * {@link apiFromDocument}, and a generated value follows the new document only while it still equals
15
+ * what the old document generated. Nothing is ever deleted: a request whose operation is gone is
16
+ * flagged `orphaned`, and one whose operation came back has the flag cleared.
17
+ *
18
+ * Pure: it reads two parsed documents and writes nothing.
19
+ */
20
+ import { generateId } from '../../project/model.js';
21
+ import { uniqueSlug } from '../../project/paths.js';
22
+ import { hookKey } from '../../webhooks/model.js';
23
+ import { createFolder } from '../model.js';
24
+ import { apiFromDocument, webhookSourcesOf, webhooksFromDocument } from './map.js';
25
+ /**
26
+ * Structural equality that terminates on cycles: a pair already under comparison is assumed equal,
27
+ * which is sound because any real difference is found along some other finite path.
28
+ */
29
+ export function sameStructure(a, b) {
30
+ return compare(a, b, new Map());
31
+ }
32
+ function compare(a, b, seen) {
33
+ if (Object.is(a, b))
34
+ return true;
35
+ if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null)
36
+ return false;
37
+ if (Array.isArray(a) !== Array.isArray(b))
38
+ return false;
39
+ let partners = seen.get(a);
40
+ if (partners?.has(b) === true)
41
+ return true;
42
+ if (partners === undefined) {
43
+ partners = new Set();
44
+ seen.set(a, partners);
45
+ }
46
+ partners.add(b);
47
+ if (Array.isArray(a)) {
48
+ const other = b;
49
+ return a.length === other.length && a.every((item, index) => compare(item, other[index], seen));
50
+ }
51
+ const left = a;
52
+ const right = b;
53
+ const keys = Object.keys(left).filter((key) => left[key] !== undefined);
54
+ const otherKeys = Object.keys(right).filter((key) => right[key] !== undefined);
55
+ return (keys.length === otherKeys.length &&
56
+ keys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && compare(left[key], right[key], seen)));
57
+ }
58
+ const keyOf = (op) => `${op.method.toLowerCase()} ${op.path}`;
59
+ function opRef(op) {
60
+ const ref = { method: op.method.toLowerCase(), path: op.path };
61
+ return op.summary === undefined ? ref : { ...ref, summary: op.summary };
62
+ }
63
+ /** Parameters keyed by location and name, so a reordered list is not a change. */
64
+ function parametersByKey(parameters) {
65
+ const byKey = {};
66
+ for (const parameter of parameters)
67
+ byKey[`${parameter.in}:${parameter.name}`] = parameter;
68
+ return byKey;
69
+ }
70
+ /**
71
+ * Why one operation differs. `servers` is part of the vocabulary but never produced here: the model
72
+ * keeps no per-operation servers, so a server change is reported once, at the API level.
73
+ */
74
+ function reasonsFor(a, b) {
75
+ const reasons = [];
76
+ if (!sameStructure(parametersByKey(a.parameters), parametersByKey(b.parameters)))
77
+ reasons.push('parameters');
78
+ if (!sameStructure(a.requestBody, b.requestBody))
79
+ reasons.push('request-body');
80
+ if (!sameStructure(a.responses, b.responses))
81
+ reasons.push('responses');
82
+ if (!sameStructure(a.security, b.security))
83
+ reasons.push('security');
84
+ return reasons;
85
+ }
86
+ function apiReasons(old, next) {
87
+ const reasons = [];
88
+ if (!sameStructure(old.servers, next.servers))
89
+ reasons.push('servers');
90
+ if (!sameStructure(old.security, next.security) || !sameStructure(old.securitySchemes, next.securitySchemes)) {
91
+ reasons.push('security');
92
+ }
93
+ if (old.info.version !== next.info.version)
94
+ reasons.push('version');
95
+ return reasons;
96
+ }
97
+ /**
98
+ * What moving from `old` to `next` would change: added and changed operations in `next`'s document
99
+ * order, removed ones in `old`'s, and the API-level differences.
100
+ */
101
+ export function planRestUpdate(old, next) {
102
+ const before = new Map();
103
+ for (const op of old.operations)
104
+ if (!before.has(keyOf(op)))
105
+ before.set(keyOf(op), op);
106
+ const after = new Set(next.operations.map(keyOf));
107
+ const added = [];
108
+ const changed = [];
109
+ const handled = new Set();
110
+ for (const op of next.operations) {
111
+ const key = keyOf(op);
112
+ if (handled.has(key))
113
+ continue;
114
+ handled.add(key);
115
+ const previous = before.get(key);
116
+ if (previous === undefined) {
117
+ added.push(opRef(op));
118
+ continue;
119
+ }
120
+ const reasons = reasonsFor(previous, op);
121
+ if (reasons.length > 0)
122
+ changed.push({ op: opRef(op), reasons });
123
+ }
124
+ const removed = [...before.entries()].filter(([key]) => !after.has(key)).map(([, op]) => opRef(op));
125
+ return { added, removed, changed, api: apiReasons(old, next), webhooks: planWebhookUpdate(old, next) };
126
+ }
127
+ /**
128
+ * What moving from `old` to `next` would change among webhooks and callbacks: added and changed
129
+ * items keyed as {@link hookKey} matches them, removed ones the same way. Mirrors
130
+ * {@link planRestUpdate}'s per-operation comparison, over {@link webhookSourcesOf} instead of
131
+ * `document.operations`.
132
+ */
133
+ export function planWebhookUpdate(old, next) {
134
+ const before = new Map(webhookSourcesOf(old).map((source) => [source.ref.key, source]));
135
+ const after = new Map(webhookSourcesOf(next).map((source) => [source.ref.key, source]));
136
+ const added = [...after.values()].filter((source) => !before.has(source.ref.key)).map((source) => source.ref);
137
+ const removed = [...before.values()].filter((source) => !after.has(source.ref.key)).map((source) => source.ref);
138
+ const changed = [];
139
+ for (const [key, source] of after) {
140
+ const previous = before.get(key);
141
+ if (previous === undefined)
142
+ continue;
143
+ const reasons = reasonsFor(previous.operation, source.operation);
144
+ if (reasons.length > 0)
145
+ changed.push({ item: source.ref, reasons });
146
+ }
147
+ return { added, removed, changed };
148
+ }
149
+ const contractKey = (request) => request.contract === undefined ? undefined : `${request.contract.method} ${request.contract.path}`;
150
+ function requestsOf(api) {
151
+ const walk = (folder) => [...folder.requests, ...folder.folders.flatMap(walk)];
152
+ return [...api.requests, ...api.folders.flatMap(walk)];
153
+ }
154
+ function byContract(api) {
155
+ const map = new Map();
156
+ for (const request of requestsOf(api)) {
157
+ const key = contractKey(request);
158
+ if (key !== undefined && !map.has(key))
159
+ map.set(key, request);
160
+ }
161
+ return map;
162
+ }
163
+ /** A row's identity within its table: headers are case-insensitive, path and query names are not. */
164
+ const rowKey = (row, caseless) => (caseless ? row.name.toLowerCase() : row.name);
165
+ const sameRow = (a, b) => a.value === b.value && a.enabled === b.enabled;
166
+ /**
167
+ * One parameter table under the per-row rule: an untouched generated row follows (or goes, when the
168
+ * new document dropped it), an edited or user-added row stays, and a row new to the document is
169
+ * appended.
170
+ *
171
+ * With one exception, {@link promoteRequired}: a row the user edited still follows the document from
172
+ * optional to required.
173
+ */
174
+ function mergeRows(current, before, after, caseless) {
175
+ const index = (rows) => {
176
+ const map = new Map();
177
+ for (const row of rows)
178
+ if (!map.has(rowKey(row, caseless)))
179
+ map.set(rowKey(row, caseless), row);
180
+ return map;
181
+ };
182
+ const oldRows = index(before);
183
+ const newRows = index(after);
184
+ const rows = [];
185
+ let removed = 0;
186
+ let changed = false;
187
+ /**
188
+ * The one thing a kept row still follows: a parameter the new document made required turns its
189
+ * row on, so the request stays sendable as the document now demands. Only the box changes — the
190
+ * user's value is kept — and a row the user added by hand has no generated counterpart and is
191
+ * left alone, since the document never claimed it. In practice this is a query parameter: a path
192
+ * row is always on and a header row never is, so neither can make this crossing.
193
+ */
194
+ const promoteRequired = (row, generated) => {
195
+ if (generated === undefined || generated.enabled || row.enabled)
196
+ return row;
197
+ return newRows.get(rowKey(row, caseless))?.enabled === true ? { ...row, enabled: true } : row;
198
+ };
199
+ // Only the first untouched row of a name follows; a duplicate of it is the user's and stays.
200
+ const replaced = new Set();
201
+ for (const row of current) {
202
+ const key = rowKey(row, caseless);
203
+ const generated = oldRows.get(key);
204
+ if (generated === undefined || !sameRow(row, generated) || replaced.has(key)) {
205
+ const kept = promoteRequired(row, generated);
206
+ if (kept !== row)
207
+ changed = true;
208
+ rows.push(kept);
209
+ continue;
210
+ }
211
+ replaced.add(key);
212
+ const replacement = newRows.get(key);
213
+ if (replacement === undefined) {
214
+ removed += 1;
215
+ changed = true;
216
+ continue;
217
+ }
218
+ if (!sameStructure(row, replacement))
219
+ changed = true;
220
+ rows.push(replacement);
221
+ }
222
+ const present = new Set(current.map((row) => rowKey(row, caseless)));
223
+ let added = 0;
224
+ for (const [key, row] of newRows) {
225
+ if (oldRows.has(key) || present.has(key))
226
+ continue;
227
+ rows.push(row);
228
+ added += 1;
229
+ changed = true;
230
+ }
231
+ return { rows, added, removed, changed };
232
+ }
233
+ /**
234
+ * One request as *Update definition* follows it: orphaned when `target` is gone, restored when it
235
+ * came back, and otherwise the per-row and whole-field follow rule against `before` (what the old
236
+ * document mapped it to) and `target` (what the new one does) — untouched url/body/auth follow the
237
+ * new document, `pathParams`/`query`/`headers` merge row by row. Shared by an API's own requests and
238
+ * a webhook group's, which is why `before` may be absent (an API row with no operation to compare
239
+ * against) as well as `target` (an orphan).
240
+ */
241
+ function followRequest(request, before, target, counters) {
242
+ if (target === undefined) {
243
+ if (request.orphaned === true)
244
+ return request;
245
+ counters.orphaned += 1;
246
+ return { ...request, orphaned: true };
247
+ }
248
+ let out = request;
249
+ if (request.orphaned === true) {
250
+ counters.restored += 1;
251
+ const { orphaned, ...rest } = request;
252
+ void orphaned;
253
+ out = rest;
254
+ }
255
+ if (before === undefined)
256
+ return out;
257
+ let rewritten = false;
258
+ if (out.url === before.url && out.url !== target.url) {
259
+ out = { ...out, url: target.url };
260
+ rewritten = true;
261
+ }
262
+ for (const table of ['pathParams', 'query', 'headers']) {
263
+ const merged = mergeRows(out[table], before[table], target[table], table === 'headers');
264
+ if (!merged.changed)
265
+ continue;
266
+ out = { ...out, [table]: merged.rows };
267
+ counters.rowsAdded += merged.added;
268
+ counters.rowsRemoved += merged.removed;
269
+ rewritten = true;
270
+ }
271
+ if (sameStructure(out.body, before.body) && !sameStructure(out.body, target.body)) {
272
+ out = { ...out, body: target.body };
273
+ rewritten = true;
274
+ }
275
+ if (sameStructure(out.auth, before.auth) && !sameStructure(out.auth, target.auth)) {
276
+ out = { ...out, auth: target.auth };
277
+ rewritten = true;
278
+ }
279
+ if (rewritten)
280
+ counters.rewritten += 1;
281
+ return out;
282
+ }
283
+ /**
284
+ * Applies `next` to an API imported from `old`: the request of every operation still in `next`
285
+ * follows it where untouched, the request of every operation gone is orphaned, and every new
286
+ * operation gets a request in the folder the importer would have put it in. Never deletes a request
287
+ * or a folder.
288
+ */
289
+ export function applyRestUpdate(api, old, next, options = {}) {
290
+ const newId = options.newId ?? generateId;
291
+ // The old mapping's ids are never kept: only its generated values are compared.
292
+ const oldMapped = apiFromDocument(old, { ...options, newId: () => 'old' }).api;
293
+ const nextMapped = apiFromDocument(next, { ...options, newId }).api;
294
+ const oldReqs = byContract(oldMapped);
295
+ const nextReqs = byContract(nextMapped);
296
+ const counters = { orphaned: 0, restored: 0, rewritten: 0, rowsAdded: 0, rowsRemoved: 0 };
297
+ const update = (request) => {
298
+ const key = contractKey(request);
299
+ if (key === undefined)
300
+ return request;
301
+ return followRequest(request, oldReqs.get(key), nextReqs.get(key), counters);
302
+ };
303
+ const updateFolder = (folder) => ({
304
+ ...folder,
305
+ folders: folder.folders.map(updateFolder),
306
+ requests: folder.requests.map(update),
307
+ });
308
+ let result = { ...api, folders: api.folders.map(updateFolder), requests: api.requests.map(update) };
309
+ // Operations the API has no request for yet: into the folder the importer names, else the root.
310
+ const have = byContract(result);
311
+ let requestsAdded = 0;
312
+ let requestsAlreadyPresent = 0;
313
+ for (const [key, fresh] of nextReqs) {
314
+ if (have.has(key)) {
315
+ // A request the user made by hand already claims this contract; the plan still lists it as
316
+ // added, so it is counted here rather than silently dropped.
317
+ if (!oldReqs.has(key))
318
+ requestsAlreadyPresent += 1;
319
+ continue;
320
+ }
321
+ const home = nextMapped.folders.find((folder) => folder.requests.some((r) => r.id === fresh.id));
322
+ const place = (siblings) => ({
323
+ ...fresh,
324
+ slug: uniqueSlug(fresh.name, new Set(siblings.map((r) => r.slug))),
325
+ order: siblings.reduce((n, r) => Math.max(n, r.order + 1), 0),
326
+ });
327
+ requestsAdded += 1;
328
+ // Which existing folder is this tag's? The one with the tag's name, else — for a folder the
329
+ // user renamed — the one already holding a request for another of the tag's operations.
330
+ const existing = home === undefined ? undefined : folderFor(result, home);
331
+ if (home === undefined) {
332
+ result = { ...result, requests: [...result.requests, place(result.requests)] };
333
+ }
334
+ else if (existing !== undefined) {
335
+ result = {
336
+ ...result,
337
+ folders: result.folders.map((folder) => folder.id === existing.id ? { ...folder, requests: [...folder.requests, place(folder.requests)] } : folder),
338
+ };
339
+ }
340
+ else {
341
+ const folder = createFolder(home.name, {
342
+ id: newId(),
343
+ slug: uniqueSlug(home.name, new Set(result.folders.map((f) => f.slug))),
344
+ order: result.folders.reduce((n, f) => Math.max(n, f.order + 1), 0),
345
+ ...(home.description !== undefined ? { description: home.description } : {}),
346
+ requests: [place([])],
347
+ });
348
+ result = { ...result, folders: [...result.folders, folder] };
349
+ }
350
+ }
351
+ // API level: the same follow rule, against what the old document mapped to.
352
+ // A value absent on both sides stays absent rather than coming back as an `undefined` key.
353
+ if (result.baseUrl === oldMapped.baseUrl && nextMapped.baseUrl !== undefined) {
354
+ result = { ...result, baseUrl: nextMapped.baseUrl };
355
+ }
356
+ if (sameStructure(result.servers, oldMapped.servers) &&
357
+ nextMapped.servers !== undefined) {
358
+ result = { ...result, servers: nextMapped.servers };
359
+ }
360
+ if (sameStructure(result.auth, oldMapped.auth) && !sameStructure(result.auth, nextMapped.auth)) {
361
+ const { auth, ...rest } = result;
362
+ void auth;
363
+ result = nextMapped.auth === undefined ? rest : { ...rest, auth: nextMapped.auth };
364
+ }
365
+ if (result.definition !== undefined) {
366
+ result = { ...result, definition: { ...result.definition, version: next.declaredVersion } };
367
+ }
368
+ return {
369
+ api: result,
370
+ requestsAdded,
371
+ requestsAlreadyPresent,
372
+ requestsOrphaned: counters.orphaned,
373
+ requestsRestored: counters.restored,
374
+ requestsRewritten: counters.rewritten,
375
+ rowsAdded: counters.rowsAdded,
376
+ rowsRemoved: counters.rowsRemoved,
377
+ };
378
+ }
379
+ /**
380
+ * The folder in `api` that stands for the new document's tag folder `home`: the one with the tag's
381
+ * name, else — for a folder the user renamed — the one already holding a request for another of the
382
+ * tag's operations. Name first: a request the user *moved* out of the tag folder would otherwise
383
+ * make its new home look like the tag's, and put the new operation somewhere the user did not mean.
384
+ */
385
+ function folderFor(api, home) {
386
+ const byName = api.folders.find((folder) => folder.name === home.name);
387
+ if (byName !== undefined)
388
+ return byName;
389
+ const keys = new Set(home.requests.map(contractKey).filter((key) => key !== undefined));
390
+ return api.folders.find((folder) => folder.requests.some((request) => {
391
+ const key = contractKey(request);
392
+ return key !== undefined && keys.has(key);
393
+ }));
394
+ }
395
+ /**
396
+ * Applies `next` to a webhook group imported from `old`: the same follow rule as
397
+ * {@link applyRestUpdate}, matched by {@link hookKey} across the group's whole tree instead of by
398
+ * contract. A request with no `hook` (added by hand) is left untouched; an item's `hook` — including
399
+ * a callback's `expression` — follows the new document, since a renamed expression is not a new
400
+ * item. A new webhook or callback method is appended to the group root with a unique slug and an
401
+ * increasing `order` — but only one truly new to `next`: an item `old` already offered and the group
402
+ * never held (an import that used `only` to leave it unticked) stays absent rather than coming back.
403
+ * Never deletes a request or a folder.
404
+ */
405
+ export function applyWebhookUpdate(folder, old, next, options = {}) {
406
+ const newId = options.newId ?? generateId;
407
+ const index = (document, ids) => {
408
+ const mapped = webhooksFromDocument(document, { ...options, apiId: folder.source?.apiId ?? '', newId: ids });
409
+ const map = new Map();
410
+ for (const request of mapped?.folder.requests ?? []) {
411
+ if (request.hook !== undefined)
412
+ map.set(hookKey(request.hook, request.method), request);
413
+ }
414
+ return map;
415
+ };
416
+ // The old mapping's ids are never kept: only its generated values are compared.
417
+ const before = index(old, () => 'old');
418
+ const after = index(next, newId);
419
+ const counters = { orphaned: 0, restored: 0, rewritten: 0, rowsAdded: 0, rowsRemoved: 0 };
420
+ const seen = new Set();
421
+ const follow = (request) => {
422
+ if (request.hook === undefined)
423
+ return request;
424
+ const key = hookKey(request.hook, request.method);
425
+ seen.add(key);
426
+ const target = after.get(key);
427
+ const followed = followRequest(request, before.get(key), target, counters);
428
+ return target?.hook !== undefined ? { ...followed, hook: target.hook } : followed;
429
+ };
430
+ const walk = (node) => ({
431
+ ...node,
432
+ folders: node.folders.map(walk),
433
+ requests: node.requests.map(follow),
434
+ });
435
+ const walked = walk(folder);
436
+ const requests = [...walked.requests];
437
+ const taken = new Set(requests.map((request) => request.slug));
438
+ let order = requests.reduce((max, request) => Math.max(max, request.order + 1), 0);
439
+ let added = 0;
440
+ for (const [key, fresh] of after) {
441
+ if (seen.has(key) || before.has(key))
442
+ continue;
443
+ const slug = uniqueSlug(fresh.name, taken);
444
+ taken.add(slug);
445
+ requests.push({ ...fresh, slug, order });
446
+ order += 1;
447
+ added += 1;
448
+ }
449
+ return {
450
+ folder: { ...walked, requests },
451
+ added,
452
+ orphaned: counters.orphaned,
453
+ restored: counters.restored,
454
+ rewritten: counters.rewritten,
455
+ };
456
+ }
@@ -26,3 +26,4 @@ export interface MappedPostmanApi {
26
26
  * Maps a parsed Postman Collection into a Wirebench REST API and import summary.
27
27
  */
28
28
  export declare function apiFromPostmanCollection(collection: PostmanCollection, options?: MapPostmanOptions): MappedPostmanApi;
29
+ export declare function unsupportedCalls(text: string): string[];
@@ -44,7 +44,10 @@ export function apiFromPostmanCollection(collection, options = {}) {
44
44
  const apiAuth = mapPostmanAuth(collection.auth, false, warnings);
45
45
  let folderCount = 0;
46
46
  let requestCount = 0;
47
- const mapItems = (items, depth) => {
47
+ let scriptedRequests = 0;
48
+ const unsupported = new Map();
49
+ const collectionParts = scriptParts(collection.event, `the collection "${name}"`);
50
+ const mapItems = (items, depth, inherited, trail) => {
48
51
  if (depth > MAX_POSTMAN_DEPTH) {
49
52
  throw tooDeep();
50
53
  }
@@ -65,7 +68,8 @@ export function apiFromPostmanCollection(collection, options = {}) {
65
68
  const slug = uniqueSlug(item.name, folderSlugs);
66
69
  folderSlugs.add(slug);
67
70
  const folderAuth = mapPostmanAuth(item.auth, false, warnings);
68
- const children = mapItems(item.item, depth + 1);
71
+ const folderTrail = [...trail, item.name];
72
+ const children = mapItems(item.item, depth + 1, joinParts(inherited, scriptParts(item.event, `the folder "${folderTrail.join(' / ')}"`)), folderTrail);
69
73
  folders.push(createFolder(item.name, {
70
74
  id: newId(),
71
75
  slug,
@@ -82,12 +86,26 @@ export function apiFromPostmanCollection(collection, options = {}) {
82
86
  const slug = uniqueSlug(item.name, requestSlugs);
83
87
  requestSlugs.add(slug);
84
88
  const mappedRequest = mapRequest(item.name, slug, requests.length, item, newId, baseUrl, warnings);
85
- requests.push(mappedRequest);
89
+ const parts = joinParts(inherited, scriptParts(item.event, 'the request'));
90
+ const scripts = importedScripts(parts);
91
+ if (scripts !== undefined) {
92
+ scriptedRequests += 1;
93
+ const calls = unsupportedCalls([...parts.pre, ...parts.post].map((part) => part.text).join('\n'));
94
+ if (calls.length > 0)
95
+ unsupported.set([...trail, item.name].join(' / '), new Set(calls));
96
+ }
97
+ requests.push(scripts !== undefined ? { ...mappedRequest, scripts } : mappedRequest);
86
98
  }
87
99
  }
88
100
  return { folders, requests };
89
101
  };
90
- const root = mapItems(collection.item, 1);
102
+ const root = mapItems(collection.item, 1, collectionParts, []);
103
+ if (scriptedRequests > 0) {
104
+ warnings.push(`Scripts on ${String(scriptedRequests)} ${scriptedRequests === 1 ? 'request was' : 'requests were'} imported switched off: read them on each request's Scripts tab, then switch them on`);
105
+ }
106
+ for (const [path, calls] of unsupported) {
107
+ warnings.push(`The scripts of "${path}" call what Wirebench does not run: ${[...calls].sort().join(', ')}`);
108
+ }
91
109
  if (unmappedVariables.size > 0) {
92
110
  warnings.push(`Collection and folder variables were not imported; define them as properties: ${[...unmappedVariables].sort().join(', ')}`);
93
111
  }
@@ -425,3 +443,47 @@ function inferBaseUrl(items, depth) {
425
443
  }
426
444
  return '';
427
445
  }
446
+ function scriptParts(events, from) {
447
+ const pre = [];
448
+ const post = [];
449
+ for (const event of events ?? []) {
450
+ (event.listen === 'prerequest' ? pre : post).push({ from, text: event.exec });
451
+ }
452
+ return { pre, post };
453
+ }
454
+ function joinParts(outer, inner) {
455
+ return { pre: [...outer.pre, ...inner.pre], post: [...outer.post, ...inner.post] };
456
+ }
457
+ /** The parts concatenated in the order Postman runs them, each under a comment saying where it came from. */
458
+ function scriptText(parts) {
459
+ return parts.map((part) => `// --- From ${part.from} ---\n${part.text.replace(/\s+$/, '')}\n`).join('\n');
460
+ }
461
+ /**
462
+ * A request's imported scripts: the collection's, then each enclosing folder's, then its own,
463
+ * written against the Postman layer and switched off until someone has read them (#63).
464
+ */
465
+ function importedScripts(parts) {
466
+ if (parts.pre.length === 0 && parts.post.length === 0)
467
+ return undefined;
468
+ return {
469
+ ...(parts.pre.length > 0 ? { pre: { text: scriptText(parts.pre) } } : {}),
470
+ ...(parts.post.length > 0 ? { post: { text: scriptText(parts.post) } } : {}),
471
+ api: 'postman',
472
+ enabled: false,
473
+ secrets: [],
474
+ };
475
+ }
476
+ /** The Postman calls a script makes that the layer does not run (spec §Postman), found by name. */
477
+ const UNSUPPORTED_CALLS = [
478
+ [/\bpm\.sendRequest\b/, 'pm.sendRequest'],
479
+ [/\bpm\.cookies\.jar\b/, 'pm.cookies.jar'],
480
+ [/\bpm\.visualizer\b/, 'pm.visualizer'],
481
+ [/\bpm\.execution\.setNextRequest\b/, 'pm.execution.setNextRequest'],
482
+ [/\bpostman\.setNextRequest\b/, 'postman.setNextRequest'],
483
+ [/\brequire\s*\(/, 'require'],
484
+ [/\bpm\.iterationData\b/, 'pm.iterationData'],
485
+ [/\bpm\.vault\b/, 'pm.vault'],
486
+ ];
487
+ export function unsupportedCalls(text) {
488
+ return UNSUPPORTED_CALLS.filter(([pattern]) => pattern.test(text)).map(([, name]) => name);
489
+ }
@@ -91,9 +91,16 @@ export interface PostmanRequest {
91
91
  readonly auth?: PostmanAuth;
92
92
  readonly description?: string;
93
93
  }
94
+ /** One of an item's scripts: `prerequest` or `test`, with its source joined into one text. */
95
+ export interface PostmanEvent {
96
+ readonly listen: 'prerequest' | 'test';
97
+ readonly exec: string;
98
+ }
94
99
  export interface PostmanItem {
95
100
  readonly name: string;
96
101
  readonly description?: string;
102
+ /** The item's scripts, kept as source (#63). */
103
+ readonly event?: readonly PostmanEvent[];
97
104
  readonly item?: readonly PostmanItem[];
98
105
  readonly request?: PostmanRequest | string;
99
106
  readonly auth?: PostmanAuth;
@@ -102,6 +109,8 @@ export interface PostmanItem {
102
109
  export interface PostmanCollection {
103
110
  readonly info: PostmanInfo;
104
111
  readonly item: readonly PostmanItem[];
112
+ /** The collection's own scripts, which run around every request in it. */
113
+ readonly event?: readonly PostmanEvent[];
105
114
  readonly auth?: PostmanAuth;
106
115
  readonly variable?: readonly PostmanVariable[];
107
116
  /** Problems found while parsing that the import summary should report. */
@@ -89,7 +89,7 @@ export function parsePostmanCollection(root) {
89
89
  throw new PostmanError('postman-not-a-collection', 'This file does not contain a Postman Collection (v2.0 or v2.1)');
90
90
  }
91
91
  const doc = root;
92
- const ctx = { dynamic: new Set(), skippedItems: 0, scriptedItems: 0 };
92
+ const ctx = { dynamic: new Set(), skippedItems: 0 };
93
93
  const rawInfo = doc['info'];
94
94
  const desc = extractDescription(rawInfo['description']);
95
95
  const version = asString(rawInfo['version']);
@@ -106,28 +106,50 @@ export function parsePostmanCollection(root) {
106
106
  const item = parseItems(rawItems, ctx, 1);
107
107
  const auth = isRecord(doc['auth']) ? parseAuth(doc['auth'], ctx) : undefined;
108
108
  const variable = Array.isArray(doc['variable']) ? parseVariables(doc['variable'], ctx) : undefined;
109
- if (hasEvents(doc))
110
- ctx.scriptedItems += 1;
109
+ const event = parseEvents(doc);
111
110
  const warnings = [];
112
111
  if (ctx.skippedItems > 0) {
113
112
  warnings.push(`${itemCount(ctx.skippedItems)} without a request ${ctx.skippedItems === 1 ? 'was' : 'were'} skipped`);
114
113
  }
115
- if (ctx.scriptedItems > 0) {
116
- warnings.push(`Scripts on ${itemCount(ctx.scriptedItems)} (pre-request and test) were not imported`);
117
- }
118
114
  if (ctx.dynamic.size > 0) {
119
115
  warnings.push(`Dynamic variables are not generated and must be defined as properties: ${[...ctx.dynamic].sort().join(', ')}`);
120
116
  }
121
117
  return {
122
118
  info,
123
119
  item,
120
+ ...(event.length > 0 ? { event } : {}),
124
121
  ...(auth !== undefined ? { auth } : {}),
125
122
  ...(variable !== undefined ? { variable } : {}),
126
123
  ...(warnings.length > 0 ? { warnings } : {}),
127
124
  };
128
125
  }
129
- function hasEvents(raw) {
130
- return Array.isArray(raw['event']) && raw['event'].length > 0;
126
+ /**
127
+ * An item's `prerequest` and `test` scripts, each as one text. `exec` may be a list of lines or one
128
+ * string; a script of another kind, or with no source, is left out.
129
+ */
130
+ function parseEvents(raw) {
131
+ if (!Array.isArray(raw['event']))
132
+ return [];
133
+ const events = [];
134
+ for (const entry of raw['event']) {
135
+ if (!isRecord(entry))
136
+ continue;
137
+ const listen = entry['listen'];
138
+ if (listen !== 'prerequest' && listen !== 'test')
139
+ continue;
140
+ const script = isRecord(entry['script']) ? entry['script'] : undefined;
141
+ if (script !== undefined && script['disabled'] === true)
142
+ continue;
143
+ const exec = script?.['exec'];
144
+ const text = Array.isArray(exec)
145
+ ? exec.filter((line) => typeof line === 'string').join('\n')
146
+ : typeof exec === 'string'
147
+ ? exec
148
+ : '';
149
+ if (text.trim() !== '')
150
+ events.push({ listen, exec: text });
151
+ }
152
+ return events;
131
153
  }
132
154
  function parseItems(raw, ctx, depth) {
133
155
  if (depth > MAX_POSTMAN_DEPTH) {
@@ -148,14 +170,14 @@ function parseItem(raw, ctx, depth) {
148
170
  const description = extractDescription(raw['description']);
149
171
  const auth = isRecord(raw['auth']) ? parseAuth(raw['auth'], ctx) : undefined;
150
172
  const variable = Array.isArray(raw['variable']) ? parseVariables(raw['variable'], ctx) : undefined;
151
- if (hasEvents(raw))
152
- ctx.scriptedItems += 1;
173
+ const event = parseEvents(raw);
153
174
  if (Array.isArray(raw['item'])) {
154
175
  // Folder item
155
176
  const children = parseItems(raw['item'], ctx, depth + 1);
156
177
  return {
157
178
  name,
158
179
  item: children,
180
+ ...(event.length > 0 ? { event } : {}),
159
181
  ...(description !== undefined ? { description } : {}),
160
182
  ...(auth !== undefined ? { auth } : {}),
161
183
  ...(variable !== undefined ? { variable } : {}),
@@ -170,6 +192,7 @@ function parseItem(raw, ctx, depth) {
170
192
  return {
171
193
  name,
172
194
  request,
195
+ ...(event.length > 0 ? { event } : {}),
173
196
  ...(description !== undefined ? { description } : {}),
174
197
  ...(auth !== undefined ? { auth } : {}),
175
198
  ...(variable !== undefined ? { variable } : {}),