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

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/components/exposition.octets/operations/delete.js +1 -1
  2. package/components/exposition.octets/operations/get.js +5 -2
  3. package/components/exposition.octets/operations/head.js +1 -1
  4. package/components/exposition.octets/operations/put.js +29 -37
  5. package/components/exposition.octets/types/toa.d.ts +1 -1
  6. package/components/identity.bans/manifest.toa.yaml +12 -13
  7. package/components/identity.bans/migrations/0001-system-properties.yaml +14 -0
  8. package/components/identity.bans/operations/transit.js +1 -1
  9. package/components/identity.bans/source/transit.ts +1 -1
  10. package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
  11. package/components/identity.bans/types/toa.d.ts +5 -5
  12. package/components/identity.basic/events/principal.js +3 -1
  13. package/components/identity.basic/manifest.toa.yaml +17 -23
  14. package/components/identity.basic/migrations/0001-system-properties.yaml +14 -0
  15. package/components/identity.basic/migrations/0002-indexes.yaml +13 -0
  16. package/components/identity.basic/operations/add.js +1 -1
  17. package/components/identity.basic/operations/authenticate.js +2 -2
  18. package/components/identity.basic/operations/check.js +4 -2
  19. package/components/identity.basic/operations/delete.js +1 -1
  20. package/components/identity.basic/operations/incept.js +1 -1
  21. package/components/identity.basic/operations/info.js +1 -1
  22. package/components/identity.basic/operations/lib/credentials.js +1 -1
  23. package/components/identity.basic/operations/transit.js +7 -8
  24. package/components/identity.basic/source/add.ts +5 -2
  25. package/components/identity.basic/source/authenticate.ts +11 -13
  26. package/components/identity.basic/source/check.ts +9 -6
  27. package/components/identity.basic/source/delete.ts +4 -1
  28. package/components/identity.basic/source/incept.ts +13 -10
  29. package/components/identity.basic/source/info.ts +4 -1
  30. package/components/identity.basic/source/lib/credentials.ts +2 -3
  31. package/components/identity.basic/source/transit.ts +27 -21
  32. package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
  33. package/components/identity.basic/types/index.d.ts +7 -3
  34. package/components/identity.basic/types/toa.d.ts +5 -5
  35. package/components/identity.clients/manifest.toa.yaml +36 -40
  36. package/components/identity.clients/migrations/0001-system-properties.yaml +14 -0
  37. package/components/identity.clients/migrations/0002-indexes.yaml +4 -0
  38. package/components/identity.clients/operations/describe.js +1 -1
  39. package/components/identity.clients/operations/lib/canonical.js +1 -1
  40. package/components/identity.clients/operations/lib/cimd.js +3 -2
  41. package/components/identity.clients/operations/lib/redirect.js +7 -4
  42. package/components/identity.clients/operations/register.js +2 -2
  43. package/components/identity.clients/source/describe.ts +6 -8
  44. package/components/identity.clients/source/lib/Context.ts +6 -3
  45. package/components/identity.clients/source/lib/Entity.ts +1 -1
  46. package/components/identity.clients/source/lib/canonical.ts +1 -1
  47. package/components/identity.clients/source/lib/cimd.test.ts +8 -6
  48. package/components/identity.clients/source/lib/cimd.ts +24 -19
  49. package/components/identity.clients/source/lib/redirect.test.ts +8 -2
  50. package/components/identity.clients/source/lib/redirect.ts +12 -8
  51. package/components/identity.clients/source/register.ts +18 -18
  52. package/components/identity.clients/tsconfig.tsbuildinfo +1 -1
  53. package/components/identity.clients/types/toa.d.ts +5 -5
  54. package/components/identity.credentials/manifest.toa.yaml +4 -4
  55. package/components/identity.credentials/operations/list.js +8 -4
  56. package/components/identity.credentials/source/list.test.ts +39 -20
  57. package/components/identity.credentials/source/list.ts +12 -8
  58. package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
  59. package/components/identity.credentials/types/toa.d.ts +2 -2
  60. package/components/identity.federation/manifest.toa.yaml +23 -32
  61. package/components/identity.federation/migrations/0001-system-properties.yaml +14 -0
  62. package/components/identity.federation/migrations/0002-indexes.yaml +25 -0
  63. package/components/identity.federation/operations/authenticate.js +4 -2
  64. package/components/identity.federation/operations/create.js +2 -2
  65. package/components/identity.federation/operations/decode.js +1 -1
  66. package/components/identity.federation/operations/delete.js +1 -1
  67. package/components/identity.federation/operations/incept.js +1 -1
  68. package/components/identity.federation/operations/lib/decode.js +1 -1
  69. package/components/identity.federation/operations/lib/discovery.js +2 -2
  70. package/components/identity.federation/operations/lib/exchange.js +8 -4
  71. package/components/identity.federation/operations/lib/principal.js +1 -1
  72. package/components/identity.federation/operations/lib/resolve.js +1 -1
  73. package/components/identity.federation/operations/list.js +2 -2
  74. package/components/identity.federation/source/authenticate.ts +19 -17
  75. package/components/identity.federation/source/create.ts +6 -7
  76. package/components/identity.federation/source/decode.ts +4 -1
  77. package/components/identity.federation/source/delete.ts +4 -1
  78. package/components/identity.federation/source/incept.ts +2 -3
  79. package/components/identity.federation/source/lib/decode.ts +4 -7
  80. package/components/identity.federation/source/lib/discovery.test.ts +15 -5
  81. package/components/identity.federation/source/lib/discovery.ts +10 -9
  82. package/components/identity.federation/source/lib/exchange.ts +18 -15
  83. package/components/identity.federation/source/lib/jose.d.ts +1 -1
  84. package/components/identity.federation/source/lib/principal.ts +5 -3
  85. package/components/identity.federation/source/lib/resolve.ts +5 -1
  86. package/components/identity.federation/source/list.test.ts +26 -10
  87. package/components/identity.federation/source/list.ts +5 -2
  88. package/components/identity.federation/source/types/context.ts +5 -2
  89. package/components/identity.federation/source/types/entity.ts +2 -2
  90. package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
  91. package/components/identity.federation/types/toa.d.ts +5 -5
  92. package/components/identity.grants/manifest.toa.yaml +27 -31
  93. package/components/identity.grants/migrations/0001-system-properties.yaml +14 -0
  94. package/components/identity.grants/migrations/0002-indexes.yaml +5 -0
  95. package/components/identity.grants/operations/authorize.js +1 -1
  96. package/components/identity.grants/operations/exchange.js +5 -2
  97. package/components/identity.grants/operations/lib/code.js +1 -1
  98. package/components/identity.grants/operations/lib/identify.js +1 -1
  99. package/components/identity.grants/operations/list.js +1 -1
  100. package/components/identity.grants/operations/revoke.js +3 -2
  101. package/components/identity.grants/source/authorize.ts +27 -19
  102. package/components/identity.grants/source/exchange.ts +15 -11
  103. package/components/identity.grants/source/lib/code.ts +20 -8
  104. package/components/identity.grants/source/lib/identify.ts +1 -1
  105. package/components/identity.grants/source/list.ts +2 -2
  106. package/components/identity.grants/source/revoke.ts +9 -7
  107. package/components/identity.grants/tsconfig.tsbuildinfo +1 -1
  108. package/components/identity.grants/types/index.d.ts +3 -3
  109. package/components/identity.grants/types/toa.d.ts +5 -5
  110. package/components/identity.keys/manifest.toa.yaml +18 -23
  111. package/components/identity.keys/migrations/0001-system-properties.yaml +14 -0
  112. package/components/identity.keys/migrations/0002-indexes.yaml +4 -0
  113. package/components/identity.keys/operations/create.js +1 -1
  114. package/components/identity.keys/operations/disable.js +1 -1
  115. package/components/identity.keys/operations/revoke.js +1 -1
  116. package/components/identity.keys/source/create.ts +2 -3
  117. package/components/identity.keys/source/disable.ts +1 -1
  118. package/components/identity.keys/source/revoke.ts +2 -2
  119. package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
  120. package/components/identity.keys/types/toa.d.ts +5 -5
  121. package/components/identity.otp/manifest.toa.yaml +16 -24
  122. package/components/identity.otp/migrations/0001-system-properties.yaml +14 -0
  123. package/components/identity.otp/migrations/0002-indexes.yaml +5 -0
  124. package/components/identity.otp/operations/authenticate.js +1 -1
  125. package/components/identity.otp/operations/issue.js +1 -1
  126. package/components/identity.otp/source/authenticate.ts +4 -7
  127. package/components/identity.otp/source/issue.ts +1 -1
  128. package/components/identity.otp/source/lib/Context.ts +1 -1
  129. package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
  130. package/components/identity.otp/types/toa.d.ts +5 -5
  131. package/components/identity.passkeys/manifest.toa.yaml +45 -53
  132. package/components/identity.passkeys/migrations/0001-system-properties.yaml +14 -0
  133. package/components/identity.passkeys/migrations/0002-indexes.yaml +11 -0
  134. package/components/identity.passkeys/operations/authenticate.js +1 -1
  135. package/components/identity.passkeys/operations/challenge.js +6 -3
  136. package/components/identity.passkeys/operations/create.js +1 -1
  137. package/components/identity.passkeys/operations/delete.js +1 -1
  138. package/components/identity.passkeys/operations/list.js +1 -1
  139. package/components/identity.passkeys/operations/use.js +1 -1
  140. package/components/identity.passkeys/source/authenticate.ts +3 -4
  141. package/components/identity.passkeys/source/challenge.ts +29 -25
  142. package/components/identity.passkeys/source/create.ts +8 -6
  143. package/components/identity.passkeys/source/delete.ts +4 -1
  144. package/components/identity.passkeys/source/list.ts +4 -1
  145. package/components/identity.passkeys/source/types/Context.ts +1 -1
  146. package/components/identity.passkeys/source/use.ts +12 -10
  147. package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
  148. package/components/identity.passkeys/types/toa.d.ts +5 -5
  149. package/components/identity.roles/manifest.toa.yaml +12 -16
  150. package/components/identity.roles/migrations/0001-system-properties.yaml +14 -0
  151. package/components/identity.roles/migrations/0002-indexes.yaml +8 -0
  152. package/components/identity.roles/operations/grant.js +1 -1
  153. package/components/identity.roles/operations/list.js +1 -1
  154. package/components/identity.roles/operations/principal.js +2 -2
  155. package/components/identity.roles/source/grant.ts +7 -6
  156. package/components/identity.roles/source/list.ts +1 -1
  157. package/components/identity.roles/source/principal.ts +5 -7
  158. package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
  159. package/components/identity.roles/types/toa.d.ts +5 -5
  160. package/components/identity.tokens/manifest.toa.yaml +17 -15
  161. package/components/identity.tokens/migrations/0001-system-properties.yaml +14 -0
  162. package/components/identity.tokens/operations/authenticate.js +2 -2
  163. package/components/identity.tokens/operations/decrypt.js +11 -5
  164. package/components/identity.tokens/operations/encrypt.js +2 -2
  165. package/components/identity.tokens/operations/issue.js +2 -4
  166. package/components/identity.tokens/operations/lib/form.js +1 -1
  167. package/components/identity.tokens/operations/lib/key.js +1 -1
  168. package/components/identity.tokens/operations/revoke.js +1 -1
  169. package/components/identity.tokens/source/authenticate.test.ts +22 -16
  170. package/components/identity.tokens/source/authenticate.ts +7 -10
  171. package/components/identity.tokens/source/decrypt.test.ts +62 -29
  172. package/components/identity.tokens/source/decrypt.ts +30 -27
  173. package/components/identity.tokens/source/encrypt.test.ts +21 -16
  174. package/components/identity.tokens/source/encrypt.ts +8 -11
  175. package/components/identity.tokens/source/issue.test.ts +4 -2
  176. package/components/identity.tokens/source/issue.ts +6 -8
  177. package/components/identity.tokens/source/lib/form.ts +5 -9
  178. package/components/identity.tokens/source/lib/jose.d.ts +1 -1
  179. package/components/identity.tokens/source/lib/key.ts +1 -1
  180. package/components/identity.tokens/source/lib/paseto.test.ts +17 -6
  181. package/components/identity.tokens/source/revoke.ts +1 -1
  182. package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
  183. package/components/identity.tokens/types/index.d.ts +13 -4
  184. package/components/identity.tokens/types/toa.d.ts +5 -5
  185. package/context.toa.yaml +2 -2
  186. package/cucumber.mjs +3 -0
  187. package/documentation/access.md +4 -3
  188. package/documentation/cache.md +17 -3
  189. package/documentation/components.md +2 -2
  190. package/documentation/credentials.md +2 -2
  191. package/documentation/identity.md +7 -9
  192. package/documentation/map.md +2 -2
  193. package/documentation/mcp.md +16 -16
  194. package/documentation/notes/peers.md +1 -1
  195. package/documentation/notes/throttling.md +1 -1
  196. package/documentation/octets.md +4 -4
  197. package/documentation/protocol.md +3 -3
  198. package/documentation/query.md +14 -8
  199. package/documentation/rpc.md +31 -21
  200. package/documentation/tracing.md +3 -3
  201. package/documentation/tree.md +1 -1
  202. package/features/auth.assert.feature +2 -2
  203. package/features/auth.bearer.feature +1 -1
  204. package/features/auth.claims.feature +5 -5
  205. package/features/auth.incept.feature +2 -2
  206. package/features/authorities.federation.feature +1 -1
  207. package/features/configuration.feature +3 -4
  208. package/features/credentials.feature +9 -9
  209. package/features/dev.feature +1 -0
  210. package/features/dynamic.feature +1 -0
  211. package/features/errors.feature +21 -0
  212. package/features/etag.feature +0 -86
  213. package/features/identity.bans.feature +3 -3
  214. package/features/identity.basic.feature +9 -9
  215. package/features/identity.federation.feature +11 -11
  216. package/features/identity.tokens.custom.feature +5 -5
  217. package/features/identity.tokens.feature +2 -2
  218. package/features/interruptions.feature +1 -0
  219. package/features/introspection.map.feature +4 -4
  220. package/features/io.throttle.feature +1 -0
  221. package/features/map.feature +2 -2
  222. package/features/octets.cloudinary.feature +1 -1
  223. package/features/octets.download.feature +1 -0
  224. package/features/require.feature +1 -2
  225. package/features/steps/Captures.ts +1 -1
  226. package/features/steps/Cloudinary.ts +1 -2
  227. package/features/steps/Common.ts +4 -5
  228. package/features/steps/Components.ts +17 -12
  229. package/features/steps/Database.ts +42 -23
  230. package/features/steps/Gateway.ts +55 -72
  231. package/features/steps/HTTP.ts +12 -15
  232. package/features/steps/IDP.ts +118 -94
  233. package/features/steps/Identity.ts +3 -3
  234. package/features/steps/OTP.ts +3 -3
  235. package/features/steps/Parameters.ts +20 -10
  236. package/features/steps/Probe.ts +9 -7
  237. package/features/steps/Realtime.ts +40 -22
  238. package/features/steps/Workspace.ts +10 -7
  239. package/features/steps/components/audit/operations/record.js +1 -1
  240. package/features/steps/components/echo/operations/affect.js +1 -1
  241. package/features/steps/components/echo/operations/compute.js +1 -1
  242. package/features/steps/components/echo/operations/echo.js +1 -1
  243. package/features/steps/components/echo/operations/error.js +1 -1
  244. package/features/steps/components/echo/operations/identity.js +1 -1
  245. package/features/steps/components/echo/operations/parameters.js +1 -1
  246. package/features/steps/components/echo/operations/ping.js +1 -1
  247. package/features/steps/components/echo/operations/unwrap.js +1 -1
  248. package/features/steps/components/greeter/operations/greet.js +1 -1
  249. package/features/steps/components/notify/operations/send.js +1 -1
  250. package/features/steps/components/octets.tester/operations/authority.js +1 -1
  251. package/features/steps/components/octets.tester/operations/bar.js +1 -1
  252. package/features/steps/components/octets.tester/operations/baz.js +1 -1
  253. package/features/steps/components/octets.tester/operations/concat.js +1 -1
  254. package/features/steps/components/octets.tester/operations/echo.js +1 -1
  255. package/features/steps/components/octets.tester/operations/err.js +1 -1
  256. package/features/steps/components/octets.tester/operations/foo.js +1 -1
  257. package/features/steps/components/octets.tester/operations/id.js +1 -1
  258. package/features/steps/components/octets.tester/operations/identity.js +1 -1
  259. package/features/steps/components/octets.tester/operations/redirect.js +6 -4
  260. package/features/steps/components/octets.tester/operations/yex.js +1 -1
  261. package/features/steps/components/octets.tester/operations/yield.js +1 -1
  262. package/features/steps/components/orders/manifest.toa.yaml +10 -12
  263. package/features/steps/components/orders/operations/create.js +4 -2
  264. package/features/steps/components/pots/manifest.toa.yaml +15 -20
  265. package/features/steps/components/pots/migrations/0002-indexes.yaml +4 -0
  266. package/features/steps/components/pricing/operations/quote.js +1 -1
  267. package/features/steps/components/sequences/manifest.toa.yaml +0 -1
  268. package/features/steps/components/sequences/operations/numbers.js +1 -1
  269. package/features/steps/components/sequences/operations/tokens.js +3 -3
  270. package/features/steps/components/users/manifest.toa.yaml +3 -5
  271. package/features/steps/components/users/operations/create.js +1 -1
  272. package/features/steps/components/users.properties/manifest.toa.yaml +5 -6
  273. package/features/steps/map.ts +2 -2
  274. package/features/timestamps.feature +1 -1
  275. package/package.json +7 -7
  276. package/readme.md +11 -11
  277. package/schemas/annotation.cos.yaml +1 -3
  278. package/schemas/method.cos.yaml +2 -0
  279. package/source/Branch.test.ts +2 -2
  280. package/source/Branch.ts +3 -5
  281. package/source/Composition.ts +5 -5
  282. package/source/Directive.test.ts +38 -20
  283. package/source/Directive.ts +61 -47
  284. package/source/Endpoint.test.ts +1 -1
  285. package/source/Endpoint.ts +27 -92
  286. package/source/Factory.ts +26 -12
  287. package/source/Gateway.ts +87 -76
  288. package/source/HTTP/Context.ts +23 -30
  289. package/source/HTTP/Probe.ts +7 -9
  290. package/source/HTTP/Server.ts +88 -69
  291. package/source/HTTP/Timing.ts +6 -21
  292. package/source/HTTP/address.test.ts +8 -2
  293. package/source/HTTP/address.ts +2 -3
  294. package/source/HTTP/exceptions.ts +20 -18
  295. package/source/HTTP/formats/form.ts +1 -1
  296. package/source/HTTP/formats/json.ts +2 -2
  297. package/source/HTTP/formats/msgpack.ts +3 -4
  298. package/source/HTTP/formats/text.ts +2 -2
  299. package/source/HTTP/formats/yaml.test.ts +4 -1
  300. package/source/HTTP/formats/yaml.ts +14 -11
  301. package/source/HTTP/messages.test.ts +38 -28
  302. package/source/HTTP/messages.ts +44 -98
  303. package/source/Interception.ts +3 -4
  304. package/source/Introspection.ts +26 -14
  305. package/source/MCP/Server.ts +114 -54
  306. package/source/MCP/discover.ts +6 -7
  307. package/source/MCP/errors.ts +7 -8
  308. package/source/MCP/schema.test.ts +9 -3
  309. package/source/MCP/schema.ts +12 -16
  310. package/source/MCP/tools.ts +33 -28
  311. package/source/Mapping.ts +25 -27
  312. package/source/Query.ts +58 -44
  313. package/source/RPC/Context.ts +8 -11
  314. package/source/RPC/Dispatcher.ts +46 -26
  315. package/source/RPC/errors.test.ts +41 -16
  316. package/source/RPC/errors.ts +9 -10
  317. package/source/RPC/names.test.ts +35 -16
  318. package/source/RPC/names.ts +22 -29
  319. package/source/RTD/Directives.ts +21 -10
  320. package/source/RTD/Endpoint.ts +4 -1
  321. package/source/RTD/Method.ts +8 -6
  322. package/source/RTD/Node.ts +32 -34
  323. package/source/RTD/Route.ts +18 -21
  324. package/source/RTD/Tree.ts +18 -18
  325. package/source/RTD/factory.ts +13 -16
  326. package/source/RTD/segment.ts +12 -10
  327. package/source/RTD/syntax/parse.test.ts +12 -6
  328. package/source/RTD/syntax/parse.ts +30 -26
  329. package/source/RTD/syntax/types.ts +17 -1
  330. package/source/RTD/walk.test.ts +59 -22
  331. package/source/Remotes.test.ts +25 -4
  332. package/source/Remotes.ts +9 -4
  333. package/source/Tenant.ts +12 -12
  334. package/source/deployment.ts +20 -20
  335. package/source/directives/auth/Anonymous.test.ts +8 -2
  336. package/source/directives/auth/Anonymous.ts +5 -8
  337. package/source/directives/auth/Anyone.ts +3 -3
  338. package/source/directives/auth/Assert.ts +10 -10
  339. package/source/directives/auth/Authorization.ts +83 -69
  340. package/source/directives/auth/Delegate.test.ts +2 -2
  341. package/source/directives/auth/Delegate.ts +8 -10
  342. package/source/directives/auth/Echo.ts +5 -8
  343. package/source/directives/auth/Federation.ts +30 -21
  344. package/source/directives/auth/Id.ts +7 -4
  345. package/source/directives/auth/Incept.ts +32 -26
  346. package/source/directives/auth/Input.ts +36 -20
  347. package/source/directives/auth/Role.test.ts +49 -23
  348. package/source/directives/auth/Role.ts +29 -22
  349. package/source/directives/auth/Rule.ts +13 -8
  350. package/source/directives/auth/Scheme.ts +7 -7
  351. package/source/directives/auth/create.ts +1 -1
  352. package/source/directives/auth/schemes.ts +1 -1
  353. package/source/directives/auth/split.ts +2 -3
  354. package/source/directives/auth/types.ts +5 -2
  355. package/source/directives/cache/Cache.ts +44 -9
  356. package/source/directives/cache/Control.ts +25 -26
  357. package/source/directives/cache/Exact.ts +1 -1
  358. package/source/directives/cache/etag.ts +38 -0
  359. package/source/directives/cors/CORS.ts +9 -7
  360. package/source/directives/dev/Development.ts +3 -4
  361. package/source/directives/dev/Faulty.ts +11 -6
  362. package/source/directives/dev/Sleep.ts +5 -7
  363. package/source/directives/dev/Stub.ts +2 -2
  364. package/source/directives/dev/Throw.ts +2 -2
  365. package/source/directives/flow/Compose.ts +26 -20
  366. package/source/directives/flow/Fetch.ts +15 -15
  367. package/source/directives/flow/Flow.ts +9 -8
  368. package/source/directives/index.ts +11 -2
  369. package/source/directives/io/IO.ts +29 -20
  370. package/source/directives/io/Input.ts +9 -12
  371. package/source/directives/io/Output.ts +20 -23
  372. package/source/directives/io/Status.test.ts +12 -8
  373. package/source/directives/io/Status.ts +9 -8
  374. package/source/directives/io/Throttle.ts +6 -7
  375. package/source/directives/io/lib/throttle/Configuration.test.ts +32 -23
  376. package/source/directives/io/lib/throttle/Configuration.ts +14 -9
  377. package/source/directives/io/lib/throttle/Keys.ts +15 -10
  378. package/source/directives/io/lib/throttle/Quotas.test.ts +33 -17
  379. package/source/directives/io/lib/throttle/Quotas.ts +20 -26
  380. package/source/directives/io/lib/throttle/Sync.test.ts +14 -10
  381. package/source/directives/io/lib/throttle/Sync.ts +9 -12
  382. package/source/directives/io/lib/throttle/Warning.ts +3 -4
  383. package/source/directives/io/lib/throttle/components/IP.ts +4 -5
  384. package/source/directives/io/lib/throttle/components/Identity.ts +1 -1
  385. package/source/directives/io/lib/throttle/components/Path.ts +1 -1
  386. package/source/directives/io/lib/throttle/components/Route.ts +2 -2
  387. package/source/directives/io/lib/throttle/components/Segment.ts +2 -2
  388. package/source/directives/io/lib/throttle/conditions/Status.ts +2 -2
  389. package/source/directives/io/schemas.test.ts +12 -6
  390. package/source/directives/map/Authority.ts +2 -2
  391. package/source/directives/map/Buffer.ts +2 -2
  392. package/source/directives/map/Claims.ts +25 -20
  393. package/source/directives/map/Headers.ts +17 -13
  394. package/source/directives/map/Language.ts +8 -5
  395. package/source/directives/map/Languages.ts +9 -3
  396. package/source/directives/map/Map.ts +25 -12
  397. package/source/directives/map/Mapping.ts +9 -6
  398. package/source/directives/map/Properties.ts +1 -1
  399. package/source/directives/map/Segments.ts +22 -15
  400. package/source/directives/mcp/MCP.ts +9 -7
  401. package/source/directives/mcp/Tool.test.ts +21 -9
  402. package/source/directives/mcp/Tool.ts +23 -11
  403. package/source/directives/oauth/Discovery.ts +7 -11
  404. package/source/directives/oauth/documents.ts +11 -14
  405. package/source/directives/octets/Context.ts +6 -3
  406. package/source/directives/octets/Delete.ts +33 -25
  407. package/source/directives/octets/Directive.ts +5 -1
  408. package/source/directives/octets/Get.ts +13 -21
  409. package/source/directives/octets/Octets.ts +20 -15
  410. package/source/directives/octets/Put.ts +62 -27
  411. package/source/directives/octets/Workflow.ts +18 -12
  412. package/source/directives/octets/bytes.ts +1 -1
  413. package/source/directives/octets/schemas.test.ts +8 -14
  414. package/source/directives/octets/workflows/Execution.ts +19 -21
  415. package/source/directives/octets/workflows/Workflow.ts +10 -7
  416. package/source/directives/require/Headers.ts +3 -4
  417. package/source/directives/require/Require.ts +3 -4
  418. package/source/exceptions.ts +19 -12
  419. package/source/index.ts +1 -1
  420. package/source/manifest.test.ts +4 -1
  421. package/source/manifest.ts +19 -13
  422. package/source/octets.d.ts +1 -1
  423. package/source/root.ts +3 -2
  424. package/source/schemas.test.ts +17 -3
  425. package/transpiled/Branch.js.map +1 -1
  426. package/transpiled/Composition.js.map +1 -1
  427. package/transpiled/Directive.js +6 -2
  428. package/transpiled/Directive.js.map +1 -1
  429. package/transpiled/Endpoint.d.ts +0 -2
  430. package/transpiled/Endpoint.js +11 -52
  431. package/transpiled/Endpoint.js.map +1 -1
  432. package/transpiled/Factory.d.ts +2 -1
  433. package/transpiled/Factory.js +1 -0
  434. package/transpiled/Factory.js.map +1 -1
  435. package/transpiled/Gateway.d.ts +2 -1
  436. package/transpiled/Gateway.js +24 -15
  437. package/transpiled/Gateway.js.map +1 -1
  438. package/transpiled/HTTP/Context.d.ts +0 -3
  439. package/transpiled/HTTP/Context.js +7 -9
  440. package/transpiled/HTTP/Context.js.map +1 -1
  441. package/transpiled/HTTP/Probe.js.map +1 -1
  442. package/transpiled/HTTP/Server.js +19 -4
  443. package/transpiled/HTTP/Server.js.map +1 -1
  444. package/transpiled/HTTP/Timing.d.ts +1 -2
  445. package/transpiled/HTTP/Timing.js +2 -10
  446. package/transpiled/HTTP/Timing.js.map +1 -1
  447. package/transpiled/HTTP/address.js.map +1 -1
  448. package/transpiled/HTTP/exceptions.js.map +1 -1
  449. package/transpiled/HTTP/formats/form.js.map +1 -1
  450. package/transpiled/HTTP/formats/json.js.map +1 -1
  451. package/transpiled/HTTP/formats/msgpack.js.map +1 -1
  452. package/transpiled/HTTP/formats/text.js.map +1 -1
  453. package/transpiled/HTTP/formats/yaml.js +4 -1
  454. package/transpiled/HTTP/formats/yaml.js.map +1 -1
  455. package/transpiled/HTTP/messages.d.ts +3 -2
  456. package/transpiled/HTTP/messages.js +1 -43
  457. package/transpiled/HTTP/messages.js.map +1 -1
  458. package/transpiled/Interception.js.map +1 -1
  459. package/transpiled/Introspection.js +13 -2
  460. package/transpiled/Introspection.js.map +1 -1
  461. package/transpiled/MCP/Server.js +15 -4
  462. package/transpiled/MCP/Server.js.map +1 -1
  463. package/transpiled/MCP/discover.js.map +1 -1
  464. package/transpiled/MCP/errors.js.map +1 -1
  465. package/transpiled/MCP/schema.js +1 -1
  466. package/transpiled/MCP/schema.js.map +1 -1
  467. package/transpiled/MCP/tools.js +10 -7
  468. package/transpiled/MCP/tools.js.map +1 -1
  469. package/transpiled/Mapping.d.ts +2 -2
  470. package/transpiled/Mapping.js +3 -5
  471. package/transpiled/Mapping.js.map +1 -1
  472. package/transpiled/Query.d.ts +6 -2
  473. package/transpiled/Query.js +23 -8
  474. package/transpiled/Query.js.map +1 -1
  475. package/transpiled/RPC/Context.js +0 -7
  476. package/transpiled/RPC/Context.js.map +1 -1
  477. package/transpiled/RPC/Dispatcher.js +4 -1
  478. package/transpiled/RPC/Dispatcher.js.map +1 -1
  479. package/transpiled/RPC/errors.js.map +1 -1
  480. package/transpiled/RPC/names.js.map +1 -1
  481. package/transpiled/RTD/Directives.d.ts +1 -1
  482. package/transpiled/RTD/Method.js +1 -3
  483. package/transpiled/RTD/Method.js.map +1 -1
  484. package/transpiled/RTD/Node.js +5 -4
  485. package/transpiled/RTD/Node.js.map +1 -1
  486. package/transpiled/RTD/Route.js +4 -1
  487. package/transpiled/RTD/Route.js.map +1 -1
  488. package/transpiled/RTD/Tree.js +1 -1
  489. package/transpiled/RTD/Tree.js.map +1 -1
  490. package/transpiled/RTD/factory.js.map +1 -1
  491. package/transpiled/RTD/segment.js.map +1 -1
  492. package/transpiled/RTD/syntax/parse.js.map +1 -1
  493. package/transpiled/RTD/syntax/types.d.ts +6 -0
  494. package/transpiled/RTD/syntax/types.js +10 -1
  495. package/transpiled/RTD/syntax/types.js.map +1 -1
  496. package/transpiled/Remotes.js.map +1 -1
  497. package/transpiled/Tenant.d.ts +1 -1
  498. package/transpiled/Tenant.js.map +1 -1
  499. package/transpiled/deployment.d.ts +3 -0
  500. package/transpiled/deployment.js +6 -1
  501. package/transpiled/deployment.js.map +1 -1
  502. package/transpiled/directives/auth/Anonymous.js +1 -3
  503. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  504. package/transpiled/directives/auth/Anyone.js.map +1 -1
  505. package/transpiled/directives/auth/Assert.js.map +1 -1
  506. package/transpiled/directives/auth/Authorization.js +7 -3
  507. package/transpiled/directives/auth/Authorization.js.map +1 -1
  508. package/transpiled/directives/auth/Delegate.js.map +1 -1
  509. package/transpiled/directives/auth/Echo.js +1 -3
  510. package/transpiled/directives/auth/Echo.js.map +1 -1
  511. package/transpiled/directives/auth/Federation.js +3 -7
  512. package/transpiled/directives/auth/Federation.js.map +1 -1
  513. package/transpiled/directives/auth/Id.js.map +1 -1
  514. package/transpiled/directives/auth/Incept.js +1 -1
  515. package/transpiled/directives/auth/Incept.js.map +1 -1
  516. package/transpiled/directives/auth/Input.js.map +1 -1
  517. package/transpiled/directives/auth/Role.js.map +1 -1
  518. package/transpiled/directives/auth/Rule.js.map +1 -1
  519. package/transpiled/directives/auth/Scheme.js +1 -2
  520. package/transpiled/directives/auth/Scheme.js.map +1 -1
  521. package/transpiled/directives/auth/create.js.map +1 -1
  522. package/transpiled/directives/auth/schemes.js.map +1 -1
  523. package/transpiled/directives/auth/split.js.map +1 -1
  524. package/transpiled/directives/auth/types.d.ts +3 -1
  525. package/transpiled/directives/cache/Cache.js +28 -2
  526. package/transpiled/directives/cache/Cache.js.map +1 -1
  527. package/transpiled/directives/cache/Control.js +1 -1
  528. package/transpiled/directives/cache/Control.js.map +1 -1
  529. package/transpiled/directives/cache/etag.d.ts +10 -0
  530. package/transpiled/directives/cache/etag.js +30 -0
  531. package/transpiled/directives/cache/etag.js.map +1 -0
  532. package/transpiled/directives/cors/CORS.js.map +1 -1
  533. package/transpiled/directives/dev/Development.js.map +1 -1
  534. package/transpiled/directives/dev/Faulty.js.map +1 -1
  535. package/transpiled/directives/dev/Sleep.js.map +1 -1
  536. package/transpiled/directives/dev/Stub.js.map +1 -1
  537. package/transpiled/directives/dev/Throw.js.map +1 -1
  538. package/transpiled/directives/flow/Compose.js +7 -3
  539. package/transpiled/directives/flow/Compose.js.map +1 -1
  540. package/transpiled/directives/flow/Fetch.js.map +1 -1
  541. package/transpiled/directives/flow/Flow.js.map +1 -1
  542. package/transpiled/directives/index.js +11 -1
  543. package/transpiled/directives/index.js.map +1 -1
  544. package/transpiled/directives/io/IO.d.ts +1 -1
  545. package/transpiled/directives/io/IO.js.map +1 -1
  546. package/transpiled/directives/io/Input.js +1 -1
  547. package/transpiled/directives/io/Input.js.map +1 -1
  548. package/transpiled/directives/io/Output.js +3 -3
  549. package/transpiled/directives/io/Output.js.map +1 -1
  550. package/transpiled/directives/io/Status.js.map +1 -1
  551. package/transpiled/directives/io/Throttle.js +1 -1
  552. package/transpiled/directives/io/Throttle.js.map +1 -1
  553. package/transpiled/directives/io/lib/throttle/Configuration.js +8 -2
  554. package/transpiled/directives/io/lib/throttle/Configuration.js.map +1 -1
  555. package/transpiled/directives/io/lib/throttle/Keys.js.map +1 -1
  556. package/transpiled/directives/io/lib/throttle/Quotas.js +4 -3
  557. package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
  558. package/transpiled/directives/io/lib/throttle/Sync.d.ts +1 -1
  559. package/transpiled/directives/io/lib/throttle/Sync.js.map +1 -1
  560. package/transpiled/directives/io/lib/throttle/Warning.js.map +1 -1
  561. package/transpiled/directives/io/lib/throttle/components/IP.js.map +1 -1
  562. package/transpiled/directives/io/lib/throttle/components/Identity.js.map +1 -1
  563. package/transpiled/directives/io/lib/throttle/components/Path.js.map +1 -1
  564. package/transpiled/directives/io/lib/throttle/components/Route.js.map +1 -1
  565. package/transpiled/directives/io/lib/throttle/components/Segment.js.map +1 -1
  566. package/transpiled/directives/io/lib/throttle/conditions/Status.js.map +1 -1
  567. package/transpiled/directives/map/Authority.js.map +1 -1
  568. package/transpiled/directives/map/Buffer.js.map +1 -1
  569. package/transpiled/directives/map/Claims.js.map +1 -1
  570. package/transpiled/directives/map/Headers.js.map +1 -1
  571. package/transpiled/directives/map/Language.js.map +1 -1
  572. package/transpiled/directives/map/Languages.js.map +1 -1
  573. package/transpiled/directives/map/Map.js.map +1 -1
  574. package/transpiled/directives/map/Mapping.js.map +1 -1
  575. package/transpiled/directives/map/Properties.js.map +1 -1
  576. package/transpiled/directives/map/Segments.js.map +1 -1
  577. package/transpiled/directives/mcp/MCP.js +1 -1
  578. package/transpiled/directives/mcp/MCP.js.map +1 -1
  579. package/transpiled/directives/mcp/Tool.js +3 -1
  580. package/transpiled/directives/mcp/Tool.js.map +1 -1
  581. package/transpiled/directives/oauth/Discovery.js.map +1 -1
  582. package/transpiled/directives/oauth/documents.js.map +1 -1
  583. package/transpiled/directives/octets/Context.js +1 -1
  584. package/transpiled/directives/octets/Context.js.map +1 -1
  585. package/transpiled/directives/octets/Delete.js.map +1 -1
  586. package/transpiled/directives/octets/Directive.js.map +1 -1
  587. package/transpiled/directives/octets/Get.js.map +1 -1
  588. package/transpiled/directives/octets/Octets.js +1 -1
  589. package/transpiled/directives/octets/Octets.js.map +1 -1
  590. package/transpiled/directives/octets/Put.js.map +1 -1
  591. package/transpiled/directives/octets/Workflow.js.map +1 -1
  592. package/transpiled/directives/octets/bytes.js.map +1 -1
  593. package/transpiled/directives/octets/workflows/Execution.js +1 -2
  594. package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
  595. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
  596. package/transpiled/directives/require/Headers.js.map +1 -1
  597. package/transpiled/directives/require/Require.js.map +1 -1
  598. package/transpiled/exceptions.js.map +1 -1
  599. package/transpiled/index.d.ts +1 -1
  600. package/transpiled/index.js +1 -1
  601. package/transpiled/index.js.map +1 -1
  602. package/transpiled/manifest.js +5 -1
  603. package/transpiled/manifest.js.map +1 -1
  604. package/transpiled/root.js.map +1 -1
  605. package/tsconfig.tsbuildinfo +1 -1
  606. package/CHANGELOG.md +0 -552
  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
@@ -1,8 +1,7 @@
1
1
  import { Readable } from 'node:stream'
2
- import { console } from 'openspan'
3
2
  import { Mapping } from './Mapping.js'
4
3
  import { take } from './Introspection.js'
5
- import { redact } from './redact.js'
4
+ import { parse } from './directives/cache/etag.js'
6
5
  import * as http from './HTTP/index.js'
7
6
  import type { Introspection, Schema } from './Introspection.js'
8
7
  import type { Remote } from '@toa.io/core'
@@ -19,56 +18,41 @@ export class Endpoint implements RTD.Endpoint {
19
18
  /** What the operation says, with what the route takes already split out of it. */
20
19
  private introspection: Introspection | null = null
21
20
 
22
- public constructor (endpoint: string, mapping: Mapping, discovery: Promise<Remote>) {
21
+ public constructor(endpoint: string, mapping: Mapping, discovery: Promise<Remote>) {
23
22
  this.endpoint = endpoint
24
23
  this.mapping = mapping
25
24
  this.discovery = discovery
26
25
  }
27
26
 
28
- public async call (context: http.Context, parameters: RTD.Parameter[]): Promise<http.OutgoingMessage> {
27
+ public async call(
28
+ context: http.Context,
29
+ parameters: RTD.Parameter[]
30
+ ): Promise<http.OutgoingMessage> {
29
31
  const body = await context.body()
30
32
  const query = this.query(context)
31
33
  const request = this.mapping.fit(body, query, parameters)
32
34
 
33
35
  this.remote ??= await this.discovery
34
36
 
35
- const endpoint = this.remote.locator.id + '.' + this.endpoint
36
-
37
- console.debug('Calling operation', { endpoint, request: redact(request) })
38
-
39
37
  const reply = await this.remote.invoke(this.endpoint, request)
40
38
 
41
- console.debug('Received reply',
42
- { endpoint, reply: reply instanceof Readable ? '[Readable stream]' : redact(reply) })
43
-
44
- if (reply instanceof Error)
45
- throw new http.UnprocessableEntity(reply)
39
+ if (reply instanceof Error) throw new http.UnprocessableEntity(reply)
46
40
 
47
- const message: http.OutgoingMessage = {}
41
+ const message: http.OutgoingMessage = { body: reply }
48
42
 
49
- // etag
50
- if (reply !== null && reply !== undefined) {
51
- const etag = context.request.headers['if-none-match']
43
+ // what the reply carries for a cache to validate by; the `cache` family sets the headers
44
+ if (typeof reply === 'object' && reply !== null && !(reply instanceof Readable)) {
45
+ if ('VERSION' in reply) message.version = reply.VERSION
52
46
 
53
- if (this.conditionalGet(reply, etag, message))
54
- return message
55
- }
56
-
57
- // last-modified
58
- if (typeof reply === 'object' && reply !== null && ('_updated' in reply || '_created' in reply)) {
59
- const timestamp: string = reply._updated ?? reply._created
60
- const date = new Date(timestamp)
47
+ const modified = reply.UPDATED ?? reply.CREATED
61
48
 
62
- message.headers ??= new Headers()
63
- message.headers.set('last-modified', date.toUTCString())
49
+ if (modified !== undefined) message.modified = modified
64
50
  }
65
51
 
66
- message.body = reply
67
-
68
52
  return message
69
53
  }
70
54
 
71
- public async explain (parameters: RTD.Parameter[]): Promise<Introspection> {
55
+ public async explain(parameters: RTD.Parameter[]): Promise<Introspection> {
72
56
  this.introspection ??= await this.introspect(parameters)
73
57
 
74
58
  // what a directive narrows is this caller's answer, not the next caller's
@@ -81,7 +65,7 @@ export class Endpoint implements RTD.Endpoint {
81
65
  * share one remote — so the copy is what keeps the second from describing what the first
82
66
  * took away.
83
67
  */
84
- private async introspect (parameters: RTD.Parameter[]): Promise<Introspection> {
68
+ private async introspect(parameters: RTD.Parameter[]): Promise<Introspection> {
85
69
  this.remote ??= await this.discovery
86
70
 
87
71
  const operation = structuredClone(await this.remote.explain(this.endpoint))
@@ -97,8 +81,7 @@ export class Endpoint implements RTD.Endpoint {
97
81
  for (const parameter of parameters) {
98
82
  const schema = take(operation, parameter.name)
99
83
 
100
- if (schema === undefined)
101
- continue
84
+ if (schema === undefined) continue
102
85
 
103
86
  route ??= {}
104
87
  route[parameter.name] = schema
@@ -107,80 +90,34 @@ export class Endpoint implements RTD.Endpoint {
107
90
  const query = this.mapping.explain(operation)
108
91
  const introspection: Introspection = {}
109
92
 
110
- if (route !== null)
111
- introspection.route = route
93
+ if (route !== null) introspection.route = route
112
94
 
113
- if (query !== null)
114
- introspection.query = query
95
+ if (query !== null) introspection.query = query
115
96
 
116
97
  Object.assign(introspection, operation)
117
98
 
118
99
  return introspection
119
100
  }
120
101
 
121
- public async close (): Promise<void> {
102
+ public async close(): Promise<void> {
122
103
  this.remote ??= await this.discovery
123
104
 
124
105
  await this.remote.disconnect(INTERRUPT)
125
106
  }
126
107
 
127
- private conditionalGet (reply: unknown, etag: string | undefined, message: http.OutgoingMessage): boolean {
128
- message.headers ??= new Headers()
129
-
130
- if (typeof reply === 'object' && reply !== null && '_version' in reply) {
131
- const version = reply._version as number
132
- const matched = etag === undefined ? null : this.matchVersion(etag)
133
-
134
- if (etag !== undefined && matched !== null && version === matched) {
135
- message.status = 304
136
- message.headers.set('etag', etag)
137
-
138
- return true
139
- }
140
-
141
- message.headers.set('etag', `"${version.toString()}"`)
142
-
143
- return false
144
- }
145
-
146
- if (reply instanceof Readable)
147
- return false
148
-
149
- /*
150
- * A reply that carries no version is tagged with a hash of its body. The body is
151
- * serialized anyway when the response is written, so the tag is computed from what
152
- * is actually sent rather than from a second serialization of the reply — which
153
- * makes it specific to the negotiated representation, hence `vary: accept`.
154
- */
155
- message.etag = true
156
-
157
- return false
158
- }
159
-
160
- private query (context: http.Context): http.Query {
108
+ private query(context: http.Context): http.Query {
161
109
  const query: http.Query = Object.fromEntries(context.url.searchParams)
162
110
  const etag = context.request.headers['if-match']
163
111
 
164
- if (etag !== undefined && this.mapping.queryable)
165
- query.version = this.version(etag)
112
+ if (etag !== undefined && this.mapping.queryable) query.version = this.version(etag)
166
113
 
167
114
  return query
168
115
  }
169
116
 
170
- private matchVersion (etag: string): number | null {
171
- const match = etag.match(ETAG)
117
+ private version(etag: string): number {
118
+ const version = parse(etag)
172
119
 
173
- if (match === null)
174
- return null
175
-
176
- return Number.parseInt(match.groups!.version)
177
- }
178
-
179
- private version (etag: string): number {
180
- const version = this.matchVersion(etag)
181
-
182
- if (version === null)
183
- throw new http.BadRequest('Invalid ETag')
120
+ if (version === null) throw new http.BadRequest('Invalid ETag')
184
121
 
185
122
  return version
186
123
  }
@@ -189,15 +126,15 @@ export class Endpoint implements RTD.Endpoint {
189
126
  export class EndpointsFactory implements RTD.EndpointsFactory {
190
127
  private readonly remotes: Remotes
191
128
 
192
- public constructor (remotes: Remotes) {
129
+ public constructor(remotes: Remotes) {
193
130
  this.remotes = remotes
194
131
  }
195
132
 
196
- public create (method: RTD.syntax.Method, context: Context): Endpoint {
133
+ public create(method: RTD.syntax.Method, context: Context): Endpoint {
197
134
  if (method.mapping === undefined)
198
135
  throw new Error('Cannot create Endpoint without mapping')
199
136
 
200
- const mapping = Mapping.create(method.mapping.query)
137
+ const mapping = Mapping.create(method.mapping.query, method.mapping.paged)
201
138
 
202
139
  const branch = context.extension
203
140
 
@@ -213,6 +150,4 @@ export class EndpointsFactory implements RTD.EndpointsFactory {
213
150
  }
214
151
  }
215
152
 
216
- const ETAG = /^(W\/)?"(?<version>\d{1,32})"$/
217
-
218
153
  const INTERRUPT = true
package/source/Factory.ts CHANGED
@@ -18,22 +18,24 @@ import * as http from './HTTP/index.js'
18
18
  import type { Branch } from './Branch.js'
19
19
  import type { syntax } from './RTD/index.js'
20
20
  import type { Broadcast } from './Gateway.js'
21
- import type { Connector, Locator, extensions } from '@toa.io/core'
21
+ import type { Connector, Locator } from '@toa.io/core'
22
+ import type { extensions } from '@toa.io/core/types'
22
23
 
23
24
  export class Factory implements extensions.Factory {
24
25
  private readonly host: Host
25
26
 
26
- public constructor (host: Host) {
27
+ public constructor(host: Host) {
27
28
  this.host = host
28
29
  }
29
30
 
30
- public async tenant (locator: Locator, node: syntax.Node): Promise<Connector> {
31
+ public async tenant(locator: Locator, node: syntax.Node): Promise<Connector> {
31
32
  const broadcast: Broadcast = await this.host.broadcast(CHANNEL, locator.id)
32
33
  const hash = createHash('sha256').update(JSON.stringify(node)).digest('hex')
33
34
 
34
35
  // no timestamp: the tenant stamps each announcement with its own start time
35
36
  const branch: Omit<Branch, 'timestamp'> = {
36
- namespace: locator.namespace,
37
+ // boot only ever hands a tenant a component's locator, which always has a namespace
38
+ namespace: locator.namespace!,
37
39
  component: locator.name,
38
40
  isolated: locator.namespace === 'identity',
39
41
  node,
@@ -43,9 +45,11 @@ export class Factory implements extensions.Factory {
43
45
  return new Tenant(broadcast, branch)
44
46
  }
45
47
 
46
- public async service (): Promise<Connector | null> {
47
- assert.ok(process.env.TOA_EXPOSITION_PROPERTIES,
48
- 'TOA_EXPOSITION_PROPERTIES is undefined')
48
+ public async service(): Promise<Connector | null> {
49
+ assert.ok(
50
+ process.env.TOA_EXPOSITION_PROPERTIES,
51
+ 'TOA_EXPOSITION_PROPERTIES is undefined'
52
+ )
49
53
 
50
54
  configureLogs()
51
55
 
@@ -62,7 +66,14 @@ export class Factory implements extensions.Factory {
62
66
  const composition = new Composition(this.host)
63
67
  const dispatcher = options.rpc === undefined ? null : new Dispatcher(options.rpc)
64
68
  const mcp = options.mcp === undefined ? null : new Model(options.mcp, tree)
65
- const gateway = new Gateway(broadcast, tree, interception, directives, dispatcher, mcp)
69
+ const gateway = new Gateway(
70
+ broadcast,
71
+ tree,
72
+ interception,
73
+ directives,
74
+ dispatcher,
75
+ mcp
76
+ )
66
77
 
67
78
  gateway.depends(remotes)
68
79
  gateway.depends(composition)
@@ -80,16 +91,19 @@ const CHANNEL = 'exposition'
80
91
  const LOGS_PREFIX = 'TOA_TELEMETRY_LOGS'
81
92
  const TRACES_ENV = 'TOA_TELEMETRY_TRACES'
82
93
 
83
- function configureLogs (): void {
94
+ function configureLogs(): void {
84
95
  const globEnv = process.env[LOGS_PREFIX]
85
96
  const level: LevelName = process.env.TOA_DEV === '1' ? 'trace' : 'info'
86
- const options = globEnv === undefined ? { level } : JSON.parse(globEnv) as { level?: LevelName }
97
+ const options =
98
+ globEnv === undefined ? { level } : (JSON.parse(globEnv) as { level?: LevelName })
87
99
 
88
100
  console.configure({ level: options.level ?? level })
89
101
 
90
102
  const tracesEnv = process.env[TRACES_ENV]
91
103
 
92
- traces(tracesEnv === undefined ? development() : JSON.parse(tracesEnv) as TracesOptions)
104
+ traces(
105
+ tracesEnv === undefined ? development() : (JSON.parse(tracesEnv) as TracesOptions)
106
+ )
93
107
  }
94
108
 
95
109
  /**
@@ -101,7 +115,7 @@ function configureLogs (): void {
101
115
  * The gateway boots without the telemetry extension, hence the copy of
102
116
  * `extensions/telemetry/source/extension.ts`.
103
117
  */
104
- function development (): TracesOptions {
118
+ function development(): TracesOptions {
105
119
  const local = process.env.TOA_DEV === '1' || process.env.TOA_BOOT_TRACE === '1'
106
120
 
107
121
  return local ? { exporters: { console: {} } } : {}
package/source/Gateway.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import assert from 'node:assert'
2
2
  import { setTimeout } from 'node:timers/promises'
3
3
  import { console } from 'openspan'
4
- import { type bindings, Connector } from '@toa.io/core'
4
+ import { Connector } from '@toa.io/core'
5
+ import type { bindings } from '@toa.io/core/types'
5
6
  import * as http from './HTTP/index.js'
6
7
  import { MCP, RPC } from './const.js'
7
8
  import { rethrow } from './exceptions.js'
@@ -9,7 +10,14 @@ import { decide } from './Branch.js'
9
10
  import type { Interception } from './Interception.js'
10
11
  import type { Dispatcher } from './RPC/index.js'
11
12
  import type { Server } from './MCP/index.js'
12
- import type { DirectiveFactory, Method, Node, Parameter, Tree, Match } from './RTD/index.js'
13
+ import type {
14
+ DirectiveFactory,
15
+ Method,
16
+ Node,
17
+ Parameter,
18
+ Tree,
19
+ Match
20
+ } from './RTD/index.js'
13
21
  import type { Label } from './discovery.js'
14
22
  import type { Branch, Exposed } from './Branch.js'
15
23
 
@@ -32,8 +40,14 @@ export class Gateway extends Connector {
32
40
  private resolveFirstMerge: (() => void) | null = null
33
41
 
34
42
  // eslint-disable-next-line max-params
35
- public constructor (broadcast: Broadcast, tree: Tree, interception: Interception,
36
- directives: DirectiveFactory, dispatcher: Dispatcher | null, mcp: Server | null) {
43
+ public constructor(
44
+ broadcast: Broadcast,
45
+ tree: Tree,
46
+ interception: Interception,
47
+ directives: DirectiveFactory,
48
+ dispatcher: Dispatcher | null,
49
+ mcp: Server | null
50
+ ) {
37
51
  super()
38
52
 
39
53
  this.broadcast = broadcast
@@ -46,22 +60,18 @@ export class Gateway extends Connector {
46
60
  this.depends(broadcast)
47
61
  }
48
62
 
49
- public async process (context: http.Context): Promise<http.OutgoingMessage> {
50
- const interception = await context.timing.capture('intercept',
51
- this.interceptor.intercept(context))
63
+ public async process(context: http.Context): Promise<http.OutgoingMessage> {
64
+ const interception = await this.interceptor.intercept(context)
52
65
 
53
- if (interception !== null)
54
- return interception
66
+ if (interception !== null) return interception
55
67
 
56
68
  // request-scoped, before anything is routed: this is where a credential is read
57
- await context.timing.capture('preflight',
58
- this.directives.preflight(context)).catch(rethrow)
69
+ await this.directives.preflight(context).catch(rethrow)
59
70
 
60
71
  const response = await this.endpoint(context)
61
72
 
62
73
  // request-scoped, on whatever is going back: this is where a credential is re-issued
63
- await context.timing.capture('depart',
64
- this.directives.depart(context, response)).catch(rethrow)
74
+ await this.directives.depart(context, response).catch(rethrow)
65
75
 
66
76
  return response
67
77
  }
@@ -70,14 +80,14 @@ export class Gateway extends Connector {
70
80
  * What answers the request: a pinned endpoint that makes calls of its own, or the route
71
81
  * the path names.
72
82
  */
73
- private async endpoint (context: http.Context): Promise<http.OutgoingMessage> {
83
+ private async endpoint(context: http.Context): Promise<http.OutgoingMessage> {
74
84
  const route: http.Processor = async (call) => await this.route(call)
75
85
 
76
86
  if (this.dispatcher !== null && context.url.pathname === RPC)
77
- return await context.timing.capture('rpc', this.dispatcher.dispatch(context, route))
87
+ return await this.dispatcher.dispatch(context, route)
78
88
 
79
89
  if (this.mcp !== null && context.url.pathname === MCP)
80
- return await context.timing.capture('mcp', this.mcp.process(context, route))
90
+ return await this.mcp.process(context, route)
81
91
 
82
92
  return await this.route(context)
83
93
  }
@@ -86,7 +96,7 @@ export class Gateway extends Connector {
86
96
  * One call: everything that needs a node. A request makes one of these, and a request
87
97
  * that carries several calls makes one per call.
88
98
  */
89
- private async route (context: http.Context): Promise<http.OutgoingMessage> {
99
+ private async route(context: http.Context): Promise<http.OutgoingMessage> {
90
100
  const { node, parameters } = this.match(context)
91
101
 
92
102
  if (context.request.method === 'OPTIONS')
@@ -94,39 +104,35 @@ export class Gateway extends Connector {
94
104
 
95
105
  let verb = context.request.method
96
106
 
97
- if (!(verb in node.methods) && verb === 'HEAD' && 'GET' in node.methods)
98
- verb = 'GET'
107
+ if (!(verb in node.methods) && verb === 'HEAD' && 'GET' in node.methods) verb = 'GET'
99
108
 
100
- if (!(verb in node.methods))
101
- throw new http.MethodNotAllowed()
109
+ if (!(verb in node.methods)) throw new http.MethodNotAllowed()
102
110
 
103
111
  const method = node.methods[verb]
104
112
 
105
- const interruption = await context.timing.capture('precall',
106
- method.directives.precall(context, parameters)).catch(rethrow)
113
+ const interruption = await method.directives
114
+ .precall(context, parameters)
115
+ .catch(rethrow)
116
+ const response = interruption ?? (await this.call(method, context, parameters))
107
117
 
108
- const response = interruption ??
109
- await context.timing.capture('call', this.call(method, context, parameters))
110
-
111
- await context.timing.capture('settle',
112
- method.directives.settle(context, response)).catch(rethrow)
118
+ await method.directives.settle(context, response).catch(rethrow)
113
119
 
114
120
  return response
115
121
  }
116
122
 
117
- protected override async open (): Promise<void> {
123
+ protected override async open(): Promise<void> {
118
124
  await this.discover()
119
125
 
120
126
  // what is served besides the tree, so that turning one on can be seen to have worked
121
127
  const pinned: string[] = []
122
128
 
123
- if (this.dispatcher !== null)
124
- pinned.push(RPC)
129
+ if (this.dispatcher !== null) pinned.push(RPC)
125
130
 
126
- if (this.mcp !== null)
127
- pinned.push(MCP)
131
+ if (this.mcp !== null) pinned.push(MCP)
128
132
 
129
- console.info('Gateway started', { endpoints: pinned.length === 0 ? 'none' : pinned.join(' ') })
133
+ console.info('Gateway started', {
134
+ endpoints: pinned.length === 0 ? 'none' : pinned.join(' ')
135
+ })
130
136
  }
131
137
 
132
138
  /**
@@ -135,17 +141,17 @@ export class Gateway extends Connector {
135
141
  * ticker firing in between calls an endpoint that has just been unbound, and reports the
136
142
  * refusal as a failure to reconcile.
137
143
  */
138
- protected override async close (): Promise<void> {
144
+ protected override async close(): Promise<void> {
139
145
  this.stopped = true
140
146
 
141
147
  this.tree.dispose()
142
148
  }
143
149
 
144
- protected override dispose (): void {
150
+ protected override dispose(): void {
145
151
  console.info('Gateway is closed')
146
152
  }
147
153
 
148
- private match (context: http.Context): Match {
154
+ private match(context: http.Context): Match {
149
155
  const match = this.tree.match(context.url.pathname)
150
156
 
151
157
  if (match === null) {
@@ -155,17 +161,15 @@ export class Gateway extends Connector {
155
161
  throw new http.NotFound('Route not found')
156
162
  }
157
163
 
158
- if (match.node.forward === null)
159
- return match
164
+ if (match.node.forward === null) return match
160
165
 
161
- const destination = match.node.forward.replace(/\/:([^/]+)/g,
162
- (_, name) => {
163
- const value = match.parameters.find((parameter) => parameter.name === name)?.value
166
+ const destination = match.node.forward.replace(/\/:([^/]+)/g, (_, name) => {
167
+ const value = match.parameters.find((parameter) => parameter.name === name)?.value
164
168
 
165
- assert.ok(value !== undefined, `Forwarded parameter '${name}' not found`)
169
+ assert.ok(value !== undefined, `Forwarded parameter '${name}' not found`)
166
170
 
167
- return `/${value}`
168
- })
171
+ return `/${value}`
172
+ })
169
173
 
170
174
  const forward = this.tree.match(destination)
171
175
 
@@ -174,23 +178,28 @@ export class Gateway extends Connector {
174
178
  return forward
175
179
  }
176
180
 
177
- private async call (method: Method, context: http.Context, parameters: Parameter[]): Promise<http.OutgoingMessage> {
181
+ private async call(
182
+ method: Method,
183
+ context: http.Context,
184
+ parameters: Parameter[]
185
+ ): Promise<http.OutgoingMessage> {
178
186
  if (context.url.pathname[context.url.pathname.length - 1] !== '/')
179
187
  throw new http.NotFound('Trailing slash is required')
180
188
 
181
- if (context.encoder === null)
182
- throw new http.NotAcceptable()
189
+ if (context.encoder === null) throw new http.NotAcceptable()
183
190
 
184
- if (method.endpoint === null)
185
- throw new http.MethodNotAllowed()
191
+ if (method.endpoint === null) throw new http.MethodNotAllowed()
186
192
 
187
- return await method.endpoint
193
+ return (await method.endpoint
188
194
  .call(context, parameters)
189
- .catch(rethrow) as http.OutgoingMessage
195
+ .catch(rethrow)) as http.OutgoingMessage
190
196
  }
191
197
 
192
- private async explain (context: http.Context, node: Node,
193
- parameters: Parameter[]): Promise<http.OutgoingMessage> {
198
+ private async explain(
199
+ context: http.Context,
200
+ node: Node,
201
+ parameters: Parameter[]
202
+ ): Promise<http.OutgoingMessage> {
194
203
  const body = await node.explain(context, parameters)
195
204
  const verbs = Object.keys(body)
196
205
 
@@ -201,7 +210,7 @@ export class Gateway extends Connector {
201
210
  return { body, headers: new Headers({ allow: verbs.join(', ') }) }
202
211
  }
203
212
 
204
- private async discover (): Promise<void> {
213
+ private async discover(): Promise<void> {
205
214
  const first = new Promise<void>((resolve) => {
206
215
  this.resolveFirstMerge = resolve
207
216
  })
@@ -217,43 +226,46 @@ export class Gateway extends Connector {
217
226
  * A single ping is enough only if every tenant is listening by then, which is
218
227
  * not the case while the deployment is still rolling out.
219
228
  */
220
- private async knock (): Promise<void> {
229
+ private async knock(): Promise<void> {
221
230
  for (const delay of KNOCK_DELAYS) {
222
- if (this.stopped)
223
- return
231
+ if (this.stopped) return
224
232
 
225
- if (delay > 0)
226
- await setTimeout(delay, undefined, { ref: false })
233
+ if (delay > 0) await setTimeout(delay, undefined, { ref: false })
227
234
 
228
235
  await this.ping()
229
236
  }
230
237
  }
231
238
 
232
- private async ping (): Promise<void> {
233
- if (this.stopped)
234
- return
239
+ private async ping(): Promise<void> {
240
+ if (this.stopped) return
235
241
 
236
242
  this.lastPing = Date.now()
237
243
 
238
- await this.broadcast.transmit<null>('ping', null)
239
- .catch((exception: Error) => console.error('Discovery ping failed',
240
- { message: exception.message }))
244
+ await this.broadcast
245
+ .transmit<null>('ping', null)
246
+ .catch((exception: Error) =>
247
+ console.error('Discovery ping failed', { message: exception.message })
248
+ )
241
249
  }
242
250
 
243
- private reping (): void {
244
- if (Date.now() - this.lastPing < PING_COOLDOWN)
245
- return
251
+ private reping(): void {
252
+ if (Date.now() - this.lastPing < PING_COOLDOWN) return
246
253
 
247
254
  void this.ping()
248
255
  }
249
256
 
250
- private async settled (first: Promise<void>): Promise<void> {
257
+ private async settled(first: Promise<void>): Promise<void> {
251
258
  const deadline = Date.now() + SETTLE_TIMEOUT
252
259
  const abort = new AbortController()
253
260
 
254
261
  // an uncancelled timer keeps the process alive long after the race is won
255
- await Promise.race([first, setTimeout(SETTLE_TIMEOUT, undefined, { signal: abort.signal })])
256
- .finally(() => { abort.abort() })
262
+ await Promise.race([
263
+ first,
264
+ setTimeout(SETTLE_TIMEOUT, undefined, { signal: abort.signal })
265
+ ])
266
+ .finally(() => {
267
+ abort.abort()
268
+ })
257
269
  .catch(() => {})
258
270
 
259
271
  if (this.lastMerge === 0) {
@@ -263,8 +275,7 @@ export class Gateway extends Connector {
263
275
  }
264
276
 
265
277
  while (Date.now() - this.lastMerge < this.quiet()) {
266
- if (Date.now() >= deadline)
267
- break
278
+ if (Date.now() >= deadline) break
268
279
 
269
280
  await setTimeout(SETTLE_POLL)
270
281
  }
@@ -277,13 +288,13 @@ export class Gateway extends Connector {
277
288
  * is enough; a rolling deployment brings them up seconds apart, and the window grows with
278
289
  * the widest gap seen so far to keep waiting for the ones still starting.
279
290
  */
280
- private quiet (): number {
291
+ private quiet(): number {
281
292
  const adaptive = this.widestGap * SETTLE_QUIET_FACTOR
282
293
 
283
294
  return Math.min(Math.max(adaptive, SETTLE_QUIET_MIN), SETTLE_QUIET_MAX)
284
295
  }
285
296
 
286
- private merge (branch: Branch): void {
297
+ private merge(branch: Branch): void {
287
298
  const id = branch.namespace + '.' + branch.component
288
299
 
289
300
  const attributes = {