@toa.io/extensions.exposition 1.0.0-alpha.285 → 1.0.0-alpha.287

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 (611) hide show
  1. package/CHANGELOG.md +1 -545
  2. package/components/exposition.octets/operations/delete.js +1 -1
  3. package/components/exposition.octets/operations/get.js +5 -2
  4. package/components/exposition.octets/operations/head.js +1 -1
  5. package/components/exposition.octets/operations/put.js +29 -37
  6. package/components/exposition.octets/types/toa.d.ts +1 -1
  7. package/components/identity.bans/manifest.toa.yaml +12 -13
  8. package/components/identity.bans/migrations/0001-system-properties.yaml +14 -0
  9. package/components/identity.bans/operations/transit.js +1 -1
  10. package/components/identity.bans/source/transit.ts +1 -1
  11. package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
  12. package/components/identity.bans/types/toa.d.ts +5 -5
  13. package/components/identity.basic/events/principal.js +3 -1
  14. package/components/identity.basic/manifest.toa.yaml +17 -23
  15. package/components/identity.basic/migrations/0001-system-properties.yaml +14 -0
  16. package/components/identity.basic/migrations/0002-indexes.yaml +13 -0
  17. package/components/identity.basic/operations/add.js +1 -1
  18. package/components/identity.basic/operations/authenticate.js +2 -2
  19. package/components/identity.basic/operations/check.js +4 -2
  20. package/components/identity.basic/operations/delete.js +1 -1
  21. package/components/identity.basic/operations/incept.js +1 -1
  22. package/components/identity.basic/operations/info.js +1 -1
  23. package/components/identity.basic/operations/lib/credentials.js +1 -1
  24. package/components/identity.basic/operations/transit.js +7 -8
  25. package/components/identity.basic/source/add.ts +5 -2
  26. package/components/identity.basic/source/authenticate.ts +11 -13
  27. package/components/identity.basic/source/check.ts +9 -6
  28. package/components/identity.basic/source/delete.ts +4 -1
  29. package/components/identity.basic/source/incept.ts +13 -10
  30. package/components/identity.basic/source/info.ts +4 -1
  31. package/components/identity.basic/source/lib/credentials.ts +2 -3
  32. package/components/identity.basic/source/transit.ts +27 -21
  33. package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
  34. package/components/identity.basic/types/index.d.ts +7 -3
  35. package/components/identity.basic/types/toa.d.ts +5 -5
  36. package/components/identity.clients/manifest.toa.yaml +36 -40
  37. package/components/identity.clients/migrations/0001-system-properties.yaml +14 -0
  38. package/components/identity.clients/migrations/0002-indexes.yaml +4 -0
  39. package/components/identity.clients/operations/describe.js +1 -1
  40. package/components/identity.clients/operations/lib/canonical.js +1 -1
  41. package/components/identity.clients/operations/lib/cimd.js +3 -2
  42. package/components/identity.clients/operations/lib/redirect.js +7 -4
  43. package/components/identity.clients/operations/register.js +2 -2
  44. package/components/identity.clients/source/describe.ts +6 -8
  45. package/components/identity.clients/source/lib/Context.ts +6 -3
  46. package/components/identity.clients/source/lib/Entity.ts +1 -1
  47. package/components/identity.clients/source/lib/canonical.ts +1 -1
  48. package/components/identity.clients/source/lib/cimd.test.ts +8 -6
  49. package/components/identity.clients/source/lib/cimd.ts +24 -19
  50. package/components/identity.clients/source/lib/redirect.test.ts +8 -2
  51. package/components/identity.clients/source/lib/redirect.ts +12 -8
  52. package/components/identity.clients/source/register.ts +18 -18
  53. package/components/identity.clients/tsconfig.tsbuildinfo +1 -1
  54. package/components/identity.clients/types/toa.d.ts +5 -5
  55. package/components/identity.credentials/manifest.toa.yaml +4 -4
  56. package/components/identity.credentials/operations/list.js +8 -4
  57. package/components/identity.credentials/source/list.test.ts +39 -20
  58. package/components/identity.credentials/source/list.ts +12 -8
  59. package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
  60. package/components/identity.credentials/types/toa.d.ts +2 -2
  61. package/components/identity.federation/manifest.toa.yaml +23 -32
  62. package/components/identity.federation/migrations/0001-system-properties.yaml +14 -0
  63. package/components/identity.federation/migrations/0002-indexes.yaml +25 -0
  64. package/components/identity.federation/operations/authenticate.js +4 -2
  65. package/components/identity.federation/operations/create.js +2 -2
  66. package/components/identity.federation/operations/decode.js +1 -1
  67. package/components/identity.federation/operations/delete.js +1 -1
  68. package/components/identity.federation/operations/incept.js +1 -1
  69. package/components/identity.federation/operations/lib/decode.js +1 -1
  70. package/components/identity.federation/operations/lib/discovery.js +2 -2
  71. package/components/identity.federation/operations/lib/exchange.js +8 -4
  72. package/components/identity.federation/operations/lib/principal.js +1 -1
  73. package/components/identity.federation/operations/lib/resolve.js +1 -1
  74. package/components/identity.federation/operations/list.js +2 -2
  75. package/components/identity.federation/source/authenticate.ts +19 -17
  76. package/components/identity.federation/source/create.ts +6 -7
  77. package/components/identity.federation/source/decode.ts +4 -1
  78. package/components/identity.federation/source/delete.ts +4 -1
  79. package/components/identity.federation/source/incept.ts +2 -3
  80. package/components/identity.federation/source/lib/decode.ts +4 -7
  81. package/components/identity.federation/source/lib/discovery.test.ts +15 -5
  82. package/components/identity.federation/source/lib/discovery.ts +10 -9
  83. package/components/identity.federation/source/lib/exchange.ts +18 -15
  84. package/components/identity.federation/source/lib/jose.d.ts +1 -1
  85. package/components/identity.federation/source/lib/principal.ts +5 -3
  86. package/components/identity.federation/source/lib/resolve.ts +5 -1
  87. package/components/identity.federation/source/list.test.ts +26 -10
  88. package/components/identity.federation/source/list.ts +5 -2
  89. package/components/identity.federation/source/types/context.ts +5 -2
  90. package/components/identity.federation/source/types/entity.ts +2 -2
  91. package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
  92. package/components/identity.federation/types/toa.d.ts +5 -5
  93. package/components/identity.grants/manifest.toa.yaml +27 -31
  94. package/components/identity.grants/migrations/0001-system-properties.yaml +14 -0
  95. package/components/identity.grants/migrations/0002-indexes.yaml +5 -0
  96. package/components/identity.grants/operations/authorize.js +1 -1
  97. package/components/identity.grants/operations/exchange.js +5 -2
  98. package/components/identity.grants/operations/lib/code.js +1 -1
  99. package/components/identity.grants/operations/lib/identify.js +1 -1
  100. package/components/identity.grants/operations/list.js +1 -1
  101. package/components/identity.grants/operations/revoke.js +3 -2
  102. package/components/identity.grants/source/authorize.ts +27 -19
  103. package/components/identity.grants/source/exchange.ts +15 -11
  104. package/components/identity.grants/source/lib/code.ts +20 -8
  105. package/components/identity.grants/source/lib/identify.ts +1 -1
  106. package/components/identity.grants/source/list.ts +2 -2
  107. package/components/identity.grants/source/revoke.ts +9 -7
  108. package/components/identity.grants/tsconfig.tsbuildinfo +1 -1
  109. package/components/identity.grants/types/index.d.ts +3 -3
  110. package/components/identity.grants/types/toa.d.ts +5 -5
  111. package/components/identity.keys/manifest.toa.yaml +18 -23
  112. package/components/identity.keys/migrations/0001-system-properties.yaml +14 -0
  113. package/components/identity.keys/migrations/0002-indexes.yaml +4 -0
  114. package/components/identity.keys/operations/create.js +1 -1
  115. package/components/identity.keys/operations/disable.js +1 -1
  116. package/components/identity.keys/operations/revoke.js +1 -1
  117. package/components/identity.keys/source/create.ts +2 -3
  118. package/components/identity.keys/source/disable.ts +1 -1
  119. package/components/identity.keys/source/revoke.ts +2 -2
  120. package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
  121. package/components/identity.keys/types/toa.d.ts +5 -5
  122. package/components/identity.otp/manifest.toa.yaml +16 -24
  123. package/components/identity.otp/migrations/0001-system-properties.yaml +14 -0
  124. package/components/identity.otp/migrations/0002-indexes.yaml +5 -0
  125. package/components/identity.otp/operations/authenticate.js +1 -1
  126. package/components/identity.otp/operations/issue.js +1 -1
  127. package/components/identity.otp/source/authenticate.ts +4 -7
  128. package/components/identity.otp/source/issue.ts +1 -1
  129. package/components/identity.otp/source/lib/Context.ts +1 -1
  130. package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
  131. package/components/identity.otp/types/toa.d.ts +5 -5
  132. package/components/identity.passkeys/manifest.toa.yaml +45 -53
  133. package/components/identity.passkeys/migrations/0001-system-properties.yaml +14 -0
  134. package/components/identity.passkeys/migrations/0002-indexes.yaml +11 -0
  135. package/components/identity.passkeys/operations/authenticate.js +1 -1
  136. package/components/identity.passkeys/operations/challenge.js +6 -3
  137. package/components/identity.passkeys/operations/create.js +1 -1
  138. package/components/identity.passkeys/operations/delete.js +1 -1
  139. package/components/identity.passkeys/operations/list.js +1 -1
  140. package/components/identity.passkeys/operations/use.js +1 -1
  141. package/components/identity.passkeys/source/authenticate.ts +3 -4
  142. package/components/identity.passkeys/source/challenge.ts +29 -25
  143. package/components/identity.passkeys/source/create.ts +8 -6
  144. package/components/identity.passkeys/source/delete.ts +4 -1
  145. package/components/identity.passkeys/source/list.ts +4 -1
  146. package/components/identity.passkeys/source/types/Context.ts +1 -1
  147. package/components/identity.passkeys/source/use.ts +12 -10
  148. package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
  149. package/components/identity.passkeys/types/toa.d.ts +5 -5
  150. package/components/identity.roles/manifest.toa.yaml +12 -16
  151. package/components/identity.roles/migrations/0001-system-properties.yaml +14 -0
  152. package/components/identity.roles/migrations/0002-indexes.yaml +8 -0
  153. package/components/identity.roles/operations/grant.js +1 -1
  154. package/components/identity.roles/operations/list.js +1 -1
  155. package/components/identity.roles/operations/principal.js +2 -2
  156. package/components/identity.roles/source/grant.ts +7 -6
  157. package/components/identity.roles/source/list.ts +1 -1
  158. package/components/identity.roles/source/principal.ts +5 -7
  159. package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
  160. package/components/identity.roles/types/toa.d.ts +5 -5
  161. package/components/identity.tokens/manifest.toa.yaml +17 -15
  162. package/components/identity.tokens/migrations/0001-system-properties.yaml +14 -0
  163. package/components/identity.tokens/operations/authenticate.js +2 -2
  164. package/components/identity.tokens/operations/decrypt.js +11 -5
  165. package/components/identity.tokens/operations/encrypt.js +2 -2
  166. package/components/identity.tokens/operations/issue.js +2 -4
  167. package/components/identity.tokens/operations/lib/form.js +1 -1
  168. package/components/identity.tokens/operations/lib/key.js +1 -1
  169. package/components/identity.tokens/operations/revoke.js +1 -1
  170. package/components/identity.tokens/source/authenticate.test.ts +22 -16
  171. package/components/identity.tokens/source/authenticate.ts +7 -10
  172. package/components/identity.tokens/source/decrypt.test.ts +62 -29
  173. package/components/identity.tokens/source/decrypt.ts +30 -27
  174. package/components/identity.tokens/source/encrypt.test.ts +21 -16
  175. package/components/identity.tokens/source/encrypt.ts +8 -11
  176. package/components/identity.tokens/source/issue.test.ts +4 -2
  177. package/components/identity.tokens/source/issue.ts +6 -8
  178. package/components/identity.tokens/source/lib/form.ts +5 -9
  179. package/components/identity.tokens/source/lib/jose.d.ts +1 -1
  180. package/components/identity.tokens/source/lib/key.ts +1 -1
  181. package/components/identity.tokens/source/lib/paseto.test.ts +17 -6
  182. package/components/identity.tokens/source/revoke.ts +1 -1
  183. package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
  184. package/components/identity.tokens/types/index.d.ts +13 -4
  185. package/components/identity.tokens/types/toa.d.ts +5 -5
  186. package/context.toa.yaml +2 -2
  187. package/cucumber.mjs +3 -0
  188. package/documentation/access.md +4 -3
  189. package/documentation/cache.md +17 -3
  190. package/documentation/components.md +2 -2
  191. package/documentation/credentials.md +2 -2
  192. package/documentation/identity.md +7 -9
  193. package/documentation/map.md +2 -2
  194. package/documentation/mcp.md +16 -16
  195. package/documentation/notes/peers.md +1 -1
  196. package/documentation/notes/throttling.md +1 -1
  197. package/documentation/octets.md +4 -4
  198. package/documentation/protocol.md +3 -3
  199. package/documentation/query.md +14 -8
  200. package/documentation/rpc.md +31 -21
  201. package/documentation/tracing.md +3 -3
  202. package/documentation/tree.md +1 -1
  203. package/features/auth.assert.feature +2 -2
  204. package/features/auth.bearer.feature +1 -1
  205. package/features/auth.claims.feature +5 -5
  206. package/features/auth.incept.feature +2 -2
  207. package/features/authorities.federation.feature +1 -1
  208. package/features/configuration.feature +3 -4
  209. package/features/credentials.feature +9 -9
  210. package/features/dev.feature +1 -0
  211. package/features/dynamic.feature +1 -0
  212. package/features/errors.feature +21 -0
  213. package/features/etag.feature +0 -86
  214. package/features/identity.bans.feature +3 -3
  215. package/features/identity.basic.feature +9 -9
  216. package/features/identity.federation.feature +11 -11
  217. package/features/identity.tokens.custom.feature +5 -5
  218. package/features/identity.tokens.feature +2 -2
  219. package/features/interruptions.feature +1 -0
  220. package/features/introspection.map.feature +4 -4
  221. package/features/io.throttle.feature +1 -0
  222. package/features/map.feature +2 -2
  223. package/features/octets.cloudinary.feature +1 -1
  224. package/features/octets.download.feature +1 -0
  225. package/features/require.feature +1 -2
  226. package/features/steps/Captures.ts +1 -1
  227. package/features/steps/Cloudinary.ts +1 -2
  228. package/features/steps/Common.ts +4 -5
  229. package/features/steps/Components.ts +17 -12
  230. package/features/steps/Database.ts +42 -23
  231. package/features/steps/Gateway.ts +55 -72
  232. package/features/steps/HTTP.ts +12 -15
  233. package/features/steps/IDP.ts +118 -94
  234. package/features/steps/Identity.ts +3 -3
  235. package/features/steps/OTP.ts +3 -3
  236. package/features/steps/Parameters.ts +20 -10
  237. package/features/steps/Probe.ts +9 -7
  238. package/features/steps/Realtime.ts +40 -22
  239. package/features/steps/Workspace.ts +10 -7
  240. package/features/steps/components/audit/operations/record.js +1 -1
  241. package/features/steps/components/echo/operations/affect.js +1 -1
  242. package/features/steps/components/echo/operations/compute.js +1 -1
  243. package/features/steps/components/echo/operations/echo.js +1 -1
  244. package/features/steps/components/echo/operations/error.js +1 -1
  245. package/features/steps/components/echo/operations/identity.js +1 -1
  246. package/features/steps/components/echo/operations/parameters.js +1 -1
  247. package/features/steps/components/echo/operations/ping.js +1 -1
  248. package/features/steps/components/echo/operations/unwrap.js +1 -1
  249. package/features/steps/components/greeter/operations/greet.js +1 -1
  250. package/features/steps/components/notify/operations/send.js +1 -1
  251. package/features/steps/components/octets.tester/operations/authority.js +1 -1
  252. package/features/steps/components/octets.tester/operations/bar.js +1 -1
  253. package/features/steps/components/octets.tester/operations/baz.js +1 -1
  254. package/features/steps/components/octets.tester/operations/concat.js +1 -1
  255. package/features/steps/components/octets.tester/operations/echo.js +1 -1
  256. package/features/steps/components/octets.tester/operations/err.js +1 -1
  257. package/features/steps/components/octets.tester/operations/foo.js +1 -1
  258. package/features/steps/components/octets.tester/operations/id.js +1 -1
  259. package/features/steps/components/octets.tester/operations/identity.js +1 -1
  260. package/features/steps/components/octets.tester/operations/redirect.js +6 -4
  261. package/features/steps/components/octets.tester/operations/yex.js +1 -1
  262. package/features/steps/components/octets.tester/operations/yield.js +1 -1
  263. package/features/steps/components/orders/manifest.toa.yaml +10 -12
  264. package/features/steps/components/orders/operations/create.js +4 -2
  265. package/features/steps/components/pots/manifest.toa.yaml +15 -20
  266. package/features/steps/components/pots/migrations/0002-indexes.yaml +4 -0
  267. package/features/steps/components/pricing/operations/quote.js +1 -1
  268. package/features/steps/components/sequences/manifest.toa.yaml +0 -1
  269. package/features/steps/components/sequences/operations/numbers.js +1 -1
  270. package/features/steps/components/sequences/operations/tokens.js +3 -3
  271. package/features/steps/components/users/manifest.toa.yaml +3 -5
  272. package/features/steps/components/users/operations/create.js +1 -1
  273. package/features/steps/components/users.properties/manifest.toa.yaml +5 -6
  274. package/features/steps/map.ts +2 -2
  275. package/features/timestamps.feature +1 -1
  276. package/package.json +7 -7
  277. package/readme.md +11 -11
  278. package/schemas/annotation.cos.yaml +1 -3
  279. package/schemas/method.cos.yaml +2 -0
  280. package/source/Branch.test.ts +2 -2
  281. package/source/Branch.ts +3 -5
  282. package/source/Composition.ts +5 -5
  283. package/source/Directive.test.ts +38 -20
  284. package/source/Directive.ts +61 -47
  285. package/source/Endpoint.test.ts +1 -1
  286. package/source/Endpoint.ts +27 -92
  287. package/source/Factory.ts +26 -12
  288. package/source/Gateway.ts +87 -76
  289. package/source/HTTP/Context.ts +23 -30
  290. package/source/HTTP/Probe.ts +7 -9
  291. package/source/HTTP/Server.ts +88 -69
  292. package/source/HTTP/Timing.ts +6 -21
  293. package/source/HTTP/address.test.ts +8 -2
  294. package/source/HTTP/address.ts +2 -3
  295. package/source/HTTP/exceptions.ts +20 -18
  296. package/source/HTTP/formats/form.ts +1 -1
  297. package/source/HTTP/formats/json.ts +2 -2
  298. package/source/HTTP/formats/msgpack.ts +3 -4
  299. package/source/HTTP/formats/text.ts +2 -2
  300. package/source/HTTP/formats/yaml.test.ts +4 -1
  301. package/source/HTTP/formats/yaml.ts +14 -11
  302. package/source/HTTP/messages.test.ts +38 -28
  303. package/source/HTTP/messages.ts +44 -98
  304. package/source/Interception.ts +3 -4
  305. package/source/Introspection.ts +26 -14
  306. package/source/MCP/Server.ts +114 -54
  307. package/source/MCP/discover.ts +6 -7
  308. package/source/MCP/errors.ts +7 -8
  309. package/source/MCP/schema.test.ts +9 -3
  310. package/source/MCP/schema.ts +12 -16
  311. package/source/MCP/tools.ts +33 -28
  312. package/source/Mapping.ts +25 -27
  313. package/source/Query.ts +58 -44
  314. package/source/RPC/Context.ts +8 -11
  315. package/source/RPC/Dispatcher.ts +46 -26
  316. package/source/RPC/errors.test.ts +41 -16
  317. package/source/RPC/errors.ts +9 -10
  318. package/source/RPC/names.test.ts +35 -16
  319. package/source/RPC/names.ts +22 -29
  320. package/source/RTD/Directives.ts +21 -10
  321. package/source/RTD/Endpoint.ts +4 -1
  322. package/source/RTD/Method.ts +8 -6
  323. package/source/RTD/Node.ts +32 -34
  324. package/source/RTD/Route.ts +18 -21
  325. package/source/RTD/Tree.ts +18 -18
  326. package/source/RTD/factory.ts +13 -16
  327. package/source/RTD/segment.ts +12 -10
  328. package/source/RTD/syntax/parse.test.ts +12 -6
  329. package/source/RTD/syntax/parse.ts +30 -26
  330. package/source/RTD/syntax/types.ts +17 -1
  331. package/source/RTD/walk.test.ts +59 -22
  332. package/source/Remotes.test.ts +25 -4
  333. package/source/Remotes.ts +9 -4
  334. package/source/Tenant.ts +12 -12
  335. package/source/deployment.ts +20 -20
  336. package/source/directives/auth/Anonymous.test.ts +8 -2
  337. package/source/directives/auth/Anonymous.ts +5 -8
  338. package/source/directives/auth/Anyone.ts +3 -3
  339. package/source/directives/auth/Assert.ts +10 -10
  340. package/source/directives/auth/Authorization.ts +83 -69
  341. package/source/directives/auth/Delegate.test.ts +2 -2
  342. package/source/directives/auth/Delegate.ts +8 -10
  343. package/source/directives/auth/Echo.ts +5 -8
  344. package/source/directives/auth/Federation.ts +30 -21
  345. package/source/directives/auth/Id.ts +7 -4
  346. package/source/directives/auth/Incept.ts +32 -26
  347. package/source/directives/auth/Input.ts +36 -20
  348. package/source/directives/auth/Role.test.ts +49 -23
  349. package/source/directives/auth/Role.ts +29 -22
  350. package/source/directives/auth/Rule.ts +13 -8
  351. package/source/directives/auth/Scheme.ts +7 -7
  352. package/source/directives/auth/create.ts +1 -1
  353. package/source/directives/auth/schemes.ts +1 -1
  354. package/source/directives/auth/split.ts +2 -3
  355. package/source/directives/auth/types.ts +5 -2
  356. package/source/directives/cache/Cache.ts +44 -9
  357. package/source/directives/cache/Control.ts +25 -26
  358. package/source/directives/cache/Exact.ts +1 -1
  359. package/source/directives/cache/etag.ts +38 -0
  360. package/source/directives/cors/CORS.ts +9 -7
  361. package/source/directives/dev/Development.ts +3 -4
  362. package/source/directives/dev/Faulty.ts +11 -6
  363. package/source/directives/dev/Sleep.ts +5 -7
  364. package/source/directives/dev/Stub.ts +2 -2
  365. package/source/directives/dev/Throw.ts +2 -2
  366. package/source/directives/flow/Compose.ts +26 -20
  367. package/source/directives/flow/Fetch.ts +15 -15
  368. package/source/directives/flow/Flow.ts +9 -8
  369. package/source/directives/index.ts +11 -2
  370. package/source/directives/io/IO.ts +29 -20
  371. package/source/directives/io/Input.ts +9 -12
  372. package/source/directives/io/Output.ts +20 -23
  373. package/source/directives/io/Status.test.ts +12 -8
  374. package/source/directives/io/Status.ts +9 -8
  375. package/source/directives/io/Throttle.ts +6 -7
  376. package/source/directives/io/lib/throttle/Configuration.test.ts +32 -23
  377. package/source/directives/io/lib/throttle/Configuration.ts +14 -9
  378. package/source/directives/io/lib/throttle/Keys.ts +15 -10
  379. package/source/directives/io/lib/throttle/Quotas.test.ts +33 -17
  380. package/source/directives/io/lib/throttle/Quotas.ts +20 -26
  381. package/source/directives/io/lib/throttle/Sync.test.ts +14 -10
  382. package/source/directives/io/lib/throttle/Sync.ts +9 -12
  383. package/source/directives/io/lib/throttle/Warning.ts +3 -4
  384. package/source/directives/io/lib/throttle/components/IP.ts +4 -5
  385. package/source/directives/io/lib/throttle/components/Identity.ts +1 -1
  386. package/source/directives/io/lib/throttle/components/Path.ts +1 -1
  387. package/source/directives/io/lib/throttle/components/Route.ts +2 -2
  388. package/source/directives/io/lib/throttle/components/Segment.ts +2 -2
  389. package/source/directives/io/lib/throttle/conditions/Status.ts +2 -2
  390. package/source/directives/io/schemas.test.ts +12 -6
  391. package/source/directives/map/Authority.ts +2 -2
  392. package/source/directives/map/Buffer.ts +2 -2
  393. package/source/directives/map/Claims.ts +25 -20
  394. package/source/directives/map/Headers.ts +17 -13
  395. package/source/directives/map/Language.ts +8 -5
  396. package/source/directives/map/Languages.ts +9 -3
  397. package/source/directives/map/Map.ts +25 -12
  398. package/source/directives/map/Mapping.ts +9 -6
  399. package/source/directives/map/Properties.ts +1 -1
  400. package/source/directives/map/Segments.ts +22 -15
  401. package/source/directives/mcp/MCP.ts +9 -7
  402. package/source/directives/mcp/Tool.test.ts +21 -9
  403. package/source/directives/mcp/Tool.ts +23 -11
  404. package/source/directives/oauth/Discovery.ts +7 -11
  405. package/source/directives/oauth/documents.ts +11 -14
  406. package/source/directives/octets/Context.ts +6 -3
  407. package/source/directives/octets/Delete.ts +33 -25
  408. package/source/directives/octets/Directive.ts +5 -1
  409. package/source/directives/octets/Get.ts +13 -21
  410. package/source/directives/octets/Octets.ts +20 -15
  411. package/source/directives/octets/Put.ts +62 -27
  412. package/source/directives/octets/Workflow.ts +18 -12
  413. package/source/directives/octets/bytes.ts +1 -1
  414. package/source/directives/octets/schemas.test.ts +8 -14
  415. package/source/directives/octets/workflows/Execution.ts +19 -21
  416. package/source/directives/octets/workflows/Workflow.ts +10 -7
  417. package/source/directives/require/Headers.ts +3 -4
  418. package/source/directives/require/Require.ts +3 -4
  419. package/source/exceptions.ts +19 -12
  420. package/source/index.ts +1 -1
  421. package/source/manifest.test.ts +4 -1
  422. package/source/manifest.ts +19 -13
  423. package/source/octets.d.ts +1 -1
  424. package/source/root.ts +3 -2
  425. package/source/schemas.test.ts +17 -3
  426. package/transpiled/Branch.js.map +1 -1
  427. package/transpiled/Composition.js.map +1 -1
  428. package/transpiled/Directive.js +6 -2
  429. package/transpiled/Directive.js.map +1 -1
  430. package/transpiled/Endpoint.d.ts +0 -2
  431. package/transpiled/Endpoint.js +11 -52
  432. package/transpiled/Endpoint.js.map +1 -1
  433. package/transpiled/Factory.d.ts +2 -1
  434. package/transpiled/Factory.js +1 -0
  435. package/transpiled/Factory.js.map +1 -1
  436. package/transpiled/Gateway.d.ts +2 -1
  437. package/transpiled/Gateway.js +24 -15
  438. package/transpiled/Gateway.js.map +1 -1
  439. package/transpiled/HTTP/Context.d.ts +0 -3
  440. package/transpiled/HTTP/Context.js +7 -9
  441. package/transpiled/HTTP/Context.js.map +1 -1
  442. package/transpiled/HTTP/Probe.js.map +1 -1
  443. package/transpiled/HTTP/Server.js +19 -4
  444. package/transpiled/HTTP/Server.js.map +1 -1
  445. package/transpiled/HTTP/Timing.d.ts +1 -2
  446. package/transpiled/HTTP/Timing.js +2 -10
  447. package/transpiled/HTTP/Timing.js.map +1 -1
  448. package/transpiled/HTTP/address.js.map +1 -1
  449. package/transpiled/HTTP/exceptions.js.map +1 -1
  450. package/transpiled/HTTP/formats/form.js.map +1 -1
  451. package/transpiled/HTTP/formats/json.js.map +1 -1
  452. package/transpiled/HTTP/formats/msgpack.js.map +1 -1
  453. package/transpiled/HTTP/formats/text.js.map +1 -1
  454. package/transpiled/HTTP/formats/yaml.js +4 -1
  455. package/transpiled/HTTP/formats/yaml.js.map +1 -1
  456. package/transpiled/HTTP/messages.d.ts +3 -2
  457. package/transpiled/HTTP/messages.js +1 -43
  458. package/transpiled/HTTP/messages.js.map +1 -1
  459. package/transpiled/Interception.js.map +1 -1
  460. package/transpiled/Introspection.js +13 -2
  461. package/transpiled/Introspection.js.map +1 -1
  462. package/transpiled/MCP/Server.js +15 -4
  463. package/transpiled/MCP/Server.js.map +1 -1
  464. package/transpiled/MCP/discover.js.map +1 -1
  465. package/transpiled/MCP/errors.js.map +1 -1
  466. package/transpiled/MCP/schema.js +1 -1
  467. package/transpiled/MCP/schema.js.map +1 -1
  468. package/transpiled/MCP/tools.js +10 -7
  469. package/transpiled/MCP/tools.js.map +1 -1
  470. package/transpiled/Mapping.d.ts +2 -2
  471. package/transpiled/Mapping.js +3 -5
  472. package/transpiled/Mapping.js.map +1 -1
  473. package/transpiled/Query.d.ts +6 -2
  474. package/transpiled/Query.js +23 -8
  475. package/transpiled/Query.js.map +1 -1
  476. package/transpiled/RPC/Context.js +0 -7
  477. package/transpiled/RPC/Context.js.map +1 -1
  478. package/transpiled/RPC/Dispatcher.js +4 -1
  479. package/transpiled/RPC/Dispatcher.js.map +1 -1
  480. package/transpiled/RPC/errors.js.map +1 -1
  481. package/transpiled/RPC/names.js.map +1 -1
  482. package/transpiled/RTD/Directives.d.ts +1 -1
  483. package/transpiled/RTD/Method.js +1 -3
  484. package/transpiled/RTD/Method.js.map +1 -1
  485. package/transpiled/RTD/Node.js +5 -4
  486. package/transpiled/RTD/Node.js.map +1 -1
  487. package/transpiled/RTD/Route.js +4 -1
  488. package/transpiled/RTD/Route.js.map +1 -1
  489. package/transpiled/RTD/Tree.js +1 -1
  490. package/transpiled/RTD/Tree.js.map +1 -1
  491. package/transpiled/RTD/factory.js.map +1 -1
  492. package/transpiled/RTD/segment.js.map +1 -1
  493. package/transpiled/RTD/syntax/parse.js.map +1 -1
  494. package/transpiled/RTD/syntax/types.d.ts +6 -0
  495. package/transpiled/RTD/syntax/types.js +10 -1
  496. package/transpiled/RTD/syntax/types.js.map +1 -1
  497. package/transpiled/Remotes.js.map +1 -1
  498. package/transpiled/Tenant.d.ts +1 -1
  499. package/transpiled/Tenant.js.map +1 -1
  500. package/transpiled/deployment.d.ts +3 -0
  501. package/transpiled/deployment.js +6 -1
  502. package/transpiled/deployment.js.map +1 -1
  503. package/transpiled/directives/auth/Anonymous.js +1 -3
  504. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  505. package/transpiled/directives/auth/Anyone.js.map +1 -1
  506. package/transpiled/directives/auth/Assert.js.map +1 -1
  507. package/transpiled/directives/auth/Authorization.js +7 -3
  508. package/transpiled/directives/auth/Authorization.js.map +1 -1
  509. package/transpiled/directives/auth/Delegate.js.map +1 -1
  510. package/transpiled/directives/auth/Echo.js +1 -3
  511. package/transpiled/directives/auth/Echo.js.map +1 -1
  512. package/transpiled/directives/auth/Federation.js +3 -7
  513. package/transpiled/directives/auth/Federation.js.map +1 -1
  514. package/transpiled/directives/auth/Id.js.map +1 -1
  515. package/transpiled/directives/auth/Incept.js +1 -1
  516. package/transpiled/directives/auth/Incept.js.map +1 -1
  517. package/transpiled/directives/auth/Input.js.map +1 -1
  518. package/transpiled/directives/auth/Role.js.map +1 -1
  519. package/transpiled/directives/auth/Rule.js.map +1 -1
  520. package/transpiled/directives/auth/Scheme.js +1 -2
  521. package/transpiled/directives/auth/Scheme.js.map +1 -1
  522. package/transpiled/directives/auth/create.js.map +1 -1
  523. package/transpiled/directives/auth/schemes.js.map +1 -1
  524. package/transpiled/directives/auth/split.js.map +1 -1
  525. package/transpiled/directives/auth/types.d.ts +3 -1
  526. package/transpiled/directives/cache/Cache.js +28 -2
  527. package/transpiled/directives/cache/Cache.js.map +1 -1
  528. package/transpiled/directives/cache/Control.js +1 -1
  529. package/transpiled/directives/cache/Control.js.map +1 -1
  530. package/transpiled/directives/cache/etag.d.ts +10 -0
  531. package/transpiled/directives/cache/etag.js +30 -0
  532. package/transpiled/directives/cache/etag.js.map +1 -0
  533. package/transpiled/directives/cors/CORS.js.map +1 -1
  534. package/transpiled/directives/dev/Development.js.map +1 -1
  535. package/transpiled/directives/dev/Faulty.js.map +1 -1
  536. package/transpiled/directives/dev/Sleep.js.map +1 -1
  537. package/transpiled/directives/dev/Stub.js.map +1 -1
  538. package/transpiled/directives/dev/Throw.js.map +1 -1
  539. package/transpiled/directives/flow/Compose.js +7 -3
  540. package/transpiled/directives/flow/Compose.js.map +1 -1
  541. package/transpiled/directives/flow/Fetch.js.map +1 -1
  542. package/transpiled/directives/flow/Flow.js.map +1 -1
  543. package/transpiled/directives/index.js +11 -1
  544. package/transpiled/directives/index.js.map +1 -1
  545. package/transpiled/directives/io/IO.d.ts +1 -1
  546. package/transpiled/directives/io/IO.js.map +1 -1
  547. package/transpiled/directives/io/Input.js +1 -1
  548. package/transpiled/directives/io/Input.js.map +1 -1
  549. package/transpiled/directives/io/Output.js +3 -3
  550. package/transpiled/directives/io/Output.js.map +1 -1
  551. package/transpiled/directives/io/Status.js.map +1 -1
  552. package/transpiled/directives/io/Throttle.js +1 -1
  553. package/transpiled/directives/io/Throttle.js.map +1 -1
  554. package/transpiled/directives/io/lib/throttle/Configuration.js +8 -2
  555. package/transpiled/directives/io/lib/throttle/Configuration.js.map +1 -1
  556. package/transpiled/directives/io/lib/throttle/Keys.js.map +1 -1
  557. package/transpiled/directives/io/lib/throttle/Quotas.js +4 -3
  558. package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
  559. package/transpiled/directives/io/lib/throttle/Sync.d.ts +1 -1
  560. package/transpiled/directives/io/lib/throttle/Sync.js.map +1 -1
  561. package/transpiled/directives/io/lib/throttle/Warning.js.map +1 -1
  562. package/transpiled/directives/io/lib/throttle/components/IP.js.map +1 -1
  563. package/transpiled/directives/io/lib/throttle/components/Identity.js.map +1 -1
  564. package/transpiled/directives/io/lib/throttle/components/Path.js.map +1 -1
  565. package/transpiled/directives/io/lib/throttle/components/Route.js.map +1 -1
  566. package/transpiled/directives/io/lib/throttle/components/Segment.js.map +1 -1
  567. package/transpiled/directives/io/lib/throttle/conditions/Status.js.map +1 -1
  568. package/transpiled/directives/map/Authority.js.map +1 -1
  569. package/transpiled/directives/map/Buffer.js.map +1 -1
  570. package/transpiled/directives/map/Claims.js.map +1 -1
  571. package/transpiled/directives/map/Headers.js.map +1 -1
  572. package/transpiled/directives/map/Language.js.map +1 -1
  573. package/transpiled/directives/map/Languages.js.map +1 -1
  574. package/transpiled/directives/map/Map.js.map +1 -1
  575. package/transpiled/directives/map/Mapping.js.map +1 -1
  576. package/transpiled/directives/map/Properties.js.map +1 -1
  577. package/transpiled/directives/map/Segments.js.map +1 -1
  578. package/transpiled/directives/mcp/MCP.js +1 -1
  579. package/transpiled/directives/mcp/MCP.js.map +1 -1
  580. package/transpiled/directives/mcp/Tool.js +3 -1
  581. package/transpiled/directives/mcp/Tool.js.map +1 -1
  582. package/transpiled/directives/oauth/Discovery.js.map +1 -1
  583. package/transpiled/directives/oauth/documents.js.map +1 -1
  584. package/transpiled/directives/octets/Context.js +1 -1
  585. package/transpiled/directives/octets/Context.js.map +1 -1
  586. package/transpiled/directives/octets/Delete.js.map +1 -1
  587. package/transpiled/directives/octets/Directive.js.map +1 -1
  588. package/transpiled/directives/octets/Get.js.map +1 -1
  589. package/transpiled/directives/octets/Octets.js +1 -1
  590. package/transpiled/directives/octets/Octets.js.map +1 -1
  591. package/transpiled/directives/octets/Put.js.map +1 -1
  592. package/transpiled/directives/octets/Workflow.js.map +1 -1
  593. package/transpiled/directives/octets/bytes.js.map +1 -1
  594. package/transpiled/directives/octets/workflows/Execution.js +1 -2
  595. package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
  596. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
  597. package/transpiled/directives/require/Headers.js.map +1 -1
  598. package/transpiled/directives/require/Require.js.map +1 -1
  599. package/transpiled/exceptions.js.map +1 -1
  600. package/transpiled/index.d.ts +1 -1
  601. package/transpiled/index.js +1 -1
  602. package/transpiled/index.js.map +1 -1
  603. package/transpiled/manifest.js +5 -1
  604. package/transpiled/manifest.js.map +1 -1
  605. package/transpiled/root.js.map +1 -1
  606. package/tsconfig.tsbuildinfo +1 -1
  607. package/source/redact.test.ts +0 -27
  608. package/source/redact.ts +0 -21
  609. package/transpiled/redact.d.ts +0 -5
  610. package/transpiled/redact.js +0 -17
  611. package/transpiled/redact.js.map +0 -1
@@ -3,24 +3,24 @@ import tsflow from 'cucumber-tsflow'
3
3
  import * as boot from '@toa.io/boot'
4
4
  import { type Connector } from '@toa.io/core'
5
5
  import { load as parse } from 'js-yaml'
6
- import { timeout } from '@toa.io/generic'
7
6
  import { Factory } from '../../source/index.js'
8
7
  import * as syntax from '../../source/RTD/syntax/index.js'
9
8
  import { shortcuts } from '../../source/Directive.js'
10
9
  import { manifests } from './map.js'
10
+ import { PORT, PROBE } from './Parameters.js'
11
11
  import type * as http from '../../source/HTTP/index.js'
12
12
 
13
13
  const { after, afterAll, binding, given } = tsflow
14
14
 
15
15
  let instance: Connector | null = null
16
+ let deployment: string | null = null
16
17
 
17
18
  @binding()
18
19
  export class Gateway {
19
- private default: boolean = true
20
20
  private written: string[] = []
21
21
 
22
22
  @given('the annotation:')
23
- public async annotate (yaml: string): Promise<void> {
23
+ public async annotate(yaml: string): Promise<void> {
24
24
  const annotation = parse(yaml) as Partial<http.Options> & { '/'?: object }
25
25
 
26
26
  if (annotation['/'] !== undefined) {
@@ -32,32 +32,21 @@ export class Gateway {
32
32
  const { debug, authorities, bouncer, ip, oauth, rpc, mcp } = annotation
33
33
  const properties = Object.assign({}, DEFAULT_PROPERTIES)
34
34
 
35
- if (debug !== undefined)
36
- properties.debug = debug
35
+ if (debug !== undefined) properties.debug = debug
37
36
 
38
- if (bouncer !== undefined)
39
- properties.bouncer = bouncer
37
+ if (bouncer !== undefined) properties.bouncer = bouncer
40
38
 
41
- if (ip !== undefined)
42
- properties.ip = ip
39
+ if (ip !== undefined) properties.ip = ip
43
40
 
44
- if (authorities !== undefined)
45
- properties.authorities = authorities
41
+ if (authorities !== undefined) properties.authorities = authorities
46
42
 
47
- if (oauth !== undefined)
48
- properties.oauth = oauth
43
+ if (oauth !== undefined) properties.oauth = oauth
49
44
 
50
- if (rpc !== undefined)
51
- properties.rpc = rpc
45
+ if (rpc !== undefined) properties.rpc = rpc
52
46
 
53
- if (mcp !== undefined)
54
- properties.mcp = mcp
47
+ if (mcp !== undefined) properties.mcp = mcp
55
48
 
56
49
  process.env.TOA_EXPOSITION_PROPERTIES = JSON.stringify(properties)
57
-
58
- await Gateway.stop()
59
-
60
- this.default = false
61
50
  }
62
51
 
63
52
  /**
@@ -65,16 +54,17 @@ export class Gateway {
65
54
  * exposition extension over them, so what lands here is what a deployment would carry.
66
55
  */
67
56
  @given('the annotation of the introspection map')
68
- public async annotateMap (): Promise<void> {
57
+ public async annotateMap(): Promise<void> {
69
58
  await this.annotateMapUnder()
70
59
  }
71
60
 
72
61
  /** The same routes under a root of the scenario's own: what an application declares around the map. */
73
62
  @given('the annotation of the introspection map under:')
74
- public async annotateMapUnder (yaml?: string): Promise<void> {
75
- const tree: syntax.Node = yaml === undefined
76
- ? { routes: [], methods: [], directives: [] }
77
- : syntax.parse((parse(yaml) as { '/': object })['/'], shortcuts)
63
+ public async annotateMapUnder(yaml?: string): Promise<void> {
64
+ const tree: syntax.Node =
65
+ yaml === undefined
66
+ ? { routes: [], methods: [], directives: [] }
67
+ : syntax.parse((parse(yaml) as { '/': object })['/'], shortcuts)
78
68
 
79
69
  for (const manifest of await manifests()) {
80
70
  const node = manifest.extensions?.[EXPOSITION] as syntax.Node | undefined
@@ -87,14 +77,10 @@ export class Gateway {
87
77
 
88
78
  process.env.TOA_EXPOSITION = JSON.stringify(tree)
89
79
  process.env.TOA_EXPOSITION_PROPERTIES = JSON.stringify(DEFAULT_PROPERTIES)
90
-
91
- await Gateway.stop()
92
-
93
- this.default = false
94
80
  }
95
81
 
96
82
  @given('the `{word}` configuration:')
97
- public async configure (id: string, yaml: string): Promise<void> {
83
+ public async configure(id: string, yaml: string): Promise<void> {
98
84
  const [name, namespace = 'default'] = id.split('.').reverse()
99
85
  const key = `TOA_CONFIGURATION_${namespace.toUpperCase()}_${name.toUpperCase()}`
100
86
  const def = DEFAULT_CONFIGURATION[id] ?? {}
@@ -105,91 +91,89 @@ export class Gateway {
105
91
  // outlives the secrets it points at, and the next scenario cannot resolve them
106
92
  this.written.push(key)
107
93
  process.env[key] = JSON.stringify(configuration)
108
-
109
- await Gateway.stop()
110
-
111
- this.default = false
112
94
  }
113
95
 
114
96
  /** The secrets a scenario's configuration refers to. */
115
97
  @given('the configuration secrets:')
116
- public async secrets (yaml: string): Promise<void> {
98
+ public async secrets(yaml: string): Promise<void> {
117
99
  const secrets = parse(yaml) as Record<string, string>
118
100
 
119
101
  for (const [name, value] of Object.entries(secrets)) {
120
102
  this.written.push(SECRET + name)
121
103
  process.env[SECRET + name] = value
122
104
  }
123
-
124
- await Gateway.stop()
125
-
126
- this.default = false
127
105
  }
128
106
 
129
107
  @given('the branch TTL is {float} second(s)')
130
- public async setBranchTTL (seconds: number): Promise<void> {
108
+ public async setBranchTTL(seconds: number): Promise<void> {
131
109
  process.env.__TESTING_EXPOSITION_BRANCH_TTL = String(seconds * 1000)
132
-
133
- await Gateway.stop()
134
-
135
- this.default = false
136
110
  }
137
111
 
138
112
  @given('the Gateway is running')
139
- public async start (): Promise<void> {
140
- if (instance !== null)
141
- return
142
-
113
+ public async start(): Promise<void> {
143
114
  process.env.TOA_EXPOSITION ??= DEFAULT_TREE
144
115
  process.env.TOA_EXPOSITION_PROPERTIES ??= JSON.stringify(DEFAULT_PROPERTIES)
145
116
 
146
117
  this.writeConfiguration()
147
118
 
119
+ const signature = Gateway.signature()
120
+
121
+ /*
122
+ * A component is published without restarting the gateway, and a scenario that asks for
123
+ * the deployment already running gets that one. Only a different deployment is a restart,
124
+ * which is what an annotation, a configuration or a branch TTL of its own amounts to.
125
+ */
126
+ if (instance !== null && signature === deployment) return
127
+
128
+ await Gateway.stop()
129
+
148
130
  const factory = new Factory(boot.host())
149
131
  const service = await factory.service()
150
132
 
151
- if (service === null)
152
- throw new Error('?')
133
+ if (service === null) throw new Error('?')
153
134
 
154
135
  instance = service
155
136
 
156
137
  await service.connect()
157
138
 
158
- /*
159
- * The gateway waits for the branches it discovers, but a component's own resources —
160
- * a storage, a queue — are still connecting when it answers. Fifty milliseconds was
161
- * enough until the composition grew, then a hundred; a scenario that asks too early
162
- * reads the 404 that precedes the route, which `realtime` was failing on in two runs
163
- * of three. It is a sleep and not a poll, so it is raised rather than fixed.
164
- */
165
- await timeout(DISCOVERY)
139
+ deployment = signature
140
+ }
141
+
142
+ /** What the running gateway was built from: a different value is a different deployment. */
143
+ private static signature(): string {
144
+ const configuration = Object.keys(process.env)
145
+ .filter((key) => key.startsWith('TOA_CONFIGURATION_'))
146
+ .sort()
147
+ .map((key) => [key, process.env[key]])
148
+
149
+ return JSON.stringify([
150
+ process.env.TOA_EXPOSITION,
151
+ process.env.TOA_EXPOSITION_PROPERTIES,
152
+ process.env.__TESTING_EXPOSITION_BRANCH_TTL,
153
+ configuration
154
+ ])
166
155
  }
167
156
 
168
157
  @after()
169
- public async cleanup (): Promise<void> {
158
+ public async cleanup(): Promise<void> {
170
159
  delete process.env.__TESTING_EXPOSITION_BRANCH_TTL
171
160
 
172
- for (const key of this.written)
173
- delete process.env[key]
161
+ for (const key of this.written) delete process.env[key]
174
162
 
175
163
  this.written = []
176
164
 
177
- if (this.default)
178
- return
179
-
180
165
  delete process.env.TOA_EXPOSITION
181
166
  delete process.env.TOA_EXPOSITION_PROPERTIES
182
-
183
- await Gateway.stop()
184
167
  }
185
168
 
186
169
  @afterAll()
187
- public static async stop (): Promise<void> {
170
+ public static async stop(): Promise<void> {
188
171
  await instance?.disconnect()
189
172
  instance = null
173
+ deployment = null
190
174
  }
191
175
 
192
- private writeConfiguration (): void {
176
+ private writeConfiguration(): void {
193
177
  for (const [id, configuration] of Object.entries(DEFAULT_CONFIGURATION)) {
194
178
  const [name, namespace = 'default'] = id.split('.').reverse()
195
179
  const key = `TOA_CONFIGURATION_${namespace.toUpperCase()}_${name.toUpperCase()}`
@@ -217,13 +201,12 @@ const DEFAULT_TREE = JSON.stringify({
217
201
  ]
218
202
  } satisfies syntax.Node)
219
203
 
220
- /** Milliseconds a composition is given to finish connecting what it needs. */
221
- const DISCOVERY = 500
222
-
223
204
  const DEFAULT_PROPERTIES: Partial<http.Options> = {
224
205
  authorities: {
225
206
  nex: 'nex.toa.io'
226
207
  },
208
+ port: PORT,
209
+ probe: PROBE,
227
210
  // `npm run features:h2c` runs the whole suite over cleartext HTTP/2
228
211
  protocol: process.env.TOA_EXPOSITION_PROTOCOL === 'h2c' ? 'h2c' : 'h1'
229
212
  }
@@ -17,25 +17,25 @@ const { binding, then, when } = tsflow
17
17
  export class HTTP extends http.Agent {
18
18
  private readonly gateway: Gateway
19
19
 
20
- public constructor (gateway: Gateway, parameters: Parameters, captures: Captures) {
20
+ public constructor(gateway: Gateway, parameters: Parameters, captures: Captures) {
21
21
  super(parameters.origin, captures)
22
22
  this.gateway = gateway
23
23
  }
24
24
 
25
25
  @when('the following request is received:')
26
- public override async request (input: string): Promise<any> {
26
+ public override async request(input: string): Promise<any> {
27
27
  await this.gateway.start()
28
28
 
29
29
  await super.request(input)
30
30
  }
31
31
 
32
32
  @then('the following reply is sent:')
33
- public override responseIncludes (expected: string): void {
33
+ public override responseIncludes(expected: string): void {
34
34
  super.responseIncludes(expected)
35
35
  }
36
36
 
37
37
  @then('response body contains {word}-encoded value:')
38
- public async bodyIs (format: string, yaml: string): Promise<void> {
38
+ public async bodyIs(format: string, yaml: string): Promise<void> {
39
39
  assert.ok(this.bytes !== null, 'Response body is not available')
40
40
 
41
41
  const value = encoders[format]?.(this.bytes)
@@ -45,12 +45,12 @@ export class HTTP extends http.Agent {
45
45
  }
46
46
 
47
47
  @then('the reply does not contain:')
48
- public override responseExcludes (expected: string): void {
48
+ public override responseExcludes(expected: string): void {
49
49
  super.responseExcludes(expected)
50
50
  }
51
51
 
52
52
  @when('the stream of `{word}` is received with the following headers:')
53
- public async streamRequest (filename: string, head: string): Promise<any> {
53
+ public async streamRequest(filename: string, head: string): Promise<any> {
54
54
  const stream = open(filename)
55
55
 
56
56
  await this.gateway.start()
@@ -58,30 +58,27 @@ export class HTTP extends http.Agent {
58
58
  }
59
59
 
60
60
  @then('the stream equals to `{word}` is sent with the following headers:')
61
- public async responseStreamMatch (filename: string, head: string): Promise<any> {
61
+ public async responseStreamMatch(filename: string, head: string): Promise<any> {
62
62
  const stream = open(filename)
63
63
 
64
64
  await super.streamMatch(head, stream)
65
65
  }
66
66
 
67
67
  @when('the following request is interrupted after {float} second(s):')
68
- public async interrupt (delay: number, input: string): Promise<any> {
68
+ public async interrupt(delay: number, input: string): Promise<any> {
69
69
  const controller = new AbortController()
70
70
 
71
71
  await this.gateway.start()
72
72
 
73
73
  setTimeout(() => {
74
- if (pending)
75
- controller.abort()
76
- else
77
- console.error('Request cannot be interrupted as it is already completed')
74
+ if (pending) controller.abort()
75
+ else console.error('Request cannot be interrupted as it is already completed')
78
76
  }, delay * 1000)
79
77
 
80
78
  let pending = true
81
79
 
82
80
  await super.fetch(input, { signal: controller.signal }).catch((e) => {
83
- if (e.name !== 'AbortError')
84
- throw e
81
+ if (e.name !== 'AbortError') throw e
85
82
  })
86
83
 
87
84
  pending = false
@@ -90,7 +87,7 @@ export class HTTP extends http.Agent {
90
87
 
91
88
  const FILES_DIR = path.resolve(import.meta.dirname, '../../../storages/source/test')
92
89
 
93
- function open (filename: string): Readable {
90
+ function open(filename: string): Readable {
94
91
  return fs.createReadStream(path.join(FILES_DIR, filename))
95
92
  }
96
93
 
@@ -20,12 +20,12 @@ export class IDP {
20
20
  private static authCodes = new Map<string, AuthCode>()
21
21
  private readonly captures: Captures
22
22
 
23
- public constructor (captures: Captures) {
23
+ public constructor(captures: Captures) {
24
24
  this.captures = captures
25
25
  }
26
26
 
27
27
  @afterAll()
28
- public static async stop (): Promise<void> {
28
+ public static async stop(): Promise<void> {
29
29
  if (this.server instanceof http.Server) {
30
30
  this.server.close()
31
31
  await once(this.server, 'close')
@@ -33,25 +33,27 @@ export class IDP {
33
33
  }
34
34
 
35
35
  @given(/local IDP is running/i)
36
- public async start (): Promise<void> {
36
+ public async start(): Promise<void> {
37
37
  if (IDP.server instanceof http.Server) return
38
38
 
39
39
  // creating the key
40
- const {
41
- publicKey,
42
- privateKey
43
- } = await util.promisify(crypto.generateKeyPair)('rsa', {
44
- modulusLength: 2048
45
- })
40
+ const { publicKey, privateKey } = await util.promisify(crypto.generateKeyPair)(
41
+ 'rsa',
42
+ {
43
+ modulusLength: 2048
44
+ }
45
+ )
46
46
 
47
47
  IDP.privateKey = privateKey
48
48
 
49
49
  const jwk = JSON.stringify({
50
- keys: [{
51
- use: 'sig',
52
- alg: 'RS256',
53
- ...publicKey.export({ format: 'jwk' })
54
- }]
50
+ keys: [
51
+ {
52
+ use: 'sig',
53
+ alg: 'RS256',
54
+ ...publicKey.export({ format: 'jwk' })
55
+ }
56
+ ]
55
57
  })
56
58
 
57
59
  const JWK_ENDPOINT = '/.well-known/jwks'
@@ -71,79 +73,83 @@ export class IDP {
71
73
  response.end(jwk)
72
74
  break
73
75
 
74
- case '/.well-known/openid-configuration': {
75
- const openIdConfiguration = JSON.stringify({
76
- issuer: IDP.issuer,
77
- jwks_uri: IDP.issuer + JWK_ENDPOINT,
78
- authorization_endpoint: IDP.issuer + AUTH_ENDPOINT,
79
- token_endpoint: IDP.issuer + TOKEN_ENDPOINT,
80
- response_types_supported: ['id_token', 'code'],
81
- grant_types_supported: ['authorization_code'],
82
- subject_types_supported: ['public'],
83
- id_token_signing_alg_values_supported: ['RS256'],
84
- scopes_supported: ['openid', 'email', 'profile']
85
- })
86
-
87
- response.writeHead(200, {
88
- 'Content-Type': 'application/json',
89
- 'Cache-Control': 'public, max-age=3600',
90
- 'Content-Length': openIdConfiguration.length
91
- })
92
-
93
- response.end(openIdConfiguration)
94
- }
95
-
96
- break
97
-
98
- case TOKEN_ENDPOINT: {
99
- if (request.method !== 'POST') {
100
- response.writeHead(405, { 'Content-Type': 'text/plain' })
101
- response.end('Method not allowed')
102
-
103
- return
104
- }
105
-
106
- const buf = await buffer(request)
107
- const body = buf.toString('utf8')
108
-
109
- const params = new URLSearchParams(body)
110
- const grantType = params.get('grant_type')!
111
- const code = params.get('code')!
112
- const redirectUri = params.get('redirect_uri')!
113
- const clientId = params.get('client_id')!
114
-
115
- if (grantType !== 'authorization_code' || !code || !clientId) {
116
- response.writeHead(400, { 'Content-Type': 'application/json' })
117
- response.end(JSON.stringify({ error: 'invalid_request' }))
76
+ case '/.well-known/openid-configuration':
77
+ {
78
+ const openIdConfiguration = JSON.stringify({
79
+ issuer: IDP.issuer,
80
+ jwks_uri: IDP.issuer + JWK_ENDPOINT,
81
+ authorization_endpoint: IDP.issuer + AUTH_ENDPOINT,
82
+ token_endpoint: IDP.issuer + TOKEN_ENDPOINT,
83
+ response_types_supported: ['id_token', 'code'],
84
+ grant_types_supported: ['authorization_code'],
85
+ subject_types_supported: ['public'],
86
+ id_token_signing_alg_values_supported: ['RS256'],
87
+ scopes_supported: ['openid', 'email', 'profile']
88
+ })
89
+
90
+ response.writeHead(200, {
91
+ 'Content-Type': 'application/json',
92
+ 'Cache-Control': 'public, max-age=3600',
93
+ 'Content-Length': openIdConfiguration.length
94
+ })
95
+
96
+ response.end(openIdConfiguration)
118
97
  }
119
98
 
120
- const codeData = IDP.authCodes.get(code)
121
-
122
- if (!codeData ||
123
- codeData.expiresAt < Date.now() ||
124
- codeData.clientId !== clientId ||
125
- (redirectUri && codeData.redirectUri !== redirectUri)) {
126
- response.writeHead(400, { 'Content-Type': 'application/json' })
127
- response.end(JSON.stringify({ error: 'invalid_grant' }))
99
+ break
128
100
 
129
- return
101
+ case TOKEN_ENDPOINT:
102
+ {
103
+ if (request.method !== 'POST') {
104
+ response.writeHead(405, { 'Content-Type': 'text/plain' })
105
+ response.end('Method not allowed')
106
+
107
+ return
108
+ }
109
+
110
+ const buf = await buffer(request)
111
+ const body = buf.toString('utf8')
112
+
113
+ const params = new URLSearchParams(body)
114
+ const grantType = params.get('grant_type')!
115
+ const code = params.get('code')!
116
+ const redirectUri = params.get('redirect_uri')!
117
+ const clientId = params.get('client_id')!
118
+
119
+ if (grantType !== 'authorization_code' || !code || !clientId) {
120
+ response.writeHead(400, { 'Content-Type': 'application/json' })
121
+ response.end(JSON.stringify({ error: 'invalid_request' }))
122
+ }
123
+
124
+ const codeData = IDP.authCodes.get(code)
125
+
126
+ if (
127
+ !codeData ||
128
+ codeData.expiresAt < Date.now() ||
129
+ codeData.clientId !== clientId ||
130
+ (redirectUri && codeData.redirectUri !== redirectUri)
131
+ ) {
132
+ response.writeHead(400, { 'Content-Type': 'application/json' })
133
+ response.end(JSON.stringify({ error: 'invalid_grant' }))
134
+
135
+ return
136
+ }
137
+
138
+ const accessToken = crypto.randomBytes(32).toString('hex')
139
+ const idToken = this.generateIdToken(codeData.sub, codeData.email, clientId)
140
+
141
+ IDP.authCodes.delete(code)
142
+
143
+ response.writeHead(200, { 'Content-Type': 'application/json' }).end(
144
+ JSON.stringify({
145
+ access_token: accessToken,
146
+ token_type: 'Bearer',
147
+ id_token: idToken,
148
+ expires_in: 3600
149
+ })
150
+ )
130
151
  }
131
152
 
132
- const accessToken = crypto.randomBytes(32).toString('hex')
133
- const idToken = this.generateIdToken(codeData.sub, codeData.email, clientId)
134
-
135
- IDP.authCodes.delete(code)
136
-
137
- response
138
- .writeHead(200, { 'Content-Type': 'application/json' })
139
- .end(JSON.stringify({
140
- access_token: accessToken,
141
- token_type: 'Bearer',
142
- id_token: idToken,
143
- expires_in: 3600
144
- }))
145
- }
146
-
147
153
  break
148
154
 
149
155
  default:
@@ -152,7 +158,8 @@ export class IDP {
152
158
  }
153
159
  })
154
160
 
155
- server.listen(44444, 'localhost')
161
+ // in Toa's own block, and out of the ephemeral range an arbitrary port would sit in
162
+ server.listen(31005, 'localhost')
156
163
  await once(server, 'listening')
157
164
 
158
165
  const address = server.address() as AddressInfo
@@ -163,7 +170,7 @@ export class IDP {
163
170
  }
164
171
 
165
172
  @given('the IDP token for {word} is issued')
166
- public async issueToken (user: string): Promise<void> {
173
+ public async issueToken(user: string): Promise<void> {
167
174
  assert.ok(IDP.privateKey, 'IdP private key is not available')
168
175
 
169
176
  const jwt = [
@@ -183,7 +190,10 @@ export class IDP {
183
190
  .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
184
191
  .join('.')
185
192
 
186
- const signature = crypto.createSign('RSA-SHA256').end(jwt).sign(IDP.privateKey, 'base64url')
193
+ const signature = crypto
194
+ .createSign('RSA-SHA256')
195
+ .end(jwt)
196
+ .sign(IDP.privateKey, 'base64url')
187
197
 
188
198
  const idToken = `${jwt}.${signature}`
189
199
 
@@ -191,7 +201,7 @@ export class IDP {
191
201
  }
192
202
 
193
203
  @given('the IDP random token is issued')
194
- public async issueNewToken (): Promise<void> {
204
+ public async issueNewToken(): Promise<void> {
195
205
  assert.ok(IDP.privateKey, 'IdP private key is not available')
196
206
 
197
207
  const sub = Math.random().toString(36).substring(7)
@@ -213,7 +223,10 @@ export class IDP {
213
223
  .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
214
224
  .join('.')
215
225
 
216
- const signature = crypto.createSign('RSA-SHA256').end(jwt).sign(IDP.privateKey, 'base64url')
226
+ const signature = crypto
227
+ .createSign('RSA-SHA256')
228
+ .end(jwt)
229
+ .sign(IDP.privateKey, 'base64url')
217
230
 
218
231
  const idToken = `${jwt}.${signature}`
219
232
 
@@ -223,7 +236,11 @@ export class IDP {
223
236
  }
224
237
 
225
238
  @given('the IDP {word} token for {word} is issued with following secret:')
226
- public async issueSymmetricToken (alg: string, user: string, secret: string): Promise<void> {
239
+ public async issueSymmetricToken(
240
+ alg: string,
241
+ user: string,
242
+ secret: string
243
+ ): Promise<void> {
227
244
  const jwt = [
228
245
  {
229
246
  typ: 'JWT',
@@ -240,7 +257,8 @@ export class IDP {
240
257
  .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
241
258
  .join('.')
242
259
 
243
- const signature = crypto.createHmac(alg.replace(/^HS(\d{3})$/, 'sha$1'), secret)
260
+ const signature = crypto
261
+ .createHmac(alg.replace(/^HS(\d{3})$/, 'sha$1'), secret)
244
262
  .update(jwt)
245
263
  .digest('base64url')
246
264
 
@@ -250,7 +268,7 @@ export class IDP {
250
268
  }
251
269
 
252
270
  @given('ID token with jti is issued for {word}')
253
- public async issueTokenWithJti (user: string): Promise<void> {
271
+ public async issueTokenWithJti(user: string): Promise<void> {
254
272
  assert.ok(IDP.privateKey, 'IdP private key is not available')
255
273
 
256
274
  const jwt = [
@@ -271,7 +289,10 @@ export class IDP {
271
289
  .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
272
290
  .join('.')
273
291
 
274
- const signature = crypto.createSign('RSA-SHA256').end(jwt).sign(IDP.privateKey, 'base64url')
292
+ const signature = crypto
293
+ .createSign('RSA-SHA256')
294
+ .end(jwt)
295
+ .sign(IDP.privateKey, 'base64url')
275
296
 
276
297
  const idToken = `${jwt}.${signature}`
277
298
 
@@ -279,7 +300,7 @@ export class IDP {
279
300
  }
280
301
 
281
302
  @given('auth code for {word} is issued for {word}')
282
- public async issueAuthCode (user: string, redirectUri: string): Promise<void> {
303
+ public async issueAuthCode(user: string, redirectUri: string): Promise<void> {
283
304
  const code = crypto.randomBytes(16).toString('hex')
284
305
  const email = user + '@test.local'
285
306
  const clientId = 'nex'
@@ -300,7 +321,7 @@ export class IDP {
300
321
  this.captures.set(`${user}.code_credentials`, base64)
301
322
  }
302
323
 
303
- private generateIdToken (sub: string, email: string, clientId: string): string {
324
+ private generateIdToken(sub: string, email: string, clientId: string): string {
304
325
  assert.ok(IDP.privateKey, 'IdP private key is not available')
305
326
  assert.ok(IDP.issuer, 'IdP issuer is not available')
306
327
 
@@ -321,7 +342,10 @@ export class IDP {
321
342
  .map((v) => Buffer.from(JSON.stringify(v)).toString('base64url'))
322
343
  .join('.')
323
344
 
324
- const signature = crypto.createSign('RSA-SHA256').end(jwt).sign(IDP.privateKey, 'base64url')
345
+ const signature = crypto
346
+ .createSign('RSA-SHA256')
347
+ .end(jwt)
348
+ .sign(IDP.privateKey, 'base64url')
325
349
 
326
350
  return `${jwt}.${signature}`
327
351
  }