@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
@@ -7,507 +7,23 @@
7
7
  * recoverable inconsistency (an orphaned envelope, an operation folder no
8
8
  * interface declares) becomes a {@link ProjectProblem} rather than an error, so
9
9
  * a slightly damaged project still opens.
10
+ *
11
+ * Core reads the manifest, environments, sequences, keystores, WS-Security references and the
12
+ * webhook collection. A container is read by its protocol's `storage.load` (`soap/storage.ts`,
13
+ * `rest/storage.ts`, `grpc/storage.ts`, `ws/storage.ts`), found through the registry.
10
14
  */
11
- import { join } from 'node:path';
12
15
  import { ProjectError } from '../errors.js';
13
- import { FORMAT_VERSION } from './model.js';
14
- import { nodeFs, readFileIfExists, readdirIfExists } from './fs.js';
16
+ import { defaultRegistry } from '../protocols.js';
17
+ import { restRequestReader, signingOf } from '../rest/storage.js';
18
+ import { readSequences } from '../sequence/load.js';
19
+ import { nodeFs, readdirIfExists } from './fs.js';
20
+ import { abs, authConfig, byOrder, exact, loadFolderContents, optional, readYaml } from './load-helpers.js';
15
21
  import { migrate } from './migrate.js';
16
- import { normalizeWsa } from '../wsa/model.js';
17
- import { API_FILE, APIS_DIR, assertPathSegment, ENVIRONMENTS_DIR, FOLDER_FILE, INTERFACES_DIR, MAX_FOLDER_DEPTH, OPERATIONS_DIR, REQUEST_SUFFIX, REQUESTS_DIR, WSS_DIR, } from './paths.js';
18
- import { apiFileSchema, apiKindOf, assertSupportedKind, grpcApiFileSchema, grpcRequestFileSchema, environmentFileSchema, interfaceFileSchema, keystoresFileSchema, manifestSchema, parseFile, requestFileSchema, restFolderFileSchema, restRequestFileSchema, wsApiFileSchema, wsRequestFileSchema, wssIncomingFileSchema, wssOutgoingFileSchema, } from './schema.js';
22
+ import { FORMAT_VERSION } from './model.js';
23
+ import { API_FILE, APIS_DIR, ENVIRONMENTS_DIR, INTERFACES_DIR, REQUESTS_DIR, WEBHOOKS_DIR, WEBHOOKS_FEATURE, WEBHOOKS_FILE, WSS_DIR, } from './paths.js';
24
+ import { parseFile } from './schema-parts.js';
25
+ import { environmentFileSchema, keystoresFileSchema, manifestSchema, webhookFolderFileSchema, webhooksFileSchema, wssIncomingFileSchema, wssOutgoingFileSchema, } from './schema.js';
19
26
  import { KEYSTORES_PATH, MANIFEST_PATH } from './serialize.js';
20
- import { parseYaml } from './yaml.js';
21
- function abs(root, relative) {
22
- return join(root, ...relative.split('/'));
23
- }
24
- async function readYaml(fs, root, relative) {
25
- const buffer = await readFileIfExists(fs, abs(root, relative));
26
- return buffer === undefined ? undefined : parseYaml(buffer.toString('utf8'), relative);
27
- }
28
- /** Orders entities by their persisted `order`, falling back to a stable name comparison. */
29
- function byOrder(a, b) {
30
- return a.order - b.order || a.name.localeCompare(b.name);
31
- }
32
- function optional(key, value) {
33
- return value === undefined ? {} : { [key]: value };
34
- }
35
- /**
36
- * Drops `undefined`-valued keys from a zod result, so an absent optional field
37
- * is truly absent rather than present-and-undefined (`exactOptionalPropertyTypes`).
38
- */
39
- function exact(value) {
40
- const out = {};
41
- for (const key of Object.keys(value)) {
42
- const entry = value[key];
43
- if (entry !== undefined) {
44
- out[key] = entry;
45
- }
46
- }
47
- return out;
48
- }
49
- async function loadRequests(fs, root, dir, problems) {
50
- const requests = [];
51
- const entries = await readdirIfExists(fs, abs(root, dir));
52
- const names = new Set(entries.filter((e) => e.isFile).map((e) => e.name));
53
- for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
54
- if (!entry.isFile || !entry.name.endsWith(REQUEST_SUFFIX)) {
55
- continue;
56
- }
57
- const slug = entry.name.slice(0, -REQUEST_SUFFIX.length);
58
- const relative = `${dir}/${entry.name}`;
59
- const document = await readYaml(fs, root, relative);
60
- assertSupportedKind(document, relative);
61
- const parsed = parseFile(requestFileSchema, document, relative);
62
- const xmlRelative = `${dir}/${slug}.xml`;
63
- const envelope = await readFileIfExists(fs, abs(root, xmlRelative));
64
- if (envelope === undefined) {
65
- problems.push({
66
- code: 'missing-envelope',
67
- message: `Request "${parsed.name}" has no envelope file; loaded with an empty body`,
68
- file: xmlRelative,
69
- });
70
- }
71
- names.delete(entry.name);
72
- names.delete(`${slug}.xml`);
73
- requests.push({
74
- kind: 'soap',
75
- id: parsed.id,
76
- name: parsed.name,
77
- slug,
78
- order: parsed.order,
79
- ...optional('description', parsed.description),
80
- ...optional('endpointId', parsed.endpointId),
81
- ...optional('endpointUrl', parsed.endpointUrl),
82
- soapVersion: parsed.soapVersion,
83
- ...optional('soapAction', parsed.soapAction),
84
- headers: parsed.headers,
85
- attachments: parsed.attachments.map((a) => exact(a)),
86
- ...optional('auth', parsed.auth),
87
- ...(parsed.wsa !== undefined ? { wsa: normalizeWsa(parsed.wsa) } : {}),
88
- ...optional('wssOutgoingRef', parsed.wssOutgoingRef),
89
- ...optional('wssIncomingRef', parsed.wssIncomingRef),
90
- properties: exact(parsed.properties),
91
- assertions: parsed.assertions.map((a) => exact(a)),
92
- ...(parsed.orphaned === true ? { orphaned: true } : {}),
93
- envelopeXml: envelope === undefined ? '' : envelope.toString('utf8'),
94
- });
95
- }
96
- for (const orphan of [...names].sort()) {
97
- problems.push({
98
- code: 'orphan-request-file',
99
- message: `"${orphan}" does not belong to any request`,
100
- file: `${dir}/${orphan}`,
101
- });
102
- }
103
- return requests.sort(byOrder);
104
- }
105
- async function loadInterface(fs, root, slug, problems) {
106
- const relative = `${INTERFACES_DIR}/${slug}/interface.yaml`;
107
- const document = await readYaml(fs, root, relative);
108
- if (document === undefined) {
109
- problems.push({
110
- code: 'missing-interface-file',
111
- message: `Folder "${slug}" has no interface.yaml and was skipped`,
112
- file: relative,
113
- });
114
- return undefined;
115
- }
116
- assertSupportedKind(document, relative);
117
- const parsed = parseFile(interfaceFileSchema, document, relative);
118
- const operationsDir = `${INTERFACES_DIR}/${slug}/${OPERATIONS_DIR}`;
119
- const folders = new Set((await readdirIfExists(fs, abs(root, operationsDir))).filter((e) => e.isDirectory).map((e) => e.name));
120
- const operations = [];
121
- for (const entry of parsed.operations) {
122
- folders.delete(entry.slug);
123
- operations.push({
124
- name: entry.name,
125
- bindingName: entry.bindingName,
126
- slug: entry.slug,
127
- order: entry.order,
128
- requests: await loadRequests(fs, root, `${operationsDir}/${entry.slug}`, problems),
129
- });
130
- }
131
- for (const orphan of [...folders].sort()) {
132
- problems.push({
133
- code: 'orphan-operation-folder',
134
- message: `Operation folder "${orphan}" is not listed in interface.yaml`,
135
- file: `${operationsDir}/${orphan}`,
136
- });
137
- }
138
- const endpoints = parsed.endpoints.map((e) => ({
139
- id: e.id,
140
- name: e.name,
141
- url: e.url,
142
- ...optional('auth', e.auth),
143
- authMode: e.authMode,
144
- }));
145
- return {
146
- kind: 'soap',
147
- id: parsed.id,
148
- name: parsed.name,
149
- slug,
150
- order: parsed.order,
151
- definitionUrl: parsed.definitionUrl,
152
- cacheDefinition: parsed.cacheDefinition,
153
- ...optional('targetNamespace', parsed.targetNamespace),
154
- endpoints,
155
- ...optional('defaultEndpointId', parsed.defaultEndpointId),
156
- wsa: normalizeWsa(parsed.wsa),
157
- ...optional('auth', parsed.auth),
158
- operations: operations.sort(byOrder),
159
- };
160
- }
161
- /**
162
- * Authentication as loaded: the same `undefined`-key drop {@link exact} performs, expressed
163
- * separately because `AuthConfig` is a union and so has no single mapped shape to hand `exact`.
164
- * The cast is safe for the same reason `exact`'s is: the schema has already established the
165
- * arm's own fields, and this only removes keys whose value is absent.
166
- */
167
- function authConfig(parsed) {
168
- const out = {};
169
- for (const [key, value] of Object.entries(parsed)) {
170
- if (value !== undefined) {
171
- out[key] = value;
172
- }
173
- }
174
- return out;
175
- }
176
- /** A table row as loaded: `enabled` defaults to true, an absent description stays absent. */
177
- function keyValueEntries(rows) {
178
- return rows.map((row) => exact({ name: row.name, value: row.value, enabled: row.enabled, description: row.description }));
179
- }
180
- /**
181
- * One request body as loaded. A raw body's text lives in a sibling file, so it is read here and
182
- * the file name is dropped: the model holds the text, the layout holds the name
183
- * (`project/paths.ts` rebuilds it on save from the language).
184
- */
185
- async function loadBody(fs, root, dir, document, requestName, problems) {
186
- switch (document.kind) {
187
- case 'raw': {
188
- const relative = `${dir}/${document.file}`;
189
- const text = await readFileIfExists(fs, abs(root, relative));
190
- if (text === undefined) {
191
- problems.push({
192
- code: 'missing-body',
193
- message: `Request "${requestName}" has no body file; loaded with an empty body`,
194
- file: relative,
195
- });
196
- }
197
- return {
198
- kind: 'raw',
199
- language: document.language,
200
- ...optional('contentType', document.contentType),
201
- text: text === undefined ? '' : text.toString('utf8'),
202
- };
203
- }
204
- case 'form':
205
- return { kind: 'form', fields: keyValueEntries(document.fields) };
206
- case 'multipart':
207
- return {
208
- kind: 'multipart',
209
- parts: document.parts.map((part) => part.kind === 'text'
210
- ? exact({ ...part, kind: 'text' })
211
- : exact({ ...part, kind: 'file' })),
212
- };
213
- case 'binary':
214
- return { kind: 'binary', source: document.source, contentType: document.contentType };
215
- default:
216
- return { kind: 'none' };
217
- }
218
- }
219
- /** Reads a REST request and its raw body file. */
220
- function restRequestReader(fs, root, problems) {
221
- return async (dir, fileName, unclaimed) => {
222
- const relative = `${dir}/${fileName}`;
223
- const document = await readYaml(fs, root, relative);
224
- assertSupportedKind(document, relative);
225
- const parsed = parseFile(restRequestFileSchema, document, relative);
226
- unclaimed.delete(fileName);
227
- if (parsed.body.kind === 'raw') {
228
- unclaimed.delete(parsed.body.file);
229
- }
230
- return {
231
- kind: 'rest',
232
- id: parsed.id,
233
- name: parsed.name,
234
- slug: fileName.slice(0, -REQUEST_SUFFIX.length),
235
- order: parsed.order,
236
- ...optional('description', parsed.description),
237
- method: parsed.method,
238
- url: parsed.url,
239
- pathParams: keyValueEntries(parsed.pathParams),
240
- query: keyValueEntries(parsed.query),
241
- headers: keyValueEntries(parsed.headers),
242
- body: await loadBody(fs, root, dir, parsed.body, parsed.name, problems),
243
- auth: authConfig(parsed.auth),
244
- settings: exact(parsed.settings),
245
- assertions: parsed.assertions.map((a) => exact(a)),
246
- ...(parsed.orphaned === true ? { orphaned: true } : {}),
247
- };
248
- };
249
- }
250
- /**
251
- * Reads a gRPC request and its message file. A request whose message file is gone loads with an
252
- * empty message and a `missing-body` problem, exactly as a REST raw body does.
253
- */
254
- function grpcRequestReader(fs, root, problems) {
255
- return async (dir, fileName, unclaimed) => {
256
- const relative = `${dir}/${fileName}`;
257
- const document = await readYaml(fs, root, relative);
258
- assertSupportedKind(document, relative);
259
- const parsed = parseFile(grpcRequestFileSchema, document, relative);
260
- unclaimed.delete(fileName);
261
- let message = '';
262
- if (parsed.message !== undefined) {
263
- unclaimed.delete(parsed.message);
264
- const messageRelative = `${dir}/${parsed.message}`;
265
- const text = await readFileIfExists(fs, abs(root, messageRelative));
266
- if (text === undefined) {
267
- problems.push({
268
- code: 'missing-body',
269
- message: `Request "${parsed.name}" has no message file; loaded with an empty message`,
270
- file: messageRelative,
271
- });
272
- }
273
- else {
274
- message = text.toString('utf8');
275
- }
276
- }
277
- return {
278
- kind: 'grpc',
279
- id: parsed.id,
280
- name: parsed.name,
281
- slug: fileName.slice(0, -REQUEST_SUFFIX.length),
282
- order: parsed.order,
283
- ...optional('description', parsed.description),
284
- service: parsed.service,
285
- method: parsed.method,
286
- methodKind: parsed.methodKind,
287
- metadata: keyValueEntries(parsed.metadata),
288
- message,
289
- auth: authConfig(parsed.auth),
290
- settings: exact(parsed.settings),
291
- ...(parsed.orphaned === true ? { orphaned: true } : {}),
292
- };
293
- };
294
- }
295
- /**
296
- * Reads a WebSocket request and its saved messages, each in its own sibling file. A message whose
297
- * file is gone loads with empty content and a `missing-body` problem, exactly as a gRPC message
298
- * does; its slug is recovered from the file name between the `.msg-` marker and the extension.
299
- */
300
- function wsRequestReader(fs, root, problems) {
301
- return async (dir, fileName, unclaimed) => {
302
- const relative = `${dir}/${fileName}`;
303
- const document = await readYaml(fs, root, relative);
304
- assertSupportedKind(document, relative);
305
- const parsed = parseFile(wsRequestFileSchema, document, relative);
306
- unclaimed.delete(fileName);
307
- const requestSlug = fileName.slice(0, -REQUEST_SUFFIX.length);
308
- const messages = [];
309
- for (const entry of parsed.messages) {
310
- assertPathSegment(entry.file);
311
- unclaimed.delete(entry.file);
312
- const messageRelative = `${dir}/${entry.file}`;
313
- const text = await readFileIfExists(fs, abs(root, messageRelative));
314
- if (text === undefined) {
315
- problems.push({
316
- code: 'missing-body',
317
- message: `Request "${parsed.name}" has no message file; loaded with an empty message`,
318
- file: messageRelative,
319
- });
320
- }
321
- const slug = entry.file.slice(`${requestSlug}.msg-`.length, entry.file.lastIndexOf('.'));
322
- messages.push({
323
- id: entry.id,
324
- name: entry.name,
325
- slug,
326
- format: entry.format,
327
- content: text === undefined ? '' : text.toString('utf8'),
328
- });
329
- }
330
- return {
331
- kind: 'websocket',
332
- id: parsed.id,
333
- name: parsed.name,
334
- slug: requestSlug,
335
- order: parsed.order,
336
- ...optional('description', parsed.description),
337
- url: parsed.url,
338
- query: keyValueEntries(parsed.query),
339
- headers: keyValueEntries(parsed.headers),
340
- subprotocols: parsed.subprotocols,
341
- auth: authConfig(parsed.auth),
342
- settings: exact(parsed.settings),
343
- messages,
344
- };
345
- };
346
- }
347
- /**
348
- * Loads one directory of an API's request tree: its `*.request.yaml` files as requests (through
349
- * the protocol's reader), its subdirectories as folders, recursively.
350
- *
351
- * A directory with no `folder.yaml` is still a folder — named after the directory, ordered after
352
- * the ones that do have a file, and given a file of its own on the next save — because a folder
353
- * someone created with `mkdir` in a checked-out project is a folder, not a fault. A directory
354
- * deeper than {@link MAX_FOLDER_DEPTH} becomes a problem and is skipped whole, so nothing is ever
355
- * written to a path that might not open on Windows.
356
- */
357
- async function loadFolderContents(fs, root, dir, depth, problems, readRequest) {
358
- const entries = await readdirIfExists(fs, abs(root, dir));
359
- const unclaimed = new Set(entries.filter((e) => e.isFile && e.name !== FOLDER_FILE).map((e) => e.name));
360
- const requests = [];
361
- const folders = [];
362
- for (const entry of [...entries].sort((a, b) => a.name.localeCompare(b.name))) {
363
- if (entry.isFile && entry.name.endsWith(REQUEST_SUFFIX)) {
364
- requests.push(await readRequest(dir, entry.name, unclaimed));
365
- continue;
366
- }
367
- if (!entry.isDirectory) {
368
- continue;
369
- }
370
- const childDir = `${dir}/${entry.name}`;
371
- if (depth + 1 > MAX_FOLDER_DEPTH) {
372
- problems.push({
373
- code: 'folder-too-deep',
374
- message: `Folder "${entry.name}" is nested more than ${String(MAX_FOLDER_DEPTH)} deep and was skipped`,
375
- file: childDir,
376
- });
377
- continue;
378
- }
379
- const contents = await loadFolderContents(fs, root, childDir, depth + 1, problems, readRequest);
380
- const relative = `${childDir}/${FOLDER_FILE}`;
381
- const document = await readYaml(fs, root, relative);
382
- const parsed = document === undefined ? undefined : parseFile(restFolderFileSchema, document, relative);
383
- folders.push({
384
- id: parsed?.id ?? `folder:${entry.name}`,
385
- name: parsed?.name ?? entry.name,
386
- slug: entry.name,
387
- order: parsed?.order ?? Number.MAX_SAFE_INTEGER,
388
- ...optional('description', parsed?.description),
389
- ...(parsed?.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
390
- folders: contents.folders,
391
- requests: contents.requests,
392
- });
393
- }
394
- for (const orphan of [...unclaimed].sort()) {
395
- problems.push({
396
- code: 'orphan-request-file',
397
- message: `"${orphan}" does not belong to any request`,
398
- file: `${dir}/${orphan}`,
399
- });
400
- }
401
- return { folders: folders.sort(byOrder), requests: requests.sort(byOrder) };
402
- }
403
- /** Loads one `apis/<slug>/` directory, or records a problem and returns nothing. */
404
- async function loadApi(fs, root, slug, problems) {
405
- const relative = `${APIS_DIR}/${slug}/${API_FILE}`;
406
- const document = await readYaml(fs, root, relative);
407
- if (document === undefined) {
408
- problems.push({
409
- code: 'missing-api-file',
410
- message: `Folder "${slug}" has no ${API_FILE} and was skipped`,
411
- file: relative,
412
- });
413
- return undefined;
414
- }
415
- assertSupportedKind(document, relative);
416
- const requestsDir = `${APIS_DIR}/${slug}/${REQUESTS_DIR}`;
417
- switch (apiKindOf(document)) {
418
- case 'grpc': {
419
- const parsed = parseFile(grpcApiFileSchema, document, relative);
420
- const contents = await loadFolderContents(fs, root, requestsDir, 0, problems, grpcRequestReader(fs, root, problems));
421
- return {
422
- kind: 'grpc',
423
- api: {
424
- kind: 'grpc',
425
- id: parsed.id,
426
- name: parsed.name,
427
- slug,
428
- order: parsed.order,
429
- ...optional('description', parsed.description),
430
- target: parsed.target,
431
- tls: parsed.tls,
432
- metadata: keyValueEntries(parsed.metadata),
433
- ...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
434
- ...(parsed.definition !== undefined
435
- ? {
436
- definition: {
437
- kind: parsed.definition.kind,
438
- source: parsed.definition.source,
439
- cache: parsed.definition.cache,
440
- roots: parsed.definition.roots,
441
- ...optional('reflectionVersion', parsed.definition.reflectionVersion),
442
- ...optional('trustInvalid', parsed.definition.trustInvalid),
443
- },
444
- }
445
- : {}),
446
- folders: contents.folders,
447
- requests: contents.requests,
448
- },
449
- };
450
- }
451
- case 'websocket': {
452
- const parsed = parseFile(wsApiFileSchema, document, relative);
453
- const contents = await loadFolderContents(fs, root, requestsDir, 0, problems, wsRequestReader(fs, root, problems));
454
- return {
455
- kind: 'websocket',
456
- api: {
457
- kind: 'websocket',
458
- id: parsed.id,
459
- name: parsed.name,
460
- slug,
461
- order: parsed.order,
462
- ...optional('description', parsed.description),
463
- url: parsed.url,
464
- headers: keyValueEntries(parsed.headers),
465
- ...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
466
- ...(parsed.definition !== undefined
467
- ? {
468
- definition: {
469
- kind: parsed.definition.kind,
470
- source: parsed.definition.source,
471
- cache: parsed.definition.cache,
472
- },
473
- }
474
- : {}),
475
- folders: contents.folders,
476
- requests: contents.requests,
477
- },
478
- };
479
- }
480
- default: {
481
- const parsed = parseFile(apiFileSchema, document, relative);
482
- const contents = await loadFolderContents(fs, root, requestsDir, 0, problems, restRequestReader(fs, root, problems));
483
- return {
484
- kind: 'rest',
485
- api: {
486
- kind: 'rest',
487
- id: parsed.id,
488
- name: parsed.name,
489
- slug,
490
- order: parsed.order,
491
- ...optional('description', parsed.description),
492
- baseUrl: parsed.baseUrl,
493
- servers: parsed.servers.map((server) => exact(server)),
494
- ...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
495
- ...(parsed.definition !== undefined
496
- ? {
497
- definition: {
498
- source: parsed.definition.source,
499
- cache: parsed.definition.cache,
500
- version: parsed.definition.version,
501
- },
502
- }
503
- : {}),
504
- folders: contents.folders,
505
- requests: contents.requests,
506
- },
507
- };
508
- }
509
- }
510
- }
511
27
  async function loadEnvironments(fs, root) {
512
28
  const environments = [];
513
29
  for (const entry of await readdirIfExists(fs, abs(root, ENVIRONMENTS_DIR))) {
@@ -542,15 +58,98 @@ async function loadWssRefs(fs, root, direction) {
542
58
  }
543
59
  return refs.sort((a, b) => a.name.localeCompare(b.name));
544
60
  }
61
+ /** Loads `webhooks/`, or nothing when the project has no `webhooks.yaml`. */
62
+ async function loadWebhooks(fs, root, problems) {
63
+ const relative = `${WEBHOOKS_DIR}/${WEBHOOKS_FILE}`;
64
+ const document = await readYaml(fs, root, relative);
65
+ if (document === undefined)
66
+ return undefined;
67
+ const parsed = parseFile(webhooksFileSchema, document, relative);
68
+ const contents = await loadFolderContents(fs, root, `${WEBHOOKS_DIR}/${REQUESTS_DIR}`, 0, problems, restRequestReader(fs, root, problems), (folderDocument, folderFile) => {
69
+ if (folderDocument === undefined)
70
+ return {};
71
+ const folder = parseFile(webhookFolderFileSchema, folderDocument, folderFile);
72
+ return {
73
+ ...optional('target', folder.target),
74
+ ...(folder.source !== undefined ? { source: { apiId: folder.source.apiId } } : {}),
75
+ ...(folder.signing !== undefined ? { signing: signingOf(folder.signing) } : {}),
76
+ };
77
+ });
78
+ return {
79
+ target: parsed.target,
80
+ ...(parsed.auth !== undefined ? { auth: authConfig(parsed.auth) } : {}),
81
+ ...(parsed.signing !== undefined ? { signing: signingOf(parsed.signing) } : {}),
82
+ folders: contents.folders,
83
+ requests: contents.requests,
84
+ };
85
+ }
545
86
  /**
546
- * Loads the project stored in the directory `root`.
87
+ * The two directories a project keeps containers in: each one's container file, the kind a file
88
+ * without one has (the directory's first protocol), and the problem an empty directory is.
89
+ */
90
+ const CONTAINER_DIRS = [
91
+ { dir: INTERFACES_DIR, file: 'interface.yaml', defaultKind: 'soap', missing: 'missing-interface-file' },
92
+ { dir: APIS_DIR, file: API_FILE, defaultKind: 'rest', missing: 'missing-api-file' },
93
+ ];
94
+ /** A container file's `kind`, or `fallback` when it has none. */
95
+ function kindOf(document, fallback) {
96
+ const kind = typeof document === 'object' && document !== null ? document['kind'] : undefined;
97
+ return typeof kind === 'string' ? kind : fallback;
98
+ }
99
+ /**
100
+ * The storage that reads a container file found in `layout.dir`: the enabled module its `kind`
101
+ * names, when that module keeps its containers in this directory. Undefined makes a placeholder.
102
+ */
103
+ function storageFor(registry, layout, document) {
104
+ const storage = registry.find(kindOf(document, layout.defaultKind))?.storage;
105
+ return storage?.dir === layout.dir ? storage : undefined;
106
+ }
107
+ /**
108
+ * What is kept of a container no enabled module reads (spec §6): where it is, its kind as written,
109
+ * why it was not loaded, and its name and order when the file has them as a string and a number.
110
+ */
111
+ function placeholderOf(registry, layout, slug, document) {
112
+ const kind = kindOf(document, layout.defaultKind);
113
+ const fields = typeof document === 'object' && document !== null ? document : {};
114
+ const name = fields['name'];
115
+ const order = fields['order'];
116
+ return {
117
+ dir: layout.dir,
118
+ slug,
119
+ kind,
120
+ // A kind the registry has a module for but in the other directory is unknown here.
121
+ reason: registry.status(kind) === 'disabled' ? 'feature-disabled' : 'unknown-kind',
122
+ ...(typeof name === 'string' ? { name } : {}),
123
+ ...(typeof order === 'number' ? { order } : {}),
124
+ };
125
+ }
126
+ /** The problem a placeholder is reported with. */
127
+ function unsupportedProblem(placeholder, file) {
128
+ const why = placeholder.reason === 'feature-disabled'
129
+ ? 'that protocol is switched off'
130
+ : `this build has no such protocol for ${placeholder.dir}/`;
131
+ return {
132
+ code: 'container-unsupported',
133
+ message: `${file} is a "${placeholder.kind}" container, and ${why}; it was not loaded and is left as it is`,
134
+ file,
135
+ details: { kind: placeholder.kind, reason: placeholder.reason, dir: placeholder.dir, slug: placeholder.slug },
136
+ };
137
+ }
138
+ /**
139
+ * Loads the project stored in the directory `root`. Each container directory under `interfaces/`
140
+ * and `apis/` is read by the protocol module its container file's `kind` names (spec §5.1). A
141
+ * container whose kind has no enabled module in that directory becomes a placeholder in
142
+ * `project.unsupported` and a `container-unsupported` problem; nothing below its directory is read
143
+ * but its container file, and a save leaves all of it as it is (spec §6).
547
144
  *
548
145
  * @throws ProjectError `project-not-found` when there is no `wirebench.yaml`,
549
146
  * `project-format-too-new` for a newer format version, `project-file-invalid`
550
- * for malformed or schema-violating YAML (with the offending file in `details`).
147
+ * for malformed or schema-violating YAML (with the offending file in `details`),
148
+ * `project-kind-not-supported` for a request file of a kind this build has no module for.
551
149
  */
552
150
  export async function loadProject(root, options) {
553
151
  const fs = options?.fs ?? nodeFs;
152
+ const registry = options?.registry ?? defaultRegistry();
554
153
  const manifestDocument = await readYaml(fs, root, MANIFEST_PATH);
555
154
  if (manifestDocument === undefined) {
556
155
  throw new ProjectError('project-not-found', `No ${MANIFEST_PATH} in ${root}`, {
@@ -559,47 +158,55 @@ export async function loadProject(root, options) {
559
158
  }
560
159
  const manifest = parseFile(manifestSchema, migrate(manifestDocument, MANIFEST_PATH), MANIFEST_PATH);
561
160
  const problems = [];
562
- const interfaces = [];
563
- for (const entry of await readdirIfExists(fs, abs(root, INTERFACES_DIR))) {
564
- if (!entry.isDirectory) {
565
- continue;
566
- }
567
- const iface = await loadInterface(fs, root, entry.name, problems);
568
- if (iface !== undefined) {
569
- interfaces.push(iface);
570
- }
571
- }
572
- const interfaceSlugs = new Set(interfaces.map((iface) => iface.slug.toLowerCase()));
573
- const apis = [];
574
- const grpcApis = [];
575
- const wsApis = [];
576
- for (const entry of await readdirIfExists(fs, abs(root, APIS_DIR))) {
577
- if (!entry.isDirectory) {
578
- continue;
579
- }
580
- const loaded = await loadApi(fs, root, entry.name, problems);
581
- if (loaded === undefined) {
582
- continue;
583
- }
584
- // An environment's endpoint overrides are keyed by slug, so two entities sharing one would
585
- // make the override ambiguous. The folders never collide; the override key would. REST and
586
- // gRPC APIs share one directory, so their slugs cannot collide with each other.
587
- if (interfaceSlugs.has(loaded.api.slug.toLowerCase())) {
588
- problems.push({
589
- code: 'api-slug-conflict',
590
- message: `API "${loaded.api.name}" and an interface share the slug "${loaded.api.slug}"; the API was skipped`,
591
- file: `${APIS_DIR}/${loaded.api.slug}/${API_FILE}`,
592
- });
593
- continue;
594
- }
595
- if (loaded.kind === 'grpc') {
596
- grpcApis.push(loaded.api);
597
- }
598
- else if (loaded.kind === 'websocket') {
599
- wsApis.push(loaded.api);
600
- }
601
- else {
602
- apis.push(loaded.api);
161
+ const ctx = { fs, root, problems };
162
+ const loaded = new Map();
163
+ const unsupported = [];
164
+ const interfaceSlugs = new Set();
165
+ for (const layout of CONTAINER_DIRS) {
166
+ for (const entry of await readdirIfExists(fs, abs(root, layout.dir))) {
167
+ if (!entry.isDirectory) {
168
+ continue;
169
+ }
170
+ const relative = `${layout.dir}/${entry.name}/${layout.file}`;
171
+ const document = await readYaml(fs, root, relative);
172
+ if (document === undefined) {
173
+ problems.push({
174
+ code: layout.missing,
175
+ message: `Folder "${entry.name}" has no ${layout.file} and was skipped`,
176
+ file: relative,
177
+ });
178
+ continue;
179
+ }
180
+ const storage = storageFor(registry, layout, document);
181
+ if (storage === undefined) {
182
+ // Kept whatever its slug: a placeholder that was skipped would not be live, and the next
183
+ // save would delete the directory this build could not read.
184
+ const placeholder = placeholderOf(registry, layout, entry.name, document);
185
+ unsupported.push(placeholder);
186
+ problems.push(unsupportedProblem(placeholder, relative));
187
+ continue;
188
+ }
189
+ const container = await storage.load(ctx, entry.name, document);
190
+ if (container === undefined) {
191
+ continue;
192
+ }
193
+ if (layout.dir === INTERFACES_DIR) {
194
+ interfaceSlugs.add(container.slug.toLowerCase());
195
+ }
196
+ else if (interfaceSlugs.has(container.slug.toLowerCase())) {
197
+ // An environment's endpoint overrides are keyed by slug, so two entities sharing one would
198
+ // make the override ambiguous. The folders never collide; the override key would. Every
199
+ // kind of API shares one directory, so their slugs cannot collide with each other.
200
+ problems.push({
201
+ code: 'api-slug-conflict',
202
+ message: `API "${container.name}" and an interface share the slug "${container.slug}"; the API was skipped`,
203
+ file: `${APIS_DIR}/${container.slug}/${API_FILE}`,
204
+ });
205
+ continue;
206
+ }
207
+ const containers = loaded.get(storage) ?? [];
208
+ containers.push(container);
209
+ loaded.set(storage, containers);
603
210
  }
604
211
  }
605
212
  const keystoresDocument = await readYaml(fs, root, KEYSTORES_PATH);
@@ -610,7 +217,11 @@ export async function loadProject(root, options) {
610
217
  name: k.name,
611
218
  document: k,
612
219
  }));
613
- const project = {
220
+ const sequenceFiles = await readSequences(fs, root);
221
+ problems.push(...sequenceFiles.problems);
222
+ // The collection is REST requests: with REST off it is not read, and a save leaves it alone.
223
+ const webhooks = registry.features.isEnabled(WEBHOOKS_FEATURE) ? await loadWebhooks(fs, root, problems) : undefined;
224
+ const core = {
614
225
  formatVersion: FORMAT_VERSION,
615
226
  id: manifest.id,
616
227
  name: manifest.name,
@@ -619,16 +230,28 @@ export async function loadProject(root, options) {
619
230
  properties: manifest.properties,
620
231
  disabledProperties: manifest.disabled ?? [],
621
232
  ...optional('activeEnvironmentId', manifest.activeEnvironmentId),
622
- interfaces: interfaces.sort(byOrder),
623
- apis: apis.sort(byOrder),
624
- grpcApis: grpcApis.sort(byOrder),
625
- wsApis: wsApis.sort(byOrder),
233
+ interfaces: [],
234
+ apis: [],
235
+ grpcApis: [],
236
+ wsApis: [],
237
+ sequences: sequenceFiles.loaded.map((entry) => entry.sequence).sort(byOrder),
238
+ ...(webhooks !== undefined ? { webhooks } : {}),
626
239
  environments: await loadEnvironments(fs, root),
627
240
  wss: {
628
241
  outgoing: await loadWssRefs(fs, root, 'outgoing'),
629
242
  incoming: await loadWssRefs(fs, root, 'incoming'),
630
243
  keystores,
631
244
  },
245
+ // Absent when there is none, as every project written before placeholders is.
246
+ ...(unsupported.length > 0
247
+ ? { unsupported: unsupported.sort((a, b) => a.dir.localeCompare(b.dir) || a.slug.localeCompare(b.slug)) }
248
+ : {}),
632
249
  };
250
+ // A module that loaded nothing is not asked: the four built-in lists are already empty, and a
251
+ // kind kept in `extraContainers` must not appear there when the project holds none of it.
252
+ let project = core;
253
+ for (const [storage, containers] of loaded) {
254
+ project = storage.withContainers(project, containers.sort(byOrder));
255
+ }
633
256
  return { project, problems };
634
257
  }