@toa.io/extensions.exposition 1.0.0-alpha.13 → 1.0.0-alpha.131

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 (678) hide show
  1. package/components/context.toa.yaml +2 -2
  2. package/components/identity.bans/manifest.toa.yaml +14 -6
  3. package/components/identity.bans/operations/transit.d.ts +14 -0
  4. package/components/identity.bans/operations/transit.js +11 -0
  5. package/components/identity.bans/operations/transit.js.map +1 -0
  6. package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -0
  7. package/components/identity.bans/source/transit.ts +21 -0
  8. package/components/identity.bans/tsconfig.json +9 -0
  9. package/components/identity.basic/manifest.toa.yaml +28 -10
  10. package/components/identity.basic/operations/authenticate.d.ts +5 -1
  11. package/components/identity.basic/operations/authenticate.js +7 -4
  12. package/components/identity.basic/operations/authenticate.js.map +1 -1
  13. package/components/identity.basic/operations/incept.d.ts +12 -0
  14. package/components/identity.basic/operations/incept.js +26 -0
  15. package/components/identity.basic/operations/incept.js.map +1 -0
  16. package/components/identity.basic/operations/transit.d.ts +4 -4
  17. package/components/identity.basic/operations/transit.js +8 -6
  18. package/components/identity.basic/operations/transit.js.map +1 -1
  19. package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
  20. package/components/identity.basic/operations/types.d.ts +8 -4
  21. package/components/identity.basic/source/authenticate.ts +18 -7
  22. package/components/identity.basic/source/incept.ts +38 -0
  23. package/components/identity.basic/source/transit.ts +11 -9
  24. package/components/identity.basic/source/types.ts +8 -4
  25. package/components/identity.federation/manifest.toa.yaml +61 -19
  26. package/components/identity.federation/operations/authenticate.d.ts +13 -2
  27. package/components/identity.federation/operations/authenticate.js +10 -11
  28. package/components/identity.federation/operations/authenticate.js.map +1 -1
  29. package/components/identity.federation/operations/decode.d.ts +2 -0
  30. package/{transpiled/directives/octets/Permute.js → components/identity.federation/operations/decode.js} +7 -32
  31. package/components/identity.federation/operations/decode.js.map +1 -0
  32. package/components/identity.federation/operations/incept.d.ts +10 -0
  33. package/components/identity.federation/operations/incept.js +14 -0
  34. package/components/identity.federation/operations/incept.js.map +1 -0
  35. package/components/identity.federation/operations/lib/assertions-as-values.js +4 -2
  36. package/components/identity.federation/operations/lib/assertions-as-values.js.map +1 -1
  37. package/components/identity.federation/operations/lib/get.d.ts +1 -0
  38. package/components/identity.federation/operations/lib/get.js +64 -0
  39. package/components/identity.federation/operations/lib/get.js.map +1 -0
  40. package/components/identity.federation/operations/lib/jwt.d.ts +4 -5
  41. package/components/identity.federation/operations/lib/jwt.js +20 -16
  42. package/components/identity.federation/operations/lib/jwt.js.map +1 -1
  43. package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
  44. package/components/identity.federation/operations/types/configuration.d.ts +15 -0
  45. package/components/identity.federation/operations/types/configuration.js +3 -0
  46. package/components/identity.federation/operations/types/configuration.js.map +1 -0
  47. package/components/identity.federation/operations/{types.d.ts → types/context.d.ts} +11 -12
  48. package/{transpiled/directives/vary/embeddings/Embedding.js → components/identity.federation/operations/types/context.js} +1 -1
  49. package/components/identity.federation/operations/types/context.js.map +1 -0
  50. package/components/identity.federation/operations/types/entity.d.ts +6 -0
  51. package/components/identity.federation/operations/types/entity.js +3 -0
  52. package/components/identity.federation/operations/types/entity.js.map +1 -0
  53. package/components/identity.federation/operations/types/index.d.ts +3 -0
  54. package/components/identity.federation/operations/types/index.js +20 -0
  55. package/components/identity.federation/operations/types/index.js.map +1 -0
  56. package/components/identity.federation/source/authenticate.ts +24 -17
  57. package/components/identity.federation/source/decode.ts +9 -0
  58. package/components/identity.federation/source/incept.ts +26 -0
  59. package/components/identity.federation/source/lib/assertions-as-values.ts +5 -2
  60. package/components/identity.federation/source/lib/get.ts +82 -0
  61. package/components/identity.federation/source/lib/jwt.test.ts +127 -4
  62. package/components/identity.federation/source/lib/jwt.ts +26 -19
  63. package/components/identity.federation/source/types/configuration.ts +16 -0
  64. package/components/identity.federation/source/{types.ts → types/context.ts} +12 -12
  65. package/components/identity.federation/source/types/entity.ts +6 -0
  66. package/components/identity.federation/source/types/index.ts +3 -0
  67. package/components/identity.federation/tsconfig.json +5 -4
  68. package/components/identity.keys/manifest.toa.yaml +57 -0
  69. package/components/identity.keys/operations/create.d.ts +22 -0
  70. package/components/identity.keys/operations/create.js +16 -0
  71. package/components/identity.keys/operations/create.js.map +1 -0
  72. package/components/identity.keys/operations/tsconfig.tsbuildinfo +1 -0
  73. package/components/identity.keys/source/create.ts +35 -0
  74. package/components/identity.keys/tsconfig.json +9 -0
  75. package/components/identity.passkeys/manifest.toa.yaml +268 -0
  76. package/components/identity.passkeys/operations/authenticate.d.ts +16 -0
  77. package/components/identity.passkeys/operations/authenticate.js +34 -0
  78. package/components/identity.passkeys/operations/authenticate.js.map +1 -0
  79. package/components/identity.passkeys/operations/challenge.d.ts +35 -0
  80. package/components/identity.passkeys/operations/challenge.js +70 -0
  81. package/components/identity.passkeys/operations/challenge.js.map +1 -0
  82. package/components/identity.passkeys/operations/create.d.ts +17 -0
  83. package/components/identity.passkeys/operations/create.js +52 -0
  84. package/components/identity.passkeys/operations/create.js.map +1 -0
  85. package/components/identity.passkeys/operations/delete.d.ts +8 -0
  86. package/components/identity.passkeys/operations/delete.js +12 -0
  87. package/components/identity.passkeys/operations/delete.js.map +1 -0
  88. package/components/identity.passkeys/operations/lib/const.d.ts +1 -0
  89. package/components/identity.passkeys/operations/lib/const.js +5 -0
  90. package/components/identity.passkeys/operations/lib/const.js.map +1 -0
  91. package/components/identity.passkeys/operations/list.d.ts +7 -0
  92. package/components/identity.passkeys/operations/list.js +15 -0
  93. package/components/identity.passkeys/operations/list.js.map +1 -0
  94. package/components/identity.passkeys/operations/tsconfig.tsbuildinfo +1 -0
  95. package/components/identity.passkeys/operations/types/Configuration.d.ts +6 -0
  96. package/components/identity.passkeys/operations/types/Configuration.js +3 -0
  97. package/components/identity.passkeys/operations/types/Configuration.js.map +1 -0
  98. package/components/identity.passkeys/operations/types/Context.d.ts +16 -0
  99. package/components/identity.passkeys/operations/types/Context.js +3 -0
  100. package/components/identity.passkeys/operations/types/Context.js.map +1 -0
  101. package/components/identity.passkeys/operations/types/Passkey.d.ts +13 -0
  102. package/components/identity.passkeys/operations/types/Passkey.js +3 -0
  103. package/components/identity.passkeys/operations/types/Passkey.js.map +1 -0
  104. package/components/identity.passkeys/operations/types/index.d.ts +2 -0
  105. package/components/identity.passkeys/operations/types/index.js +3 -0
  106. package/components/identity.passkeys/operations/types/index.js.map +1 -0
  107. package/components/identity.passkeys/operations/use.d.ts +14 -0
  108. package/components/identity.passkeys/operations/use.js +52 -0
  109. package/components/identity.passkeys/operations/use.js.map +1 -0
  110. package/components/identity.passkeys/source/authenticate.ts +48 -0
  111. package/components/identity.passkeys/source/challenge.ts +111 -0
  112. package/components/identity.passkeys/source/create.ts +71 -0
  113. package/components/identity.passkeys/source/delete.ts +15 -0
  114. package/components/identity.passkeys/source/lib/const.ts +1 -0
  115. package/components/identity.passkeys/source/list.ts +17 -0
  116. package/components/identity.passkeys/source/types/Configuration.ts +6 -0
  117. package/components/identity.passkeys/source/types/Context.ts +17 -0
  118. package/components/identity.passkeys/source/types/Passkey.ts +14 -0
  119. package/components/identity.passkeys/source/types/index.ts +2 -0
  120. package/components/identity.passkeys/source/use.ts +70 -0
  121. package/components/identity.passkeys/tsconfig.json +9 -0
  122. package/components/identity.roles/manifest.toa.yaml +7 -5
  123. package/components/identity.roles/operations/grant.d.ts +1 -1
  124. package/components/identity.roles/operations/grant.js +8 -7
  125. package/components/identity.roles/operations/grant.js.map +1 -1
  126. package/components/identity.roles/operations/lib/Entity.d.ts +1 -1
  127. package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
  128. package/components/identity.roles/source/grant.ts +9 -8
  129. package/components/identity.roles/source/lib/Entity.ts +1 -1
  130. package/components/identity.tokens/manifest.toa.yaml +98 -13
  131. package/components/identity.tokens/operations/authenticate.d.ts +3 -3
  132. package/components/identity.tokens/operations/authenticate.js +20 -13
  133. package/components/identity.tokens/operations/authenticate.js.map +1 -1
  134. package/components/identity.tokens/operations/decrypt.d.ts +12 -3
  135. package/components/identity.tokens/operations/decrypt.js +62 -17
  136. package/components/identity.tokens/operations/decrypt.js.map +1 -1
  137. package/components/identity.tokens/operations/encrypt.d.ts +3 -3
  138. package/components/identity.tokens/operations/encrypt.js +26 -6
  139. package/components/identity.tokens/operations/encrypt.js.map +1 -1
  140. package/components/identity.tokens/operations/issue.d.ts +24 -0
  141. package/components/identity.tokens/operations/issue.js +59 -0
  142. package/components/identity.tokens/operations/issue.js.map +1 -0
  143. package/components/identity.tokens/operations/lib/index.d.ts +2 -0
  144. package/components/identity.tokens/operations/lib/index.js +19 -0
  145. package/components/identity.tokens/operations/lib/index.js.map +1 -0
  146. package/components/identity.tokens/operations/lib/pad.d.ts +1 -0
  147. package/components/identity.tokens/operations/lib/pad.js +5 -0
  148. package/components/identity.tokens/operations/lib/pad.js.map +1 -0
  149. package/components/identity.tokens/operations/lib/types.d.ts +74 -0
  150. package/components/identity.tokens/operations/lib/types.js.map +1 -0
  151. package/components/identity.tokens/operations/revoke.d.ts +2 -2
  152. package/components/identity.tokens/operations/revoke.js.map +1 -1
  153. package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
  154. package/components/identity.tokens/receivers/identity.bans.created.js +3 -0
  155. package/components/identity.tokens/source/authenticate.test.ts +22 -9
  156. package/components/identity.tokens/source/authenticate.ts +23 -15
  157. package/components/identity.tokens/source/decrypt.test.ts +33 -18
  158. package/components/identity.tokens/source/decrypt.ts +91 -20
  159. package/components/identity.tokens/source/encrypt.test.ts +47 -13
  160. package/components/identity.tokens/source/encrypt.ts +37 -9
  161. package/components/identity.tokens/source/issue.ts +82 -0
  162. package/components/identity.tokens/source/lib/index.ts +2 -0
  163. package/components/identity.tokens/source/lib/pad.ts +1 -0
  164. package/components/identity.tokens/source/lib/paseto.test.ts +16 -0
  165. package/components/identity.tokens/source/lib/types.ts +85 -0
  166. package/components/identity.tokens/source/revoke.ts +2 -2
  167. package/components/octets.storage/manifest.toa.yaml +11 -11
  168. package/components/octets.storage/operations/get.js +3 -3
  169. package/components/octets.storage/operations/head.js +7 -0
  170. package/components/octets.storage/operations/put.js +135 -0
  171. package/documentation/access.md +91 -29
  172. package/documentation/authorities.md +48 -0
  173. package/documentation/cache.md +8 -1
  174. package/documentation/components.md +125 -54
  175. package/documentation/dev.md +30 -0
  176. package/documentation/flow.md +44 -0
  177. package/documentation/identity.md +30 -23
  178. package/documentation/introspection.md +82 -0
  179. package/documentation/map.md +76 -0
  180. package/documentation/octets.md +122 -69
  181. package/documentation/passkeys.md +4 -0
  182. package/documentation/protocol.md +11 -4
  183. package/documentation/query.md +29 -4
  184. package/documentation/require.md +15 -0
  185. package/documentation/tree.md +13 -0
  186. package/features/access.feature +129 -48
  187. package/features/annotation.feature +1 -0
  188. package/features/auth.claims.feature +171 -0
  189. package/features/auth.incept.feature +120 -0
  190. package/features/auth.input.feature +59 -0
  191. package/features/auth.issue.feature +32 -0
  192. package/features/authorities.basic.feature +141 -0
  193. package/features/authorities.feature +32 -0
  194. package/features/authorities.federation.feature +100 -0
  195. package/features/authorities.tokens.feature +117 -0
  196. package/features/body.feature +2 -0
  197. package/features/cache.feature +125 -5
  198. package/features/cors.feature +8 -2
  199. package/features/debug.feature +34 -0
  200. package/features/dev.feature +56 -0
  201. package/features/directives.feature +3 -0
  202. package/features/dynamic.feature +48 -0
  203. package/features/errors.feature +32 -7
  204. package/features/etag.feature +109 -1
  205. package/features/flow.feature +148 -0
  206. package/features/identity.bans.feature +137 -0
  207. package/features/identity.basic.feature +85 -28
  208. package/features/identity.feature +18 -6
  209. package/features/identity.federation.feature +89 -18
  210. package/features/identity.roles.feature +112 -19
  211. package/features/identity.tokens.feature +13 -44
  212. package/features/identtiy.tokens.custom.feature +247 -0
  213. package/features/interruptions.feature +19 -0
  214. package/features/introspection.feature +153 -0
  215. package/features/io.feature +38 -1
  216. package/features/map.feature +305 -0
  217. package/features/methods.feature +47 -0
  218. package/features/octets.cloudinary.feature +71 -0
  219. package/features/octets.download.feature +189 -0
  220. package/features/octets.entries.feature +13 -55
  221. package/features/octets.feature +90 -114
  222. package/features/octets.head.feature +40 -0
  223. package/features/octets.location.feature +83 -0
  224. package/features/octets.meta.feature +65 -15
  225. package/features/octets.workflows.feature +339 -66
  226. package/features/passkeys.feature +61 -0
  227. package/features/probes.feature +14 -0
  228. package/features/{queries.feature → query.feature} +77 -2
  229. package/features/realtime.feature +34 -0
  230. package/features/require.feature +67 -0
  231. package/features/response.feature +34 -2
  232. package/features/routes.feature +93 -2
  233. package/features/server.feature +21 -0
  234. package/features/steps/.env.example +3 -0
  235. package/features/steps/Common.ts +4 -0
  236. package/features/steps/Database.ts +16 -10
  237. package/features/steps/Gateway.ts +26 -7
  238. package/features/steps/HTTP.ts +25 -2
  239. package/features/steps/IdP.ts +63 -25
  240. package/features/steps/Identity.ts +51 -0
  241. package/features/steps/Parameters.ts +44 -1
  242. package/features/steps/Realtime.ts +151 -0
  243. package/features/steps/components/echo/manifest.toa.yaml +17 -1
  244. package/features/steps/components/echo/operations/echo.js +7 -0
  245. package/features/steps/components/echo/operations/identity.js +7 -0
  246. package/features/steps/components/echo/operations/parameters.js +7 -0
  247. package/features/steps/components/echo.beacon/manifest.toa.yaml +2 -0
  248. package/features/steps/components/echo.beacon/operations/hello.js +5 -0
  249. package/features/steps/components/greeter/manifest.toa.yaml +0 -1
  250. package/features/steps/components/octets.tester/manifest.toa.yaml +25 -3
  251. package/features/steps/components/octets.tester/operations/authority.js +7 -0
  252. package/features/steps/components/octets.tester/operations/bar.js +0 -1
  253. package/features/steps/components/octets.tester/operations/baz.js +0 -2
  254. package/features/steps/components/octets.tester/operations/echo.js +1 -1
  255. package/features/steps/components/octets.tester/operations/foo.js +1 -2
  256. package/features/steps/components/octets.tester/operations/id.js +7 -0
  257. package/features/steps/components/octets.tester/operations/identity.js +7 -0
  258. package/features/steps/components/octets.tester/operations/redirect.js +12 -0
  259. package/features/steps/components/octets.tester/operations/yex.js +16 -0
  260. package/features/steps/components/octets.tester/operations/yield.js +13 -0
  261. package/features/steps/components/pots/manifest.toa.yaml +12 -4
  262. package/features/steps/components/sequences/manifest.toa.yaml +0 -1
  263. package/features/steps/components/users/manifest.toa.yaml +4 -3
  264. package/features/steps/components/users/operations/create.js +15 -0
  265. package/features/steps/components/users.properties/manifest.toa.yaml +1 -2
  266. package/features/streams.feature +5 -0
  267. package/features/timestamps.feature +41 -0
  268. package/features/timing.feature +4 -1
  269. package/package.json +27 -13
  270. package/readme.md +19 -14
  271. package/schemas/annotation.cos.yaml +1 -1
  272. package/schemas/method.cos.yaml +2 -1
  273. package/schemas/node.cos.yaml +2 -0
  274. package/schemas/octets/put.cos.yaml +28 -0
  275. package/schemas/query.cos.yaml +4 -10
  276. package/source/Annotation.ts +3 -3
  277. package/source/Branch.ts +1 -0
  278. package/source/Composition.ts +0 -6
  279. package/source/Context.ts +1 -0
  280. package/source/Directive.test.ts +1 -1
  281. package/source/Directive.ts +16 -8
  282. package/source/Endpoint.ts +70 -17
  283. package/source/Factory.ts +22 -13
  284. package/source/Gateway.ts +73 -19
  285. package/source/HTTP/Context.ts +29 -7
  286. package/source/HTTP/Server.ts +113 -50
  287. package/source/HTTP/exceptions.ts +13 -1
  288. package/source/HTTP/formats/index.ts +3 -3
  289. package/source/HTTP/messages.test.ts +46 -2
  290. package/source/HTTP/messages.ts +41 -9
  291. package/source/Introspection.ts +11 -0
  292. package/source/Mapping.ts +68 -21
  293. package/source/Query.test.ts +3 -3
  294. package/source/Query.ts +123 -33
  295. package/source/RTD/Context.ts +1 -1
  296. package/source/RTD/Endpoint.ts +3 -0
  297. package/source/RTD/Method.ts +16 -0
  298. package/source/RTD/Node.ts +29 -13
  299. package/source/RTD/Route.ts +5 -4
  300. package/source/RTD/Tree.ts +2 -2
  301. package/source/RTD/factory.ts +5 -2
  302. package/source/RTD/syntax/parse.test.ts +1 -1
  303. package/source/RTD/syntax/parse.ts +37 -24
  304. package/source/RTD/syntax/types.ts +6 -4
  305. package/source/Remotes.ts +7 -6
  306. package/source/Tenant.ts +6 -20
  307. package/source/deployment.ts +33 -23
  308. package/source/directives/auth/Anonymous.ts +3 -3
  309. package/source/directives/auth/Anyone.ts +13 -0
  310. package/source/directives/auth/Authorization.ts +66 -26
  311. package/source/directives/auth/Delegate.ts +13 -6
  312. package/source/directives/auth/Echo.ts +16 -6
  313. package/source/directives/auth/Federation.ts +84 -0
  314. package/source/directives/auth/Id.ts +1 -1
  315. package/source/directives/auth/Incept.ts +54 -17
  316. package/source/directives/auth/Input.ts +72 -0
  317. package/source/directives/auth/Role.test.ts +53 -6
  318. package/source/directives/auth/Role.ts +23 -19
  319. package/source/directives/auth/Rule.ts +3 -5
  320. package/source/directives/auth/Scheme.ts +5 -5
  321. package/source/directives/auth/create.ts +11 -0
  322. package/source/directives/auth/schemes.ts +2 -0
  323. package/source/directives/auth/split.ts +1 -1
  324. package/source/directives/auth/types.ts +11 -6
  325. package/source/directives/cache/Cache.ts +15 -6
  326. package/source/directives/cache/Control.ts +45 -19
  327. package/source/directives/cors/CORS.ts +3 -2
  328. package/source/directives/dev/Development.ts +12 -7
  329. package/source/directives/dev/Sleep.ts +40 -0
  330. package/source/directives/dev/types.ts +1 -1
  331. package/source/directives/flow/Compose.ts +92 -0
  332. package/source/directives/flow/Fetch.ts +86 -0
  333. package/source/directives/flow/Flow.ts +42 -0
  334. package/source/directives/flow/index.ts +3 -0
  335. package/source/directives/flow/types.ts +7 -0
  336. package/source/directives/index.ts +4 -2
  337. package/source/directives/io/IO.ts +1 -1
  338. package/source/directives/io/Input.ts +8 -5
  339. package/source/directives/io/Output.ts +5 -4
  340. package/source/directives/map/Authority.ts +15 -0
  341. package/source/directives/map/Claims.ts +58 -0
  342. package/source/directives/map/Directive.ts +4 -0
  343. package/source/directives/map/Headers.ts +38 -0
  344. package/source/directives/map/Language.ts +42 -0
  345. package/source/directives/map/Languages.ts +11 -0
  346. package/source/directives/map/Map.ts +61 -0
  347. package/source/directives/map/Mapping.ts +19 -0
  348. package/source/directives/{vary → map}/Properties.ts +2 -4
  349. package/source/directives/map/Segments.ts +27 -0
  350. package/source/directives/map/index.ts +3 -0
  351. package/source/directives/octets/Context.ts +3 -2
  352. package/source/directives/octets/Delete.ts +21 -17
  353. package/source/directives/octets/Get.ts +86 -0
  354. package/source/directives/octets/Octets.ts +9 -12
  355. package/source/directives/octets/{Store.ts → Put.ts} +52 -38
  356. package/source/directives/octets/Workflow.ts +9 -3
  357. package/source/directives/octets/bytes.test.ts +30 -0
  358. package/source/directives/octets/bytes.ts +18 -0
  359. package/source/directives/octets/schemas.ts +4 -8
  360. package/source/directives/octets/types.ts +2 -0
  361. package/source/directives/octets/workflows/Execution.ts +61 -8
  362. package/source/directives/octets/workflows/Workflow.ts +17 -7
  363. package/source/directives/octets/workflows/index.ts +1 -1
  364. package/source/directives/require/Directive.ts +5 -0
  365. package/source/directives/require/Headers.ts +20 -0
  366. package/source/directives/require/Require.ts +28 -0
  367. package/source/directives/require/index.ts +3 -0
  368. package/source/exceptions.ts +14 -6
  369. package/source/manifest.ts +10 -11
  370. package/source/root.ts +16 -1
  371. package/source/schemas.ts +1 -1
  372. package/transpiled/Annotation.d.ts +3 -3
  373. package/transpiled/Branch.d.ts +1 -0
  374. package/transpiled/Composition.d.ts +0 -1
  375. package/transpiled/Composition.js +0 -4
  376. package/transpiled/Composition.js.map +1 -1
  377. package/transpiled/Context.d.ts +1 -0
  378. package/transpiled/Directive.js +15 -8
  379. package/transpiled/Directive.js.map +1 -1
  380. package/transpiled/Endpoint.d.ts +6 -4
  381. package/transpiled/Endpoint.js +46 -9
  382. package/transpiled/Endpoint.js.map +1 -1
  383. package/transpiled/Factory.d.ts +3 -2
  384. package/transpiled/Factory.js +18 -10
  385. package/transpiled/Factory.js.map +1 -1
  386. package/transpiled/Gateway.d.ts +3 -0
  387. package/transpiled/Gateway.js +55 -12
  388. package/transpiled/Gateway.js.map +1 -1
  389. package/transpiled/HTTP/Context.d.ts +9 -2
  390. package/transpiled/HTTP/Context.js +19 -6
  391. package/transpiled/HTTP/Context.js.map +1 -1
  392. package/transpiled/HTTP/Server.d.ts +15 -4
  393. package/transpiled/HTTP/Server.js +81 -41
  394. package/transpiled/HTTP/Server.js.map +1 -1
  395. package/transpiled/HTTP/exceptions.d.ts +7 -1
  396. package/transpiled/HTTP/exceptions.js +13 -1
  397. package/transpiled/HTTP/exceptions.js.map +1 -1
  398. package/transpiled/HTTP/formats/index.js +3 -3
  399. package/transpiled/HTTP/formats/index.js.map +1 -1
  400. package/transpiled/HTTP/messages.d.ts +2 -1
  401. package/transpiled/HTTP/messages.js +38 -8
  402. package/transpiled/HTTP/messages.js.map +1 -1
  403. package/transpiled/Introspection.d.ts +9 -0
  404. package/transpiled/Introspection.js +3 -0
  405. package/transpiled/Introspection.js.map +1 -0
  406. package/transpiled/Mapping.d.ts +11 -2
  407. package/transpiled/Mapping.js +50 -19
  408. package/transpiled/Mapping.js.map +1 -1
  409. package/transpiled/Query.d.ts +10 -1
  410. package/transpiled/Query.js +87 -30
  411. package/transpiled/Query.js.map +1 -1
  412. package/transpiled/RTD/Context.d.ts +1 -1
  413. package/transpiled/RTD/Endpoint.d.ts +1 -0
  414. package/transpiled/RTD/Method.d.ts +4 -0
  415. package/transpiled/RTD/Method.js +11 -0
  416. package/transpiled/RTD/Method.js.map +1 -1
  417. package/transpiled/RTD/Node.d.ts +4 -1
  418. package/transpiled/RTD/Node.js +23 -12
  419. package/transpiled/RTD/Node.js.map +1 -1
  420. package/transpiled/RTD/Route.d.ts +1 -1
  421. package/transpiled/RTD/Route.js +0 -1
  422. package/transpiled/RTD/Route.js.map +1 -1
  423. package/transpiled/RTD/Tree.d.ts +1 -1
  424. package/transpiled/RTD/Tree.js.map +1 -1
  425. package/transpiled/RTD/factory.js +5 -2
  426. package/transpiled/RTD/factory.js.map +1 -1
  427. package/transpiled/RTD/syntax/parse.js +34 -22
  428. package/transpiled/RTD/syntax/parse.js.map +1 -1
  429. package/transpiled/RTD/syntax/types.d.ts +5 -3
  430. package/transpiled/RTD/syntax/types.js +1 -1
  431. package/transpiled/RTD/syntax/types.js.map +1 -1
  432. package/transpiled/Remotes.d.ts +4 -4
  433. package/transpiled/Remotes.js +6 -5
  434. package/transpiled/Remotes.js.map +1 -1
  435. package/transpiled/Tenant.d.ts +5 -5
  436. package/transpiled/Tenant.js +2 -13
  437. package/transpiled/Tenant.js.map +1 -1
  438. package/transpiled/deployment.d.ts +1 -1
  439. package/transpiled/deployment.js +28 -20
  440. package/transpiled/deployment.js.map +1 -1
  441. package/transpiled/directives/auth/Anonymous.d.ts +2 -2
  442. package/transpiled/directives/auth/Anonymous.js +2 -2
  443. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  444. package/transpiled/directives/auth/Anyone.d.ts +6 -0
  445. package/transpiled/directives/auth/Anyone.js +14 -0
  446. package/transpiled/directives/auth/Anyone.js.map +1 -0
  447. package/transpiled/directives/auth/Authorization.d.ts +4 -3
  448. package/transpiled/directives/auth/Authorization.js +50 -23
  449. package/transpiled/directives/auth/Authorization.js.map +1 -1
  450. package/transpiled/directives/auth/Delegate.d.ts +5 -4
  451. package/transpiled/directives/auth/Delegate.js +10 -4
  452. package/transpiled/directives/auth/Delegate.js.map +1 -1
  453. package/transpiled/directives/auth/Echo.d.ts +4 -4
  454. package/transpiled/directives/auth/Echo.js +11 -4
  455. package/transpiled/directives/auth/Echo.js.map +1 -1
  456. package/transpiled/directives/auth/Federation.d.ts +16 -0
  457. package/transpiled/directives/auth/Federation.js +57 -0
  458. package/transpiled/directives/auth/Federation.js.map +1 -0
  459. package/transpiled/directives/auth/Id.d.ts +1 -1
  460. package/transpiled/directives/auth/Id.js.map +1 -1
  461. package/transpiled/directives/auth/Incept.d.ts +5 -3
  462. package/transpiled/directives/auth/Incept.js +42 -13
  463. package/transpiled/directives/auth/Incept.js.map +1 -1
  464. package/transpiled/directives/auth/Input.d.ts +13 -0
  465. package/transpiled/directives/auth/Input.js +49 -0
  466. package/transpiled/directives/auth/Input.js.map +1 -0
  467. package/transpiled/directives/auth/Role.d.ts +5 -2
  468. package/transpiled/directives/auth/Role.js +22 -18
  469. package/transpiled/directives/auth/Role.js.map +1 -1
  470. package/transpiled/directives/auth/Rule.d.ts +2 -4
  471. package/transpiled/directives/auth/Rule.js +2 -2
  472. package/transpiled/directives/auth/Rule.js.map +1 -1
  473. package/transpiled/directives/auth/Scheme.d.ts +2 -2
  474. package/transpiled/directives/auth/Scheme.js +4 -4
  475. package/transpiled/directives/auth/Scheme.js.map +1 -1
  476. package/transpiled/directives/auth/create.d.ts +2 -0
  477. package/transpiled/directives/auth/create.js +14 -0
  478. package/transpiled/directives/auth/create.js.map +1 -0
  479. package/transpiled/directives/auth/schemes.d.ts +1 -0
  480. package/transpiled/directives/auth/schemes.js +2 -1
  481. package/transpiled/directives/auth/schemes.js.map +1 -1
  482. package/transpiled/directives/auth/split.js +1 -1
  483. package/transpiled/directives/auth/split.js.map +1 -1
  484. package/transpiled/directives/auth/types.d.ts +8 -5
  485. package/transpiled/directives/cache/Cache.d.ts +3 -3
  486. package/transpiled/directives/cache/Cache.js +12 -4
  487. package/transpiled/directives/cache/Cache.js.map +1 -1
  488. package/transpiled/directives/cache/Control.d.ts +3 -2
  489. package/transpiled/directives/cache/Control.js +32 -15
  490. package/transpiled/directives/cache/Control.js.map +1 -1
  491. package/transpiled/directives/cors/CORS.js +3 -2
  492. package/transpiled/directives/cors/CORS.js.map +1 -1
  493. package/transpiled/directives/dev/Development.d.ts +1 -1
  494. package/transpiled/directives/dev/Development.js +13 -7
  495. package/transpiled/directives/dev/Development.js.map +1 -1
  496. package/transpiled/directives/dev/Sleep.d.ts +8 -0
  497. package/transpiled/directives/dev/Sleep.js +36 -0
  498. package/transpiled/directives/dev/Sleep.js.map +1 -0
  499. package/transpiled/directives/dev/types.d.ts +1 -1
  500. package/transpiled/directives/flow/Compose.d.ts +9 -0
  501. package/transpiled/directives/flow/Compose.js +94 -0
  502. package/transpiled/directives/flow/Compose.js.map +1 -0
  503. package/transpiled/directives/flow/Fetch.d.ts +12 -0
  504. package/transpiled/directives/flow/Fetch.js +58 -0
  505. package/transpiled/directives/flow/Fetch.js.map +1 -0
  506. package/transpiled/directives/flow/Flow.d.ts +10 -0
  507. package/transpiled/directives/flow/Flow.js +33 -0
  508. package/transpiled/directives/flow/Flow.js.map +1 -0
  509. package/transpiled/directives/flow/index.d.ts +2 -0
  510. package/transpiled/directives/flow/index.js +6 -0
  511. package/transpiled/directives/flow/index.js.map +1 -0
  512. package/transpiled/directives/flow/types.d.ts +6 -0
  513. package/transpiled/directives/flow/types.js.map +1 -0
  514. package/transpiled/directives/index.js +4 -2
  515. package/transpiled/directives/index.js.map +1 -1
  516. package/transpiled/directives/io/IO.js +1 -1
  517. package/transpiled/directives/io/IO.js.map +1 -1
  518. package/transpiled/directives/io/Input.js +4 -2
  519. package/transpiled/directives/io/Input.js.map +1 -1
  520. package/transpiled/directives/io/Output.js +2 -2
  521. package/transpiled/directives/io/Output.js.map +1 -1
  522. package/transpiled/directives/map/Authority.d.ts +6 -0
  523. package/transpiled/directives/map/Authority.js +19 -0
  524. package/transpiled/directives/map/Authority.js.map +1 -0
  525. package/transpiled/directives/map/Claims.d.ts +10 -0
  526. package/transpiled/directives/map/Claims.js +44 -0
  527. package/transpiled/directives/map/Claims.js.map +1 -0
  528. package/transpiled/directives/map/Directive.d.ts +3 -0
  529. package/transpiled/directives/map/Directive.js.map +1 -0
  530. package/transpiled/directives/map/Headers.d.ts +7 -0
  531. package/transpiled/directives/map/Headers.js +34 -0
  532. package/transpiled/directives/map/Headers.js.map +1 -0
  533. package/transpiled/directives/map/Language.d.ts +10 -0
  534. package/transpiled/directives/map/Language.js +38 -0
  535. package/transpiled/directives/map/Language.js.map +1 -0
  536. package/transpiled/directives/map/Languages.d.ts +4 -0
  537. package/transpiled/directives/map/Languages.js +17 -0
  538. package/transpiled/directives/map/Languages.js.map +1 -0
  539. package/transpiled/directives/map/Map.d.ts +13 -0
  540. package/transpiled/directives/map/Map.js +46 -0
  541. package/transpiled/directives/map/Map.js.map +1 -0
  542. package/transpiled/directives/map/Mapping.d.ts +13 -0
  543. package/transpiled/directives/map/Mapping.js +13 -0
  544. package/transpiled/directives/map/Mapping.js.map +1 -0
  545. package/transpiled/directives/{vary → map}/Properties.d.ts +2 -2
  546. package/transpiled/directives/{vary → map}/Properties.js +1 -3
  547. package/transpiled/directives/map/Properties.js.map +1 -0
  548. package/transpiled/directives/map/Segments.d.ts +6 -0
  549. package/transpiled/directives/map/Segments.js +26 -0
  550. package/transpiled/directives/map/Segments.js.map +1 -0
  551. package/transpiled/directives/map/index.d.ts +2 -0
  552. package/transpiled/directives/map/index.js +6 -0
  553. package/transpiled/directives/map/index.js.map +1 -0
  554. package/transpiled/directives/octets/Context.js +4 -24
  555. package/transpiled/directives/octets/Context.js.map +1 -1
  556. package/transpiled/directives/octets/Delete.js +15 -12
  557. package/transpiled/directives/octets/Delete.js.map +1 -1
  558. package/transpiled/directives/octets/{Fetch.d.ts → Get.d.ts} +5 -6
  559. package/transpiled/directives/octets/{Fetch.js → Get.js} +25 -29
  560. package/transpiled/directives/octets/Get.js.map +1 -0
  561. package/transpiled/directives/octets/Octets.js +9 -12
  562. package/transpiled/directives/octets/Octets.js.map +1 -1
  563. package/transpiled/directives/octets/{Store.d.ts → Put.d.ts} +8 -2
  564. package/transpiled/directives/octets/{Store.js → Put.js} +33 -27
  565. package/transpiled/directives/octets/Put.js.map +1 -0
  566. package/transpiled/directives/octets/Workflow.js +7 -2
  567. package/transpiled/directives/octets/Workflow.js.map +1 -1
  568. package/transpiled/directives/octets/bytes.d.ts +1 -0
  569. package/transpiled/directives/octets/bytes.js +21 -0
  570. package/transpiled/directives/octets/bytes.js.map +1 -0
  571. package/transpiled/directives/octets/schemas.d.ts +4 -8
  572. package/transpiled/directives/octets/schemas.js +3 -6
  573. package/transpiled/directives/octets/schemas.js.map +1 -1
  574. package/transpiled/directives/octets/types.d.ts +2 -0
  575. package/transpiled/directives/octets/workflows/Execution.d.ts +6 -1
  576. package/transpiled/directives/octets/workflows/Execution.js +44 -9
  577. package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
  578. package/transpiled/directives/octets/workflows/Workflow.d.ts +8 -3
  579. package/transpiled/directives/octets/workflows/Workflow.js +9 -4
  580. package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
  581. package/transpiled/directives/octets/workflows/index.d.ts +1 -1
  582. package/transpiled/directives/octets/workflows/index.js.map +1 -1
  583. package/transpiled/directives/require/Directive.d.ts +4 -0
  584. package/transpiled/directives/require/Directive.js +3 -0
  585. package/transpiled/directives/require/Directive.js.map +1 -0
  586. package/transpiled/directives/require/Headers.d.ts +7 -0
  587. package/transpiled/directives/require/Headers.js +19 -0
  588. package/transpiled/directives/require/Headers.js.map +1 -0
  589. package/transpiled/directives/require/Require.d.ts +9 -0
  590. package/transpiled/directives/require/Require.js +27 -0
  591. package/transpiled/directives/require/Require.js.map +1 -0
  592. package/transpiled/directives/require/index.d.ts +2 -0
  593. package/transpiled/directives/require/index.js +6 -0
  594. package/transpiled/directives/require/index.js.map +1 -0
  595. package/transpiled/exceptions.d.ts +3 -2
  596. package/transpiled/exceptions.js +8 -1
  597. package/transpiled/exceptions.js.map +1 -1
  598. package/transpiled/manifest.js +10 -11
  599. package/transpiled/manifest.js.map +1 -1
  600. package/transpiled/root.js +16 -1
  601. package/transpiled/root.js.map +1 -1
  602. package/transpiled/schemas.d.ts +1 -1
  603. package/transpiled/schemas.js +2 -2
  604. package/transpiled/schemas.js.map +1 -1
  605. package/transpiled/tsconfig.tsbuildinfo +1 -1
  606. package/components/identity.basic/operations/create.d.ts +0 -10
  607. package/components/identity.basic/operations/create.js +0 -10
  608. package/components/identity.basic/operations/create.js.map +0 -1
  609. package/components/identity.basic/source/create.ts +0 -18
  610. package/components/identity.federation/operations/create.d.ts +0 -10
  611. package/components/identity.federation/operations/create.js +0 -15
  612. package/components/identity.federation/operations/create.js.map +0 -1
  613. package/components/identity.federation/operations/schemas.d.ts +0 -59
  614. package/components/identity.federation/operations/schemas.js +0 -9
  615. package/components/identity.federation/operations/schemas.js.map +0 -1
  616. package/components/identity.federation/operations/types.js.map +0 -1
  617. package/components/identity.federation/source/create.ts +0 -26
  618. package/components/identity.federation/source/schemas.ts +0 -61
  619. package/components/identity.tokens/operations/types.d.ts +0 -40
  620. package/components/identity.tokens/operations/types.js.map +0 -1
  621. package/components/identity.tokens/source/types.ts +0 -48
  622. package/components/octets.storage/operations/fetch.js +0 -46
  623. package/components/octets.storage/operations/list.js +0 -7
  624. package/components/octets.storage/operations/permute.js +0 -7
  625. package/components/octets.storage/operations/store.js +0 -11
  626. package/documentation/vary.md +0 -69
  627. package/features/steps/components/octets.tester/operations/diversify.js +0 -14
  628. package/features/vary.feature +0 -180
  629. package/schemas/octets/context.cos.yaml +0 -1
  630. package/schemas/octets/fetch.cos.yaml +0 -3
  631. package/schemas/octets/permute.cos.yaml +0 -1
  632. package/schemas/octets/store.cos.yaml +0 -3
  633. package/source/HTTP/Server.test.ts +0 -126
  634. package/source/directives/octets/Fetch.ts +0 -100
  635. package/source/directives/octets/List.ts +0 -72
  636. package/source/directives/octets/Permute.ts +0 -44
  637. package/source/directives/vary/Directive.ts +0 -6
  638. package/source/directives/vary/Embed.ts +0 -62
  639. package/source/directives/vary/Vary.ts +0 -48
  640. package/source/directives/vary/embeddings/Embedding.ts +0 -6
  641. package/source/directives/vary/embeddings/Header.ts +0 -32
  642. package/source/directives/vary/embeddings/Language.ts +0 -31
  643. package/source/directives/vary/embeddings/index.ts +0 -11
  644. package/source/directives/vary/index.ts +0 -3
  645. package/transpiled/directives/octets/Fetch.js.map +0 -1
  646. package/transpiled/directives/octets/List.d.ts +0 -16
  647. package/transpiled/directives/octets/List.js +0 -74
  648. package/transpiled/directives/octets/List.js.map +0 -1
  649. package/transpiled/directives/octets/Permute.d.ts +0 -11
  650. package/transpiled/directives/octets/Permute.js.map +0 -1
  651. package/transpiled/directives/octets/Store.js.map +0 -1
  652. package/transpiled/directives/vary/Directive.d.ts +0 -5
  653. package/transpiled/directives/vary/Directive.js.map +0 -1
  654. package/transpiled/directives/vary/Embed.d.ts +0 -10
  655. package/transpiled/directives/vary/Embed.js +0 -49
  656. package/transpiled/directives/vary/Embed.js.map +0 -1
  657. package/transpiled/directives/vary/Properties.js.map +0 -1
  658. package/transpiled/directives/vary/Vary.d.ts +0 -10
  659. package/transpiled/directives/vary/Vary.js +0 -36
  660. package/transpiled/directives/vary/Vary.js.map +0 -1
  661. package/transpiled/directives/vary/embeddings/Embedding.d.ts +0 -5
  662. package/transpiled/directives/vary/embeddings/Embedding.js.map +0 -1
  663. package/transpiled/directives/vary/embeddings/Header.d.ts +0 -7
  664. package/transpiled/directives/vary/embeddings/Header.js +0 -28
  665. package/transpiled/directives/vary/embeddings/Header.js.map +0 -1
  666. package/transpiled/directives/vary/embeddings/Language.d.ts +0 -7
  667. package/transpiled/directives/vary/embeddings/Language.js +0 -28
  668. package/transpiled/directives/vary/embeddings/Language.js.map +0 -1
  669. package/transpiled/directives/vary/embeddings/index.d.ts +0 -5
  670. package/transpiled/directives/vary/embeddings/index.js +0 -10
  671. package/transpiled/directives/vary/embeddings/index.js.map +0 -1
  672. package/transpiled/directives/vary/index.d.ts +0 -2
  673. package/transpiled/directives/vary/index.js +0 -6
  674. package/transpiled/directives/vary/index.js.map +0 -1
  675. /package/components/{identity.federation/operations → identity.tokens/operations/lib}/types.js +0 -0
  676. /package/schemas/octets/{list.cos.yaml → get.cos.yaml} +0 -0
  677. /package/{components/identity.tokens/operations → transpiled/directives/flow}/types.js +0 -0
  678. /package/transpiled/directives/{vary → map}/Directive.js +0 -0
package/source/Factory.ts CHANGED
@@ -1,14 +1,19 @@
1
+ import assert from 'node:assert'
2
+ import { decode } from '@toa.io/generic'
1
3
  import { Tenant } from './Tenant'
2
4
  import { Gateway } from './Gateway'
3
5
  import { Remotes } from './Remotes'
4
- import { Tree, syntax } from './RTD'
5
- import { Server } from './HTTP'
6
+ import { Tree } from './RTD'
6
7
  import { EndpointsFactory } from './Endpoint'
7
8
  import { families, interceptors } from './directives'
8
9
  import { DirectivesFactory } from './Directive'
9
10
  import { Composition } from './Composition'
10
11
  import * as root from './root'
11
12
  import { Interception } from './Interception'
13
+ import * as http from './HTTP'
14
+ import type { Manifest } from '@toa.io/norm'
15
+ import type { Branch } from './Branch'
16
+ import type { syntax } from './RTD'
12
17
  import type { Broadcast } from './Gateway'
13
18
  import type { Connector, Locator, extensions } from '@toa.io/core'
14
19
 
@@ -19,23 +24,27 @@ export class Factory implements extensions.Factory {
19
24
  this.boot = boot
20
25
  }
21
26
 
22
- public tenant (locator: Locator, node: syntax.Node): Connector {
27
+ public tenant (locator: Locator, node: syntax.Node, manifest: Manifest): Connector {
23
28
  const broadcast: Broadcast = this.boot.bindings.broadcast(CHANNEL, locator.id)
24
29
 
25
- return new Tenant(broadcast, locator, node)
30
+ const branch: Branch = {
31
+ namespace: locator.namespace,
32
+ component: locator.name,
33
+ isolated: locator.namespace === 'identity',
34
+ node,
35
+ version: manifest.version
36
+ }
37
+
38
+ return new Tenant(broadcast, branch)
26
39
  }
27
40
 
28
41
  public service (): Connector | null {
29
- const debug = process.env.TOA_EXPOSITION_DEBUG === '1'
30
- const trace = process.env.TOA_EXPOSITION_TRACE === '1'
31
- const broadcast: Broadcast = this.boot.bindings.broadcast(CHANNEL)
32
-
33
- const server = Server.create({
34
- methods: syntax.verbs,
35
- debug,
36
- trace
37
- })
42
+ assert.ok(process.env.TOA_EXPOSITION_PROPERTIES,
43
+ 'TOA_EXPOSITION_PROPERTIES is undefined')
38
44
 
45
+ const options = decode<http.Options>(process.env.TOA_EXPOSITION_PROPERTIES)
46
+ const broadcast: Broadcast = this.boot.bindings.broadcast(CHANNEL)
47
+ const server = http.Server.create({ ...options })
39
48
  const remotes = new Remotes(this.boot)
40
49
  const node = root.resolve()
41
50
  const methods = new EndpointsFactory(remotes)
package/source/Gateway.ts CHANGED
@@ -1,8 +1,10 @@
1
+ import assert from 'node:assert'
2
+ import { console } from 'openspan'
1
3
  import { type bindings, Connector } from '@toa.io/core'
2
4
  import * as http from './HTTP'
3
5
  import { rethrow } from './exceptions'
4
6
  import type { Interception } from './Interception'
5
- import type { Method, Parameter, Tree } from './RTD'
7
+ import type { Node, Method, Parameter, Tree, Match } from './RTD'
6
8
  import type { Label } from './discovery'
7
9
  import type { Branch } from './Branch'
8
10
 
@@ -10,6 +12,7 @@ export class Gateway extends Connector {
10
12
  private readonly broadcast: Broadcast
11
13
  private readonly tree: Tree
12
14
  private readonly interceptor: Interception
15
+ private readonly merged = new Set<string>()
13
16
 
14
17
  public constructor (broadcast: Broadcast, tree: Tree, interception: Interception) {
15
18
  super()
@@ -28,20 +31,20 @@ export class Gateway extends Connector {
28
31
  if (interception !== null)
29
32
  return interception
30
33
 
31
- const match = this.tree.match(context.url.pathname)
34
+ const { node, parameters } = this.match(context)
32
35
 
33
- if (match === null)
34
- throw new http.NotFound()
36
+ if (context.request.method === 'OPTIONS')
37
+ return await this.explain(node, parameters)
35
38
 
36
- const {
37
- node,
38
- parameters
39
- } = match
39
+ let verb = context.request.method
40
40
 
41
- if (!(context.request.method in node.methods))
41
+ if (!(verb in node.methods) && verb === 'HEAD' && 'GET' in node.methods)
42
+ verb = 'GET'
43
+
44
+ if (!(verb in node.methods))
42
45
  throw new http.MethodNotAllowed()
43
46
 
44
- const method = node.methods[context.request.method]
47
+ const method = node.methods[verb]
45
48
 
46
49
  const interruption = await context.timing.capture('preflight',
47
50
  method.directives.preflight(context, parameters)).catch(rethrow)
@@ -58,17 +61,41 @@ export class Gateway extends Connector {
58
61
  protected override async open (): Promise<void> {
59
62
  await this.discover()
60
63
 
61
- console.info('Gateway has started and is awaiting resource branches.')
64
+ console.info('Gateway started')
62
65
  }
63
66
 
64
67
  protected override dispose (): void {
65
- console.info('Gateway is closed.')
68
+ console.info('Gateway is closed')
66
69
  }
67
70
 
68
- private async call (method: Method, context: http.Context, parameters: Parameter[]):
69
- Promise<http.OutgoingMessage> {
71
+ private match (context: http.Context): Match {
72
+ const match = this.tree.match(context.url.pathname)
73
+
74
+ if (match === null)
75
+ throw new http.NotFound('Route not found')
76
+
77
+ if (match.node.forward === null)
78
+ return match
79
+
80
+ const destination = match.node.forward.replace(/\/:([^/]+)/g,
81
+ (_, name) => {
82
+ const value = match.parameters.find((parameter) => parameter.name === name)?.value
83
+
84
+ assert.ok(value !== undefined, `Forwarded parameter '${name}' not found`)
85
+
86
+ return `/${value}`
87
+ })
88
+
89
+ const forward = this.tree.match(destination)
90
+
91
+ assert.ok(forward !== null, 'Forwarded route not found')
92
+
93
+ return forward
94
+ }
95
+
96
+ private async call (method: Method, context: http.Context, parameters: Parameter[]): Promise<http.OutgoingMessage> {
70
97
  if (context.url.pathname[context.url.pathname.length - 1] !== '/')
71
- throw new http.NotFound('Trailing slash is required.')
98
+ throw new http.NotFound('Trailing slash is required')
72
99
 
73
100
  if (context.encoder === null)
74
101
  throw new http.NotAcceptable()
@@ -81,19 +108,46 @@ export class Gateway extends Connector {
81
108
  .catch(rethrow) as http.OutgoingMessage
82
109
  }
83
110
 
111
+ private async explain (node: Node, parameters: Parameter[]): Promise<http.OutgoingMessage> {
112
+ const body = await node.explain(parameters)
113
+ const allow = [...Object.keys(node.methods)].join(', ')
114
+ const headers = new Headers({ allow })
115
+
116
+ return { body, headers }
117
+ }
118
+
84
119
  private async discover (): Promise<void> {
85
120
  await this.broadcast.receive<Branch>('expose', this.merge.bind(this))
86
121
  await this.broadcast.transmit<null>('ping', null)
87
122
  }
88
123
 
89
124
  private merge (branch: Branch): void {
125
+ const id = branch.namespace + '.' + branch.component + '@' + branch.version
126
+
127
+ if (this.merged.has(id)) {
128
+ console.debug('Branch already merged, ignoring', {
129
+ namespace: branch.namespace,
130
+ component: branch.component,
131
+ version: branch.version
132
+ })
133
+
134
+ return
135
+ }
136
+
137
+ this.merged.add(id)
138
+
139
+ const attributes = {
140
+ namespace: branch.namespace,
141
+ component: branch.component,
142
+ version: branch.version
143
+ }
144
+
90
145
  try {
91
146
  this.tree.merge(branch.node, branch)
92
147
 
93
- console.info('Resource branch of ' +
94
- `'${branch.namespace}.${branch.component}' has been merged.`)
95
- } catch (exception) {
96
- console.error(exception)
148
+ console.info('Branch merged', attributes)
149
+ } catch (exception: unknown) {
150
+ console.error('Branch merge exception', { exception, ...attributes })
97
151
  }
98
152
  }
99
153
  }
@@ -1,4 +1,5 @@
1
1
  import Negotiator from 'negotiator'
2
+ import { console } from 'openspan'
2
3
  import { Timing } from './Timing'
3
4
  import { type Format, formats, types } from './formats'
4
5
  import { read } from './messages'
@@ -6,22 +7,27 @@ import type { OutgoingMessage } from './messages'
6
7
  import type * as http from 'node:http'
7
8
 
8
9
  export class Context {
10
+ public readonly authority: string
9
11
  public readonly request: IncomingMessage
10
12
  public readonly url: URL
11
13
  public readonly subtype: string | null = null
12
14
  public readonly encoder: Format | null = null
13
15
  public readonly timing: Timing
16
+ public readonly debug: boolean
14
17
 
15
18
  public readonly pipelines: Pipelines = {
16
19
  body: [],
17
20
  response: []
18
21
  }
19
22
 
20
- public constructor (request: IncomingMessage, trace = false) {
23
+ public constructor (authority: string, request: IncomingMessage, properties: Properties) {
24
+ this.authority = authority
21
25
  this.request = request
22
26
 
23
27
  this.url = new URL(request.url, `https://${request.headers.host}`)
24
- this.timing = new Timing(trace)
28
+ this.timing = new Timing(properties.trace)
29
+ this.debug = properties.debug
30
+ this.log(request)
25
31
 
26
32
  if (this.request.headers.accept !== undefined) {
27
33
  const match = SUBTYPE.exec(this.request.headers.accept)
@@ -46,11 +52,22 @@ export class Context {
46
52
  }
47
53
 
48
54
  public async body<T> (): Promise<T> {
49
- const value = await read(this)
55
+ let value = await read(this)
50
56
 
51
- return this.pipelines.body.length === 0
52
- ? value
53
- : this.pipelines.body.reduce((value, transform) => transform(value), value)
57
+ for (const transform of this.pipelines.body)
58
+ value = await transform(value)
59
+
60
+ return value
61
+ }
62
+
63
+ private log (request: IncomingMessage): void {
64
+ const headers = { ...request.headers }
65
+
66
+ if (headers.authorization !== undefined)
67
+ // only scheme
68
+ headers.authorization = headers.authorization.slice(0, headers.authorization.indexOf(' '))
69
+
70
+ console.debug('Received request', { method: request.method, url: request.url, headers })
54
71
  }
55
72
  }
56
73
 
@@ -61,7 +78,12 @@ export interface IncomingMessage extends http.IncomingMessage {
61
78
 
62
79
  interface Pipelines {
63
80
  body: Array<(input: unknown) => unknown>
64
- response: Array<(output: OutgoingMessage) => void>
81
+ response: Array<(output: OutgoingMessage) => void | Promise<void>>
82
+ }
83
+
84
+ interface Properties {
85
+ debug: boolean
86
+ trace: boolean
65
87
  }
66
88
 
67
89
  const SUBTYPE = /^(?<type>\w{1,32})\/(vnd\.toa\.(?<subtype>\S{1,32})\+)(?<suffix>\S{1,32})$/
@@ -1,10 +1,11 @@
1
+ import assert from 'node:assert'
1
2
  import fs from 'node:fs'
2
3
  import os from 'node:os'
3
4
  import * as http from 'node:http'
4
- import assert from 'node:assert'
5
5
  import { once } from 'node:events'
6
+ import { setTimeout } from 'node:timers/promises'
7
+ import { console } from 'openspan'
6
8
  import { Connector } from '@toa.io/core'
7
- import { promex } from '@toa.io/generic'
8
9
  import { type OutgoingMessage, write } from './messages'
9
10
  import { ClientError, Exception } from './exceptions'
10
11
  import { Context } from './Context'
@@ -13,83 +14,104 @@ import type { IncomingMessage } from './Context'
13
14
  export class Server extends Connector {
14
15
  private readonly server: http.Server = http.createServer()
15
16
  private readonly properties: Properties
16
- private process?: Processing
17
+ private readonly authorities: Record<string, string>
18
+ private process?: Processor
19
+ private ready: boolean = false
20
+ private startedAt: number = 0
17
21
 
18
22
  private constructor (properties: Properties) {
19
23
  super()
20
24
 
21
25
  this.properties = properties
22
-
26
+ this.authorities = Object.fromEntries(Object.entries(properties.authorities).map(([key, value]) => [value, key]))
23
27
  this.server.on('request', (req, res) => this.listener(req, res))
24
28
  }
25
29
 
26
- public get port (): number {
27
- if (this.properties.port !== 0)
28
- return this.properties.port
29
-
30
- const address = this.server.address()
31
-
32
- if (address === null || typeof address === 'string')
33
- throw new Error('Server is not listening on a port.')
34
-
35
- return address.port
36
- }
37
-
38
- public static create (options?: Partial<Properties>): Server {
39
- const properties = options === undefined
40
- ? DEFAULTS
41
- : { ...DEFAULTS, ...options }
30
+ public static create (options: Options): Server {
31
+ const properties: Properties = { ...DEFAULTS, ...options }
42
32
 
43
33
  return new Server(properties)
44
34
  }
45
35
 
46
- public attach (process: Processing): void {
36
+ public attach (process: Processor): void {
47
37
  this.process = process
48
38
  }
49
39
 
50
40
  protected override async open (): Promise<void> {
41
+ this.startedAt = Date.now()
51
42
  this.server.listen(this.properties.port)
52
43
 
53
44
  await once(this.server, 'listening')
54
45
 
55
- console.info('HTTP Server is listening.')
46
+ console.info('HTTP Server is listening')
47
+
48
+ await setTimeout(this.properties.delay)
49
+
50
+ this.ready = true
51
+
52
+ console.info('Ready')
56
53
  }
57
54
 
58
55
  protected override async close (): Promise<void> {
59
56
  this.server.close()
57
+ this.ready = false
60
58
 
61
- console.info('HTTP Server stopped accepting new connections.')
59
+ console.info('Stopped accepting new connections')
62
60
 
63
61
  await once(this.server, 'close')
64
62
 
65
- console.info('HTTP Server has been stopped.')
63
+ console.info('Stopped')
66
64
  }
67
65
 
68
66
  private listener (request: http.IncomingMessage, response: http.ServerResponse): void {
67
+ const invalid = validate(request)
68
+
69
+ if (invalid !== null) {
70
+ console.warn('Invalid request', errorAttributes(request, invalid))
71
+
72
+ response.writeHead(400).end()
73
+
74
+ return
75
+ }
76
+
77
+ request.on('error', (error) => console.warn('Request error', errorAttributes(request, error)))
78
+ response.on('error', (error) => console.warn('Response error', errorAttributes(request, error)))
79
+
69
80
  if (request.method === undefined || !this.properties.methods.has(request.method)) {
70
81
  response.writeHead(501).end()
71
82
 
72
83
  return
73
84
  }
74
85
 
75
- if (request.url === undefined) {
76
- response.writeHead(400).end()
86
+ if (request.url === '/.ready') {
87
+ if (this.ready)
88
+ response.writeHead(200, { 'cache-control': 'no-store' }).end()
89
+ else {
90
+ const remaining = (Math.ceil((Date.now() - this.startedAt) / 1000)).toString()
91
+
92
+ response.writeHead(503, { 'retry-after': remaining }).end()
93
+ }
77
94
 
78
95
  return
79
96
  }
80
97
 
81
- assert.ok(this.process !== undefined,
82
- 'No processing function has been attached to the server.')
98
+ assert(this.process !== undefined, 'Request processor is not attached')
83
99
 
84
- const context = new Context(request as IncomingMessage, this.properties.trace)
100
+ const host = request.headers.host!
101
+ const authority = this.authorities[host] ?? host
102
+ const context = new Context(authority, request as IncomingMessage, this.properties)
85
103
 
86
104
  this.process(context)
87
105
  .then(this.success(context, response))
88
106
  .catch(this.fail(context, response))
107
+ .finally(() => {
108
+ request.removeAllListeners('error')
109
+ response.removeAllListeners('error')
110
+ })
89
111
  }
90
112
 
91
113
  private success (context: Context, response: http.ServerResponse) {
92
- return (message: OutgoingMessage) => {
114
+ return async (message: OutgoingMessage) => {
93
115
  let status = message.status
94
116
 
95
117
  if (status === undefined)
@@ -97,13 +119,13 @@ export class Server extends Connector {
97
119
  status = 404
98
120
  else if (context.request.method === 'POST')
99
121
  status = 201
100
- else if (message.body === undefined)
122
+ else if (message.body === undefined && context.request.method !== 'HEAD')
101
123
  status = 204
102
124
  else
103
125
  status = 200
104
126
 
105
127
  response.statusCode = message.status = status
106
- write(context, response, message)
128
+ await write(context, response, message)
107
129
  }
108
130
  }
109
131
 
@@ -112,47 +134,88 @@ export class Server extends Connector {
112
134
  if (!context.request.complete)
113
135
  await adam(context.request)
114
136
 
115
- response.statusCode = exception instanceof Exception
116
- ? exception.status
117
- : 500
137
+ response.statusCode = exception instanceof Exception ? exception.status : 500
118
138
 
119
139
  const message: OutgoingMessage = { status: response.statusCode }
120
- const verbose = exception instanceof ClientError || this.properties.debug
121
140
 
122
- if (verbose)
123
- message.body = exception instanceof Exception
124
- ? exception.body
125
- : (exception.stack ?? exception.message)
141
+ if (context.encoder === null)
142
+ message.body = undefined
143
+ else if (exception instanceof ClientError || this.properties.debug)
144
+ message.body =
145
+ exception instanceof Exception
146
+ ? exception.body
147
+ : exception.stack ?? exception.message
126
148
 
127
- write(context, response, message)
149
+ await write(context, response, message)
128
150
  }
129
151
  }
130
152
  }
131
153
 
154
+ function validate (request: http.IncomingMessage): null | Error {
155
+ try {
156
+ void new URL(request.url!, `https://${request.headers.host}`)
157
+
158
+ return null
159
+ } catch (error) {
160
+ return error as Error
161
+ }
162
+ }
163
+
132
164
  // https://github.com/whatwg/fetch/issues/1254
133
165
  async function adam (request: http.IncomingMessage): Promise<void> {
134
- const completed = promex()
135
166
  const devnull = fs.createWriteStream(os.devNull)
136
167
 
137
- request
138
- .on('end', completed.callback)
139
- .pipe(devnull)
168
+ request.pipe(devnull)
169
+
170
+ await once(request, 'end')
171
+ }
172
+
173
+ function errorAttributes (request: http.IncomingMessage, error: Error & any): RequestErrorAttributes {
174
+ const attributes: RequestErrorAttributes = {
175
+ path: request.url!,
176
+ method: request.method!,
177
+ name: error.name
178
+ }
179
+
180
+ if (typeof error.code === 'string')
181
+ attributes.code = error.code
140
182
 
141
- return completed
183
+ if (typeof error.stack === 'string')
184
+ attributes.stack = error.stack
185
+
186
+ return attributes
142
187
  }
143
188
 
144
- const DEFAULTS: Properties = {
145
- methods: new Set<string>(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS']),
189
+ export const PORT = 8000
190
+ export const DELAY = 3 // seconds
191
+
192
+ const DEFAULTS: Omit<Properties, 'authorities'> = {
193
+ methods: new Set<string>(['OPTIONS', 'GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'DELETE', 'LOCK', 'UNLOCK']),
146
194
  debug: false,
147
195
  trace: false,
148
- port: 8000
196
+ port: PORT,
197
+ delay: DELAY * 1000
149
198
  }
150
199
 
151
200
  interface Properties {
201
+ authorities: Record<string, string>
152
202
  methods: Set<string>
153
203
  debug: boolean
154
204
  trace: boolean
155
205
  port: number
206
+ delay: number
156
207
  }
157
208
 
158
- export type Processing = (input: Context) => Promise<OutgoingMessage>
209
+ export type Options = { authorities: Properties['authorities'] } & {
210
+ [K in Exclude<keyof Properties, 'authorities'>]?: Properties[K]
211
+ }
212
+
213
+ export type Processor = (input: Context) => Promise<OutgoingMessage>
214
+
215
+ interface RequestErrorAttributes {
216
+ path: string
217
+ method: string
218
+ name: string
219
+ code?: string
220
+ stack?: string
221
+ }
@@ -37,11 +37,17 @@ export class NotFound extends ClientError {
37
37
  }
38
38
 
39
39
  export class Conflict extends ClientError {
40
- public constructor (body: any) {
40
+ public constructor (body?: any) {
41
41
  super(409, body)
42
42
  }
43
43
  }
44
44
 
45
+ export class UnprocessableEntity extends ClientError {
46
+ public constructor (body?: any) {
47
+ super(422, body)
48
+ }
49
+ }
50
+
45
51
  export class MethodNotAllowed extends ClientError {
46
52
  public constructor () {
47
53
  super(405)
@@ -65,3 +71,9 @@ export class PreconditionFailed extends ClientError {
65
71
  super(412)
66
72
  }
67
73
  }
74
+
75
+ export class RequestEntityTooLarge extends ClientError {
76
+ public constructor (body?: any) {
77
+ super(413, body)
78
+ }
79
+ }
@@ -5,10 +5,10 @@ import * as msgpack from './msgpack'
5
5
  import * as text from './text'
6
6
 
7
7
  export const formats: Record<string, Format> = {
8
- [msgpack.type]: msgpack,
9
- [yaml.type]: yaml,
10
8
  [json.type]: json,
11
- [text.type]: text
9
+ [yaml.type]: yaml,
10
+ [text.type]: text,
11
+ [msgpack.type]: msgpack
12
12
  }
13
13
 
14
14
  export const types = Object.keys(formats)
@@ -1,9 +1,13 @@
1
- import { Readable } from 'node:stream'
1
+ import { PassThrough, Readable } from 'node:stream'
2
+ import * as streamConsumers from 'node:stream/consumers'
3
+ import { once } from 'node:events'
2
4
  import { generate } from 'randomstring'
3
5
  import * as msgpack from 'msgpackr'
4
- import { read } from './messages'
6
+ import { multipart, read, type OutgoingMessage } from './messages'
5
7
  import { BadRequest, UnsupportedMediaType } from './exceptions'
8
+ import { formats } from './formats'
6
9
  import { Timing } from './Timing'
10
+ import type * as http from 'node:http'
7
11
  import type { Context } from './Context'
8
12
 
9
13
  beforeEach(() => {
@@ -69,6 +73,45 @@ describe('read', () => {
69
73
 
70
74
  await expect(read(request)).rejects.toThrow(BadRequest)
71
75
  })
76
+
77
+ it('should output correct mulitpart format', async () => {
78
+ const response = new class extends PassThrough {
79
+ public readonly headers = new Headers()
80
+
81
+ public setHeader (key: string, value: string): this {
82
+ this.headers.set(key, value)
83
+
84
+ return this
85
+ }
86
+ }()
87
+
88
+ const context = { encoder: formats['text/plain'] } as unknown as Context
89
+ const message = { body: Readable.from(['Hello', 'New', 'World']) } as unknown as OutgoingMessage
90
+
91
+ multipart(message, context, response as unknown as http.ServerResponse)
92
+
93
+ await once(message.body, 'end')
94
+
95
+ const result = await streamConsumers.text(response)
96
+
97
+ expect(result).toBe([
98
+ '--cut',
99
+ '',
100
+ 'ACK',
101
+ '--cut',
102
+ '',
103
+ 'Hello',
104
+ '--cut',
105
+ '',
106
+ 'New',
107
+ '--cut',
108
+ '',
109
+ 'World',
110
+ '--cut',
111
+ '',
112
+ 'FIN',
113
+ '--cut--'].join('\r\n'))
114
+ })
72
115
  })
73
116
 
74
117
  export function createContext
@@ -82,6 +125,7 @@ jest.MockedObject<Context> {
82
125
  url,
83
126
  headers
84
127
  }) as unknown as Context['request'],
128
+ url: new URL(url, 'https://host.local'),
85
129
  timing: new Timing(false)
86
130
  }
87
131