@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,122 @@
1
+ import { describe, it } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import * as http from '../HTTP/index.js'
5
+ import { segment } from '../RTD/segment.js'
6
+ import { address, name, refusal } from './names.js'
7
+
8
+ describe('address', () => {
9
+ it('should resolve a name without variables', () => {
10
+ assert.deepEqual(address('pots/GET', {}),
11
+ { path: '/pots/', verb: 'GET', variables: [] })
12
+ })
13
+
14
+ it('should resolve the trunk', () => {
15
+ assert.deepEqual(address('GET', {}),
16
+ { path: '/', verb: 'GET', variables: [] })
17
+ })
18
+
19
+ it('should substitute a variable and report it taken', () => {
20
+ assert.deepEqual(address('pots/_id/GET', { id: 'a1b2', title: 'Kettle' }),
21
+ { path: '/pots/a1b2/', verb: 'GET', variables: ['id'] })
22
+ })
23
+
24
+ it('should substitute every variable', () => {
25
+ assert.deepEqual(address('users/_user/pots/_id/PATCH', { user: 'bob', id: 'a1b2' }),
26
+ { path: '/users/bob/pots/a1b2/', verb: 'PATCH', variables: ['user', 'id'] })
27
+ })
28
+
29
+ it('should let a tail carry separators', () => {
30
+ assert.deepEqual(address('files/__/GET', { '**': 'a/b/c' }),
31
+ { path: '/files/a/b/c/', verb: 'GET', variables: ['**'] })
32
+ })
33
+
34
+ it('should not confuse a trailing literal with a verb', () => {
35
+ assert.deepEqual(address('pots/GET/POST', {}),
36
+ { path: '/pots/GET/', verb: 'POST', variables: [] })
37
+ })
38
+
39
+ it('should refuse a name that states no verb', () => {
40
+ assert.throws(() => address('pots/_id', { id: 'a1b2' }), http.NotFound)
41
+ })
42
+
43
+ it('should refuse a verb no method uses', () => {
44
+ assert.throws(() => address('pots/FETCH', {}), http.NotFound)
45
+ })
46
+
47
+ it('should refuse a segment no name can spell', () => {
48
+ assert.throws(() => address('pots/v1.0/GET', {}), http.NotFound)
49
+ assert.throws(() => address('a_b/GET', {}), http.NotFound)
50
+ assert.throws(() => address('pots//GET', {}), http.NotFound)
51
+ })
52
+
53
+ it('should refuse a variable of no name', () => {
54
+ assert.throws(() => address('pots/_/GET', { '': 'a1b2' }), http.NotFound)
55
+ })
56
+
57
+ it('should refuse a missing variable', () => {
58
+ assert.throws(() => address('pots/_id/GET', {}), http.BadRequest)
59
+ })
60
+
61
+ it('should refuse a variable that would divide the path', () => {
62
+ assert.throws(() => address('pots/_id/GET', { id: 'a/b' }), http.BadRequest)
63
+ assert.throws(() => address('pots/_id/GET', { id: 'a?b' }), http.BadRequest)
64
+ assert.throws(() => address('pots/_id/GET', { id: 'a#b' }), http.BadRequest)
65
+ })
66
+
67
+ it('should refuse a tail that would end the path', () => {
68
+ assert.throws(() => address('files/__/GET', { '**': 'a?b' }), http.BadRequest)
69
+ })
70
+ })
71
+
72
+ describe('name', () => {
73
+ it('should name the trunk by its verb alone', () => {
74
+ assert.equal(name(segment('/'), 'GET'), 'GET')
75
+ })
76
+
77
+ it('should name a route', () => {
78
+ assert.equal(name(segment('/pots'), 'GET'), 'pots/GET')
79
+ assert.equal(name(segment('/identity/tokens'), 'POST'), 'identity/tokens/POST')
80
+ })
81
+
82
+ it('should mark a variable', () => {
83
+ assert.equal(name(segment('/pots/:id'), 'GET'), 'pots/_id/GET')
84
+ assert.equal(name(segment('/identity/tokens/:identity'), 'POST'),
85
+ 'identity/tokens/_identity/POST')
86
+ })
87
+
88
+ it('should mark a tail', () => {
89
+ assert.equal(name(segment('/files/**'), 'GET'), 'files/__/GET')
90
+ })
91
+
92
+ it('should keep a hyphen', () => {
93
+ assert.equal(name(segment('/jpeg-or-png'), 'GET'), 'jpeg-or-png/GET')
94
+ })
95
+
96
+ it('should name nothing where a segment cannot be spelled', () => {
97
+ assert.equal(name(segment('/v1.0/pots'), 'GET'), null)
98
+ assert.equal(name(segment('/a_b'), 'GET'), null)
99
+ assert.equal(name(segment('/pots/*'), 'GET'), null)
100
+ assert.equal(name(segment('/messages/:sender-:recipient'), 'GET'), null)
101
+ })
102
+
103
+ it('should round-trip what it names', () => {
104
+ const named = name(segment('/pots/:id'), 'GET')!
105
+
106
+ assert.deepEqual(address(named, { id: 'a1b2' }),
107
+ { path: '/pots/a1b2/', verb: 'GET', variables: ['id'] })
108
+ })
109
+ })
110
+
111
+ describe('refusal', () => {
112
+ it('should name nothing where every segment can be spelled', () => {
113
+ assert.equal(refusal(segment('/pots/:id')), null)
114
+ })
115
+
116
+ it('should name the segment as it was declared', () => {
117
+ assert.equal(refusal(segment('/v1.0/pots')), 'v1.0')
118
+ assert.equal(refusal(segment('/pots/a_b')), 'a_b')
119
+ assert.equal(refusal(segment('/pots/*')), '*')
120
+ assert.equal(refusal(segment('/messages/:sender-:recipient')), ':sender-:recipient')
121
+ })
122
+ })
@@ -0,0 +1,182 @@
1
+ import * as http from '../HTTP/index.js'
2
+ import { verbs } from '../RTD/syntax/index.js'
3
+ import type { Segment } from '../RTD/segment.js'
4
+ import { QUERY, type Params } from './types.js'
5
+
6
+ /**
7
+ * What a name resolves to: the path the call is made at, and the verb it is made with.
8
+ *
9
+ * A name is the route template with its variables marked and the verb appended as a segment
10
+ * of its own — `pots/_id/GET`. Neither `/` nor a verb can be mistaken for anything else: the
11
+ * verb is always the last segment, and `/` cannot occur inside one.
12
+ */
13
+ export interface Address {
14
+ path: string
15
+ verb: string
16
+
17
+ /** the `params` the path took, which are therefore not the operation's input */
18
+ variables: string[]
19
+ }
20
+
21
+ export function address (method: string, params: Params): Address {
22
+ const parts = method.split(SEPARATOR)
23
+ const verb = parts.pop()!
24
+
25
+ if (!verbs.has(verb))
26
+ throw new http.NotFound(`'${method}' names no method`)
27
+
28
+ const variables: string[] = []
29
+ const fragments: string[] = []
30
+
31
+ for (const part of parts) {
32
+ const key = parameter(part)
33
+
34
+ if (key === null) {
35
+ fragments.push(literal(part, method))
36
+
37
+ continue
38
+ }
39
+
40
+ if (part !== TAIL && !NAMEABLE.test(key))
41
+ throw new http.NotFound(`'${method}' names no procedure`)
42
+
43
+ const value = params[key]
44
+
45
+ if (value === undefined || value === null)
46
+ throw new http.BadRequest(`'${method}' requires the parameter '${key}'`)
47
+
48
+ const fragment = String(value)
49
+
50
+ // `__` stands for the rest of the path and may carry separators; a variable is one segment
51
+ if (!(part === TAIL ? TAILED : OPAQUE).test(fragment))
52
+ throw new http.BadRequest(`The parameter '${key}' cannot be a path of its own`)
53
+
54
+ variables.push(key)
55
+ fragments.push(fragment)
56
+ }
57
+
58
+ // a route is matched with its trailing slash, and the trunk is the bare one
59
+ const path = fragments.length === 0 ? '/' : `/${fragments.join('/')}/`
60
+
61
+ return { path, verb, variables }
62
+ }
63
+
64
+ /**
65
+ * What the call carries, as a request carries it: the path took its variables, `query` is
66
+ * the querystring, and the rest is the body.
67
+ */
68
+ export function split (params: Params, variables: string[]): { query?: Params, input?: Params } {
69
+ const input: Params = {}
70
+ let query: Params | undefined
71
+
72
+ for (const [key, value] of Object.entries(params)) {
73
+ if (variables.includes(key))
74
+ continue
75
+
76
+ if (key !== QUERY) {
77
+ input[key] = value
78
+
79
+ continue
80
+ }
81
+
82
+ if (typeof value !== 'object' || value === null || Array.isArray(value))
83
+ throw new http.BadRequest(`'${QUERY}' must be an object`)
84
+
85
+ query = value as Params
86
+ }
87
+
88
+ // an absent body is what a request without one has, and the mapping fills it as it does
89
+ return { query, input: Object.keys(input).length === 0 ? undefined : input }
90
+ }
91
+
92
+ /** The parameter a part reads, or nothing where the part is a literal segment. */
93
+ function parameter (part: string): string | null {
94
+ if (part === TAIL)
95
+ return WILDCARD
96
+
97
+ return part[0] === VARIABLE ? part.slice(1) : null
98
+ }
99
+
100
+ /** A segment a name cannot spell is a segment no name has, so this one names nothing. */
101
+ function literal (part: string, method: string): string {
102
+ if (!NAMEABLE.test(part))
103
+ throw new http.NotFound(`'${method}' names no procedure`)
104
+
105
+ return part
106
+ }
107
+
108
+ /** The name of a method on this route, or nothing where the route has none. */
109
+ export function name (segments: Segment[], verb: string): string | null {
110
+ const parts: string[] = []
111
+
112
+ for (const segment of segments) {
113
+ const part = component(segment)
114
+
115
+ if (part === null)
116
+ return null
117
+
118
+ parts.push(part)
119
+ }
120
+
121
+ parts.push(verb)
122
+
123
+ return parts.join(SEPARATOR)
124
+ }
125
+
126
+ /** The segment that leaves a route unnameable, as it was declared, or nothing where none does. */
127
+ export function refusal (segments: Segment[]): string | null {
128
+ for (const segment of segments)
129
+ if (component(segment) === null)
130
+ return declared(segment)
131
+
132
+ return null
133
+ }
134
+
135
+ function component (segment: Segment): string | null {
136
+ if (segment.fragment !== null)
137
+ return NAMEABLE.test(segment.fragment) ? segment.fragment : null
138
+
139
+ if (segment.wildcard === true)
140
+ return TAIL
141
+
142
+ // it stands for a segment the caller cannot name, so there is nothing to substitute
143
+ if (segment.placeholder === null)
144
+ return null
145
+
146
+ return NAMEABLE.test(segment.placeholder) ? VARIABLE + segment.placeholder : null
147
+ }
148
+
149
+ /** The route as it was declared, which is how a message about it should read. */
150
+ export function template (segments: Segment[]): string {
151
+ return '/' + segments.map(declared).join('/')
152
+ }
153
+
154
+ function declared (segment: Segment): string {
155
+ if (segment.fragment !== null)
156
+ return segment.fragment
157
+
158
+ if (segment.wildcard === true)
159
+ return '**'
160
+
161
+ return segment.placeholder === null ? '*' : ':' + segment.placeholder
162
+ }
163
+
164
+ const SEPARATOR = '/'
165
+ const VARIABLE = '_'
166
+ const TAIL = '__'
167
+
168
+ /** How the RTD names the rest of a path, wherever a parameter of it is read. */
169
+ const WILDCARD = '**'
170
+
171
+ /**
172
+ * What a segment may hold to have a name. `_` is the convention's own, and every other
173
+ * character a client leaves alone is here: a client shows a model the name with the rest
174
+ * turned into `_`, and two names must not become one.
175
+ */
176
+ const NAMEABLE = /^[A-Za-z0-9-]+$/
177
+
178
+ /** A segment ends at what divides or ends a path. */
179
+ const OPAQUE = /^[^/?#]*$/
180
+
181
+ /** A tail is several segments, so it keeps the divider and loses only what ends a path. */
182
+ const TAILED = /^[^?#]*$/
@@ -0,0 +1,34 @@
1
+ /** The version every call and every response states. */
2
+ export const VERSION = '2.0'
3
+
4
+ /**
5
+ * The member `params` reserves for what a querystring would carry. An operation's input is
6
+ * free to have an `id` or a `limit` of its own, so the two cannot share one object.
7
+ */
8
+ export const QUERY = 'query'
9
+
10
+ export type Params = Record<string, unknown>
11
+
12
+ export interface Call {
13
+ jsonrpc: string
14
+ method: string
15
+ params?: Params
16
+
17
+ /** Absent makes this a notification: it runs, and nothing is returned for it. */
18
+ id?: string | number
19
+ }
20
+
21
+ export interface Response {
22
+ jsonrpc: string
23
+
24
+ /** `null` where the request was not readable enough to carry one. */
25
+ id: string | number | null
26
+ result?: unknown
27
+ error?: Failure
28
+ }
29
+
30
+ export interface Failure {
31
+ code: number
32
+ message: string
33
+ data?: unknown
34
+ }
@@ -2,18 +2,36 @@ import type { Parameter } from './Match.js'
2
2
  import type * as syntax from './syntax/index.js'
3
3
  import type { Context, OutgoingMessage, Options } from '../HTTP/index.js'
4
4
  import type { Output } from '../io.js'
5
+ import type { Introspection } from '../Introspection.js'
5
6
  import type { extensions } from '@toa.io/core'
6
7
 
7
8
  type Host = extensions.Host
8
9
 
9
10
  export interface Directives {
10
- preflight: (context: Context, parameters: Parameter[]) => Promise<Output>
11
+ /**
12
+ * The directives of one family on this method, or nothing where it declares none of it.
13
+ * For a consumer of a declaration rather than of a stage: what a method is published as
14
+ * is stated on the route, and read where the publishing happens.
15
+ */
16
+ declared: <T>(family: string) => T[] | undefined
17
+
18
+ precall: (context: Context, parameters: Parameter[]) => Promise<Output>
19
+
20
+ /** What this route's directives make of what its method says about itself. */
21
+ explain: (context: Context, introspection: Introspection) => Promise<Introspection | null>
11
22
  settle: (context: Context, response: OutgoingMessage) => Promise<void>
12
23
  dispose: () => void
13
24
  }
14
25
 
15
26
  export interface DirectiveFactory {
16
27
  create: (directives: syntax.Directive[], route: string) => Directives
28
+
29
+ /** Runs every family's `preflight`, which is request-scoped and needs no node. */
30
+ preflight: (context: Context) => Promise<void>
31
+
32
+ /** Runs every family's `depart`, the counterpart of `preflight`. */
33
+ depart: (context: Context, response: OutgoingMessage) => Promise<void>
34
+
17
35
  dispose: () => void
18
36
  }
19
37
 
@@ -43,13 +61,45 @@ export interface DirectiveFamily<TDirective = any, TExtension = any> {
43
61
  */
44
62
  arrange?: (directives: TDirective[]) => void
45
63
 
46
- preflight?: (directives: TDirective[],
64
+ /**
65
+ * Request-scoped, before anything is routed. It takes no directives: no node is known
66
+ * yet, and a request that carries several calls has no single node at all. What a
67
+ * directive declares is call-scoped by definition, so only what a family does on its
68
+ * own behalf — authenticating a credential — belongs here. It answers nothing: a stage
69
+ * that runs before a route is known has no reply to make, and refuses by throwing.
70
+ */
71
+ preflight?: (request: Context & TExtension) => void | Promise<void>
72
+
73
+ /** Call-scoped, with what the node declares. Runs once per call. */
74
+ precall?: (directives: TDirective[],
47
75
  request: Context & TExtension,
48
76
  parameters: Parameter[]) => Output | Promise<Output>
49
77
 
78
+ /**
79
+ * What this family's directives make of what the method says about itself, which is
80
+ * what `OPTIONS` answers and what a tool is described by. `null` refuses: the method
81
+ * is not reachable by this caller, and is not described at all.
82
+ *
83
+ * There is no request here — no route variable has a value and no body has arrived, which
84
+ * is why no parameters are passed — so a directive that can only tell from one hands back
85
+ * what it was given.
86
+ */
87
+ explain?: (directives: TDirective[],
88
+ request: Context & TExtension,
89
+ introspection: Introspection) => Introspection | null | Promise<Introspection | null>
90
+
91
+ /** Call-scoped, on the message that call produced. */
50
92
  settle?: (directives: TDirective[],
51
93
  request: Context & TExtension,
52
94
  response: OutgoingMessage) => void | Promise<void>
53
95
 
96
+ /**
97
+ * Request-scoped, on the message going back — the counterpart of `preflight`, and
98
+ * likewise without directives. A reply the whole request carries, such as a re-issued
99
+ * credential, is written here rather than by a call that would not own it.
100
+ */
101
+ depart?: (request: Context & TExtension,
102
+ response: OutgoingMessage) => void | Promise<void>
103
+
54
104
  dispose?: (directives: TDirective[]) => void
55
105
  }
@@ -2,11 +2,12 @@ import { type Context } from './Context.js'
2
2
  import type * as http from '../HTTP/index.js'
3
3
  import type * as syntax from './syntax/index.js'
4
4
  import type * as RTD from './index.js'
5
+ import type { Introspection } from '../Introspection.js'
5
6
 
6
7
  export interface Endpoint {
7
8
  call: (context: http.Context, parameters: RTD.Parameter[]) => Promise<http.OutgoingMessage>
8
9
 
9
- explain: (parameters: RTD.Parameter[]) => Promise<unknown>
10
+ explain: (parameters: RTD.Parameter[]) => Promise<Introspection>
10
11
 
11
12
  close: () => Promise<void>
12
13
  }
@@ -1,29 +1,32 @@
1
1
  import type { Parameter } from './Match.js'
2
2
  import type { Endpoint } from './Endpoint.js'
3
3
  import type { Directives } from './Directives.js'
4
+ import type { Context } from '../HTTP/index.js'
5
+ import { order } from '../Introspection.js'
6
+ import type { Introspection } from '../Introspection.js'
4
7
 
5
8
  export class Method {
6
9
  public readonly endpoint: Endpoint | null
7
10
  public readonly directives: Directives
8
- private introspection: unknown | null = null
9
- private introspecting: Promise<unknown> | null = null
10
11
 
11
12
  public constructor (endpoint: Endpoint | null, directives: Directives) {
12
13
  this.endpoint = endpoint
13
14
  this.directives = directives
14
15
  }
15
16
 
16
- public async explain (parameters: Parameter[]): Promise<unknown> {
17
- if (this.introspection !== null)
18
- return this.introspection
17
+ /**
18
+ * What this method says about itself, as its directives leave it, or nothing where they
19
+ * refuse this caller. A method of no endpoint — one a directive answers on its own —
20
+ * states nothing of its own, and its directives still have their say.
21
+ */
22
+ public async explain (context: Context, parameters: Parameter[]): Promise<Introspection | null> {
23
+ const introspection = this.endpoint === null
24
+ ? {}
25
+ : await this.endpoint.explain(parameters)
19
26
 
20
- if (this.introspecting === null)
21
- // eslint-disable-next-line @typescript-eslint/no-non-null-asserted-optional-chain
22
- this.introspecting = this.endpoint?.explain(parameters)!
27
+ const described = await this.directives.explain(context, introspection)
23
28
 
24
- this.introspection = await this.introspecting
25
-
26
- return this.introspection
29
+ return described === null ? null : order(described)
27
30
  }
28
31
 
29
32
  public async close (): Promise<void> {
@@ -1,6 +1,9 @@
1
1
  import { type Route } from './Route.js'
2
- import { type Methods } from './Method.js'
2
+ import { type Method, type Methods } from './Method.js'
3
3
  import { type Match, type Parameter } from './Match.js'
4
+ import type { Segment } from './segment.js'
5
+ import type { Context } from '../HTTP/index.js'
6
+ import type { Introspection } from '../Introspection.js'
4
7
 
5
8
  export class Node {
6
9
  public intermediate: boolean
@@ -52,14 +55,35 @@ export class Node {
52
55
  this.expiration = expiration
53
56
  }
54
57
 
55
- public async explain (parameters: Parameter[]): Promise<Record<string, unknown>> {
56
- const methods: Record<string, unknown> = {}
58
+ /**
59
+ * Every method under this node, with the template it answers at.
60
+ *
61
+ * An intermediate node is skipped: it is never what a path matches, because its `/` route
62
+ * answers at the same place and is reached instead. The trunk is the exception `match`
63
+ * makes for it — `'/'` answers the trunk itself, whatever it holds.
64
+ */
65
+ public * walk (segments: Segment[], trunk = false): Generator<Mount> {
66
+ if (trunk || !this.intermediate)
67
+ for (const [verb, method] of Object.entries(this.methods))
68
+ yield { segments, verb, method }
69
+
70
+ for (const route of this.routes)
71
+ yield * route.walk(segments)
72
+ }
57
73
 
58
- const explained = Object.entries(this.methods)
59
- .map(async ([verb, method]) =>
60
- (methods[verb] = await method.explain(parameters)))
74
+ /** Every method of this node that this caller may reach, in the order they were declared. */
75
+ public async explain (context: Context,
76
+ parameters: Parameter[]): Promise<Record<string, Introspection>> {
77
+ const entries = Object.entries(this.methods)
61
78
 
62
- await Promise.all(explained)
79
+ const explained = await Promise.all(entries
80
+ .map(async ([, method]) => await method.explain(context, parameters)))
81
+
82
+ const methods: Record<string, Introspection> = {}
83
+
84
+ for (let i = 0; i < entries.length; i++)
85
+ if (explained[i] !== null)
86
+ methods[entries[i][0]] = explained[i]!
63
87
 
64
88
  return methods
65
89
  }
@@ -119,6 +143,13 @@ export class Node {
119
143
  }
120
144
  }
121
145
 
146
+ /** A method, and the route template it is reached by. */
147
+ export interface Mount {
148
+ segments: Segment[]
149
+ verb: string
150
+ method: Method
151
+ }
152
+
122
153
  export interface Properties {
123
154
  protected: boolean
124
155
  forward?: string
@@ -1,6 +1,6 @@
1
1
  import { type Segment } from './segment.js'
2
2
  import { type Match, type Parameter } from './Match.js'
3
- import type { Node } from './Node.js'
3
+ import type { Mount, Node } from './Node.js'
4
4
 
5
5
  export class Route {
6
6
  public readonly root: boolean
@@ -32,10 +32,13 @@ export class Route {
32
32
  return null
33
33
 
34
34
  if (segment.fragment === null && segment.placeholder !== null)
35
- parameters.push({ name: segment.placeholder, value: fragments[i] })
35
+ parameters.push({ name: segment.placeholder, value: decode(fragments[i]) })
36
36
 
37
37
  if (segment.fragment === null && segment.wildcard === true)
38
- parameters.push({ name: '**', value: fragments.slice(this.segments.length - 1).join('/') })
38
+ parameters.push({
39
+ name: '**',
40
+ value: fragments.slice(this.segments.length - 1).map(decode).join('/')
41
+ })
39
42
  }
40
43
 
41
44
  const exact = this.segments.length === fragments.length
@@ -46,6 +49,14 @@ export class Route {
46
49
  return this.matchNested(fragments, parameters)
47
50
  }
48
51
 
52
+ public * walk (prefix: Segment[]): Generator<Mount> {
53
+ // an expired branch is not matched, so nothing under it is reachable to name
54
+ if (Date.now() >= this.node.expiration)
55
+ return
56
+
57
+ yield * this.node.walk(prefix.concat(this.segments))
58
+ }
59
+
49
60
  public equals (route: Route): boolean {
50
61
  if (route.segments.length !== this.segments.length)
51
62
  return false
@@ -67,3 +78,19 @@ export class Route {
67
78
  return this.node.match(fragments, parameters)
68
79
  }
69
80
  }
81
+
82
+ /**
83
+ * What the segment says, rather than how it was written: a value is percent-encoded to
84
+ * survive the path, and an operation reads what a caller meant — a `client_id` that is a
85
+ * URL arrives as one. A literal segment is matched as written, which is how it is declared.
86
+ *
87
+ * An escape that decodes to nothing valid is left as it stands; refusing the route over it
88
+ * would answer `404` to a request whose only fault is its spelling.
89
+ */
90
+ function decode (fragment: string): string {
91
+ try {
92
+ return decodeURIComponent(fragment)
93
+ } catch {
94
+ return fragment
95
+ }
96
+ }
@@ -1,6 +1,8 @@
1
+ import { console } from 'openspan'
2
+ import { refusal, template } from '../RPC/names.js'
1
3
  import { branchTTL, createNode } from './factory.js'
2
4
  import { fragment } from './segment.js'
3
- import type { Node } from './Node.js'
5
+ import type { Mount, Node } from './Node.js'
4
6
  import type { Match } from './Match.js'
5
7
  import type { Context } from './Context.js'
6
8
  import type { DirectiveFactory } from './Directives.js'
@@ -18,6 +20,8 @@ export class Tree {
18
20
  this.directives = directives
19
21
  this.root = node
20
22
  this.trunk = this.createNode(node, PROTECTED)
23
+
24
+ unnameable(this.trunk)
21
25
  }
22
26
 
23
27
  public match (path: string): Match | null {
@@ -32,9 +36,16 @@ export class Tree {
32
36
  return this.trunk.match(fragments)
33
37
  }
34
38
 
39
+ /** Every method in the tree, with the template it answers at. */
40
+ public walk (): Generator<Mount> {
41
+ return this.trunk.walk([], TRUNK)
42
+ }
43
+
35
44
  public merge (node: syntax.Node, extension: unknown): Node[] {
36
45
  const branch = this.createNode(node, !PROTECTED, extension)
37
46
 
47
+ unnameable(branch)
48
+
38
49
  return this.trunk.merge(branch)
39
50
  }
40
51
 
@@ -72,6 +83,30 @@ export class Tree {
72
83
  }
73
84
  }
74
85
 
86
+ /**
87
+ * What is served but cannot be called by name. Said once per route as it is built, because a
88
+ * procedure that is missing is otherwise noticed only by the caller who cannot find it.
89
+ */
90
+ function unnameable (node: Node): void {
91
+ const said = new Set<string>()
92
+
93
+ for (const { segments } of node.walk([], TRUNK)) {
94
+ const segment = refusal(segments)
95
+
96
+ if (segment === null)
97
+ continue
98
+
99
+ const route = template(segments)
100
+
101
+ if (said.has(route))
102
+ continue
103
+
104
+ said.add(route)
105
+
106
+ console.warn('Route cannot be addressed as a procedure', { route, segment })
107
+ }
108
+ }
109
+
75
110
  /**
76
111
  * A branch's routes are relative to wherever it is merged, and the mount point is not
77
112
  * known while it is being built — so the component it came from is what keeps two
@@ -89,3 +124,4 @@ function label (extension: unknown): string {
89
124
  }
90
125
 
91
126
  const PROTECTED = true
127
+ const TRUNK = true
@@ -10,7 +10,7 @@ const endpoints = {} as unknown as EndpointsFactory
10
10
 
11
11
  const directives = {
12
12
  create: () => ({
13
- preflight: async () => null,
13
+ precall: async () => null,
14
14
  settle: async () => undefined,
15
15
  dispose: () => undefined
16
16
  }),