@toa.io/extensions.exposition 1.0.0-alpha.282 → 1.0.0-alpha.284

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 (667) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/components/exposition.octets/manifest.toa.yaml +11 -0
  3. package/components/exposition.octets/types/index.d.ts +3 -0
  4. package/components/exposition.octets/types/toa.d.ts +41 -0
  5. package/components/identity.bans/operations/transit.js +1 -1
  6. package/components/identity.bans/tsconfig.json +1 -1
  7. package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
  8. package/components/identity.bans/types/index.d.ts +3 -0
  9. package/components/identity.bans/types/toa.d.ts +34 -0
  10. package/components/identity.basic/manifest.toa.yaml +13 -2
  11. package/components/identity.basic/operations/add.js +1 -1
  12. package/components/identity.basic/operations/authenticate.js +1 -1
  13. package/components/identity.basic/operations/check.js +1 -1
  14. package/components/identity.basic/operations/delete.js +1 -1
  15. package/components/identity.basic/operations/incept.js +18 -2
  16. package/components/identity.basic/operations/info.js +1 -1
  17. package/components/identity.basic/operations/lib/credentials.js +1 -1
  18. package/components/identity.basic/operations/transit.js +3 -2
  19. package/components/identity.basic/source/add.ts +3 -3
  20. package/components/identity.basic/source/authenticate.ts +2 -2
  21. package/components/identity.basic/source/check.ts +1 -1
  22. package/components/identity.basic/source/delete.ts +2 -2
  23. package/components/identity.basic/source/incept.ts +31 -3
  24. package/components/identity.basic/source/info.ts +1 -1
  25. package/components/identity.basic/source/transit.ts +6 -4
  26. package/components/identity.basic/tsconfig.json +1 -1
  27. package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
  28. package/components/identity.basic/types/index.d.ts +22 -0
  29. package/components/identity.basic/types/toa.d.ts +121 -0
  30. package/components/identity.clients/manifest.toa.yaml +243 -0
  31. package/components/identity.clients/operations/describe.js +44 -0
  32. package/components/identity.clients/operations/lib/Context.js +2 -0
  33. package/components/identity.clients/operations/lib/Entity.js +2 -0
  34. package/components/identity.clients/operations/lib/canonical.js +24 -0
  35. package/components/identity.clients/operations/lib/cimd.js +86 -0
  36. package/components/identity.clients/operations/lib/errors.js +5 -0
  37. package/components/identity.clients/operations/lib/index.js +7 -0
  38. package/components/identity.clients/operations/lib/redirect.js +32 -0
  39. package/components/identity.clients/operations/register.js +84 -0
  40. package/components/identity.clients/source/describe.ts +65 -0
  41. package/components/identity.clients/source/lib/Context.ts +38 -0
  42. package/components/identity.clients/source/lib/Entity.ts +31 -0
  43. package/components/identity.clients/source/lib/canonical.test.ts +43 -0
  44. package/components/identity.clients/source/lib/canonical.ts +27 -0
  45. package/components/identity.clients/source/lib/cimd.test.ts +120 -0
  46. package/components/identity.clients/source/lib/cimd.ts +107 -0
  47. package/components/identity.clients/source/lib/errors.ts +4 -0
  48. package/components/identity.clients/source/lib/index.ts +6 -0
  49. package/components/identity.clients/source/lib/redirect.test.ts +41 -0
  50. package/components/identity.clients/source/lib/redirect.ts +35 -0
  51. package/components/identity.clients/source/register.ts +125 -0
  52. package/components/identity.clients/tsconfig.json +10 -0
  53. package/components/identity.clients/tsconfig.tsbuildinfo +1 -0
  54. package/components/identity.clients/types/index.d.ts +3 -0
  55. package/components/identity.clients/types/toa.d.ts +109 -0
  56. package/components/identity.credentials/operations/list.js +1 -1
  57. package/components/identity.credentials/source/list.ts +2 -1
  58. package/components/identity.credentials/tsconfig.json +4 -2
  59. package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
  60. package/components/identity.credentials/types/index.d.ts +3 -0
  61. package/components/identity.credentials/types/toa.d.ts +30 -0
  62. package/components/identity.federation/manifest.toa.yaml +37 -1
  63. package/components/identity.federation/operations/authenticate.js +7 -3
  64. package/components/identity.federation/operations/create.js +1 -1
  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 +6 -2
  68. package/components/identity.federation/operations/lib/Configuration.js +1 -1
  69. package/components/identity.federation/operations/lib/Ctx.js +1 -1
  70. package/components/identity.federation/operations/lib/Payload.js +1 -1
  71. package/components/identity.federation/operations/lib/decode.js +23 -9
  72. package/components/identity.federation/operations/lib/discovery.js +1 -1
  73. package/components/identity.federation/operations/lib/errors.js +5 -1
  74. package/components/identity.federation/operations/lib/exchange.js +12 -7
  75. package/components/identity.federation/operations/lib/index.js +2 -1
  76. package/components/identity.federation/operations/lib/jose.js +1 -1
  77. package/components/identity.federation/operations/lib/principal.js +14 -0
  78. package/components/identity.federation/operations/lib/resolve.js +1 -1
  79. package/components/identity.federation/operations/list.js +1 -1
  80. package/components/identity.federation/operations/types/Scheme.js +1 -1
  81. package/components/identity.federation/operations/types/configuration.js +1 -1
  82. package/components/identity.federation/operations/types/context.js +1 -1
  83. package/components/identity.federation/operations/types/entity.js +1 -1
  84. package/components/identity.federation/operations/types/index.js +1 -1
  85. package/components/identity.federation/source/authenticate.ts +9 -3
  86. package/components/identity.federation/source/incept.ts +7 -1
  87. package/components/identity.federation/source/lib/Ctx.ts +2 -2
  88. package/components/identity.federation/source/lib/decode.ts +25 -9
  89. package/components/identity.federation/source/lib/errors.ts +5 -0
  90. package/components/identity.federation/source/lib/exchange.ts +11 -7
  91. package/components/identity.federation/source/lib/index.ts +1 -0
  92. package/components/identity.federation/source/lib/principal.ts +17 -0
  93. package/components/identity.federation/source/types/configuration.ts +1 -1
  94. package/components/identity.federation/source/types/context.ts +6 -2
  95. package/components/identity.federation/tsconfig.json +4 -2
  96. package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
  97. package/components/identity.federation/types/index.d.ts +3 -0
  98. package/components/identity.federation/types/toa.d.ts +127 -0
  99. package/components/identity.grants/manifest.toa.yaml +245 -0
  100. package/components/identity.grants/operations/authorize.js +54 -0
  101. package/components/identity.grants/operations/exchange.js +89 -0
  102. package/components/identity.grants/operations/lib/code.js +30 -0
  103. package/components/identity.grants/operations/lib/identify.js +15 -0
  104. package/components/identity.grants/operations/lib/index.js +3 -0
  105. package/components/identity.grants/operations/list.js +18 -0
  106. package/components/identity.grants/operations/revoke.js +25 -0
  107. package/components/identity.grants/source/authorize.ts +90 -0
  108. package/components/identity.grants/source/exchange.ts +130 -0
  109. package/components/identity.grants/source/lib/code.ts +39 -0
  110. package/components/identity.grants/source/lib/identify.ts +16 -0
  111. package/components/identity.grants/source/lib/index.ts +3 -0
  112. package/components/identity.grants/source/list.ts +28 -0
  113. package/components/identity.grants/source/revoke.ts +38 -0
  114. package/components/identity.grants/tsconfig.json +10 -0
  115. package/components/identity.grants/tsconfig.tsbuildinfo +1 -0
  116. package/components/identity.grants/types/index.d.ts +60 -0
  117. package/components/identity.grants/types/toa.d.ts +108 -0
  118. package/components/identity.keys/manifest.toa.yaml +1 -0
  119. package/components/identity.keys/operations/create.js +1 -1
  120. package/components/identity.keys/operations/disable.js +1 -1
  121. package/components/identity.keys/operations/revoke.js +1 -1
  122. package/components/identity.keys/source/create.ts +1 -1
  123. package/components/identity.keys/source/revoke.ts +1 -1
  124. package/components/identity.keys/tsconfig.json +1 -1
  125. package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
  126. package/components/identity.keys/types/index.d.ts +3 -0
  127. package/components/identity.keys/types/toa.d.ts +47 -0
  128. package/components/identity.otp/operations/authenticate.js +1 -1
  129. package/components/identity.otp/operations/issue.js +1 -1
  130. package/components/identity.otp/operations/lib/Context.js +1 -1
  131. package/components/identity.otp/operations/lib/Entity.js +1 -1
  132. package/components/identity.otp/operations/lib/index.js +1 -1
  133. package/components/identity.otp/source/lib/Context.ts +4 -2
  134. package/components/identity.otp/tsconfig.json +1 -1
  135. package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
  136. package/components/identity.otp/types/index.d.ts +3 -0
  137. package/components/identity.otp/types/toa.d.ts +56 -0
  138. package/components/identity.passkeys/manifest.toa.yaml +3 -0
  139. package/components/identity.passkeys/operations/authenticate.js +1 -1
  140. package/components/identity.passkeys/operations/challenge.js +1 -1
  141. package/components/identity.passkeys/operations/create.js +1 -1
  142. package/components/identity.passkeys/operations/delete.js +1 -1
  143. package/components/identity.passkeys/operations/lib/const.js +1 -1
  144. package/components/identity.passkeys/operations/list.js +1 -1
  145. package/components/identity.passkeys/operations/types/Configuration.js +1 -1
  146. package/components/identity.passkeys/operations/types/Context.js +1 -1
  147. package/components/identity.passkeys/operations/types/Passkey.js +1 -1
  148. package/components/identity.passkeys/operations/types/index.js +1 -1
  149. package/components/identity.passkeys/operations/use.js +1 -1
  150. package/components/identity.passkeys/source/authenticate.ts +1 -1
  151. package/components/identity.passkeys/source/challenge.ts +1 -1
  152. package/components/identity.passkeys/source/create.ts +1 -1
  153. package/components/identity.passkeys/source/types/Context.ts +2 -1
  154. package/components/identity.passkeys/source/use.ts +1 -1
  155. package/components/identity.passkeys/tsconfig.json +1 -1
  156. package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
  157. package/components/identity.passkeys/types/index.d.ts +3 -0
  158. package/components/identity.passkeys/types/toa.d.ts +120 -0
  159. package/components/identity.roles/operations/grant.js +1 -1
  160. package/components/identity.roles/operations/lib/Entity.js +1 -1
  161. package/components/identity.roles/operations/list.js +1 -1
  162. package/components/identity.roles/operations/principal.js +29 -5
  163. package/components/identity.roles/source/principal.ts +33 -5
  164. package/components/identity.roles/tsconfig.json +1 -1
  165. package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
  166. package/components/identity.roles/types/index.d.ts +3 -0
  167. package/components/identity.roles/types/toa.d.ts +43 -0
  168. package/components/identity.tokens/manifest.toa.yaml +34 -3
  169. package/components/identity.tokens/operations/authenticate.js +9 -1
  170. package/components/identity.tokens/operations/decrypt.js +3 -3
  171. package/components/identity.tokens/operations/encrypt.js +1 -1
  172. package/components/identity.tokens/operations/issue.js +3 -2
  173. package/components/identity.tokens/operations/lib/form.js +24 -0
  174. package/components/identity.tokens/operations/lib/index.js +2 -2
  175. package/components/identity.tokens/operations/lib/jose.js +1 -1
  176. package/components/identity.tokens/operations/lib/key.js +1 -1
  177. package/components/identity.tokens/operations/lib/pad.js +1 -1
  178. package/components/identity.tokens/operations/revoke.js +1 -1
  179. package/components/identity.tokens/source/authenticate.test.ts +8 -5
  180. package/components/identity.tokens/source/authenticate.ts +12 -1
  181. package/components/identity.tokens/source/decrypt.test.ts +1 -1
  182. package/components/identity.tokens/source/decrypt.ts +4 -3
  183. package/components/identity.tokens/source/encrypt.test.ts +1 -1
  184. package/components/identity.tokens/source/encrypt.ts +2 -1
  185. package/components/identity.tokens/source/issue.test.ts +71 -0
  186. package/components/identity.tokens/source/issue.ts +4 -2
  187. package/components/identity.tokens/source/lib/form.test.ts +25 -0
  188. package/components/identity.tokens/source/lib/form.ts +31 -0
  189. package/components/identity.tokens/source/lib/index.ts +2 -1
  190. package/components/identity.tokens/tsconfig.json +1 -1
  191. package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
  192. package/components/identity.tokens/types/index.d.ts +61 -0
  193. package/components/identity.tokens/types/toa.d.ts +113 -0
  194. package/documentation/access.md +13 -0
  195. package/documentation/cache.md +10 -1
  196. package/documentation/components.md +3 -0
  197. package/documentation/consent.md +101 -0
  198. package/documentation/identity.md +3 -1
  199. package/documentation/introspection.md +13 -5
  200. package/documentation/io.md +42 -2
  201. package/documentation/map.md +8 -0
  202. package/documentation/mcp.md +180 -0
  203. package/documentation/oauth.md +180 -0
  204. package/documentation/protocol.md +4 -0
  205. package/documentation/rpc.md +140 -0
  206. package/documentation/tree.md +3 -0
  207. package/features/auth.bearer.feature +120 -0
  208. package/features/cache.feature +46 -0
  209. package/features/identity.basic.feature +44 -0
  210. package/features/identity.federation.feature +2 -5
  211. package/features/introspection.feature +333 -0
  212. package/features/mcp.feature +687 -0
  213. package/features/oauth.clients.feature +195 -0
  214. package/features/oauth.discovery.feature +164 -0
  215. package/features/oauth.grants.feature +299 -0
  216. package/features/octets.cloudinary.feature +1 -0
  217. package/features/rpc.feature +429 -0
  218. package/features/steps/Cloudinary.ts +13 -0
  219. package/features/steps/Components.ts +0 -4
  220. package/features/steps/Gateway.ts +23 -2
  221. package/features/steps/Parameters.ts +22 -7
  222. package/features/steps/Realtime.ts +3 -0
  223. package/features/steps/components/echo/manifest.toa.yaml +3 -0
  224. package/features/steps/components/octets.tester/manifest.toa.yaml +2 -0
  225. package/features/steps/components/octets.tester/operations/redirect.js +6 -1
  226. package/features/steps/components/pots/manifest.toa.yaml +2 -0
  227. package/features/steps/components/users/manifest.toa.yaml +1 -0
  228. package/package.json +8 -6
  229. package/readme.md +6 -0
  230. package/schemas/annotation.cos.yaml +63 -0
  231. package/schemas/call.cos.yaml +18 -0
  232. package/source/Annotation.ts +54 -0
  233. package/source/Directive.test.ts +15 -15
  234. package/source/Directive.ts +77 -9
  235. package/source/Endpoint.test.ts +67 -0
  236. package/source/Endpoint.ts +31 -11
  237. package/source/Factory.ts +6 -2
  238. package/source/Gateway.ts +73 -11
  239. package/source/HTTP/Context.ts +7 -0
  240. package/source/HTTP/Server.ts +15 -5
  241. package/source/HTTP/exceptions.ts +2 -2
  242. package/source/HTTP/formats/form.ts +21 -0
  243. package/source/HTTP/formats/index.ts +17 -2
  244. package/source/HTTP/messages.test.ts +25 -1
  245. package/source/HTTP/messages.ts +20 -4
  246. package/source/Interception.ts +8 -2
  247. package/source/Introspection.ts +102 -0
  248. package/source/MCP/Server.ts +275 -0
  249. package/source/MCP/discover.ts +52 -0
  250. package/source/MCP/errors.ts +81 -0
  251. package/source/MCP/index.ts +1 -0
  252. package/source/MCP/schema.test.ts +85 -0
  253. package/source/MCP/schema.ts +87 -0
  254. package/source/MCP/tools.ts +156 -0
  255. package/source/MCP/types.ts +81 -0
  256. package/source/Query.ts +48 -8
  257. package/source/RPC/Context.ts +78 -0
  258. package/source/RPC/Dispatcher.ts +130 -0
  259. package/source/RPC/errors.test.ts +52 -0
  260. package/source/RPC/errors.ts +83 -0
  261. package/source/RPC/index.ts +1 -0
  262. package/source/RPC/names.test.ts +122 -0
  263. package/source/RPC/names.ts +182 -0
  264. package/source/RPC/types.ts +34 -0
  265. package/source/RTD/Directives.ts +52 -2
  266. package/source/RTD/Endpoint.ts +2 -1
  267. package/source/RTD/Method.ts +14 -11
  268. package/source/RTD/Node.ts +38 -7
  269. package/source/RTD/Route.ts +30 -3
  270. package/source/RTD/Tree.ts +37 -1
  271. package/source/RTD/expiration.test.ts +1 -1
  272. package/source/RTD/walk.test.ts +110 -0
  273. package/source/const.ts +15 -0
  274. package/source/deployment.ts +11 -1
  275. package/source/directives/auth/Anonymous.test.ts +38 -0
  276. package/source/directives/auth/Anonymous.ts +12 -0
  277. package/source/directives/auth/Anyone.ts +4 -0
  278. package/source/directives/auth/Authorization.ts +108 -22
  279. package/source/directives/auth/Delegate.test.ts +36 -0
  280. package/source/directives/auth/Delegate.ts +14 -0
  281. package/source/directives/auth/Echo.ts +5 -0
  282. package/source/directives/auth/Incept.ts +16 -10
  283. package/source/directives/auth/Role.ts +13 -0
  284. package/source/directives/auth/Rule.ts +29 -0
  285. package/source/directives/auth/Scheme.ts +5 -0
  286. package/source/directives/auth/schemes.test.ts +8 -4
  287. package/source/directives/auth/schemes.ts +22 -9
  288. package/source/directives/auth/types.ts +26 -2
  289. package/source/directives/cache/Cache.ts +14 -5
  290. package/source/directives/cache/Control.ts +0 -3
  291. package/source/directives/dev/Development.ts +1 -1
  292. package/source/directives/flow/Fetch.ts +1 -1
  293. package/source/directives/flow/Flow.ts +1 -1
  294. package/source/directives/index.ts +5 -2
  295. package/source/directives/io/Directive.ts +1 -1
  296. package/source/directives/io/IO.ts +34 -3
  297. package/source/directives/io/Input.ts +3 -2
  298. package/source/directives/io/Output.ts +10 -4
  299. package/source/directives/io/Status.test.ts +84 -0
  300. package/source/directives/io/Status.ts +46 -0
  301. package/source/directives/io/Throttle.ts +1 -1
  302. package/source/directives/io/lib/throttle/Quotas.ts +2 -2
  303. package/source/directives/map/Headers.ts +11 -0
  304. package/source/directives/map/Map.ts +10 -1
  305. package/source/directives/map/Mapping.ts +23 -0
  306. package/source/directives/map/Segments.ts +12 -0
  307. package/source/directives/mcp/MCP.ts +33 -0
  308. package/source/directives/mcp/Tool.test.ts +66 -0
  309. package/source/directives/mcp/Tool.ts +28 -0
  310. package/source/directives/mcp/index.ts +6 -0
  311. package/source/directives/oauth/Discovery.ts +70 -0
  312. package/source/directives/oauth/documents.ts +113 -0
  313. package/source/directives/oauth/index.ts +3 -0
  314. package/source/directives/octets/Delete.ts +1 -1
  315. package/source/directives/octets/Get.ts +1 -1
  316. package/source/directives/octets/Octets.ts +1 -1
  317. package/source/directives/octets/Workflow.ts +1 -1
  318. package/source/directives/octets/workflows/Execution.ts +1 -1
  319. package/source/directives/require/Directive.ts +1 -1
  320. package/source/directives/require/Headers.ts +1 -1
  321. package/source/directives/require/Require.ts +2 -2
  322. package/source/index.ts +6 -0
  323. package/source/octets.d.ts +17 -0
  324. package/source/schemas.ts +2 -0
  325. package/source/userland.ts +47 -0
  326. package/transpiled/Annotation.d.ts +41 -0
  327. package/transpiled/Directive.d.ts +18 -1
  328. package/transpiled/Directive.js +50 -6
  329. package/transpiled/Directive.js.map +1 -1
  330. package/transpiled/Endpoint.d.ts +9 -0
  331. package/transpiled/Endpoint.js +27 -11
  332. package/transpiled/Endpoint.js.map +1 -1
  333. package/transpiled/Factory.js +6 -2
  334. package/transpiled/Factory.js.map +1 -1
  335. package/transpiled/Gateway.d.ts +19 -2
  336. package/transpiled/Gateway.js +51 -9
  337. package/transpiled/Gateway.js.map +1 -1
  338. package/transpiled/HTTP/Context.d.ts +6 -0
  339. package/transpiled/HTTP/Context.js +6 -0
  340. package/transpiled/HTTP/Context.js.map +1 -1
  341. package/transpiled/HTTP/Server.d.ts +8 -1
  342. package/transpiled/HTTP/Server.js +4 -3
  343. package/transpiled/HTTP/Server.js.map +1 -1
  344. package/transpiled/HTTP/exceptions.d.ts +1 -1
  345. package/transpiled/HTTP/exceptions.js +2 -2
  346. package/transpiled/HTTP/exceptions.js.map +1 -1
  347. package/transpiled/HTTP/formats/form.d.ts +9 -0
  348. package/transpiled/HTTP/formats/form.js +18 -0
  349. package/transpiled/HTTP/formats/form.js.map +1 -0
  350. package/transpiled/HTTP/formats/index.d.ts +10 -2
  351. package/transpiled/HTTP/formats/index.js +10 -0
  352. package/transpiled/HTTP/formats/index.js.map +1 -1
  353. package/transpiled/HTTP/messages.d.ts +12 -0
  354. package/transpiled/HTTP/messages.js +12 -4
  355. package/transpiled/HTTP/messages.js.map +1 -1
  356. package/transpiled/Interception.d.ts +4 -1
  357. package/transpiled/Interception.js +4 -2
  358. package/transpiled/Interception.js.map +1 -1
  359. package/transpiled/Introspection.d.ts +40 -0
  360. package/transpiled/Introspection.js +50 -1
  361. package/transpiled/Introspection.js.map +1 -1
  362. package/transpiled/MCP/Server.d.ts +41 -0
  363. package/transpiled/MCP/Server.js +180 -0
  364. package/transpiled/MCP/Server.js.map +1 -0
  365. package/transpiled/MCP/discover.d.ts +13 -0
  366. package/transpiled/MCP/discover.js +29 -0
  367. package/transpiled/MCP/discover.js.map +1 -0
  368. package/transpiled/MCP/errors.d.ts +24 -0
  369. package/transpiled/MCP/errors.js +67 -0
  370. package/transpiled/MCP/errors.js.map +1 -0
  371. package/transpiled/MCP/index.d.ts +1 -0
  372. package/transpiled/MCP/index.js +2 -0
  373. package/transpiled/MCP/index.js.map +1 -0
  374. package/transpiled/MCP/schema.d.ts +18 -0
  375. package/transpiled/MCP/schema.js +64 -0
  376. package/transpiled/MCP/schema.js.map +1 -0
  377. package/transpiled/MCP/tools.d.ts +31 -0
  378. package/transpiled/MCP/tools.js +121 -0
  379. package/transpiled/MCP/tools.js.map +1 -0
  380. package/transpiled/MCP/types.d.ts +64 -0
  381. package/transpiled/MCP/types.js +13 -0
  382. package/transpiled/MCP/types.js.map +1 -0
  383. package/transpiled/Query.d.ts +7 -0
  384. package/transpiled/Query.js +38 -7
  385. package/transpiled/Query.js.map +1 -1
  386. package/transpiled/RPC/Context.d.ts +11 -0
  387. package/transpiled/RPC/Context.js +63 -0
  388. package/transpiled/RPC/Context.js.map +1 -0
  389. package/transpiled/RPC/Dispatcher.d.ts +19 -0
  390. package/transpiled/RPC/Dispatcher.js +100 -0
  391. package/transpiled/RPC/Dispatcher.js.map +1 -0
  392. package/transpiled/RPC/errors.d.ts +18 -0
  393. package/transpiled/RPC/errors.js +67 -0
  394. package/transpiled/RPC/errors.js.map +1 -0
  395. package/transpiled/RPC/index.d.ts +1 -0
  396. package/transpiled/RPC/index.js +2 -0
  397. package/transpiled/RPC/index.js.map +1 -0
  398. package/transpiled/RPC/names.d.ts +30 -0
  399. package/transpiled/RPC/names.js +121 -0
  400. package/transpiled/RPC/names.js.map +1 -0
  401. package/transpiled/RPC/types.d.ts +27 -0
  402. package/transpiled/RPC/types.js +8 -0
  403. package/transpiled/RPC/types.js.map +1 -0
  404. package/transpiled/RTD/Directives.d.ts +41 -2
  405. package/transpiled/RTD/Endpoint.d.ts +2 -1
  406. package/transpiled/RTD/Method.d.ts +8 -3
  407. package/transpiled/RTD/Method.js +12 -10
  408. package/transpiled/RTD/Method.js.map +1 -1
  409. package/transpiled/RTD/Node.d.ts +20 -2
  410. package/transpiled/RTD/Node.js +22 -4
  411. package/transpiled/RTD/Node.js.map +1 -1
  412. package/transpiled/RTD/Route.d.ts +2 -1
  413. package/transpiled/RTD/Route.js +27 -2
  414. package/transpiled/RTD/Route.js.map +1 -1
  415. package/transpiled/RTD/Tree.d.ts +3 -1
  416. package/transpiled/RTD/Tree.js +26 -0
  417. package/transpiled/RTD/Tree.js.map +1 -1
  418. package/transpiled/const.d.ts +12 -0
  419. package/transpiled/const.js +12 -0
  420. package/transpiled/const.js.map +1 -1
  421. package/transpiled/deployment.js +6 -0
  422. package/transpiled/deployment.js.map +1 -1
  423. package/transpiled/directives/auth/Anonymous.d.ts +6 -0
  424. package/transpiled/directives/auth/Anonymous.js +10 -0
  425. package/transpiled/directives/auth/Anonymous.js.map +1 -1
  426. package/transpiled/directives/auth/Anyone.d.ts +1 -0
  427. package/transpiled/directives/auth/Anyone.js +3 -0
  428. package/transpiled/directives/auth/Anyone.js.map +1 -1
  429. package/transpiled/directives/auth/Authorization.d.ts +28 -2
  430. package/transpiled/directives/auth/Authorization.js +87 -19
  431. package/transpiled/directives/auth/Authorization.js.map +1 -1
  432. package/transpiled/directives/auth/Delegate.d.ts +5 -0
  433. package/transpiled/directives/auth/Delegate.js +10 -0
  434. package/transpiled/directives/auth/Delegate.js.map +1 -1
  435. package/transpiled/directives/auth/Echo.d.ts +2 -0
  436. package/transpiled/directives/auth/Echo.js +4 -0
  437. package/transpiled/directives/auth/Echo.js.map +1 -1
  438. package/transpiled/directives/auth/Incept.d.ts +1 -1
  439. package/transpiled/directives/auth/Incept.js +13 -8
  440. package/transpiled/directives/auth/Incept.js.map +1 -1
  441. package/transpiled/directives/auth/Role.d.ts +2 -0
  442. package/transpiled/directives/auth/Role.js +9 -0
  443. package/transpiled/directives/auth/Role.js.map +1 -1
  444. package/transpiled/directives/auth/Rule.d.ts +5 -0
  445. package/transpiled/directives/auth/Rule.js +20 -0
  446. package/transpiled/directives/auth/Rule.js.map +1 -1
  447. package/transpiled/directives/auth/Scheme.d.ts +2 -0
  448. package/transpiled/directives/auth/Scheme.js +4 -0
  449. package/transpiled/directives/auth/Scheme.js.map +1 -1
  450. package/transpiled/directives/auth/schemes.d.ts +16 -4
  451. package/transpiled/directives/auth/schemes.js +20 -8
  452. package/transpiled/directives/auth/schemes.js.map +1 -1
  453. package/transpiled/directives/auth/types.d.ts +20 -2
  454. package/transpiled/directives/cache/Cache.d.ts +1 -1
  455. package/transpiled/directives/cache/Cache.js +10 -3
  456. package/transpiled/directives/cache/Cache.js.map +1 -1
  457. package/transpiled/directives/cache/Control.js +0 -2
  458. package/transpiled/directives/cache/Control.js.map +1 -1
  459. package/transpiled/directives/dev/Development.d.ts +1 -1
  460. package/transpiled/directives/dev/Development.js +1 -1
  461. package/transpiled/directives/dev/Development.js.map +1 -1
  462. package/transpiled/directives/flow/Flow.d.ts +1 -1
  463. package/transpiled/directives/flow/Flow.js +1 -1
  464. package/transpiled/directives/flow/Flow.js.map +1 -1
  465. package/transpiled/directives/index.js +4 -2
  466. package/transpiled/directives/index.js.map +1 -1
  467. package/transpiled/directives/io/Directive.d.ts +1 -1
  468. package/transpiled/directives/io/IO.d.ts +7 -1
  469. package/transpiled/directives/io/IO.js +25 -3
  470. package/transpiled/directives/io/IO.js.map +1 -1
  471. package/transpiled/directives/io/Input.d.ts +3 -2
  472. package/transpiled/directives/io/Input.js +2 -1
  473. package/transpiled/directives/io/Input.js.map +1 -1
  474. package/transpiled/directives/io/Output.d.ts +5 -3
  475. package/transpiled/directives/io/Output.js +8 -3
  476. package/transpiled/directives/io/Output.js.map +1 -1
  477. package/transpiled/directives/io/Status.d.ts +19 -0
  478. package/transpiled/directives/io/Status.js +34 -0
  479. package/transpiled/directives/io/Status.js.map +1 -0
  480. package/transpiled/directives/io/Throttle.d.ts +1 -1
  481. package/transpiled/directives/io/Throttle.js +1 -1
  482. package/transpiled/directives/io/Throttle.js.map +1 -1
  483. package/transpiled/directives/io/lib/throttle/Quotas.d.ts +1 -1
  484. package/transpiled/directives/io/lib/throttle/Quotas.js +2 -2
  485. package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
  486. package/transpiled/directives/map/Headers.d.ts +2 -0
  487. package/transpiled/directives/map/Headers.js +8 -0
  488. package/transpiled/directives/map/Headers.js.map +1 -1
  489. package/transpiled/directives/map/Map.d.ts +3 -1
  490. package/transpiled/directives/map/Map.js +7 -1
  491. package/transpiled/directives/map/Map.js.map +1 -1
  492. package/transpiled/directives/map/Mapping.d.ts +13 -0
  493. package/transpiled/directives/map/Mapping.js +20 -0
  494. package/transpiled/directives/map/Mapping.js.map +1 -1
  495. package/transpiled/directives/map/Segments.d.ts +3 -0
  496. package/transpiled/directives/map/Segments.js +9 -0
  497. package/transpiled/directives/map/Segments.js.map +1 -1
  498. package/transpiled/directives/mcp/MCP.d.ts +15 -0
  499. package/transpiled/directives/mcp/MCP.js +23 -0
  500. package/transpiled/directives/mcp/MCP.js.map +1 -0
  501. package/transpiled/directives/mcp/Tool.d.ts +13 -0
  502. package/transpiled/directives/mcp/Tool.js +23 -0
  503. package/transpiled/directives/mcp/Tool.js.map +1 -0
  504. package/transpiled/directives/mcp/index.d.ts +4 -0
  505. package/transpiled/directives/mcp/index.js +4 -0
  506. package/transpiled/directives/mcp/index.js.map +1 -0
  507. package/transpiled/directives/oauth/Discovery.d.ts +23 -0
  508. package/transpiled/directives/oauth/Discovery.js +55 -0
  509. package/transpiled/directives/oauth/Discovery.js.map +1 -0
  510. package/transpiled/directives/oauth/documents.d.ts +9 -0
  511. package/transpiled/directives/oauth/documents.js +82 -0
  512. package/transpiled/directives/oauth/documents.js.map +1 -0
  513. package/transpiled/directives/oauth/index.d.ts +2 -0
  514. package/transpiled/directives/oauth/index.js +3 -0
  515. package/transpiled/directives/oauth/index.js.map +1 -0
  516. package/transpiled/directives/octets/Octets.d.ts +1 -1
  517. package/transpiled/directives/octets/Octets.js +1 -1
  518. package/transpiled/directives/octets/Octets.js.map +1 -1
  519. package/transpiled/directives/require/Directive.d.ts +1 -1
  520. package/transpiled/directives/require/Headers.d.ts +1 -1
  521. package/transpiled/directives/require/Headers.js +1 -1
  522. package/transpiled/directives/require/Headers.js.map +1 -1
  523. package/transpiled/directives/require/Require.d.ts +1 -1
  524. package/transpiled/directives/require/Require.js +2 -2
  525. package/transpiled/directives/require/Require.js.map +1 -1
  526. package/transpiled/index.d.ts +2 -0
  527. package/transpiled/schemas.d.ts +2 -0
  528. package/transpiled/schemas.js +1 -0
  529. package/transpiled/schemas.js.map +1 -1
  530. package/transpiled/userland.d.ts +39 -0
  531. package/transpiled/userland.js +7 -0
  532. package/transpiled/userland.js.map +1 -0
  533. package/tsconfig.tsbuildinfo +1 -1
  534. package/components/identity.bans/operations/transit.d.ts +0 -14
  535. package/components/identity.bans/operations/transit.js.map +0 -1
  536. package/components/identity.basic/operations/add.d.ts +0 -3
  537. package/components/identity.basic/operations/add.js.map +0 -1
  538. package/components/identity.basic/operations/authenticate.d.ts +0 -13
  539. package/components/identity.basic/operations/authenticate.js.map +0 -1
  540. package/components/identity.basic/operations/check.d.ts +0 -7
  541. package/components/identity.basic/operations/check.js.map +0 -1
  542. package/components/identity.basic/operations/delete.d.ts +0 -7
  543. package/components/identity.basic/operations/delete.js.map +0 -1
  544. package/components/identity.basic/operations/incept.d.ts +0 -12
  545. package/components/identity.basic/operations/incept.js.map +0 -1
  546. package/components/identity.basic/operations/info.d.ts +0 -10
  547. package/components/identity.basic/operations/info.js.map +0 -1
  548. package/components/identity.basic/operations/lib/credentials.d.ts +0 -5
  549. package/components/identity.basic/operations/lib/credentials.js.map +0 -1
  550. package/components/identity.basic/operations/transit.d.ts +0 -14
  551. package/components/identity.basic/operations/transit.js.map +0 -1
  552. package/components/identity.basic/operations/types.d.ts +0 -61
  553. package/components/identity.basic/operations/types.js +0 -2
  554. package/components/identity.basic/operations/types.js.map +0 -1
  555. package/components/identity.basic/source/types.ts +0 -69
  556. package/components/identity.credentials/operations/list.d.ts +0 -51
  557. package/components/identity.credentials/operations/list.js.map +0 -1
  558. package/components/identity.federation/operations/authenticate.d.ts +0 -16
  559. package/components/identity.federation/operations/authenticate.js.map +0 -1
  560. package/components/identity.federation/operations/create.d.ts +0 -8
  561. package/components/identity.federation/operations/create.js.map +0 -1
  562. package/components/identity.federation/operations/decode.d.ts +0 -3
  563. package/components/identity.federation/operations/decode.js.map +0 -1
  564. package/components/identity.federation/operations/delete.d.ts +0 -8
  565. package/components/identity.federation/operations/delete.js.map +0 -1
  566. package/components/identity.federation/operations/incept.d.ts +0 -11
  567. package/components/identity.federation/operations/incept.js.map +0 -1
  568. package/components/identity.federation/operations/lib/Configuration.d.ts +0 -39
  569. package/components/identity.federation/operations/lib/Configuration.js.map +0 -1
  570. package/components/identity.federation/operations/lib/Ctx.d.ts +0 -8
  571. package/components/identity.federation/operations/lib/Ctx.js.map +0 -1
  572. package/components/identity.federation/operations/lib/Payload.d.ts +0 -5
  573. package/components/identity.federation/operations/lib/Payload.js.map +0 -1
  574. package/components/identity.federation/operations/lib/decode.d.ts +0 -3
  575. package/components/identity.federation/operations/lib/decode.js.map +0 -1
  576. package/components/identity.federation/operations/lib/discovery.d.ts +0 -5
  577. package/components/identity.federation/operations/lib/discovery.js.map +0 -1
  578. package/components/identity.federation/operations/lib/errors.d.ts +0 -70
  579. package/components/identity.federation/operations/lib/errors.js.map +0 -1
  580. package/components/identity.federation/operations/lib/exchange.d.ts +0 -3
  581. package/components/identity.federation/operations/lib/exchange.js.map +0 -1
  582. package/components/identity.federation/operations/lib/index.d.ts +0 -4
  583. package/components/identity.federation/operations/lib/index.js.map +0 -1
  584. package/components/identity.federation/operations/lib/jose.d.ts +0 -1
  585. package/components/identity.federation/operations/lib/jose.js.map +0 -1
  586. package/components/identity.federation/operations/lib/resolve.d.ts +0 -3
  587. package/components/identity.federation/operations/lib/resolve.js.map +0 -1
  588. package/components/identity.federation/operations/list.d.ts +0 -7
  589. package/components/identity.federation/operations/list.js.map +0 -1
  590. package/components/identity.federation/operations/types/Scheme.d.ts +0 -1
  591. package/components/identity.federation/operations/types/Scheme.js.map +0 -1
  592. package/components/identity.federation/operations/types/configuration.d.ts +0 -22
  593. package/components/identity.federation/operations/types/configuration.js.map +0 -1
  594. package/components/identity.federation/operations/types/context.d.ts +0 -35
  595. package/components/identity.federation/operations/types/context.js.map +0 -1
  596. package/components/identity.federation/operations/types/entity.d.ts +0 -9
  597. package/components/identity.federation/operations/types/entity.js.map +0 -1
  598. package/components/identity.federation/operations/types/index.d.ts +0 -4
  599. package/components/identity.federation/operations/types/index.js.map +0 -1
  600. package/components/identity.keys/operations/create.d.ts +0 -22
  601. package/components/identity.keys/operations/create.js.map +0 -1
  602. package/components/identity.keys/operations/disable.d.ts +0 -5
  603. package/components/identity.keys/operations/disable.js.map +0 -1
  604. package/components/identity.keys/operations/revoke.d.ts +0 -15
  605. package/components/identity.keys/operations/revoke.js.map +0 -1
  606. package/components/identity.otp/operations/authenticate.d.ts +0 -12
  607. package/components/identity.otp/operations/authenticate.js.map +0 -1
  608. package/components/identity.otp/operations/issue.d.ts +0 -12
  609. package/components/identity.otp/operations/issue.js.map +0 -1
  610. package/components/identity.otp/operations/lib/Context.d.ts +0 -14
  611. package/components/identity.otp/operations/lib/Context.js.map +0 -1
  612. package/components/identity.otp/operations/lib/Entity.d.ts +0 -6
  613. package/components/identity.otp/operations/lib/Entity.js.map +0 -1
  614. package/components/identity.otp/operations/lib/index.d.ts +0 -1
  615. package/components/identity.otp/operations/lib/index.js.map +0 -1
  616. package/components/identity.passkeys/operations/authenticate.d.ts +0 -16
  617. package/components/identity.passkeys/operations/authenticate.js.map +0 -1
  618. package/components/identity.passkeys/operations/challenge.d.ts +0 -35
  619. package/components/identity.passkeys/operations/challenge.js.map +0 -1
  620. package/components/identity.passkeys/operations/create.d.ts +0 -19
  621. package/components/identity.passkeys/operations/create.js.map +0 -1
  622. package/components/identity.passkeys/operations/delete.d.ts +0 -8
  623. package/components/identity.passkeys/operations/delete.js.map +0 -1
  624. package/components/identity.passkeys/operations/lib/const.d.ts +0 -1
  625. package/components/identity.passkeys/operations/lib/const.js.map +0 -1
  626. package/components/identity.passkeys/operations/list.d.ts +0 -7
  627. package/components/identity.passkeys/operations/list.js.map +0 -1
  628. package/components/identity.passkeys/operations/types/Configuration.d.ts +0 -6
  629. package/components/identity.passkeys/operations/types/Configuration.js.map +0 -1
  630. package/components/identity.passkeys/operations/types/Context.d.ts +0 -15
  631. package/components/identity.passkeys/operations/types/Context.js.map +0 -1
  632. package/components/identity.passkeys/operations/types/Passkey.d.ts +0 -12
  633. package/components/identity.passkeys/operations/types/Passkey.js.map +0 -1
  634. package/components/identity.passkeys/operations/types/index.d.ts +0 -2
  635. package/components/identity.passkeys/operations/types/index.js.map +0 -1
  636. package/components/identity.passkeys/operations/use.d.ts +0 -16
  637. package/components/identity.passkeys/operations/use.js.map +0 -1
  638. package/components/identity.roles/operations/grant.d.ts +0 -10
  639. package/components/identity.roles/operations/grant.js.map +0 -1
  640. package/components/identity.roles/operations/lib/Entity.d.ts +0 -5
  641. package/components/identity.roles/operations/lib/Entity.js.map +0 -1
  642. package/components/identity.roles/operations/list.d.ts +0 -2
  643. package/components/identity.roles/operations/list.js.map +0 -1
  644. package/components/identity.roles/operations/principal.d.ts +0 -13
  645. package/components/identity.roles/operations/principal.js.map +0 -1
  646. package/components/identity.tokens/operations/authenticate.d.ts +0 -9
  647. package/components/identity.tokens/operations/authenticate.js.map +0 -1
  648. package/components/identity.tokens/operations/decrypt.d.ts +0 -15
  649. package/components/identity.tokens/operations/decrypt.js.map +0 -1
  650. package/components/identity.tokens/operations/encrypt.d.ts +0 -8
  651. package/components/identity.tokens/operations/encrypt.js.map +0 -1
  652. package/components/identity.tokens/operations/issue.d.ts +0 -24
  653. package/components/identity.tokens/operations/issue.js.map +0 -1
  654. package/components/identity.tokens/operations/lib/index.d.ts +0 -3
  655. package/components/identity.tokens/operations/lib/index.js.map +0 -1
  656. package/components/identity.tokens/operations/lib/jose.d.ts +0 -1
  657. package/components/identity.tokens/operations/lib/jose.js.map +0 -1
  658. package/components/identity.tokens/operations/lib/key.d.ts +0 -1
  659. package/components/identity.tokens/operations/lib/key.js.map +0 -1
  660. package/components/identity.tokens/operations/lib/pad.d.ts +0 -1
  661. package/components/identity.tokens/operations/lib/pad.js.map +0 -1
  662. package/components/identity.tokens/operations/lib/types.d.ts +0 -88
  663. package/components/identity.tokens/operations/lib/types.js +0 -2
  664. package/components/identity.tokens/operations/lib/types.js.map +0 -1
  665. package/components/identity.tokens/operations/revoke.d.ts +0 -2
  666. package/components/identity.tokens/operations/revoke.js.map +0 -1
  667. package/components/identity.tokens/source/lib/types.ts +0 -102
@@ -0,0 +1,110 @@
1
+ import { describe, it, mock } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { Tree } from './Tree.js'
5
+ import { address, name } from '../RPC/names.js'
6
+ import type { EndpointsFactory } from '../Endpoint.js'
7
+ import type { DirectiveFactory } from './Directives.js'
8
+ import type * as syntax from './syntax/index.js'
9
+
10
+ const endpoints = {} as unknown as EndpointsFactory
11
+
12
+ const directives = {
13
+ create: () => ({
14
+ precall: async () => null,
15
+ settle: async () => undefined,
16
+ dispose: () => undefined
17
+ }),
18
+ dispose: mock.fn()
19
+ } as unknown as DirectiveFactory
20
+
21
+ const node = (path: string, verbs: string[] = [], routes: syntax.Route[] = []): syntax.Route => ({
22
+ path,
23
+ node: {
24
+ routes,
25
+ methods: verbs.map((verb) => ({ verb, directives: [] })),
26
+ directives: []
27
+ }
28
+ })
29
+
30
+ const trunk = (routes: syntax.Route[], verbs: string[] = []): syntax.Node => ({
31
+ routes,
32
+ methods: verbs.map((verb) => ({ verb, directives: [] })),
33
+ directives: []
34
+ })
35
+
36
+ /** What a walk names, which is what a caller of `/.rpc` would write. */
37
+ function names (tree: Tree): string[] {
38
+ return [...tree.walk()].map(({ segments, verb }) => name(segments, verb))
39
+ .filter((named): named is string => named !== null)
40
+ }
41
+
42
+ describe('walk', () => {
43
+ it('should name the trunk by its verb alone', () => {
44
+ const tree = new Tree(trunk([], ['GET']), endpoints, directives)
45
+
46
+ assert.deepEqual(names(tree), ['GET'])
47
+ })
48
+
49
+ it('should name every method of every route', () => {
50
+ const tree = new Tree(trunk([
51
+ node('/pots', ['GET', 'POST'], [node('/:id', ['GET', 'DELETE'])])
52
+ ]), endpoints, directives)
53
+
54
+ assert.deepEqual(names(tree).sort(), [
55
+ 'pots/GET', 'pots/POST', 'pots/_id/DELETE', 'pots/_id/GET'
56
+ ])
57
+ })
58
+
59
+ it('should walk a branch that was merged', () => {
60
+ const tree = new Tree(trunk([]), endpoints, directives)
61
+
62
+ tree.merge(trunk([node('/pots', ['GET'])]), { namespace: 'default', component: 'pots' })
63
+
64
+ assert.deepEqual(names(tree), ['pots/GET'])
65
+ })
66
+
67
+ it('should name a tail', () => {
68
+ const tree = new Tree(trunk([node('/files', [], [node('/**', ['GET'])])]),
69
+ endpoints, directives)
70
+
71
+ assert.deepEqual(names(tree), ['files/__/GET'])
72
+ })
73
+
74
+ it('should skip an intermediate node, whose route answers in its place', () => {
75
+ const tree = new Tree(trunk([
76
+ // `/posts` is intermediate: `/posts/` is answered by its `/` route, not by itself
77
+ node('/posts', ['PATCH'], [node('/', ['PUT'])])
78
+ ]), endpoints, directives)
79
+
80
+ assert.deepEqual(names(tree), ['posts/PUT'])
81
+ })
82
+
83
+ it('should name nothing where a segment cannot be spelled', () => {
84
+ const tree = new Tree(trunk([node('/v1.0', ['GET']), node('/pots', ['GET'])]),
85
+ endpoints, directives)
86
+
87
+ assert.deepEqual(names(tree), ['pots/GET'])
88
+ })
89
+
90
+ it('should name what the tree then matches', () => {
91
+ const tree = new Tree(trunk([
92
+ node('/pots', ['GET'], [node('/:id', ['GET']), node('/hot', ['GET'])]),
93
+ node('/files', [], [node('/**', ['GET'])])
94
+ ], ['GET']), endpoints, directives)
95
+
96
+ const params = { id: 'a1b2', '**': 'a/b/c' }
97
+
98
+ for (const { segments, verb } of tree.walk()) {
99
+ const named = name(segments, verb)
100
+
101
+ assert.notStrictEqual(named, null, 'every walked method has a name')
102
+
103
+ const { path } = address(named!, params)
104
+ const match = tree.match(path)
105
+
106
+ assert.notStrictEqual(match, null, `'${named!}' resolves to '${path}', which matches`)
107
+ assert.ok(verb in match!.node.methods, `'${named!}' matches a node that answers ${verb}`)
108
+ }
109
+ })
110
+ })
package/source/const.ts CHANGED
@@ -2,3 +2,18 @@ export const BRANCH_TTL = 1_800_000
2
2
 
3
3
  /** The replicas of the gateway decide together, whatever context they serve. */
4
4
  export const ATOM_GROUP = 'exposition'
5
+
6
+ /**
7
+ * Where JSON-RPC is served, for every procedure at once. Pinned rather than configured: a
8
+ * path an application could choose is a path it could collide with a route of its own.
9
+ */
10
+ export const RPC = '/.rpc'
11
+
12
+ /** Calls one request may carry where the annotation does not say. */
13
+ export const BATCH = 32
14
+
15
+ /**
16
+ * Where the Model Context Protocol is served. Pinned for the reason `/.rpc` is: a path an
17
+ * application could choose is a path it could collide with a route of its own.
18
+ */
19
+ export const MCP = '/.mcp'
@@ -67,6 +67,15 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
67
67
  if (annotation.bouncer !== undefined)
68
68
  properties.bouncer = annotation.bouncer
69
69
 
70
+ if (annotation.oauth !== undefined)
71
+ properties.oauth = annotation.oauth
72
+
73
+ if (annotation.rpc !== undefined)
74
+ properties.rpc = annotation.rpc
75
+
76
+ if (annotation.mcp !== undefined)
77
+ properties.mcp = annotation.mcp
78
+
70
79
  service.variables!.push({
71
80
  name: 'TOA_EXPOSITION_PROPERTIES',
72
81
  value: JSON.stringify(properties)
@@ -83,4 +92,5 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
83
92
  return { services: [service] }
84
93
  }
85
94
 
86
- type Properties = Pick<Annotation, 'authorities' | 'debug' | 'protocol' | 'bouncer' | 'ip'>
95
+ type Properties = Pick<Annotation,
96
+ 'authorities' | 'debug' | 'protocol' | 'bouncer' | 'ip' | 'oauth' | 'rpc' | 'mcp'>
@@ -0,0 +1,38 @@
1
+ import { describe, it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { Anonymous } from './Anonymous.js'
5
+ import type { Context } from './types.js'
6
+
7
+ const context = (headers: Record<string, string>, procedural = false): Context =>
8
+ ({ request: { headers }, procedural }) as unknown as Context
9
+
10
+ describe('anonymous', () => {
11
+ it('should admit a request that presents nothing', () => {
12
+ assert.equal(new Anonymous(true).authorize(null, context({})), true)
13
+ })
14
+
15
+ it('should refuse a request that presents a credential', () => {
16
+ // it would make the reply uncacheable, which is the whole of the rule
17
+ assert.equal(new Anonymous(true).authorize(null, context({ authorization: 'Token x' })), false)
18
+ })
19
+
20
+ it('should admit a procedure whatever the request presented', () => {
21
+ // what a procedure answers is a value in an envelope, and the envelope is `no-store`
22
+ const procedural = context({ authorization: 'Token x' }, true)
23
+
24
+ assert.equal(new Anonymous(true).authorize(null, procedural), true)
25
+ })
26
+
27
+ it('should refuse where it admits nobody', () => {
28
+ assert.equal(new Anonymous(false).authorize(null, context({})), false)
29
+ assert.equal(new Anonymous(false).authorize(null, context({}, true)), false)
30
+ })
31
+
32
+ it('should describe a method as it authorizes one', () => {
33
+ const directive = new Anonymous(true)
34
+
35
+ assert.equal(directive.admits(null, context({ authorization: 'Token x' })), false)
36
+ assert.equal(directive.admits(null, context({ authorization: 'Token x' }, true)), true)
37
+ })
38
+ })
@@ -7,9 +7,21 @@ export class Anonymous implements Directive {
7
7
  this.allow = allow
8
8
  }
9
9
 
10
+ /**
11
+ * A credential refuses, because it would make the reply uncacheable — which is the whole
12
+ * of the rule, and none of it applies to a procedure: what a procedure answers is a value
13
+ * in an envelope, and the envelope is the one thing that is cached or not.
14
+ */
10
15
  public authorize (_: any, context: Context): boolean {
16
+ if (context.procedural)
17
+ return this.allow
18
+
11
19
  return 'authorization' in context.request.headers
12
20
  ? false
13
21
  : this.allow
14
22
  }
23
+
24
+ public admits (_: any, context: Context): boolean {
25
+ return this.authorize(_, context)
26
+ }
15
27
  }
@@ -10,4 +10,8 @@ export class Anyone implements Directive {
10
10
  public authorize (_: any, context: Context): boolean {
11
11
  return context.identity !== null && this.allow
12
12
  }
13
+
14
+ public admits (_: any, context: Context): boolean {
15
+ return this.authorize(_, context)
16
+ }
13
17
  }
@@ -16,11 +16,12 @@ import { Federation } from './Federation.js'
16
16
  import { Anyone } from './Anyone.js'
17
17
  import { Input, type Declaration } from './Input.js'
18
18
  import { split } from './split.js'
19
- import { PRIMARY, provider as providerOf } from './schemes.js'
19
+ import { PRIMARY, UNRECOGNIZED, providers as providersOf } from './schemes.js'
20
20
  import { ATOM_GROUP } from '../../const.js'
21
21
  import { Quotas, Sync } from '../io/lib/throttle/index.js'
22
22
  import { Keys } from '../io/lib/throttle/Keys.js'
23
23
  import type { Output } from '../../io.js'
24
+ import type { Introspection } from '../../Introspection.js'
24
25
  import type { Component } from '@toa.io/core'
25
26
  import type { Remotes } from '../../Remotes.js'
26
27
  import type { Parameter, DirectiveFamily } from '../../RTD/index.js'
@@ -34,7 +35,7 @@ import type {
34
35
  Identity,
35
36
  Context,
36
37
  Remote,
37
- Schemes
38
+ Components
38
39
  } from './types.js'
39
40
 
40
41
  export class Authorization implements DirectiveFamily<Directive, Extension> {
@@ -42,7 +43,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
42
43
  public readonly name: string = 'auth'
43
44
  public readonly mandatory: boolean = true
44
45
 
45
- private readonly schemes = {} as unknown as Schemes
46
+ private readonly components: Components = {}
46
47
  private readonly discovery = {} as unknown as Discovery
47
48
  private tokens: Component | null = null
48
49
  private bans: Component | null = null
@@ -100,11 +101,18 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
100
101
  directives.sort((a, b) => (a.priority ?? 1) - (b.priority ?? 1))
101
102
  }
102
103
 
103
- public async preflight (directives: Directive[],
104
- context: Context,
105
- parameters: Parameter[]): Promise<Output> {
104
+ /**
105
+ * Authentication: who the credential names, if one is presented. A credential belongs to
106
+ * the request, so it is read once however many calls the request carries.
107
+ */
108
+ public async preflight (context: Context): Promise<void> {
106
109
  context.identity = await this.resolve(context)
110
+ }
107
111
 
112
+ /** Authorization: whether that identity may make this call, which every call asks anew. */
113
+ public async precall (directives: Directive[],
114
+ context: Context,
115
+ parameters: Parameter[]): Promise<Output> {
108
116
  for (const directive of directives) {
109
117
  const allow = await directive.authorize(context.identity, context, parameters)
110
118
 
@@ -121,18 +129,69 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
121
129
  throw new http.Forbidden()
122
130
  }
123
131
 
132
+ /**
133
+ * The same disjunction as `precall`, over what can be told without a request. A method no
134
+ * directive admits, and none is undecided about, is not this caller's to be told about —
135
+ * `null` takes it out of the answer.
136
+ *
137
+ * A permission is matched against a path, and a description is not a request to one, so
138
+ * `permits` has no say here. The call it describes is still checked, which is where a
139
+ * token's permissions belong.
140
+ *
141
+ * A method that is described is then described by each of them, which is a separate pass:
142
+ * admission is a disjunction and stops at the first that admits, while what the directives
143
+ * fill is not any one of them's to state alone.
144
+ */
145
+ public async explain (directives: Directive[], context: Context,
146
+ introspection: Introspection): Promise<Introspection | null> {
147
+ let untold = false
148
+ let admitted = false
149
+
150
+ for (const directive of directives) {
151
+ const admits = await directive.admits?.(context.identity, context)
152
+
153
+ if (admits === undefined) {
154
+ untold = true
155
+
156
+ continue
157
+ }
158
+
159
+ if (admits) {
160
+ admitted = true
161
+
162
+ break
163
+ }
164
+ }
165
+
166
+ if (!admitted && !untold)
167
+ return null
168
+
169
+ // whichever of them admitted, a property any of them fills from the identity is filled
170
+ // from the identity: what a caller sent there would be overwritten or forged
171
+ for (const directive of directives)
172
+ introspection = directive.describe?.(introspection) ?? introspection
173
+
174
+ return introspection
175
+ }
176
+
124
177
  public async settle (directives: Directive[],
125
178
  context: Context,
126
179
  response: http.OutgoingMessage): Promise<void> {
127
180
  await Promise.all(directives.map(async (directive) =>
128
181
  directive.settle?.(context, response)))
182
+ }
129
183
 
184
+ /**
185
+ * Re-issuing a credential, and refusing a ban, are the request's business: the header
186
+ * carries one token however many calls were made, and a ban refuses all of them.
187
+ */
188
+ public async depart (context: Context, response: http.OutgoingMessage): Promise<void> {
130
189
  const identity = context.identity
131
190
 
132
191
  if (identity === null)
133
192
  return
134
193
 
135
- if (identity.scheme === PRIMARY && !identity.refresh)
194
+ if (identity.provider === PRIMARY && !identity.refresh)
136
195
  return
137
196
 
138
197
  if (await this.banned(identity))
@@ -140,7 +199,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
140
199
 
141
200
  // a token carries the roles it was issued with, and the refresh is where they are read again;
142
201
  // any other scheme has just read them, unless a Role directive already did
143
- if (identity.scheme === PRIMARY)
202
+ if (identity.provider === PRIMARY)
144
203
  identity.roles = await Role.get(identity, this.discovery.roles)
145
204
  else
146
205
  identity.roles ??= await Role.get(identity, this.discovery.roles)
@@ -170,25 +229,40 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
170
229
  throw new http.TooManyRequests(retry)
171
230
 
172
231
  const [scheme, credentials] = split(authorization)
173
- const provider = providerOf(scheme)
232
+ const candidates = providersOf(scheme)
174
233
 
175
- if (provider === undefined)
234
+ if (candidates === undefined)
176
235
  throw new http.Unauthorized(`Unknown authentication scheme '${scheme}'`)
177
236
 
178
- this.schemes[scheme] ??= await this.discovery[provider]
237
+ let provider: Remote | null = null
238
+ let result: AuthenticationResult | null = null
179
239
 
180
- const result = await this.schemes[scheme].invoke<AuthenticationResult>('authenticate', {
181
- input: {
182
- scheme,
183
- authority,
184
- credentials
185
- }
186
- })
240
+ // the first provider that does not decline has claimed the credentials, and answers
241
+ // for them: a rejection from one that never recognized them is not the rejection
242
+ for (const candidate of candidates) {
243
+ this.components[candidate] ??= await this.discovery[candidate]
244
+
245
+ const answer = await this.components[candidate]!.invoke<AuthenticationResult>('authenticate', {
246
+ input: {
247
+ scheme,
248
+ authority,
249
+ credentials
250
+ }
251
+ })
252
+
253
+ if (declined(answer))
254
+ continue
187
255
 
188
- if (result instanceof Error) {
189
- const code: string | unknown = (result as unknown as { code: string }).code
256
+ provider = candidate
257
+ result = answer
190
258
 
191
- if (typeof code === 'string') {
259
+ break
260
+ }
261
+
262
+ if (result === null || result instanceof Error) {
263
+ const code = result === null ? UNRECOGNIZED : codeOf(result)
264
+
265
+ if (code !== undefined) {
192
266
  console.info('Authentication failed', { code })
193
267
 
194
268
  context.rejection = code
@@ -201,9 +275,10 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
201
275
 
202
276
  const identity = result.identity
203
277
 
204
- if (scheme !== PRIMARY && (await this.banned(identity))) throw new http.Unauthorized()
278
+ if (provider !== PRIMARY && (await this.banned(identity))) throw new http.Unauthorized()
205
279
 
206
280
  identity.scheme = scheme
281
+ identity.provider = provider!
207
282
  identity.refresh = result.refresh
208
283
 
209
284
  return identity
@@ -228,6 +303,17 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
228
303
  }
229
304
  }
230
305
 
306
+ /** Whether a provider says the credentials are not of its kind, so the next is asked. */
307
+ function declined (result: AuthenticationResult): boolean {
308
+ return result instanceof Error && codeOf(result) === UNRECOGNIZED
309
+ }
310
+
311
+ function codeOf (result: Error): string | undefined {
312
+ const code: string | unknown = (result as unknown as { code: string }).code
313
+
314
+ return typeof code === 'string' ? code : undefined
315
+ }
316
+
231
317
  /** Whether the permissions admit the method on the path the request is routed by. */
232
318
  export function permits (permissions: Record<string, string[]>, method: string, pathname: string): boolean {
233
319
  return Object.entries(permissions).some(([pattern, methods]) =>
@@ -0,0 +1,36 @@
1
+ import assert from 'node:assert'
2
+ import { describe, it } from 'node:test'
3
+ import { Delegate } from './Delegate.js'
4
+ import type { Introspection } from '../../Introspection.js'
5
+
6
+ describe('auth:delegate', () => {
7
+ function explanation (): Introspection {
8
+ return {
9
+ input: {
10
+ type: 'object',
11
+ properties: {
12
+ identity: { type: 'object' },
13
+ title: { type: 'string' }
14
+ },
15
+ required: ['identity', 'title']
16
+ }
17
+ } as unknown as Introspection
18
+ }
19
+
20
+ it('should take the property it embeds out of the input', () => {
21
+ const delegate = new Delegate('identity', null as never)
22
+ const described = delegate.describe(explanation())
23
+ const input = described.input as { properties: object, required: string[] }
24
+
25
+ assert.deepStrictEqual(Object.keys(input.properties), ['title'])
26
+ assert.deepStrictEqual(input.required, ['title'])
27
+ })
28
+
29
+ it('should leave an input that does not declare it alone', () => {
30
+ const delegate = new Delegate('originator', null as never)
31
+ const described = delegate.describe(explanation())
32
+ const input = described.input as { properties: object }
33
+
34
+ assert.deepStrictEqual(Object.keys(input.properties), ['identity', 'title'])
35
+ })
36
+ })
@@ -1,5 +1,7 @@
1
1
  import { BadRequest } from '../../HTTP/index.js'
2
+ import { take } from '../../Introspection.js'
2
3
  import { Role } from './Role.js'
4
+ import type { Introspection } from '../../Introspection.js'
3
5
  import type { Context, Directive, Identity } from './types.js'
4
6
  import type { Component } from '@toa.io/core'
5
7
 
@@ -22,6 +24,18 @@ export class Delegate implements Directive {
22
24
  return true
23
25
  }
24
26
 
27
+ /** It admits whoever there is, and embedding the identity is the request's business. */
28
+ public admits (identity: Identity | null): boolean {
29
+ return identity !== null
30
+ }
31
+
32
+ /** The property it embeds is the identity's, so a caller has nothing to put there. */
33
+ public describe (introspection: Introspection): Introspection {
34
+ take(introspection, this.property)
35
+
36
+ return introspection
37
+ }
38
+
25
39
  private embed (body: unknown, identity: Identity): Record<string, unknown> {
26
40
  if (body === undefined)
27
41
  body = {}
@@ -12,6 +12,11 @@ export class Echo implements Directive {
12
12
  return true
13
13
  }
14
14
 
15
+ /** What `authorize` answers, without inventing the identity it would go on to invent. */
16
+ public admits (identity: Identity | null, context: Context): boolean {
17
+ return !(identity === null && 'authorization' in context.request.headers)
18
+ }
19
+
15
20
  public reply (context: Context): OutgoingMessage {
16
21
  const body = context.identity!
17
22
 
@@ -3,14 +3,14 @@ import { console } from 'openspan'
3
3
  import * as http from '../../HTTP/index.js'
4
4
  import { split } from './split.js'
5
5
  import { create } from './create.js'
6
- import { INCEPTION, UNKNOWN, provider as providerOf } from './schemes.js'
6
+ import { INCEPTION, UNKNOWN, providers as providersOf } from './schemes.js'
7
7
  import { Role } from './Role.js'
8
8
  import type { Component } from '@toa.io/core'
9
- import type { Maybe } from '@toa.io/types'
10
- import type { Directive, Discovery, Identity, Context, Schemes, Ban } from './types.js'
9
+ import type { Maybe } from '@toa.io/core'
10
+ import type { Directive, Discovery, Identity, Context, Components, Ban } from './types.js'
11
11
 
12
12
  export class Incept implements Directive {
13
- private static readonly schemes: Schemes = {} as unknown as Schemes
13
+ private static readonly components: Components = {}
14
14
  private static discovery: Discovery
15
15
  private static bans: Component | null = null
16
16
 
@@ -26,12 +26,17 @@ export class Incept implements Directive {
26
26
 
27
27
  public static async incept (context: Context, id: string): Promise<Identity> {
28
28
  const [scheme, credentials] = split(context.request.headers.authorization!)
29
- const provider = providerOf(scheme)
29
+ const candidates = providersOf(scheme)
30
30
 
31
- if (provider === undefined)
31
+ if (candidates === undefined)
32
32
  throw new http.BadRequest('Authentication scheme is not supported')
33
33
 
34
- if (!INCEPTION.includes(provider))
34
+ // a scheme several providers claim is incepted by the one that incepts; `Bearer`
35
+ // carries an access token this gateway issued, and an identity cannot be incepted
36
+ // from a credential it would itself have to exist to hold
37
+ const provider = candidates.find((candidate) => INCEPTION.includes(candidate))
38
+
39
+ if (provider === undefined)
35
40
  throw new http.Unauthorized()
36
41
 
37
42
  Incept.bans ??= await Incept.discovery.bans
@@ -41,9 +46,9 @@ export class Incept implements Directive {
41
46
  if (ban.banned)
42
47
  throw new http.Unauthorized()
43
48
 
44
- Incept.schemes[scheme] ??= await Incept.discovery[provider]
49
+ Incept.components[provider] ??= await Incept.discovery[provider]
45
50
 
46
- const identity = await Incept.schemes[scheme].invoke<Maybe<Identity>>('incept', {
51
+ const identity = await Incept.components[provider]!.invoke<Maybe<Identity>>('incept', {
47
52
  input: {
48
53
  scheme,
49
54
  authority: context.authority,
@@ -56,8 +61,9 @@ export class Incept implements Directive {
56
61
  throw new http.UnprocessableEntity(identity)
57
62
 
58
63
  identity.scheme = scheme
59
- identity.roles = []
60
64
 
65
+ // the roles are read where the token is minted: an Identity incepted as the principal
66
+ // has one already
61
67
  return identity
62
68
  }
63
69
 
@@ -36,6 +36,19 @@ export class Role implements Directive {
36
36
  return this.match(identity.roles, parameters)
37
37
  }
38
38
 
39
+ /** A role naming a route variable cannot be told from a description, which has no values. */
40
+ public async admits (identity: Identity | null): Promise<boolean | undefined> {
41
+ if (this.dynamic)
42
+ return undefined
43
+
44
+ if (identity === null)
45
+ return false
46
+
47
+ identity.roles ??= await Role.get(identity, this.discovery)
48
+
49
+ return this.match(identity.roles, [])
50
+ }
51
+
39
52
  private match (roles: string[], parameters: Parameter[]): boolean {
40
53
  const required = this.dynamic ? this.substitute(parameters) : this.roles
41
54
 
@@ -1,4 +1,5 @@
1
1
  import { type Parameter } from '../../RTD/index.js'
2
+ import type { Introspection } from '../../Introspection.js'
2
3
  import type { Context, Directive, Identity, Create } from './types.js'
3
4
 
4
5
  export class Rule implements Directive {
@@ -22,4 +23,32 @@ export class Rule implements Directive {
22
23
 
23
24
  return true
24
25
  }
26
+
27
+ /** Whatever each of them makes of it, in the order they were declared. */
28
+ public describe (introspection: Introspection): Introspection {
29
+ for (const directive of this.directives)
30
+ introspection = directive.describe?.(introspection) ?? introspection
31
+
32
+ return introspection
33
+ }
34
+
35
+ /** All of them, so one that refuses ends it and one that cannot tell leaves it untold. */
36
+ public async admits (identity: Identity | null, context: Context): Promise<boolean | undefined> {
37
+ let untold = false
38
+
39
+ for (const directive of this.directives) {
40
+ const admits = await directive.admits?.(identity, context)
41
+
42
+ if (admits === undefined) {
43
+ untold = true
44
+
45
+ continue
46
+ }
47
+
48
+ if (!admits)
49
+ return false
50
+ }
51
+
52
+ return untold ? undefined : true
53
+ }
25
54
  }
@@ -23,4 +23,9 @@ export class Scheme implements Directive {
23
23
 
24
24
  return false
25
25
  }
26
+
27
+ /** It admits nobody: it is there to refuse a scheme, not to authorize one. */
28
+ public admits (): boolean {
29
+ return false
30
+ }
26
31
  }
@@ -1,14 +1,18 @@
1
1
  import { it } from 'node:test'
2
2
  import assert from 'node:assert/strict'
3
3
 
4
- import { provider } from './schemes.js'
4
+ import { providers } from './schemes.js'
5
5
 
6
6
  it('should resolve a known scheme', () => {
7
- assert.equal(provider('basic'), 'basic')
8
- assert.equal(provider('bearer'), 'federation')
7
+ assert.deepEqual(providers('basic'), ['basic'])
8
+ assert.deepEqual(providers('code'), ['federation'])
9
+ })
10
+
11
+ it('should resolve every provider claiming a scheme, in order', () => {
12
+ assert.deepEqual(providers('bearer'), ['tokens', 'federation'])
9
13
  })
10
14
 
11
15
  it('should not resolve a property of Object.prototype', () => {
12
16
  for (const name of ['constructor', '__proto__', 'toString', 'hasOwnProperty'])
13
- assert.equal(provider(name), undefined)
17
+ assert.equal(providers(name), undefined)
14
18
  })