@toa.io/extensions.exposition 1.0.0-alpha.291 → 1.0.0-alpha.293

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 (526) hide show
  1. package/components/identity.basic/package.json +8 -0
  2. package/components/identity.federation/package.json +8 -0
  3. package/components/identity.passkeys/package.json +8 -0
  4. package/components/identity.tokens/package.json +10 -0
  5. package/package.json +25 -13
  6. package/transpiled/Discovery/Explorer.js +1 -1
  7. package/transpiled/Discovery/Explorer.js.map +1 -1
  8. package/transpiled/Discovery/Site.js +1 -1
  9. package/transpiled/Discovery/Site.js.map +1 -1
  10. package/transpiled/Discovery/trunk.js +1 -1
  11. package/transpiled/Discovery/trunk.js.map +1 -1
  12. package/transpiled/Endpoint.js +3 -0
  13. package/transpiled/Endpoint.js.map +1 -1
  14. package/transpiled/Factory.js +1 -1
  15. package/transpiled/Factory.js.map +1 -1
  16. package/transpiled/Gateway.js +1 -1
  17. package/transpiled/Gateway.js.map +1 -1
  18. package/transpiled/HTTP/Server.d.ts +1 -1
  19. package/transpiled/HTTP/Server.js +1 -1
  20. package/transpiled/HTTP/Server.js.map +1 -1
  21. package/transpiled/Introspection.d.ts +6 -0
  22. package/transpiled/Introspection.js +1 -0
  23. package/transpiled/Introspection.js.map +1 -1
  24. package/transpiled/MCP/Server.d.ts +1 -1
  25. package/transpiled/MCP/Server.js +1 -1
  26. package/transpiled/MCP/Server.js.map +1 -1
  27. package/transpiled/MCP/discover.d.ts +1 -1
  28. package/transpiled/MCP/schema.js +2 -2
  29. package/transpiled/Query.d.ts +2 -12
  30. package/transpiled/Query.js +3 -13
  31. package/transpiled/Query.js.map +1 -1
  32. package/transpiled/RPC/Dispatcher.d.ts +1 -1
  33. package/transpiled/RPC/Dispatcher.js +2 -2
  34. package/transpiled/RPC/Dispatcher.js.map +1 -1
  35. package/transpiled/RTD/Endpoint.d.ts +2 -3
  36. package/transpiled/RTD/Tree.js +1 -1
  37. package/transpiled/RTD/Tree.js.map +1 -1
  38. package/transpiled/RTD/factory.js +1 -1
  39. package/transpiled/RTD/factory.js.map +1 -1
  40. package/transpiled/RTD/syntax/index.d.ts +1 -2
  41. package/transpiled/RTD/syntax/index.js +1 -2
  42. package/transpiled/RTD/syntax/index.js.map +1 -1
  43. package/transpiled/Tenant.js +1 -1
  44. package/transpiled/Tenant.js.map +1 -1
  45. package/transpiled/directives/auth/Authorization.js +1 -1
  46. package/transpiled/directives/auth/Authorization.js.map +1 -1
  47. package/transpiled/directives/io/IO.js +1 -1
  48. package/transpiled/directives/io/IO.js.map +1 -1
  49. package/transpiled/directives/oauth/documents.d.ts +1 -1
  50. package/transpiled/index.d.ts +0 -2
  51. package/transpiled/index.js +0 -2
  52. package/transpiled/index.js.map +1 -1
  53. package/transpiled/service.js +1 -1
  54. package/transpiled/service.js.map +1 -1
  55. package/ui/dist/_app/immutable/assets/0.Cu0AnR_8.css +2 -0
  56. package/ui/dist/_app/immutable/assets/2.BghF56l_.css +1 -0
  57. package/ui/dist/_app/immutable/assets/ui.C8aD6zzF.css +1 -0
  58. package/ui/dist/_app/immutable/chunks/B8GvXrmq.js +1 -0
  59. package/ui/dist/_app/immutable/chunks/BVDJTrf4.js +3 -0
  60. package/ui/dist/_app/immutable/chunks/D6q28_Ok.js +86 -0
  61. package/ui/dist/_app/immutable/chunks/{D9tE1yyO.js → DVlaUfVU.js} +1 -1
  62. package/ui/dist/_app/immutable/chunks/DpB73ZB6.js +6 -0
  63. package/ui/dist/_app/immutable/entry/app.CTava8yn.js +2 -0
  64. package/ui/dist/_app/immutable/entry/start.yWN0gSLA.js +1 -0
  65. package/ui/dist/_app/immutable/nodes/0.HKRDBYrC.js +1 -0
  66. package/ui/dist/_app/immutable/nodes/1.CLa0ydOi.js +1 -0
  67. package/ui/dist/_app/immutable/nodes/2.C9Kaym8C.js +8 -0
  68. package/ui/dist/_app/immutable/nodes/3.C1X4_rXZ.js +1 -0
  69. package/ui/dist/_app/immutable/nodes/4.DdzDIi9E.js +1 -0
  70. package/ui/dist/_app/immutable/nodes/5.DpbmCMdw.js +1 -0
  71. package/ui/dist/_app/version.json +1 -1
  72. package/ui/dist/index.html +12 -12
  73. package/CHANGELOG.md +0 -35
  74. package/components/identity.bans/tsconfig.tsbuildinfo +0 -1
  75. package/components/identity.basic/source/lib/credentials.test.ts +0 -18
  76. package/components/identity.basic/tsconfig.tsbuildinfo +0 -1
  77. package/components/identity.clients/source/lib/canonical.test.ts +0 -43
  78. package/components/identity.clients/source/lib/cimd.test.ts +0 -122
  79. package/components/identity.clients/source/lib/redirect.test.ts +0 -47
  80. package/components/identity.clients/tsconfig.tsbuildinfo +0 -1
  81. package/components/identity.credentials/source/list.test.ts +0 -70
  82. package/components/identity.credentials/tsconfig.tsbuildinfo +0 -1
  83. package/components/identity.federation/source/lib/discovery.test.ts +0 -60
  84. package/components/identity.federation/source/list.test.ts +0 -41
  85. package/components/identity.federation/tsconfig.tsbuildinfo +0 -1
  86. package/components/identity.grants/tsconfig.tsbuildinfo +0 -1
  87. package/components/identity.keys/tsconfig.tsbuildinfo +0 -1
  88. package/components/identity.otp/tsconfig.tsbuildinfo +0 -1
  89. package/components/identity.passkeys/source/errors.test.ts +0 -34
  90. package/components/identity.passkeys/source/webauthn.test.ts +0 -26
  91. package/components/identity.passkeys/tsconfig.tsbuildinfo +0 -1
  92. package/components/identity.roles/tsconfig.tsbuildinfo +0 -1
  93. package/components/identity.tokens/source/authenticate.test.ts +0 -112
  94. package/components/identity.tokens/source/decrypt.test.ts +0 -216
  95. package/components/identity.tokens/source/encrypt.test.ts +0 -150
  96. package/components/identity.tokens/source/issue.test.ts +0 -73
  97. package/components/identity.tokens/source/lib/form.test.ts +0 -25
  98. package/components/identity.tokens/source/lib/paseto.test.ts +0 -62
  99. package/components/identity.tokens/tsconfig.tsbuildinfo +0 -1
  100. package/context.toa.yaml +0 -31
  101. package/cucumber.mjs +0 -7
  102. package/documentation/.assets/ia3-dark.jpg +0 -0
  103. package/documentation/.assets/ia3-light.jpg +0 -0
  104. package/documentation/.assets/overview-dark.jpg +0 -0
  105. package/documentation/.assets/overview-light.jpg +0 -0
  106. package/documentation/.assets/role-scopes-dark.jpg +0 -0
  107. package/documentation/.assets/role-scopes-light.jpg +0 -0
  108. package/documentation/.assets/rtd-dark.jpg +0 -0
  109. package/documentation/.assets/rtd-light.jpg +0 -0
  110. package/documentation/access.md +0 -350
  111. package/documentation/authorities.md +0 -51
  112. package/documentation/cache.md +0 -72
  113. package/documentation/components.md +0 -472
  114. package/documentation/consent.md +0 -101
  115. package/documentation/credentials.md +0 -88
  116. package/documentation/dev.md +0 -30
  117. package/documentation/discovery.md +0 -81
  118. package/documentation/flow.md +0 -44
  119. package/documentation/help.md +0 -122
  120. package/documentation/identity.md +0 -304
  121. package/documentation/introspection.md +0 -123
  122. package/documentation/io.md +0 -167
  123. package/documentation/ip.md +0 -24
  124. package/documentation/map.md +0 -123
  125. package/documentation/mcp.md +0 -183
  126. package/documentation/notes/desync.jpg +0 -0
  127. package/documentation/notes/peers.md +0 -59
  128. package/documentation/notes/sse.md +0 -71
  129. package/documentation/notes/throttling.md +0 -122
  130. package/documentation/oauth.md +0 -180
  131. package/documentation/octets.md +0 -334
  132. package/documentation/passkeys.md +0 -11
  133. package/documentation/protocol.md +0 -120
  134. package/documentation/query.md +0 -324
  135. package/documentation/require.md +0 -15
  136. package/documentation/rpc.md +0 -154
  137. package/documentation/tracing.md +0 -70
  138. package/documentation/tree.md +0 -199
  139. package/features/access.feature +0 -596
  140. package/features/annotation.feature +0 -32
  141. package/features/auth.assert.feature +0 -55
  142. package/features/auth.bearer.feature +0 -120
  143. package/features/auth.claims.feature +0 -171
  144. package/features/auth.incept.feature +0 -166
  145. package/features/auth.input.feature +0 -59
  146. package/features/authorities.basic.feature +0 -141
  147. package/features/authorities.feature +0 -71
  148. package/features/authorities.federation.feature +0 -100
  149. package/features/authorities.tokens.feature +0 -117
  150. package/features/body.feature +0 -76
  151. package/features/cache.feature +0 -368
  152. package/features/configuration.feature +0 -206
  153. package/features/cors.feature +0 -127
  154. package/features/credentials.feature +0 -106
  155. package/features/debug.feature +0 -34
  156. package/features/dev.feature +0 -90
  157. package/features/directives.feature +0 -61
  158. package/features/discovery.feature +0 -213
  159. package/features/discovery.ui.feature +0 -213
  160. package/features/dynamic.feature +0 -192
  161. package/features/errors.feature +0 -258
  162. package/features/etag.feature +0 -239
  163. package/features/flow.feature +0 -148
  164. package/features/help.feature +0 -512
  165. package/features/identity.bans.feature +0 -200
  166. package/features/identity.basic.feature +0 -666
  167. package/features/identity.feature +0 -240
  168. package/features/identity.federation.feature +0 -396
  169. package/features/identity.otp.feature +0 -142
  170. package/features/identity.roles.feature +0 -568
  171. package/features/identity.tokens.custom.feature +0 -430
  172. package/features/identity.tokens.feature +0 -131
  173. package/features/interruptions.feature +0 -20
  174. package/features/introspection.feature +0 -565
  175. package/features/introspection.map.feature +0 -108
  176. package/features/io.feature +0 -204
  177. package/features/io.throttle.feature +0 -166
  178. package/features/map.feature +0 -360
  179. package/features/mcp.feature +0 -753
  180. package/features/methods.feature +0 -48
  181. package/features/oauth.clients.feature +0 -195
  182. package/features/oauth.discovery.feature +0 -164
  183. package/features/oauth.grants.feature +0 -301
  184. package/features/octets.cloudinary.feature +0 -233
  185. package/features/octets.download.feature +0 -194
  186. package/features/octets.entries.feature +0 -83
  187. package/features/octets.feature +0 -306
  188. package/features/octets.head.feature +0 -40
  189. package/features/octets.location.feature +0 -83
  190. package/features/octets.meta.feature +0 -117
  191. package/features/octets.workflows.feature +0 -565
  192. package/features/passkeys.feature +0 -66
  193. package/features/probes.feature +0 -18
  194. package/features/query.feature +0 -389
  195. package/features/realtime.feature +0 -34
  196. package/features/require.feature +0 -66
  197. package/features/response.feature +0 -103
  198. package/features/routes.feature +0 -224
  199. package/features/rpc.feature +0 -429
  200. package/features/server.feature +0 -21
  201. package/features/site/_app/immutable/asset.js +0 -1
  202. package/features/site/favicon.ico +0 -0
  203. package/features/site/index.html +0 -10
  204. package/features/steps/.env.example +0 -5
  205. package/features/steps/Captures.ts +0 -20
  206. package/features/steps/Cloudinary.ts +0 -12
  207. package/features/steps/Common.ts +0 -38
  208. package/features/steps/Components.ts +0 -115
  209. package/features/steps/Database.ts +0 -106
  210. package/features/steps/Gateway.ts +0 -240
  211. package/features/steps/HTTP.ts +0 -96
  212. package/features/steps/IDP.ts +0 -361
  213. package/features/steps/Identity.ts +0 -54
  214. package/features/steps/OTP.ts +0 -42
  215. package/features/steps/Parameters.ts +0 -162
  216. package/features/steps/Probe.ts +0 -38
  217. package/features/steps/Realtime.ts +0 -175
  218. package/features/steps/Workspace.ts +0 -48
  219. package/features/steps/components/audit/manifest.toa.yaml +0 -20
  220. package/features/steps/components/audit/operations/record.js +0 -5
  221. package/features/steps/components/echo/manifest.toa.yaml +0 -59
  222. package/features/steps/components/echo/operations/affect.js +0 -3
  223. package/features/steps/components/echo/operations/compute.js +0 -3
  224. package/features/steps/components/echo/operations/echo.js +0 -3
  225. package/features/steps/components/echo/operations/error.js +0 -7
  226. package/features/steps/components/echo/operations/identity.js +0 -3
  227. package/features/steps/components/echo/operations/parameters.js +0 -3
  228. package/features/steps/components/echo/operations/ping.js +0 -3
  229. package/features/steps/components/echo/operations/unwrap.js +0 -3
  230. package/features/steps/components/echo.beacon/manifest.toa.yaml +0 -2
  231. package/features/steps/components/echo.beacon/operations/hello.js +0 -3
  232. package/features/steps/components/greeter/manifest.toa.yaml +0 -5
  233. package/features/steps/components/greeter/operations/greet.js +0 -3
  234. package/features/steps/components/notify/manifest.toa.yaml +0 -20
  235. package/features/steps/components/notify/operations/send.js +0 -5
  236. package/features/steps/components/octets.tester/manifest.toa.yaml +0 -73
  237. package/features/steps/components/octets.tester/operations/authority.js +0 -3
  238. package/features/steps/components/octets.tester/operations/bar.js +0 -9
  239. package/features/steps/components/octets.tester/operations/baz.js +0 -9
  240. package/features/steps/components/octets.tester/operations/concat.js +0 -5
  241. package/features/steps/components/octets.tester/operations/echo.js +0 -5
  242. package/features/steps/components/octets.tester/operations/err.js +0 -14
  243. package/features/steps/components/octets.tester/operations/foo.js +0 -5
  244. package/features/steps/components/octets.tester/operations/id.js +0 -5
  245. package/features/steps/components/octets.tester/operations/identity.js +0 -5
  246. package/features/steps/components/octets.tester/operations/lenna.png +0 -0
  247. package/features/steps/components/octets.tester/operations/redirect.js +0 -17
  248. package/features/steps/components/octets.tester/operations/yex.js +0 -14
  249. package/features/steps/components/octets.tester/operations/yield.js +0 -11
  250. package/features/steps/components/orders/manifest.toa.yaml +0 -30
  251. package/features/steps/components/orders/operations/create.js +0 -7
  252. package/features/steps/components/pots/manifest.toa.yaml +0 -91
  253. package/features/steps/components/pots/migrations/0002-indexes.yaml +0 -4
  254. package/features/steps/components/pricing/manifest.toa.yaml +0 -13
  255. package/features/steps/components/pricing/operations/quote.js +0 -3
  256. package/features/steps/components/sequences/manifest.toa.yaml +0 -11
  257. package/features/steps/components/sequences/operations/numbers.js +0 -5
  258. package/features/steps/components/sequences/operations/tokens.js +0 -14
  259. package/features/steps/components/users/manifest.toa.yaml +0 -30
  260. package/features/steps/components/users/operations/create.js +0 -11
  261. package/features/steps/components/users.properties/manifest.toa.yaml +0 -22
  262. package/features/steps/map.ts +0 -30
  263. package/features/steps/tsconfig.json +0 -9
  264. package/features/streams.feature +0 -35
  265. package/features/timestamps.feature +0 -41
  266. package/features/timing.feature +0 -49
  267. package/features/tracing.feature +0 -123
  268. package/schemas/annotation.cos.yaml +0 -125
  269. package/schemas/call.cos.yaml +0 -18
  270. package/schemas/directive.cos.yaml +0 -7
  271. package/schemas/method.cos.yaml +0 -23
  272. package/schemas/node.cos.yaml +0 -22
  273. package/schemas/query.cos.yaml +0 -31
  274. package/schemas/querystring.cos.yaml +0 -19
  275. package/schemas/range.cos.yaml +0 -10
  276. package/schemas/route.cos.yaml +0 -6
  277. package/source/Annotation.ts +0 -89
  278. package/source/Branch.test.ts +0 -40
  279. package/source/Branch.ts +0 -44
  280. package/source/Composition.ts +0 -51
  281. package/source/Context.ts +0 -11
  282. package/source/Directive.test.ts +0 -199
  283. package/source/Directive.ts +0 -248
  284. package/source/Discovery/Explorer.ts +0 -34
  285. package/source/Discovery/Site.test.ts +0 -147
  286. package/source/Discovery/Site.ts +0 -202
  287. package/source/Discovery/index.ts +0 -3
  288. package/source/Discovery/tree.test.ts +0 -175
  289. package/source/Discovery/tree.ts +0 -77
  290. package/source/Discovery/trunk.ts +0 -33
  291. package/source/Endpoint.test.ts +0 -67
  292. package/source/Endpoint.ts +0 -157
  293. package/source/Factory.ts +0 -42
  294. package/source/Gateway.ts +0 -390
  295. package/source/HTTP/Context.ts +0 -143
  296. package/source/HTTP/Probe.ts +0 -99
  297. package/source/HTTP/Server.ts +0 -430
  298. package/source/HTTP/Timing.ts +0 -14
  299. package/source/HTTP/address.test.ts +0 -28
  300. package/source/HTTP/address.ts +0 -16
  301. package/source/HTTP/exceptions.ts +0 -99
  302. package/source/HTTP/formats/form.ts +0 -21
  303. package/source/HTTP/formats/index.ts +0 -36
  304. package/source/HTTP/formats/json.ts +0 -14
  305. package/source/HTTP/formats/msgpack.ts +0 -14
  306. package/source/HTTP/formats/text.ts +0 -10
  307. package/source/HTTP/formats/yaml.test.ts +0 -22
  308. package/source/HTTP/formats/yaml.ts +0 -40
  309. package/source/HTTP/index.ts +0 -6
  310. package/source/HTTP/messages.test.ts +0 -196
  311. package/source/HTTP/messages.ts +0 -186
  312. package/source/HTTP/types.ts +0 -39
  313. package/source/Interception.ts +0 -37
  314. package/source/Introspection.ts +0 -179
  315. package/source/MCP/Server.ts +0 -335
  316. package/source/MCP/discover.ts +0 -51
  317. package/source/MCP/errors.ts +0 -80
  318. package/source/MCP/index.ts +0 -1
  319. package/source/MCP/schema.test.ts +0 -91
  320. package/source/MCP/schema.ts +0 -94
  321. package/source/MCP/tools.ts +0 -144
  322. package/source/MCP/types.ts +0 -84
  323. package/source/Mapping.ts +0 -101
  324. package/source/Query.test.ts +0 -54
  325. package/source/Query.ts +0 -277
  326. package/source/RPC/Context.ts +0 -75
  327. package/source/RPC/Dispatcher.ts +0 -150
  328. package/source/RPC/errors.test.ts +0 -77
  329. package/source/RPC/errors.ts +0 -82
  330. package/source/RPC/index.ts +0 -1
  331. package/source/RPC/names.test.ts +0 -141
  332. package/source/RPC/names.ts +0 -176
  333. package/source/RPC/types.ts +0 -34
  334. package/source/RTD/Context.ts +0 -16
  335. package/source/RTD/Directives.ts +0 -126
  336. package/source/RTD/Endpoint.ts +0 -27
  337. package/source/RTD/Match.ts +0 -11
  338. package/source/RTD/Method.ts +0 -39
  339. package/source/RTD/Node.ts +0 -169
  340. package/source/RTD/Route.ts +0 -93
  341. package/source/RTD/Tree.ts +0 -137
  342. package/source/RTD/expiration.test.ts +0 -81
  343. package/source/RTD/factory.ts +0 -105
  344. package/source/RTD/index.ts +0 -8
  345. package/source/RTD/segment.test.ts +0 -35
  346. package/source/RTD/segment.ts +0 -51
  347. package/source/RTD/syntax/index.ts +0 -2
  348. package/source/RTD/syntax/parse.test.ts +0 -196
  349. package/source/RTD/syntax/parse.ts +0 -171
  350. package/source/RTD/syntax/types.ts +0 -69
  351. package/source/RTD/walk.test.ts +0 -147
  352. package/source/Remotes.test.ts +0 -79
  353. package/source/Remotes.ts +0 -39
  354. package/source/Tenant.ts +0 -73
  355. package/source/const.ts +0 -45
  356. package/source/deployment.ts +0 -96
  357. package/source/directives/auth/Anonymous.test.ts +0 -70
  358. package/source/directives/auth/Anonymous.ts +0 -36
  359. package/source/directives/auth/Anyone.ts +0 -23
  360. package/source/directives/auth/Assert.ts +0 -43
  361. package/source/directives/auth/Authorization.test.ts +0 -24
  362. package/source/directives/auth/Authorization.ts +0 -388
  363. package/source/directives/auth/Delegate.test.ts +0 -36
  364. package/source/directives/auth/Delegate.ts +0 -54
  365. package/source/directives/auth/Echo.ts +0 -24
  366. package/source/directives/auth/Federation.ts +0 -104
  367. package/source/directives/auth/Id.ts +0 -37
  368. package/source/directives/auth/Incept.ts +0 -117
  369. package/source/directives/auth/Input.ts +0 -92
  370. package/source/directives/auth/Role.test.ts +0 -147
  371. package/source/directives/auth/Role.ts +0 -99
  372. package/source/directives/auth/Rule.ts +0 -59
  373. package/source/directives/auth/Scheme.ts +0 -31
  374. package/source/directives/auth/create.ts +0 -11
  375. package/source/directives/auth/index.ts +0 -3
  376. package/source/directives/auth/schemes.test.ts +0 -18
  377. package/source/directives/auth/schemes.ts +0 -39
  378. package/source/directives/auth/split.ts +0 -14
  379. package/source/directives/auth/types.ts +0 -75
  380. package/source/directives/cache/Cache.ts +0 -92
  381. package/source/directives/cache/Control.ts +0 -81
  382. package/source/directives/cache/Exact.ts +0 -7
  383. package/source/directives/cache/etag.ts +0 -38
  384. package/source/directives/cache/index.ts +0 -3
  385. package/source/directives/cache/types.ts +0 -9
  386. package/source/directives/cors/CORS.test.ts +0 -75
  387. package/source/directives/cors/CORS.ts +0 -88
  388. package/source/directives/cors/index.ts +0 -3
  389. package/source/directives/dev/Development.ts +0 -41
  390. package/source/directives/dev/Faulty.ts +0 -31
  391. package/source/directives/dev/Sleep.ts +0 -53
  392. package/source/directives/dev/Stub.ts +0 -14
  393. package/source/directives/dev/Throw.ts +0 -14
  394. package/source/directives/dev/index.ts +0 -3
  395. package/source/directives/dev/types.ts +0 -5
  396. package/source/directives/flow/Compose.ts +0 -98
  397. package/source/directives/flow/Fetch.ts +0 -86
  398. package/source/directives/flow/Flow.ts +0 -43
  399. package/source/directives/flow/index.ts +0 -3
  400. package/source/directives/flow/types.ts +0 -7
  401. package/source/directives/help/Family.ts +0 -122
  402. package/source/directives/help/Help.test.ts +0 -227
  403. package/source/directives/help/Help.ts +0 -47
  404. package/source/directives/help/Parameters.ts +0 -47
  405. package/source/directives/help/described.ts +0 -57
  406. package/source/directives/help/index.ts +0 -45
  407. package/source/directives/index.ts +0 -33
  408. package/source/directives/io/Directive.ts +0 -17
  409. package/source/directives/io/IO.ts +0 -118
  410. package/source/directives/io/Input.ts +0 -55
  411. package/source/directives/io/Message.ts +0 -1
  412. package/source/directives/io/Output.ts +0 -81
  413. package/source/directives/io/Status.test.ts +0 -88
  414. package/source/directives/io/Status.ts +0 -47
  415. package/source/directives/io/Throttle.ts +0 -30
  416. package/source/directives/io/index.ts +0 -3
  417. package/source/directives/io/lib/throttle/Configuration.test.ts +0 -72
  418. package/source/directives/io/lib/throttle/Configuration.ts +0 -68
  419. package/source/directives/io/lib/throttle/Keys.ts +0 -53
  420. package/source/directives/io/lib/throttle/Quotas.test.ts +0 -411
  421. package/source/directives/io/lib/throttle/Quotas.ts +0 -190
  422. package/source/directives/io/lib/throttle/Sync.test.ts +0 -163
  423. package/source/directives/io/lib/throttle/Sync.ts +0 -93
  424. package/source/directives/io/lib/throttle/Warning.test.ts +0 -32
  425. package/source/directives/io/lib/throttle/Warning.ts +0 -29
  426. package/source/directives/io/lib/throttle/components/Component.ts +0 -7
  427. package/source/directives/io/lib/throttle/components/IP.ts +0 -30
  428. package/source/directives/io/lib/throttle/components/Identity.ts +0 -19
  429. package/source/directives/io/lib/throttle/components/Path.ts +0 -8
  430. package/source/directives/io/lib/throttle/components/Route.ts +0 -19
  431. package/source/directives/io/lib/throttle/components/Segment.ts +0 -19
  432. package/source/directives/io/lib/throttle/components/index.ts +0 -19
  433. package/source/directives/io/lib/throttle/conditions/Condition.ts +0 -5
  434. package/source/directives/io/lib/throttle/conditions/Status.ts +0 -17
  435. package/source/directives/io/lib/throttle/conditions/index.ts +0 -11
  436. package/source/directives/io/lib/throttle/index.ts +0 -4
  437. package/source/directives/io/schemas.test.ts +0 -40
  438. package/source/directives/io/schemas.ts +0 -16
  439. package/source/directives/map/Authority.ts +0 -15
  440. package/source/directives/map/Buffer.ts +0 -15
  441. package/source/directives/map/Claims.ts +0 -63
  442. package/source/directives/map/Directive.ts +0 -4
  443. package/source/directives/map/Headers.ts +0 -60
  444. package/source/directives/map/Language.ts +0 -45
  445. package/source/directives/map/Languages.ts +0 -17
  446. package/source/directives/map/Map.ts +0 -85
  447. package/source/directives/map/Mapping.ts +0 -45
  448. package/source/directives/map/Properties.ts +0 -15
  449. package/source/directives/map/Segments.ts +0 -52
  450. package/source/directives/map/index.ts +0 -3
  451. package/source/directives/mcp/MCP.ts +0 -33
  452. package/source/directives/mcp/Tool.test.ts +0 -56
  453. package/source/directives/mcp/Tool.ts +0 -32
  454. package/source/directives/mcp/index.ts +0 -6
  455. package/source/directives/oauth/Discovery.ts +0 -66
  456. package/source/directives/oauth/documents.ts +0 -110
  457. package/source/directives/oauth/index.ts +0 -3
  458. package/source/directives/octets/Context.ts +0 -23
  459. package/source/directives/octets/Delete.ts +0 -96
  460. package/source/directives/octets/Directive.ts +0 -21
  461. package/source/directives/octets/Get.ts +0 -88
  462. package/source/directives/octets/Octets.ts +0 -82
  463. package/source/directives/octets/Put.ts +0 -186
  464. package/source/directives/octets/Workflow.ts +0 -60
  465. package/source/directives/octets/bytes.test.ts +0 -33
  466. package/source/directives/octets/bytes.ts +0 -18
  467. package/source/directives/octets/index.ts +0 -3
  468. package/source/directives/octets/schemas.test.ts +0 -20
  469. package/source/directives/octets/schemas.ts +0 -15
  470. package/source/directives/octets/types.ts +0 -9
  471. package/source/directives/octets/workflows/Execution.ts +0 -130
  472. package/source/directives/octets/workflows/Workflow.ts +0 -51
  473. package/source/directives/octets/workflows/index.ts +0 -1
  474. package/source/directives/require/Directive.ts +0 -5
  475. package/source/directives/require/Headers.ts +0 -19
  476. package/source/directives/require/Require.ts +0 -27
  477. package/source/directives/require/index.ts +0 -3
  478. package/source/discovery.ts +0 -1
  479. package/source/exceptions.ts +0 -47
  480. package/source/index.ts +0 -12
  481. package/source/io.ts +0 -4
  482. package/source/manifest.test.ts +0 -56
  483. package/source/manifest.ts +0 -56
  484. package/source/octets.d.ts +0 -17
  485. package/source/root.ts +0 -59
  486. package/source/schemas.test.ts +0 -31
  487. package/source/schemas.ts +0 -15
  488. package/source/service.ts +0 -94
  489. package/source/shortcuts.ts +0 -14
  490. package/source/userland.ts +0 -47
  491. package/transpiled/Annotation.d.ts +0 -70
  492. package/transpiled/Annotation.js +0 -2
  493. package/transpiled/Annotation.js.map +0 -1
  494. package/transpiled/RTD/syntax/parse.d.ts +0 -4
  495. package/transpiled/RTD/syntax/parse.js +0 -112
  496. package/transpiled/RTD/syntax/parse.js.map +0 -1
  497. package/transpiled/RTD/syntax/types.d.ts +0 -52
  498. package/transpiled/RTD/syntax/types.js +0 -11
  499. package/transpiled/RTD/syntax/types.js.map +0 -1
  500. package/transpiled/const.d.ts +0 -36
  501. package/transpiled/const.js +0 -37
  502. package/transpiled/const.js.map +0 -1
  503. package/transpiled/deployment.d.ts +0 -6
  504. package/transpiled/deployment.js +0 -76
  505. package/transpiled/deployment.js.map +0 -1
  506. package/transpiled/manifest.d.ts +0 -3
  507. package/transpiled/manifest.js +0 -39
  508. package/transpiled/manifest.js.map +0 -1
  509. package/transpiled/schemas.d.ts +0 -9
  510. package/transpiled/schemas.js +0 -9
  511. package/transpiled/schemas.js.map +0 -1
  512. package/transpiled/shortcuts.d.ts +0 -3
  513. package/transpiled/shortcuts.js +0 -13
  514. package/transpiled/shortcuts.js.map +0 -1
  515. package/tsconfig.json +0 -13
  516. package/tsconfig.tsbuildinfo +0 -1
  517. package/ui/dist/_app/immutable/assets/0.Bl7vLmIK.css +0 -2
  518. package/ui/dist/_app/immutable/assets/2.BC0-Jhqu.css +0 -1
  519. package/ui/dist/_app/immutable/chunks/B_pK3U1C.js +0 -6
  520. package/ui/dist/_app/immutable/chunks/CiKbPLyY.js +0 -1
  521. package/ui/dist/_app/immutable/chunks/DjIYL2zC.js +0 -3
  522. package/ui/dist/_app/immutable/entry/app.DMqmL4NY.js +0 -2
  523. package/ui/dist/_app/immutable/entry/start.CRe7HWBI.js +0 -1
  524. package/ui/dist/_app/immutable/nodes/0.D9m-6cbM.js +0 -1
  525. package/ui/dist/_app/immutable/nodes/1.Cgi_RcSO.js +0 -1
  526. package/ui/dist/_app/immutable/nodes/2.D_Cbxgz4.js +0 -14
package/source/Gateway.ts DELETED
@@ -1,390 +0,0 @@
1
- import assert from 'node:assert'
2
- import { setTimeout } from 'node:timers/promises'
3
- import { console } from 'openspan'
4
- import { Connector } from '@toa.io/core'
5
- import type { bindings } from '@toa.io/core/types'
6
- import * as http from './HTTP/index.js'
7
- import { DISCOVERY, MCP, RPC } from './const.js'
8
- import { rethrow } from './exceptions.js'
9
- import { decide } from './Branch.js'
10
- import { describing } from './Introspection.js'
11
- import { Explorer, looking } from './Discovery/index.js'
12
- import type { Interception } from './Interception.js'
13
- import type { Dispatcher } from './RPC/index.js'
14
- import type { Server } from './MCP/index.js'
15
- import type {
16
- DirectiveFactory,
17
- Method,
18
- Node,
19
- Parameter,
20
- Tree,
21
- Match
22
- } from './RTD/index.js'
23
- import type { Label } from './discovery.js'
24
- import type { Branch, Exposed } from './Branch.js'
25
-
26
- export class Gateway extends Connector {
27
- private readonly broadcast: Broadcast
28
- private readonly tree: Tree
29
- private readonly interceptor: Interception
30
- private readonly directives: DirectiveFactory
31
-
32
- /** JSON-RPC is served only where the annotation asked for it. */
33
- private readonly dispatcher: Dispatcher | null
34
-
35
- /** And the same of MCP. */
36
- private readonly mcp: Server | null
37
-
38
- /** The tree, for every route at once. Served always, and so not nullable. */
39
- private readonly explorer: Explorer
40
- private readonly branches = new Map<string, Exposed>()
41
- private lastMerge = 0
42
- private widestGap = 0
43
- private lastPing = 0
44
- private stopped = false
45
- private resolveFirstMerge: (() => void) | null = null
46
-
47
- // eslint-disable-next-line max-params
48
- public constructor(
49
- broadcast: Broadcast,
50
- tree: Tree,
51
- interception: Interception,
52
- directives: DirectiveFactory,
53
- dispatcher: Dispatcher | null,
54
- mcp: Server | null
55
- ) {
56
- super()
57
-
58
- this.broadcast = broadcast
59
- this.tree = tree
60
- this.interceptor = interception
61
- this.directives = directives
62
- this.dispatcher = dispatcher
63
- this.mcp = mcp
64
- this.explorer = new Explorer(tree)
65
-
66
- this.depends(broadcast)
67
- }
68
-
69
- public async process(context: http.Context): Promise<http.OutgoingMessage> {
70
- const interception = await this.interceptor.intercept(context)
71
-
72
- if (interception !== null) return interception
73
-
74
- // request-scoped, before anything is routed: this is where a credential is read
75
- await this.directives.preflight(context).catch(rethrow)
76
-
77
- const response = await this.endpoint(context)
78
-
79
- // request-scoped, on whatever is going back: this is where a credential is re-issued
80
- await this.directives.depart(context, response).catch(rethrow)
81
-
82
- return response
83
- }
84
-
85
- /**
86
- * What answers the request: a pinned endpoint that makes calls of its own, or the route
87
- * the path names.
88
- */
89
- private async endpoint(context: http.Context): Promise<http.OutgoingMessage> {
90
- const route: http.Processor = async (call) => await this.route(call)
91
-
92
- if (this.dispatcher !== null && context.url.pathname === RPC)
93
- return await this.dispatcher.dispatch(context, route)
94
-
95
- if (this.mcp !== null && context.url.pathname === MCP)
96
- return await this.mcp.process(context, route)
97
-
98
- // the page under this prefix is an interceptor's, and has already answered
99
- if (context.url.pathname === DISCOVERY || context.url.pathname === DISCOVERY + '/')
100
- return await this.explorer.process(context)
101
-
102
- // a browser that asked for the trunk of an API is looking for the page, and where the
103
- // application answers there itself, that is what answers
104
- if (context.url.pathname === '/' && !this.serves(context)) {
105
- const page = looking(context)
106
-
107
- if (page !== null) return page
108
- }
109
-
110
- return await this.route(context)
111
- }
112
-
113
- /** Whether the application serves the trunk with the verb the request was made with. */
114
- private serves(context: http.Context): boolean {
115
- const match = this.tree.match('/')
116
-
117
- return match !== null && context.request.method in match.node.methods
118
- }
119
-
120
- /**
121
- * One call: everything that needs a node. A request makes one of these, and a request
122
- * that carries several calls makes one per call.
123
- */
124
- private async route(context: http.Context): Promise<http.OutgoingMessage> {
125
- const { node, parameters } = this.match(context)
126
-
127
- if (context.request.method === 'OPTIONS')
128
- return await this.explain(context, node, parameters)
129
-
130
- let verb = context.request.method
131
-
132
- if (!(verb in node.methods) && verb === 'HEAD' && 'GET' in node.methods) verb = 'GET'
133
-
134
- if (!(verb in node.methods)) throw new http.MethodNotAllowed()
135
-
136
- const method = node.methods[verb]
137
-
138
- const interruption = await method.directives
139
- .precall(context, parameters)
140
- .catch(rethrow)
141
- const response = interruption ?? (await this.call(method, context, parameters))
142
-
143
- await method.directives.settle(context, response).catch(rethrow)
144
-
145
- return response
146
- }
147
-
148
- protected override async open(): Promise<void> {
149
- await this.discover()
150
-
151
- // what is served besides the tree, so that turning one on can be seen to have worked
152
- const pinned: string[] = []
153
-
154
- if (this.dispatcher !== null) pinned.push(RPC)
155
-
156
- if (this.mcp !== null) pinned.push(MCP)
157
-
158
- console.info('Gateway started', {
159
- endpoints: pinned.length === 0 ? 'none' : pinned.join(' ')
160
- })
161
- }
162
-
163
- /**
164
- * Both of these reach into components, and a dependency is torn down only once this has
165
- * returned — where `dispose` runs after every one of them already has. The throttling
166
- * ticker firing in between calls an endpoint that has just been unbound, and reports the
167
- * refusal as a failure to reconcile.
168
- */
169
- protected override async close(): Promise<void> {
170
- this.stopped = true
171
-
172
- this.tree.dispose()
173
- }
174
-
175
- protected override dispose(): void {
176
- console.info('Gateway is closed')
177
- }
178
-
179
- private match(context: http.Context): Match {
180
- const match = this.tree.match(context.url.pathname)
181
-
182
- if (match === null) {
183
- // the route may be missing because an expose has been lost
184
- this.reping()
185
-
186
- throw new http.NotFound('Route not found')
187
- }
188
-
189
- if (match.node.forward === null) return match
190
-
191
- const destination = match.node.forward.replace(/\/:([^/]+)/g, (_, name) => {
192
- const value = match.parameters.find((parameter) => parameter.name === name)?.value
193
-
194
- assert.ok(value !== undefined, `Forwarded parameter '${name}' not found`)
195
-
196
- return `/${value}`
197
- })
198
-
199
- const forward = this.tree.match(destination)
200
-
201
- assert.ok(forward !== null, 'Forwarded route not found')
202
-
203
- return forward
204
- }
205
-
206
- private async call(
207
- method: Method,
208
- context: http.Context,
209
- parameters: Parameter[]
210
- ): Promise<http.OutgoingMessage> {
211
- if (context.url.pathname[context.url.pathname.length - 1] !== '/')
212
- throw new http.NotFound('Trailing slash is required')
213
-
214
- if (context.encoder === null) throw new http.NotAcceptable()
215
-
216
- if (method.endpoint === null) throw new http.MethodNotAllowed()
217
-
218
- return (await method.endpoint
219
- .call(context, parameters)
220
- .catch(rethrow)) as http.OutgoingMessage
221
- }
222
-
223
- private async explain(
224
- context: http.Context,
225
- node: Node,
226
- parameters: Parameter[]
227
- ): Promise<http.OutgoingMessage> {
228
- const { described, methods } = await node.explain(describing(context), parameters)
229
- const verbs = Object.keys(methods)
230
-
231
- // what a caller may not use is not a resource to them, and describing it would be the leak
232
- if (verbs.length === 0 && Object.keys(node.methods).length > 0)
233
- throw new http.Forbidden()
234
-
235
- // what the resource is, beside the methods it serves; a verb is upper case and cannot
236
- // collide with either key
237
- return {
238
- body: { ...described, ...methods },
239
- headers: new Headers({ allow: verbs.join(', ') })
240
- }
241
- }
242
-
243
- private async discover(): Promise<void> {
244
- const first = new Promise<void>((resolve) => {
245
- this.resolveFirstMerge = resolve
246
- })
247
-
248
- await this.broadcast.receive<Branch>('expose', this.merge.bind(this))
249
-
250
- void this.knock()
251
-
252
- await this.settled(first)
253
- }
254
-
255
- /**
256
- * A single ping is enough only if every tenant is listening by then, which is
257
- * not the case while the deployment is still rolling out.
258
- */
259
- private async knock(): Promise<void> {
260
- for (const delay of KNOCK_DELAYS) {
261
- if (this.stopped) return
262
-
263
- if (delay > 0) await setTimeout(delay, undefined, { ref: false })
264
-
265
- await this.ping()
266
- }
267
- }
268
-
269
- private async ping(): Promise<void> {
270
- if (this.stopped) return
271
-
272
- this.lastPing = Date.now()
273
-
274
- await this.broadcast
275
- .transmit<null>('ping', null)
276
- .catch((exception: Error) =>
277
- console.error('Discovery ping failed', { message: exception.message })
278
- )
279
- }
280
-
281
- private reping(): void {
282
- if (Date.now() - this.lastPing < PING_COOLDOWN) return
283
-
284
- void this.ping()
285
- }
286
-
287
- private async settled(first: Promise<void>): Promise<void> {
288
- const deadline = Date.now() + SETTLE_TIMEOUT
289
- const abort = new AbortController()
290
-
291
- // an uncancelled timer keeps the process alive long after the race is won
292
- await Promise.race([
293
- first,
294
- setTimeout(SETTLE_TIMEOUT, undefined, { signal: abort.signal })
295
- ])
296
- .finally(() => {
297
- abort.abort()
298
- })
299
- .catch(() => {})
300
-
301
- if (this.lastMerge === 0) {
302
- console.warn('Discovery timed out waiting for the first expose')
303
-
304
- return
305
- }
306
-
307
- while (Date.now() - this.lastMerge < this.quiet()) {
308
- if (Date.now() >= deadline) break
309
-
310
- await setTimeout(SETTLE_POLL)
311
- }
312
- }
313
-
314
- /**
315
- * How long the branches must stay quiet before discovery counts as settled.
316
- *
317
- * Every tenant of a local composition answers the first ping at once, so a short window
318
- * is enough; a rolling deployment brings them up seconds apart, and the window grows with
319
- * the widest gap seen so far to keep waiting for the ones still starting.
320
- */
321
- private quiet(): number {
322
- const adaptive = this.widestGap * SETTLE_QUIET_FACTOR
323
-
324
- return Math.min(Math.max(adaptive, SETTLE_QUIET_MIN), SETTLE_QUIET_MAX)
325
- }
326
-
327
- private merge(branch: Branch): void {
328
- const id = branch.namespace + '.' + branch.component
329
-
330
- const attributes = {
331
- namespace: branch.namespace,
332
- component: branch.component,
333
- version: branch.version
334
- }
335
-
336
- const exposed = this.branches.get(id)
337
-
338
- if (exposed !== undefined)
339
- switch (decide(exposed, branch)) {
340
- // rebuilding an identical branch would only tear down its live endpoints
341
- case 'refresh':
342
- this.tree.refresh(exposed.nodes)
343
- console.trace('Branch refreshed', attributes)
344
-
345
- return
346
-
347
- case 'superseded':
348
- console.debug('Branch superseded', {
349
- ...attributes,
350
- timestamp: branch.timestamp,
351
- exposed: exposed.timestamp
352
- })
353
-
354
- return
355
- }
356
-
357
- let nodes: Node[]
358
-
359
- try {
360
- nodes = this.tree.merge(branch.node, branch)
361
- } catch (exception: unknown) {
362
- const message = exception instanceof Error ? exception.message : 'Unknown error'
363
-
364
- console.error('Branch merge exception', { message, ...attributes })
365
-
366
- return
367
- }
368
-
369
- this.branches.set(id, { version: branch.version, timestamp: branch.timestamp, nodes })
370
-
371
- if (this.lastMerge !== 0)
372
- this.widestGap = Math.max(this.widestGap, Date.now() - this.lastMerge)
373
-
374
- this.lastMerge = Date.now()
375
- this.resolveFirstMerge?.()
376
- this.resolveFirstMerge = null
377
-
378
- console.info('Branch merged', attributes)
379
- }
380
- }
381
-
382
- export type Broadcast = bindings.Broadcast<Label>
383
-
384
- const SETTLE_QUIET_MIN = 500
385
- const SETTLE_QUIET_MAX = 10_000
386
- const SETTLE_QUIET_FACTOR = 2
387
- const SETTLE_TIMEOUT = 30_000
388
- const SETTLE_POLL = 50
389
- const KNOCK_DELAYS = [0, 500, 1000, 1500]
390
- const PING_COOLDOWN = 5_000
@@ -1,143 +0,0 @@
1
- import { buffer } from 'node:stream/consumers'
2
- import Negotiator from 'negotiator'
3
- import { console } from 'openspan'
4
- import { Timing } from './Timing.js'
5
- import { type Format, formats, types } from './formats/index.js'
6
- import { read } from './messages.js'
7
- import { address } from './address.js'
8
- import type { OutgoingMessage } from './messages.js'
9
- import type { IncomingMessage } from './types.js'
10
-
11
- export class Context {
12
- public readonly authority: string
13
- public readonly request: IncomingMessage
14
-
15
- /** the client address, read as the deployment says; none otherwise, see `documentation/ip.md` */
16
- public readonly ip: string | undefined
17
- public readonly url: URL
18
- public readonly subtype: string | null = null
19
- public readonly encoder: Format | null = null
20
- public readonly timing: Timing
21
-
22
- /**
23
- * Whether this is a procedure a request made, rather than the request. What forks one
24
- * says so, and a directive that answers differently to a procedure than to a request
25
- * reads it here.
26
- */
27
- public readonly procedural: boolean = false
28
-
29
- /**
30
- * Whether this describes a resource rather than calling one. What builds a describing
31
- * context says so, and a directive that answers differently to a description than to a
32
- * call reads it here.
33
- */
34
- public readonly exploratory: boolean = false
35
-
36
- public readonly pipelines: Pipelines = {
37
- body: [],
38
- response: []
39
- }
40
-
41
- private consumed = false
42
-
43
- // eslint-disable-next-line max-params
44
- public constructor(
45
- authority: string,
46
- request: IncomingMessage,
47
- properties: Properties,
48
- url: URL
49
- ) {
50
- this.authority = authority
51
- this.request = request
52
- this.ip = address(request, properties.ip)
53
-
54
- // parsed by the server, which had to parse it anyway to know the request is valid
55
- this.url = url
56
- this.timing = new Timing()
57
- this.log(request)
58
-
59
- const accept = this.request.headers.accept
60
-
61
- if (accept !== undefined) {
62
- const match = SUBTYPE.exec(accept)
63
-
64
- if (match !== null) {
65
- const { type, subtype, suffix } = match.groups!
66
-
67
- this.request.headers.accept = `${type}/${suffix}`
68
- this.subtype = subtype
69
- }
70
- }
71
-
72
- const encoder = negotiate(this.request)
73
-
74
- if (encoder !== undefined) this.encoder = encoder
75
- }
76
-
77
- public async buffer(): Promise<Buffer> {
78
- this.consumed = true
79
-
80
- return await buffer(this.request)
81
- }
82
-
83
- public async body<T>(): Promise<T> {
84
- let value = this.consumed ? null : await read(this)
85
-
86
- for (const transform of this.pipelines.body) value = await transform(value)
87
-
88
- return value
89
- }
90
-
91
- private log(request: IncomingMessage): void {
92
- // built only when the line is written, which at `info` it is not
93
- console.debug('Received request', () => {
94
- const headers = { ...request.headers }
95
-
96
- if (headers.authorization !== undefined)
97
- headers.authorization = SCHEME.exec(headers.authorization)?.[1] ?? '[malformed]'
98
-
99
- return { method: request.method, url: request.url, headers }
100
- })
101
- }
102
- }
103
-
104
- /** The scheme of an `authorization` header; the value after it is a credential. */
105
- const SCHEME = /^(\w{1,32})(?: |$)/
106
-
107
- interface Pipelines {
108
- body: Array<(input: unknown) => unknown>
109
- response: Array<(output: OutgoingMessage) => void | Promise<void>>
110
- }
111
-
112
- interface Properties {
113
- /** the header the client address is read from; the connection's without one */
114
- ip?: string
115
- }
116
-
117
- /**
118
- * Negotiation parses the header and sorts the candidates, and the value repeats:
119
- * clients send one of a handful of `accept` strings. Bounded, the header is theirs.
120
- */
121
- function negotiate(request: IncomingMessage): Format | undefined {
122
- const accept = request.headers.accept ?? ''
123
- const known = NEGOTIATED.get(accept)
124
-
125
- if (known !== undefined) return known === NONE ? undefined : known
126
-
127
- const mediaType = new Negotiator(request).mediaType(types)
128
- const encoder = mediaType === undefined ? undefined : formats[mediaType]
129
-
130
- if (NEGOTIATED.size >= NEGOTIATED_LIMIT) NEGOTIATED.clear()
131
-
132
- NEGOTIATED.set(accept, encoder ?? NONE)
133
-
134
- return encoder
135
- }
136
-
137
- /** distinguishes "negotiated to nothing" from "not negotiated yet" */
138
- const NONE = Symbol('not acceptable') as unknown as Format
139
- const NEGOTIATED = new Map<string, Format>()
140
- const NEGOTIATED_LIMIT = 1024
141
-
142
- const SUBTYPE =
143
- /^(?<type>\w{1,32})\/(vnd\.toa\.(?<subtype>\S{1,32})\+)(?<suffix>\S{1,32})$/
@@ -1,99 +0,0 @@
1
- import * as http from 'node:http'
2
- import { console } from 'openspan'
3
-
4
- /**
5
- * The readiness probe, on a port of its own.
6
- *
7
- * It cannot share the port the gateway serves traffic on: kubelet speaks HTTP/1.1 only, and a
8
- * cleartext HTTP/2 server answers nothing else on its port — there is no ALPN to negotiate with.
9
- *
10
- * It is the gateway's own readiness, not the process's. The identity composition nested in this
11
- * process connects before route discovery has settled, so a probe tied to that composition would
12
- * report ready while the gateway still had no routes and no open port.
13
- */
14
- export class Probe {
15
- private readonly server = http.createServer()
16
- private readonly port: number
17
- private readonly path: string
18
-
19
- private ready = false
20
- private startedAt = 0
21
- private listening = false
22
- private skipped = false
23
-
24
- public constructor(port: number, path: string = PATH) {
25
- this.port = port
26
- this.path = path
27
-
28
- this.server.on('request', (request, response) => this.listener(request, response))
29
- }
30
-
31
- public async listen(): Promise<void> {
32
- this.startedAt = Date.now()
33
-
34
- try {
35
- await new Promise<void>((resolve, reject) => {
36
- this.server.once('error', reject)
37
- this.server.listen(this.port, () => {
38
- this.server.removeListener('error', reject)
39
- resolve()
40
- })
41
- })
42
- } catch (error: any) {
43
- // processes sharing a host share the port; in a pod nothing else claims it
44
- if (error?.code === 'EADDRINUSE') {
45
- this.skipped = true
46
-
47
- console.warn('Ready probe port already in use, skipping', { port: this.port })
48
-
49
- return
50
- }
51
-
52
- throw error
53
- }
54
-
55
- this.listening = true
56
-
57
- // a probe answers while the process runs; it must never be the reason it keeps running
58
- this.server.unref()
59
- }
60
-
61
- /** The gateway is listening and has routes: answer `200`. */
62
- public complete(): void {
63
- this.ready = true
64
-
65
- // the IPC signal is not tied to the probe: a process that gave up the shared port is
66
- // still ready, and pm2 `wait_ready` would otherwise block until `listen_timeout`
67
- process.send?.('ready')
68
- }
69
-
70
- public async close(): Promise<void> {
71
- this.ready = false
72
-
73
- if (!this.listening || this.skipped) return
74
-
75
- this.listening = false
76
-
77
- // keep-alive connections would otherwise hold the server handle, delaying the exit
78
- this.server.closeAllConnections()
79
-
80
- await new Promise<void>((resolve) => this.server.close(() => resolve()))
81
- }
82
-
83
- private listener(request: http.IncomingMessage, response: http.ServerResponse): void {
84
- if (request.url !== this.path) {
85
- response.writeHead(404).end()
86
-
87
- return
88
- }
89
-
90
- if (this.ready) response.writeHead(200, { 'cache-control': 'no-store' }).end()
91
- else {
92
- const remaining = Math.ceil((Date.now() - this.startedAt) / 1000).toString()
93
-
94
- response.writeHead(503, { 'retry-after': remaining }).end()
95
- }
96
- }
97
- }
98
-
99
- export const PATH = '/.ready'