@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,41 @@
1
+ import type { ProjectFiles } from '../project/serialize.js';
2
+ /** The outcome of laying one side's files back over the other's. */
3
+ export interface FileMerge {
4
+ /** The files the merged tree should be read from. */
5
+ readonly files: ProjectFiles;
6
+ /**
7
+ * Changed on both sides; the `unsaved` (mine) version was kept — or, for a deletion on the
8
+ * `unsaved` side of a file that changed on `disk`, the disk version was. With `modifyDelete:
9
+ * 'conflict'`, also a change on the `unsaved` side of a file deleted on `disk`, whose unsaved
10
+ * version was kept.
11
+ */
12
+ readonly conflicts: readonly string[];
13
+ /** Changed on the `unsaved` side but deleted on `disk`; the change was dropped. Always empty with `modifyDelete: 'conflict'`. */
14
+ readonly dropped: readonly string[];
15
+ /** Whether the merged files differ from `disk` at all. */
16
+ readonly changed: boolean;
17
+ }
18
+ /** How {@link mergeFiles} treats a file changed on the `unsaved` side and deleted on `disk`. */
19
+ export interface MergeFilesOptions {
20
+ /** 'drop' (default, unsaved-changes recovery): changed on the unsaved side, deleted on disk → dropped.
21
+ * 'conflict' (sync): the same case is a conflict, and the unsaved (mine) version is kept in `files`. */
22
+ readonly modifyDelete?: 'drop' | 'conflict';
23
+ }
24
+ /**
25
+ * Three-way merge, one file at a time, of the `baseline` (B) both sides started from, the files
26
+ * on `disk` (D, "theirs") and the `unsaved` files (U, "mine"):
27
+ *
28
+ * - U = B → D (only disk changed, or nothing did);
29
+ * - D = B → U (only the unsaved side changed — including an unsaved deletion);
30
+ * - both changed:
31
+ * - D = U → U (the same change on both sides);
32
+ * - deleted on disk → dropped (the file, e.g. a request, no longer exists) — or, with
33
+ * `modifyDelete: 'conflict'`, U, flagged: sync must never lose a change silently, and git
34
+ * calls this case a conflict too;
35
+ * - deleted in the unsaved record → D, flagged (a change on disk beats an unsaved deletion);
36
+ * - otherwise → U, flagged (unsaved changes are restored on top).
37
+ *
38
+ * Every value is compared whole, so the merge does not care what a value encodes (sync passes
39
+ * `encoding:content` strings).
40
+ */
41
+ export declare function mergeFiles(baseline: ProjectFiles, disk: ProjectFiles, unsaved: ProjectFiles, options?: MergeFilesOptions): FileMerge;
@@ -0,0 +1,85 @@
1
+ /**
2
+ * A per-file three-way merge shared by the desktop's unsaved-changes recovery and the sync
3
+ * backends (the fake one in the desktop's tests, and `ServerBackend` for Wirebench Server). It lives
4
+ * in the engine so both run the same code — the point of ADR-0008's "one repository, two
5
+ * transports".
6
+ */
7
+ import { MANIFEST_PATH } from '../project/serialize.js';
8
+ /**
9
+ * The manifest records which save wrote it (`writtenBy: wirebench (manual)`), so two otherwise
10
+ * identical manifests differ after every save. That line is not a change anyone made.
11
+ */
12
+ function comparable(path, content) {
13
+ if (content === undefined || path !== MANIFEST_PATH) {
14
+ return content;
15
+ }
16
+ return content
17
+ .split('\n')
18
+ .filter((line) => !/^writtenBy:/.test(line))
19
+ .join('\n');
20
+ }
21
+ function same(path, a, b) {
22
+ return comparable(path, a) === comparable(path, b);
23
+ }
24
+ /**
25
+ * Three-way merge, one file at a time, of the `baseline` (B) both sides started from, the files
26
+ * on `disk` (D, "theirs") and the `unsaved` files (U, "mine"):
27
+ *
28
+ * - U = B → D (only disk changed, or nothing did);
29
+ * - D = B → U (only the unsaved side changed — including an unsaved deletion);
30
+ * - both changed:
31
+ * - D = U → U (the same change on both sides);
32
+ * - deleted on disk → dropped (the file, e.g. a request, no longer exists) — or, with
33
+ * `modifyDelete: 'conflict'`, U, flagged: sync must never lose a change silently, and git
34
+ * calls this case a conflict too;
35
+ * - deleted in the unsaved record → D, flagged (a change on disk beats an unsaved deletion);
36
+ * - otherwise → U, flagged (unsaved changes are restored on top).
37
+ *
38
+ * Every value is compared whole, so the merge does not care what a value encodes (sync passes
39
+ * `encoding:content` strings).
40
+ */
41
+ export function mergeFiles(baseline, disk, unsaved, options) {
42
+ const modifyDelete = options?.modifyDelete ?? 'drop';
43
+ const files = new Map();
44
+ const conflicts = [];
45
+ const dropped = [];
46
+ const paths = [...new Set([...baseline.keys(), ...disk.keys(), ...unsaved.keys()])].sort();
47
+ for (const path of paths) {
48
+ const b = baseline.get(path);
49
+ const d = disk.get(path);
50
+ const u = unsaved.get(path);
51
+ let take;
52
+ if (same(path, u, b)) {
53
+ take = d;
54
+ }
55
+ else if (same(path, d, b)) {
56
+ take = u;
57
+ }
58
+ else if (same(path, d, u)) {
59
+ take = u;
60
+ }
61
+ else if (d === undefined) {
62
+ if (modifyDelete === 'conflict') {
63
+ conflicts.push(path);
64
+ take = u;
65
+ }
66
+ else {
67
+ dropped.push(path);
68
+ take = undefined;
69
+ }
70
+ }
71
+ else if (u === undefined) {
72
+ conflicts.push(path);
73
+ take = d;
74
+ }
75
+ else {
76
+ conflicts.push(path);
77
+ take = u;
78
+ }
79
+ if (take !== undefined) {
80
+ files.set(path, take);
81
+ }
82
+ }
83
+ const changed = [...new Set([...files.keys(), ...disk.keys()])].some((path) => !same(path, files.get(path), disk.get(path)));
84
+ return { files, conflicts, dropped, changed };
85
+ }
@@ -0,0 +1,34 @@
1
+ /** Everything that makes up a workspace tree, in the order a share moves them (formerly private to the desktop's workspace-share.ts). */
2
+ export declare const TREE_ITEMS: readonly ["workspace.yaml", "environments", "projects", ".gitattributes", "team-secrets"];
3
+ /** Longest tree path the sync accepts, in characters (§3.2). */
4
+ export declare const MAX_TREE_PATH_LENGTH = 512;
5
+ /**
6
+ * Machine-local names that never travel: 'share.yaml', 'local.yaml' and the 'unsaved' directory
7
+ * (the desktop's `UNSAVED_DIR`). They live beside the tree in a workspace's app-data folder, and a
8
+ * snapshot or a commit that carried one would leak one machine's state (and a secret-bearing
9
+ * recovery record) to every member.
10
+ */
11
+ export declare const MACHINE_LOCAL_PATHS: readonly string[];
12
+ /**
13
+ * Returns `path` when it is a relative, normalised, forward-slash tree path of at most 512
14
+ * characters: no '..', '.' or empty segment, no '.git' segment (in any spelling git refuses), no
15
+ * segment Windows cannot hold (a device name, a trailing dot or space, one of `<>:"|?*`), no
16
+ * backslash or control character, not absolute, not machine-local, whose first segment is one of
17
+ * TREE_ITEMS, and which names a file (`workspace.yaml` and `.gitattributes` stand alone; the three
18
+ * directories need something below them — and under `team-secrets/` specifically, exactly
19
+ * `keys/<id>.yaml`, `access/<id>.yaml` or `values/<id>.yaml`, per {@link isTeamSecretsPath}).
20
+ *
21
+ * @throws WirebenchError 'sync-path-refused' otherwise, with `details.reason` naming the rule and
22
+ * `details.path` the path, cut to {@link MAX_TREE_PATH_LENGTH} characters.
23
+ */
24
+ export declare function assertTreePath(path: string): string;
25
+ /** Whether {@link assertTreePath} would accept `path`. */
26
+ export declare function isTreePath(path: string): boolean;
27
+ /**
28
+ * Whether a single filesystem entry name (never a `/`-joined path) is one the tree rules refuse
29
+ * anywhere: empty, `.`/`..`, a control character, a `.git` spelling, or a Windows-unsafe name.
30
+ * Unlike {@link isTreePath} it never asks whether the name completes a valid tree path — a directory
31
+ * has no such thing — so a tree walk can prune an unsafe folder (a nested `.git`, say) before
32
+ * descending into it, rather than reading it and refusing every file inside one at a time.
33
+ */
34
+ export declare function isSafeTreeSegment(segment: string): boolean;
@@ -0,0 +1,131 @@
1
+ /**
2
+ * The rules a path in a synced workspace tree obeys (server-sync spec §3.2, §6). Wirebench Server
3
+ * checks every path a push names before any git call. The desktop checks every path a snapshot or a
4
+ * change names before it writes to disk. Both call {@link assertTreePath}, so both ends refuse
5
+ * exactly the same paths.
6
+ */
7
+ import { WirebenchError } from '../errors.js';
8
+ import { isTeamSecretsPath } from '../team-secrets/schema.js';
9
+ import { WORKSPACE_LOCAL_FILE } from '../workspace/local-state.js';
10
+ import { GIT_ATTRIBUTES_FILE, TEAM_SECRETS_DIR, WORKSPACE_ENVIRONMENTS_DIR, WORKSPACE_MANIFEST, WORKSPACE_PROJECTS_DIR, } from '../workspace/paths.js';
11
+ import { WORKSPACE_SHARE_FILE } from '../workspace/share.js';
12
+ /** Everything that makes up a workspace tree, in the order a share moves them (formerly private to the desktop's workspace-share.ts). */
13
+ export const TREE_ITEMS = [
14
+ WORKSPACE_MANIFEST,
15
+ WORKSPACE_ENVIRONMENTS_DIR,
16
+ WORKSPACE_PROJECTS_DIR,
17
+ GIT_ATTRIBUTES_FILE,
18
+ TEAM_SECRETS_DIR,
19
+ ];
20
+ /** The tree items that are single files. The other three are directories, so a path names a file below them. */
21
+ const FILE_ITEMS = new Set([WORKSPACE_MANIFEST, GIT_ATTRIBUTES_FILE]);
22
+ /** Longest tree path the sync accepts, in characters (§3.2). */
23
+ export const MAX_TREE_PATH_LENGTH = 512;
24
+ /**
25
+ * Machine-local names that never travel: 'share.yaml', 'local.yaml' and the 'unsaved' directory
26
+ * (the desktop's `UNSAVED_DIR`). They live beside the tree in a workspace's app-data folder, and a
27
+ * snapshot or a commit that carried one would leak one machine's state (and a secret-bearing
28
+ * recovery record) to every member.
29
+ */
30
+ export const MACHINE_LOCAL_PATHS = [WORKSPACE_SHARE_FILE, WORKSPACE_LOCAL_FILE, 'unsaved'];
31
+ /** C0 controls and DEL: git's `-z` output and `update-index` input cannot carry them faithfully. */
32
+ const CONTROL_CHARACTER = /[\x00-\x1f\x7f]/;
33
+ /** A POSIX root, or a Windows drive. */
34
+ const ABSOLUTE = /^(?:\/|[A-Za-z]:)/;
35
+ /**
36
+ * `.git` in any case, with the trailing dots or spaces Windows ignores, its 8.3 short name, and any
37
+ * of those followed by an NTFS alternate-data-stream suffix (`:$INDEX_ALLOCATION`, a bare `:`, or
38
+ * `git~1:x`) — every spelling git itself refuses in a tree under `core.protectNTFS`.
39
+ */
40
+ const GIT_SEGMENT = /^(?:\.git|git~\d+)[. ]*(?::.*)?$/i;
41
+ /**
42
+ * A segment Windows cannot hold: a reserved device name, with or without an extension (and with the
43
+ * spaces Windows ignores before it); a trailing dot or space, which Windows drops; or a character
44
+ * Windows refuses in a name. A Mac or Linux editor can create one, and once pushed it would stop
45
+ * every Windows teammate from opening the workspace, so both ends refuse it (`assertPathSegment`'s
46
+ * rules for the name part).
47
+ */
48
+ const WINDOWS_UNSAFE_SEGMENT = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9]) *(?:\.|$)|[. ]$|[<>:"|?*]/i;
49
+ function refusal(path) {
50
+ if (path.length === 0) {
51
+ return 'empty';
52
+ }
53
+ if (path.length > MAX_TREE_PATH_LENGTH) {
54
+ return 'too-long';
55
+ }
56
+ if (CONTROL_CHARACTER.test(path)) {
57
+ return 'control-character';
58
+ }
59
+ if (path.includes('\\')) {
60
+ return 'backslash';
61
+ }
62
+ if (ABSOLUTE.test(path)) {
63
+ return 'absolute';
64
+ }
65
+ const segments = path.split('/');
66
+ if (segments.some((segment) => segment.length === 0)) {
67
+ return 'empty-segment';
68
+ }
69
+ if (segments.some((segment) => segment === '.' || segment === '..')) {
70
+ return 'dot-segment';
71
+ }
72
+ if (segments.some((segment) => GIT_SEGMENT.test(segment))) {
73
+ return 'git-segment';
74
+ }
75
+ if (segments.some((segment) => WINDOWS_UNSAFE_SEGMENT.test(segment))) {
76
+ return 'windows-unsafe';
77
+ }
78
+ const first = segments[0] ?? '';
79
+ if (MACHINE_LOCAL_PATHS.includes(first)) {
80
+ return 'machine-local';
81
+ }
82
+ if (!TREE_ITEMS.includes(first)) {
83
+ return 'not-in-tree';
84
+ }
85
+ if (FILE_ITEMS.has(first) !== (segments.length === 1)) {
86
+ return 'not-a-file';
87
+ }
88
+ if (first === TEAM_SECRETS_DIR && !isTeamSecretsPath(path)) {
89
+ return 'not-a-file';
90
+ }
91
+ return undefined;
92
+ }
93
+ /**
94
+ * Returns `path` when it is a relative, normalised, forward-slash tree path of at most 512
95
+ * characters: no '..', '.' or empty segment, no '.git' segment (in any spelling git refuses), no
96
+ * segment Windows cannot hold (a device name, a trailing dot or space, one of `<>:"|?*`), no
97
+ * backslash or control character, not absolute, not machine-local, whose first segment is one of
98
+ * TREE_ITEMS, and which names a file (`workspace.yaml` and `.gitattributes` stand alone; the three
99
+ * directories need something below them — and under `team-secrets/` specifically, exactly
100
+ * `keys/<id>.yaml`, `access/<id>.yaml` or `values/<id>.yaml`, per {@link isTeamSecretsPath}).
101
+ *
102
+ * @throws WirebenchError 'sync-path-refused' otherwise, with `details.reason` naming the rule and
103
+ * `details.path` the path, cut to {@link MAX_TREE_PATH_LENGTH} characters.
104
+ */
105
+ export function assertTreePath(path) {
106
+ const reason = refusal(path);
107
+ if (reason !== undefined) {
108
+ const shown = path.slice(0, MAX_TREE_PATH_LENGTH);
109
+ throw new WirebenchError('sync-path-refused', `${JSON.stringify(shown.slice(0, 120))} cannot be part of a shared workspace.`, { details: { path: shown, reason } });
110
+ }
111
+ return path;
112
+ }
113
+ /** Whether {@link assertTreePath} would accept `path`. */
114
+ export function isTreePath(path) {
115
+ return refusal(path) === undefined;
116
+ }
117
+ /**
118
+ * Whether a single filesystem entry name (never a `/`-joined path) is one the tree rules refuse
119
+ * anywhere: empty, `.`/`..`, a control character, a `.git` spelling, or a Windows-unsafe name.
120
+ * Unlike {@link isTreePath} it never asks whether the name completes a valid tree path — a directory
121
+ * has no such thing — so a tree walk can prune an unsafe folder (a nested `.git`, say) before
122
+ * descending into it, rather than reading it and refusing every file inside one at a time.
123
+ */
124
+ export function isSafeTreeSegment(segment) {
125
+ return (segment.length > 0 &&
126
+ segment !== '.' &&
127
+ segment !== '..' &&
128
+ !CONTROL_CHARACTER.test(segment) &&
129
+ !GIT_SEGMENT.test(segment) &&
130
+ !WINDOWS_UNSAFE_SEGMENT.test(segment));
131
+ }
@@ -0,0 +1,10 @@
1
+ import { type MachineKeys } from './keys.js';
2
+ export declare const WRAP_INFO = "wirebench-team-secrets-v1-wrap";
3
+ export declare function newDataKey(): Buffer;
4
+ export declare function encryptValue(value: string, dataKey: Buffer, entryId: string): string;
5
+ /** @throws WirebenchError `team-secrets-decrypt-failed` | `team-secrets-bad-key` */
6
+ export declare function decryptValue(cipher: string, dataKey: Buffer, entryId: string): string;
7
+ /** @throws WirebenchError `team-secrets-bad-key` */
8
+ export declare function wrapDataKey(dataKey: Buffer, recipientEncryptionKey: string): string;
9
+ /** @throws WirebenchError `team-secrets-decrypt-failed` | `team-secrets-bad-key` */
10
+ export declare function unwrapDataKey(wrap: string, keys: MachineKeys): Buffer;
@@ -0,0 +1,121 @@
1
+ /**
2
+ * The vault envelope (§4): a value is encrypted once with a random data key (AES-256-GCM, the vault entry id
3
+ * as additional data, so a cipher cannot be moved to another secret), and the data key is wrapped for each
4
+ * approved machine. A wrap is a fresh ephemeral X25519 public key, a nonce and the sealed data key; the
5
+ * sealing key is HKDF-SHA256 of the ECDH secret, salted with both public keys.
6
+ *
7
+ * Every binary field is base64url: `nonce || ciphertext || tag` for a cipher, `ephemeral || nonce ||
8
+ * sealed || tag` for a wrap.
9
+ */
10
+ import { createCipheriv, createDecipheriv, diffieHellman, generateKeyPairSync, hkdfSync, randomBytes, } from 'node:crypto';
11
+ import { WirebenchError } from '../errors.js';
12
+ import { teamSecretsError } from './errors.js';
13
+ import { base64url, encryptionPrivateKey, encryptionPublicKey, fromBase64url } from './keys.js';
14
+ export const WRAP_INFO = 'wirebench-team-secrets-v1-wrap';
15
+ const NONCE_BYTES = 12;
16
+ const TAG_BYTES = 16;
17
+ const KEY_BYTES = 32;
18
+ const PUBLIC_KEY_BYTES = 32;
19
+ function failed(cause) {
20
+ return teamSecretsError('team-secrets-decrypt-failed', cause !== undefined ? { cause } : undefined);
21
+ }
22
+ /** A malformed or out-of-range key or data key. Never carries the offending key material. */
23
+ function badKey() {
24
+ return teamSecretsError('team-secrets-bad-key');
25
+ }
26
+ function seal(key, plaintext, aad) {
27
+ const nonce = randomBytes(NONCE_BYTES);
28
+ const cipher = createCipheriv('aes-256-gcm', key, nonce);
29
+ if (aad !== undefined) {
30
+ cipher.setAAD(aad);
31
+ }
32
+ const body = Buffer.concat([cipher.update(plaintext), cipher.final()]);
33
+ return Buffer.concat([nonce, body, cipher.getAuthTag()]);
34
+ }
35
+ function open(key, sealed, aad) {
36
+ if (sealed.length < NONCE_BYTES + TAG_BYTES) {
37
+ throw failed();
38
+ }
39
+ try {
40
+ const decipher = createDecipheriv('aes-256-gcm', key, sealed.subarray(0, NONCE_BYTES));
41
+ if (aad !== undefined) {
42
+ decipher.setAAD(aad);
43
+ }
44
+ decipher.setAuthTag(sealed.subarray(sealed.length - TAG_BYTES));
45
+ return Buffer.concat([decipher.update(sealed.subarray(NONCE_BYTES, sealed.length - TAG_BYTES)), decipher.final()]);
46
+ }
47
+ catch (error) {
48
+ throw failed(error);
49
+ }
50
+ }
51
+ export function newDataKey() {
52
+ return randomBytes(KEY_BYTES);
53
+ }
54
+ /** @throws WirebenchError `team-secrets-bad-key` if `dataKey` is not exactly 32 bytes. */
55
+ function assertDataKey(dataKey) {
56
+ if (dataKey.length !== KEY_BYTES) {
57
+ throw badKey();
58
+ }
59
+ }
60
+ /**
61
+ * A recipient's X25519 public key as a `KeyObject`, and the ECDH secret computed with it. Throws
62
+ * `team-secrets-bad-key` for anything that is not a well-formed, non-degenerate point: malformed
63
+ * base64url, the wrong length, or a low-order point whose shared secret is all-zero — never the raw
64
+ * `TypeError`/`RangeError`/OpenSSL error, and never the key material itself.
65
+ */
66
+ function sharedSecretWith(privateKey, recipientRaw) {
67
+ let publicKey;
68
+ try {
69
+ publicKey = encryptionPublicKey(recipientRaw);
70
+ }
71
+ catch {
72
+ throw badKey();
73
+ }
74
+ let shared;
75
+ try {
76
+ shared = diffieHellman({ privateKey, publicKey });
77
+ }
78
+ catch {
79
+ throw badKey();
80
+ }
81
+ if (shared.equals(Buffer.alloc(shared.length))) {
82
+ // A low-order point collapses ECDH to an all-zero secret regardless of the private key.
83
+ throw badKey();
84
+ }
85
+ return shared;
86
+ }
87
+ export function encryptValue(value, dataKey, entryId) {
88
+ assertDataKey(dataKey);
89
+ return base64url(seal(dataKey, Buffer.from(value, 'utf8'), Buffer.from(entryId, 'utf8')));
90
+ }
91
+ /** @throws WirebenchError `team-secrets-decrypt-failed` | `team-secrets-bad-key` */
92
+ export function decryptValue(cipher, dataKey, entryId) {
93
+ assertDataKey(dataKey);
94
+ return open(dataKey, fromBase64url(cipher), Buffer.from(entryId, 'utf8')).toString('utf8');
95
+ }
96
+ function wrapKey(shared, ephemeral, recipient) {
97
+ return Buffer.from(hkdfSync('sha256', shared, Buffer.concat([ephemeral, recipient]), WRAP_INFO, KEY_BYTES));
98
+ }
99
+ /** @throws WirebenchError `team-secrets-bad-key` */
100
+ export function wrapDataKey(dataKey, recipientEncryptionKey) {
101
+ assertDataKey(dataKey);
102
+ const pair = generateKeyPairSync('x25519');
103
+ const ephemeral = fromBase64url(String(pair.publicKey.export({ format: 'jwk' }).x));
104
+ const shared = sharedSecretWith(pair.privateKey, recipientEncryptionKey);
105
+ const key = wrapKey(shared, ephemeral, fromBase64url(recipientEncryptionKey));
106
+ return base64url(Buffer.concat([ephemeral, seal(key, dataKey)]));
107
+ }
108
+ /** @throws WirebenchError `team-secrets-decrypt-failed` | `team-secrets-bad-key` */
109
+ export function unwrapDataKey(wrap, keys) {
110
+ const bytes = fromBase64url(wrap);
111
+ if (bytes.length < PUBLIC_KEY_BYTES + NONCE_BYTES + TAG_BYTES) {
112
+ throw failed();
113
+ }
114
+ const ephemeral = bytes.subarray(0, PUBLIC_KEY_BYTES);
115
+ const shared = sharedSecretWith(encryptionPrivateKey(keys), base64url(ephemeral));
116
+ const dataKey = open(wrapKey(shared, ephemeral, fromBase64url(keys.encryptionKey)), bytes.subarray(PUBLIC_KEY_BYTES));
117
+ if (dataKey.length !== KEY_BYTES) {
118
+ throw failed();
119
+ }
120
+ return dataKey;
121
+ }
@@ -0,0 +1,26 @@
1
+ import { WirebenchError } from '../errors.js';
2
+ /** The user-facing team-secrets failures (spec §3.8), one message each. */
3
+ export declare const TEAM_SECRETS_MESSAGES: {
4
+ readonly 'team-secrets-pending': "This machine is waiting for an admin to approve it for team secrets.";
5
+ readonly 'team-secrets-removed': "An admin removed this machine from team secrets.";
6
+ readonly 'team-secrets-declined': "An admin declined this machine's request for team secrets.";
7
+ readonly 'team-secrets-no-safe-storage': "Team secrets need the system keychain, which is not available on this machine.";
8
+ readonly 'team-secrets-admin-only': "Only a workspace admin can change who has access to team secrets.";
9
+ readonly 'team-secrets-untrusted': "Ignored a secret signed by a key that is not approved.";
10
+ readonly 'team-secrets-last-admin': "A workspace needs at least one admin for team secrets.";
11
+ readonly 'team-secrets-not-canonical': "A team secrets document contained a value that could not be signed.";
12
+ readonly 'team-secrets-bad-key': "A team secrets key was malformed.";
13
+ readonly 'team-secrets-decrypt-failed': "A team secret could not be decrypted.";
14
+ readonly 'team-secrets-not-shared': "Team secrets need a shared workspace.";
15
+ readonly 'team-secrets-no-such-key': "That machine is not waiting for approval, or not approved, as this change needs.";
16
+ readonly 'team-secrets-server-authority': "On a server workspace, the server roles decide who is an admin.";
17
+ readonly 'team-secrets-remove-self': "Ask another admin to remove this machine.";
18
+ readonly 'team-secrets-cannot-reencrypt': "Some team secrets are not readable on this machine, so they cannot be re-encrypted. Ask another admin to remove this machine, or wait for this machine to receive them.";
19
+ readonly 'team-secrets-already-admin': "That machine is already a team secrets admin.";
20
+ readonly 'team-secrets-not-admin': "That machine is not a team secrets admin.";
21
+ readonly 'team-secrets-last-approved': "A workspace needs at least one approved machine for team secrets.";
22
+ readonly 'team-secrets-not-allowed': "That change to team secrets access is not allowed.";
23
+ readonly 'team-secrets-damaged': "The team secrets access log on this machine does not match what it saw before; this machine will not change team secrets until it is repaired.";
24
+ };
25
+ export type TeamSecretsErrorCode = keyof typeof TEAM_SECRETS_MESSAGES;
26
+ export declare function teamSecretsError(code: TeamSecretsErrorCode, details?: Readonly<Record<string, unknown>>): WirebenchError;
@@ -0,0 +1,27 @@
1
+ import { WirebenchError } from '../errors.js';
2
+ /** The user-facing team-secrets failures (spec §3.8), one message each. */
3
+ export const TEAM_SECRETS_MESSAGES = {
4
+ 'team-secrets-pending': 'This machine is waiting for an admin to approve it for team secrets.',
5
+ 'team-secrets-removed': 'An admin removed this machine from team secrets.',
6
+ 'team-secrets-declined': "An admin declined this machine's request for team secrets.",
7
+ 'team-secrets-no-safe-storage': 'Team secrets need the system keychain, which is not available on this machine.',
8
+ 'team-secrets-admin-only': 'Only a workspace admin can change who has access to team secrets.',
9
+ 'team-secrets-untrusted': 'Ignored a secret signed by a key that is not approved.',
10
+ 'team-secrets-last-admin': 'A workspace needs at least one admin for team secrets.',
11
+ 'team-secrets-not-canonical': 'A team secrets document contained a value that could not be signed.',
12
+ 'team-secrets-bad-key': 'A team secrets key was malformed.',
13
+ 'team-secrets-decrypt-failed': 'A team secret could not be decrypted.',
14
+ 'team-secrets-not-shared': 'Team secrets need a shared workspace.',
15
+ 'team-secrets-no-such-key': 'That machine is not waiting for approval, or not approved, as this change needs.',
16
+ 'team-secrets-server-authority': 'On a server workspace, the server roles decide who is an admin.',
17
+ 'team-secrets-remove-self': 'Ask another admin to remove this machine.',
18
+ 'team-secrets-cannot-reencrypt': 'Some team secrets are not readable on this machine, so they cannot be re-encrypted. Ask another admin to remove this machine, or wait for this machine to receive them.',
19
+ 'team-secrets-already-admin': 'That machine is already a team secrets admin.',
20
+ 'team-secrets-not-admin': 'That machine is not a team secrets admin.',
21
+ 'team-secrets-last-approved': 'A workspace needs at least one approved machine for team secrets.',
22
+ 'team-secrets-not-allowed': 'That change to team secrets access is not allowed.',
23
+ 'team-secrets-damaged': 'The team secrets access log on this machine does not match what it saw before; this machine will not change team secrets until it is repaired.',
24
+ };
25
+ export function teamSecretsError(code, details) {
26
+ return new WirebenchError(code, TEAM_SECRETS_MESSAGES[code], details !== undefined ? { details } : undefined);
27
+ }
@@ -0,0 +1,14 @@
1
+ export { decryptValue, encryptValue, newDataKey, unwrapDataKey, WRAP_INFO, wrapDataKey } from './envelope.js';
2
+ export { TEAM_SECRETS_MESSAGES, teamSecretsError } from './errors.js';
3
+ export type { TeamSecretsErrorCode } from './errors.js';
4
+ export { base32, base64url, encryptionPrivateKey, encryptionPublicKey, fingerprintOf, fromBase64url, generateMachineKeys, KEY_ID_PATTERN, keyIdOf, parseMachineKeys, serializeMachineKeys, signingPrivateKey, signingPublicKey, } from './keys.js';
5
+ export type { MachineKeys, MachinePublicKeys } from './keys.js';
6
+ export { nextAccessEntryId, replayAccessLog, verifiedKeys } from './log.js';
7
+ export type { AccessState, KeyInfo, LogProblem, Removal } from './log.js';
8
+ export { vaultConflictWinner } from './resolve-conflict.js';
9
+ export { ACCESS_ACTIONS, accessEntryFileSchema, accessEntryPath, isTeamSecretsPath, isVaultEntryPath, keyIdSchema, keyRequestFileSchema, keyRequestPath, parseTeamSecretsFile, readTeamSecretsFiles, sameSecret, secretKeySchema, TEAM_SECRETS_ACCESS_DIR, TEAM_SECRETS_FORMAT_VERSION, TEAM_SECRETS_KEYS_DIR, TEAM_SECRETS_VALUES_DIR, teamSecretsFileText, ULID_PATTERN, vaultEntryFileSchema, vaultEntryId, vaultEntryIdOfPath, vaultEntryPath, } from './schema.js';
10
+ export type { AccessAction, AccessEntryFile, KeyRequestFile, SecretKey, TeamSecretsFiles, VaultEntryFile, } from './schema.js';
11
+ export { canonicalJson, signDocument, verifyDocument, withoutSignature } from './sign.js';
12
+ export type { Signed } from './sign.js';
13
+ export { approvedRecipients, buildVaultEntry, healVaultEntry, openVaultEntry, rotateMarks, rotateMarksFor, sealVaultEntry, verifyVaultEntry, wrapsUnapprovedKey, } from './vault.js';
14
+ export type { RotateMark, VaultVerdict } from './vault.js';
@@ -0,0 +1,8 @@
1
+ export { decryptValue, encryptValue, newDataKey, unwrapDataKey, WRAP_INFO, wrapDataKey } from './envelope.js';
2
+ export { TEAM_SECRETS_MESSAGES, teamSecretsError } from './errors.js';
3
+ export { base32, base64url, encryptionPrivateKey, encryptionPublicKey, fingerprintOf, fromBase64url, generateMachineKeys, KEY_ID_PATTERN, keyIdOf, parseMachineKeys, serializeMachineKeys, signingPrivateKey, signingPublicKey, } from './keys.js';
4
+ export { nextAccessEntryId, replayAccessLog, verifiedKeys } from './log.js';
5
+ export { vaultConflictWinner } from './resolve-conflict.js';
6
+ export { ACCESS_ACTIONS, accessEntryFileSchema, accessEntryPath, isTeamSecretsPath, isVaultEntryPath, keyIdSchema, keyRequestFileSchema, keyRequestPath, parseTeamSecretsFile, readTeamSecretsFiles, sameSecret, secretKeySchema, TEAM_SECRETS_ACCESS_DIR, TEAM_SECRETS_FORMAT_VERSION, TEAM_SECRETS_KEYS_DIR, TEAM_SECRETS_VALUES_DIR, teamSecretsFileText, ULID_PATTERN, vaultEntryFileSchema, vaultEntryId, vaultEntryIdOfPath, vaultEntryPath, } from './schema.js';
7
+ export { canonicalJson, signDocument, verifyDocument, withoutSignature } from './sign.js';
8
+ export { approvedRecipients, buildVaultEntry, healVaultEntry, openVaultEntry, rotateMarks, rotateMarksFor, sealVaultEntry, verifyVaultEntry, wrapsUnapprovedKey, } from './vault.js';
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Machine keys for team secrets (team-secrets spec §2, §4): one X25519 pair to decrypt and one Ed25519
3
+ * pair to sign, per machine per workspace. Keys travel as base64url of their raw 32 bytes, which is what
4
+ * a JWK's `x` and `d` already are, so `node:crypto` imports them without any DER handling.
5
+ *
6
+ * Pure: no I/O. The desktop keeps the private halves in its keychain-backed store; nothing else does.
7
+ */
8
+ import { type KeyObject } from 'node:crypto';
9
+ /** A key id: the first 26 base32 characters of SHA-256 over both public keys. */
10
+ export declare const KEY_ID_PATTERN: RegExp;
11
+ /** The two public keys a key request publishes. */
12
+ export interface MachinePublicKeys {
13
+ /** X25519, base64url of 32 bytes. */
14
+ readonly encryptionKey: string;
15
+ /** Ed25519, base64url of 32 bytes. */
16
+ readonly signingKey: string;
17
+ }
18
+ /** A machine's full key set. The private halves never leave the desktop's main process. */
19
+ export interface MachineKeys extends MachinePublicKeys {
20
+ readonly keyId: string;
21
+ readonly encryptionPrivate: string;
22
+ readonly signingPrivate: string;
23
+ }
24
+ export declare function base64url(bytes: Uint8Array): string;
25
+ /**
26
+ * Strict base64url decoding: Node's own decoder tolerates padding, standard `+`/`/`, and embedded
27
+ * whitespace, silently turning any of those into *some* bytes. A team-secrets field is either exactly
28
+ * base64url or it is corrupt, so this instead requires the alphabet `[A-Za-z0-9_-]` with no padding, and
29
+ * that re-encoding the decoded bytes reproduces the input exactly (catching a truncated last group, which
30
+ * the pattern alone would not).
31
+ *
32
+ * @throws WirebenchError `team-secrets-bad-key` if `text` is not strictly base64url.
33
+ */
34
+ export declare function fromBase64url(text: string): Buffer;
35
+ /** RFC 4648 base32 without padding. */
36
+ export declare function base32(bytes: Uint8Array): string;
37
+ export declare function keyIdOf(keys: MachinePublicKeys): string;
38
+ /** What an admin reads out to the person (§3.2): the first 16 hex of the same digest, in groups of four. */
39
+ export declare function fingerprintOf(keys: MachinePublicKeys): string;
40
+ export declare function generateMachineKeys(): MachineKeys;
41
+ export declare function encryptionPublicKey(raw: string): KeyObject;
42
+ export declare function encryptionPrivateKey(keys: MachineKeys): KeyObject;
43
+ export declare function signingPublicKey(raw: string): KeyObject;
44
+ export declare function signingPrivateKey(keys: MachineKeys): KeyObject;
45
+ /** The stored form, kept in the keychain-backed store only. */
46
+ export declare function serializeMachineKeys(keys: MachineKeys): string;
47
+ /**
48
+ * Reads the stored form back; `undefined` for anything malformed, whose key id does not match its public
49
+ * keys, or whose public keys are not the ones its private halves actually derive (a stored file could
50
+ * otherwise carry a public key from one machine paired with a private key from another).
51
+ */
52
+ export declare function parseMachineKeys(text: string): MachineKeys | undefined;