@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.
- package/CHANGELOG.md +56 -0
- package/components/exposition.octets/manifest.toa.yaml +11 -0
- package/components/exposition.octets/types/index.d.ts +3 -0
- package/components/exposition.octets/types/toa.d.ts +41 -0
- package/components/identity.bans/operations/transit.js +1 -1
- package/components/identity.bans/tsconfig.json +1 -1
- package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/types/index.d.ts +3 -0
- package/components/identity.bans/types/toa.d.ts +34 -0
- package/components/identity.basic/manifest.toa.yaml +13 -2
- package/components/identity.basic/operations/add.js +1 -1
- package/components/identity.basic/operations/authenticate.js +1 -1
- package/components/identity.basic/operations/check.js +1 -1
- package/components/identity.basic/operations/delete.js +1 -1
- package/components/identity.basic/operations/incept.js +18 -2
- package/components/identity.basic/operations/info.js +1 -1
- package/components/identity.basic/operations/lib/credentials.js +1 -1
- package/components/identity.basic/operations/transit.js +3 -2
- package/components/identity.basic/source/add.ts +3 -3
- package/components/identity.basic/source/authenticate.ts +2 -2
- package/components/identity.basic/source/check.ts +1 -1
- package/components/identity.basic/source/delete.ts +2 -2
- package/components/identity.basic/source/incept.ts +31 -3
- package/components/identity.basic/source/info.ts +1 -1
- package/components/identity.basic/source/transit.ts +6 -4
- package/components/identity.basic/tsconfig.json +1 -1
- package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/types/index.d.ts +22 -0
- package/components/identity.basic/types/toa.d.ts +121 -0
- package/components/identity.clients/manifest.toa.yaml +243 -0
- package/components/identity.clients/operations/describe.js +44 -0
- package/components/identity.clients/operations/lib/Context.js +2 -0
- package/components/identity.clients/operations/lib/Entity.js +2 -0
- package/components/identity.clients/operations/lib/canonical.js +24 -0
- package/components/identity.clients/operations/lib/cimd.js +86 -0
- package/components/identity.clients/operations/lib/errors.js +5 -0
- package/components/identity.clients/operations/lib/index.js +7 -0
- package/components/identity.clients/operations/lib/redirect.js +32 -0
- package/components/identity.clients/operations/register.js +84 -0
- package/components/identity.clients/source/describe.ts +65 -0
- package/components/identity.clients/source/lib/Context.ts +38 -0
- package/components/identity.clients/source/lib/Entity.ts +31 -0
- package/components/identity.clients/source/lib/canonical.test.ts +43 -0
- package/components/identity.clients/source/lib/canonical.ts +27 -0
- package/components/identity.clients/source/lib/cimd.test.ts +120 -0
- package/components/identity.clients/source/lib/cimd.ts +107 -0
- package/components/identity.clients/source/lib/errors.ts +4 -0
- package/components/identity.clients/source/lib/index.ts +6 -0
- package/components/identity.clients/source/lib/redirect.test.ts +41 -0
- package/components/identity.clients/source/lib/redirect.ts +35 -0
- package/components/identity.clients/source/register.ts +125 -0
- package/components/identity.clients/tsconfig.json +10 -0
- package/components/identity.clients/tsconfig.tsbuildinfo +1 -0
- package/components/identity.clients/types/index.d.ts +3 -0
- package/components/identity.clients/types/toa.d.ts +109 -0
- package/components/identity.credentials/operations/list.js +1 -1
- package/components/identity.credentials/source/list.ts +2 -1
- package/components/identity.credentials/tsconfig.json +4 -2
- package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
- package/components/identity.credentials/types/index.d.ts +3 -0
- package/components/identity.credentials/types/toa.d.ts +30 -0
- package/components/identity.federation/manifest.toa.yaml +37 -1
- package/components/identity.federation/operations/authenticate.js +7 -3
- package/components/identity.federation/operations/create.js +1 -1
- package/components/identity.federation/operations/decode.js +1 -1
- package/components/identity.federation/operations/delete.js +1 -1
- package/components/identity.federation/operations/incept.js +6 -2
- package/components/identity.federation/operations/lib/Configuration.js +1 -1
- package/components/identity.federation/operations/lib/Ctx.js +1 -1
- package/components/identity.federation/operations/lib/Payload.js +1 -1
- package/components/identity.federation/operations/lib/decode.js +23 -9
- package/components/identity.federation/operations/lib/discovery.js +1 -1
- package/components/identity.federation/operations/lib/errors.js +5 -1
- package/components/identity.federation/operations/lib/exchange.js +12 -7
- package/components/identity.federation/operations/lib/index.js +2 -1
- package/components/identity.federation/operations/lib/jose.js +1 -1
- package/components/identity.federation/operations/lib/principal.js +14 -0
- package/components/identity.federation/operations/lib/resolve.js +1 -1
- package/components/identity.federation/operations/list.js +1 -1
- package/components/identity.federation/operations/types/Scheme.js +1 -1
- package/components/identity.federation/operations/types/configuration.js +1 -1
- package/components/identity.federation/operations/types/context.js +1 -1
- package/components/identity.federation/operations/types/entity.js +1 -1
- package/components/identity.federation/operations/types/index.js +1 -1
- package/components/identity.federation/source/authenticate.ts +9 -3
- package/components/identity.federation/source/incept.ts +7 -1
- package/components/identity.federation/source/lib/Ctx.ts +2 -2
- package/components/identity.federation/source/lib/decode.ts +25 -9
- package/components/identity.federation/source/lib/errors.ts +5 -0
- package/components/identity.federation/source/lib/exchange.ts +11 -7
- package/components/identity.federation/source/lib/index.ts +1 -0
- package/components/identity.federation/source/lib/principal.ts +17 -0
- package/components/identity.federation/source/types/configuration.ts +1 -1
- package/components/identity.federation/source/types/context.ts +6 -2
- package/components/identity.federation/tsconfig.json +4 -2
- package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/types/index.d.ts +3 -0
- package/components/identity.federation/types/toa.d.ts +127 -0
- package/components/identity.grants/manifest.toa.yaml +245 -0
- package/components/identity.grants/operations/authorize.js +54 -0
- package/components/identity.grants/operations/exchange.js +89 -0
- package/components/identity.grants/operations/lib/code.js +30 -0
- package/components/identity.grants/operations/lib/identify.js +15 -0
- package/components/identity.grants/operations/lib/index.js +3 -0
- package/components/identity.grants/operations/list.js +18 -0
- package/components/identity.grants/operations/revoke.js +25 -0
- package/components/identity.grants/source/authorize.ts +90 -0
- package/components/identity.grants/source/exchange.ts +130 -0
- package/components/identity.grants/source/lib/code.ts +39 -0
- package/components/identity.grants/source/lib/identify.ts +16 -0
- package/components/identity.grants/source/lib/index.ts +3 -0
- package/components/identity.grants/source/list.ts +28 -0
- package/components/identity.grants/source/revoke.ts +38 -0
- package/components/identity.grants/tsconfig.json +10 -0
- package/components/identity.grants/tsconfig.tsbuildinfo +1 -0
- package/components/identity.grants/types/index.d.ts +60 -0
- package/components/identity.grants/types/toa.d.ts +108 -0
- package/components/identity.keys/manifest.toa.yaml +1 -0
- package/components/identity.keys/operations/create.js +1 -1
- package/components/identity.keys/operations/disable.js +1 -1
- package/components/identity.keys/operations/revoke.js +1 -1
- package/components/identity.keys/source/create.ts +1 -1
- package/components/identity.keys/source/revoke.ts +1 -1
- package/components/identity.keys/tsconfig.json +1 -1
- package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.keys/types/index.d.ts +3 -0
- package/components/identity.keys/types/toa.d.ts +47 -0
- package/components/identity.otp/operations/authenticate.js +1 -1
- package/components/identity.otp/operations/issue.js +1 -1
- package/components/identity.otp/operations/lib/Context.js +1 -1
- package/components/identity.otp/operations/lib/Entity.js +1 -1
- package/components/identity.otp/operations/lib/index.js +1 -1
- package/components/identity.otp/source/lib/Context.ts +4 -2
- package/components/identity.otp/tsconfig.json +1 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/types/index.d.ts +3 -0
- package/components/identity.otp/types/toa.d.ts +56 -0
- package/components/identity.passkeys/manifest.toa.yaml +3 -0
- package/components/identity.passkeys/operations/authenticate.js +1 -1
- package/components/identity.passkeys/operations/challenge.js +1 -1
- package/components/identity.passkeys/operations/create.js +1 -1
- package/components/identity.passkeys/operations/delete.js +1 -1
- package/components/identity.passkeys/operations/lib/const.js +1 -1
- package/components/identity.passkeys/operations/list.js +1 -1
- package/components/identity.passkeys/operations/types/Configuration.js +1 -1
- package/components/identity.passkeys/operations/types/Context.js +1 -1
- package/components/identity.passkeys/operations/types/Passkey.js +1 -1
- package/components/identity.passkeys/operations/types/index.js +1 -1
- package/components/identity.passkeys/operations/use.js +1 -1
- package/components/identity.passkeys/source/authenticate.ts +1 -1
- package/components/identity.passkeys/source/challenge.ts +1 -1
- package/components/identity.passkeys/source/create.ts +1 -1
- package/components/identity.passkeys/source/types/Context.ts +2 -1
- package/components/identity.passkeys/source/use.ts +1 -1
- package/components/identity.passkeys/tsconfig.json +1 -1
- package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/types/index.d.ts +3 -0
- package/components/identity.passkeys/types/toa.d.ts +120 -0
- package/components/identity.roles/operations/grant.js +1 -1
- package/components/identity.roles/operations/lib/Entity.js +1 -1
- package/components/identity.roles/operations/list.js +1 -1
- package/components/identity.roles/operations/principal.js +29 -5
- package/components/identity.roles/source/principal.ts +33 -5
- package/components/identity.roles/tsconfig.json +1 -1
- package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/types/index.d.ts +3 -0
- package/components/identity.roles/types/toa.d.ts +43 -0
- package/components/identity.tokens/manifest.toa.yaml +34 -3
- package/components/identity.tokens/operations/authenticate.js +9 -1
- package/components/identity.tokens/operations/decrypt.js +3 -3
- package/components/identity.tokens/operations/encrypt.js +1 -1
- package/components/identity.tokens/operations/issue.js +3 -2
- package/components/identity.tokens/operations/lib/form.js +24 -0
- package/components/identity.tokens/operations/lib/index.js +2 -2
- package/components/identity.tokens/operations/lib/jose.js +1 -1
- package/components/identity.tokens/operations/lib/key.js +1 -1
- package/components/identity.tokens/operations/lib/pad.js +1 -1
- package/components/identity.tokens/operations/revoke.js +1 -1
- package/components/identity.tokens/source/authenticate.test.ts +8 -5
- package/components/identity.tokens/source/authenticate.ts +12 -1
- package/components/identity.tokens/source/decrypt.test.ts +1 -1
- package/components/identity.tokens/source/decrypt.ts +4 -3
- package/components/identity.tokens/source/encrypt.test.ts +1 -1
- package/components/identity.tokens/source/encrypt.ts +2 -1
- package/components/identity.tokens/source/issue.test.ts +71 -0
- package/components/identity.tokens/source/issue.ts +4 -2
- package/components/identity.tokens/source/lib/form.test.ts +25 -0
- package/components/identity.tokens/source/lib/form.ts +31 -0
- package/components/identity.tokens/source/lib/index.ts +2 -1
- package/components/identity.tokens/tsconfig.json +1 -1
- package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/types/index.d.ts +61 -0
- package/components/identity.tokens/types/toa.d.ts +113 -0
- package/documentation/access.md +13 -0
- package/documentation/cache.md +10 -1
- package/documentation/components.md +3 -0
- package/documentation/consent.md +101 -0
- package/documentation/identity.md +3 -1
- package/documentation/introspection.md +13 -5
- package/documentation/io.md +42 -2
- package/documentation/map.md +8 -0
- package/documentation/mcp.md +180 -0
- package/documentation/oauth.md +180 -0
- package/documentation/protocol.md +4 -0
- package/documentation/rpc.md +140 -0
- package/documentation/tree.md +3 -0
- package/features/auth.bearer.feature +120 -0
- package/features/cache.feature +46 -0
- package/features/identity.basic.feature +44 -0
- package/features/identity.federation.feature +2 -5
- package/features/introspection.feature +333 -0
- package/features/mcp.feature +687 -0
- package/features/oauth.clients.feature +195 -0
- package/features/oauth.discovery.feature +164 -0
- package/features/oauth.grants.feature +299 -0
- package/features/octets.cloudinary.feature +1 -0
- package/features/rpc.feature +429 -0
- package/features/steps/Cloudinary.ts +13 -0
- package/features/steps/Components.ts +0 -4
- package/features/steps/Gateway.ts +23 -2
- package/features/steps/Parameters.ts +22 -7
- package/features/steps/Realtime.ts +3 -0
- package/features/steps/components/echo/manifest.toa.yaml +3 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +2 -0
- package/features/steps/components/octets.tester/operations/redirect.js +6 -1
- package/features/steps/components/pots/manifest.toa.yaml +2 -0
- package/features/steps/components/users/manifest.toa.yaml +1 -0
- package/package.json +8 -6
- package/readme.md +6 -0
- package/schemas/annotation.cos.yaml +63 -0
- package/schemas/call.cos.yaml +18 -0
- package/source/Annotation.ts +54 -0
- package/source/Directive.test.ts +15 -15
- package/source/Directive.ts +77 -9
- package/source/Endpoint.test.ts +67 -0
- package/source/Endpoint.ts +31 -11
- package/source/Factory.ts +6 -2
- package/source/Gateway.ts +73 -11
- package/source/HTTP/Context.ts +7 -0
- package/source/HTTP/Server.ts +15 -5
- package/source/HTTP/exceptions.ts +2 -2
- package/source/HTTP/formats/form.ts +21 -0
- package/source/HTTP/formats/index.ts +17 -2
- package/source/HTTP/messages.test.ts +25 -1
- package/source/HTTP/messages.ts +20 -4
- package/source/Interception.ts +8 -2
- package/source/Introspection.ts +102 -0
- package/source/MCP/Server.ts +275 -0
- package/source/MCP/discover.ts +52 -0
- package/source/MCP/errors.ts +81 -0
- package/source/MCP/index.ts +1 -0
- package/source/MCP/schema.test.ts +85 -0
- package/source/MCP/schema.ts +87 -0
- package/source/MCP/tools.ts +156 -0
- package/source/MCP/types.ts +81 -0
- package/source/Query.ts +48 -8
- package/source/RPC/Context.ts +78 -0
- package/source/RPC/Dispatcher.ts +130 -0
- package/source/RPC/errors.test.ts +52 -0
- package/source/RPC/errors.ts +83 -0
- package/source/RPC/index.ts +1 -0
- package/source/RPC/names.test.ts +122 -0
- package/source/RPC/names.ts +182 -0
- package/source/RPC/types.ts +34 -0
- package/source/RTD/Directives.ts +52 -2
- package/source/RTD/Endpoint.ts +2 -1
- package/source/RTD/Method.ts +14 -11
- package/source/RTD/Node.ts +38 -7
- package/source/RTD/Route.ts +30 -3
- package/source/RTD/Tree.ts +37 -1
- package/source/RTD/expiration.test.ts +1 -1
- package/source/RTD/walk.test.ts +110 -0
- package/source/const.ts +15 -0
- package/source/deployment.ts +11 -1
- package/source/directives/auth/Anonymous.test.ts +38 -0
- package/source/directives/auth/Anonymous.ts +12 -0
- package/source/directives/auth/Anyone.ts +4 -0
- package/source/directives/auth/Authorization.ts +108 -22
- package/source/directives/auth/Delegate.test.ts +36 -0
- package/source/directives/auth/Delegate.ts +14 -0
- package/source/directives/auth/Echo.ts +5 -0
- package/source/directives/auth/Incept.ts +16 -10
- package/source/directives/auth/Role.ts +13 -0
- package/source/directives/auth/Rule.ts +29 -0
- package/source/directives/auth/Scheme.ts +5 -0
- package/source/directives/auth/schemes.test.ts +8 -4
- package/source/directives/auth/schemes.ts +22 -9
- package/source/directives/auth/types.ts +26 -2
- package/source/directives/cache/Cache.ts +14 -5
- package/source/directives/cache/Control.ts +0 -3
- package/source/directives/dev/Development.ts +1 -1
- package/source/directives/flow/Fetch.ts +1 -1
- package/source/directives/flow/Flow.ts +1 -1
- package/source/directives/index.ts +5 -2
- package/source/directives/io/Directive.ts +1 -1
- package/source/directives/io/IO.ts +34 -3
- package/source/directives/io/Input.ts +3 -2
- package/source/directives/io/Output.ts +10 -4
- package/source/directives/io/Status.test.ts +84 -0
- package/source/directives/io/Status.ts +46 -0
- package/source/directives/io/Throttle.ts +1 -1
- package/source/directives/io/lib/throttle/Quotas.ts +2 -2
- package/source/directives/map/Headers.ts +11 -0
- package/source/directives/map/Map.ts +10 -1
- package/source/directives/map/Mapping.ts +23 -0
- package/source/directives/map/Segments.ts +12 -0
- package/source/directives/mcp/MCP.ts +33 -0
- package/source/directives/mcp/Tool.test.ts +66 -0
- package/source/directives/mcp/Tool.ts +28 -0
- package/source/directives/mcp/index.ts +6 -0
- package/source/directives/oauth/Discovery.ts +70 -0
- package/source/directives/oauth/documents.ts +113 -0
- package/source/directives/oauth/index.ts +3 -0
- package/source/directives/octets/Delete.ts +1 -1
- package/source/directives/octets/Get.ts +1 -1
- package/source/directives/octets/Octets.ts +1 -1
- package/source/directives/octets/Workflow.ts +1 -1
- package/source/directives/octets/workflows/Execution.ts +1 -1
- package/source/directives/require/Directive.ts +1 -1
- package/source/directives/require/Headers.ts +1 -1
- package/source/directives/require/Require.ts +2 -2
- package/source/index.ts +6 -0
- package/source/octets.d.ts +17 -0
- package/source/schemas.ts +2 -0
- package/source/userland.ts +47 -0
- package/transpiled/Annotation.d.ts +41 -0
- package/transpiled/Directive.d.ts +18 -1
- package/transpiled/Directive.js +50 -6
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +9 -0
- package/transpiled/Endpoint.js +27 -11
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +6 -2
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +19 -2
- package/transpiled/Gateway.js +51 -9
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +6 -0
- package/transpiled/HTTP/Context.js +6 -0
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Server.d.ts +8 -1
- package/transpiled/HTTP/Server.js +4 -3
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/exceptions.d.ts +1 -1
- package/transpiled/HTTP/exceptions.js +2 -2
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/formats/form.d.ts +9 -0
- package/transpiled/HTTP/formats/form.js +18 -0
- package/transpiled/HTTP/formats/form.js.map +1 -0
- package/transpiled/HTTP/formats/index.d.ts +10 -2
- package/transpiled/HTTP/formats/index.js +10 -0
- package/transpiled/HTTP/formats/index.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +12 -0
- package/transpiled/HTTP/messages.js +12 -4
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Interception.d.ts +4 -1
- package/transpiled/Interception.js +4 -2
- package/transpiled/Interception.js.map +1 -1
- package/transpiled/Introspection.d.ts +40 -0
- package/transpiled/Introspection.js +50 -1
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/Server.d.ts +41 -0
- package/transpiled/MCP/Server.js +180 -0
- package/transpiled/MCP/Server.js.map +1 -0
- package/transpiled/MCP/discover.d.ts +13 -0
- package/transpiled/MCP/discover.js +29 -0
- package/transpiled/MCP/discover.js.map +1 -0
- package/transpiled/MCP/errors.d.ts +24 -0
- package/transpiled/MCP/errors.js +67 -0
- package/transpiled/MCP/errors.js.map +1 -0
- package/transpiled/MCP/index.d.ts +1 -0
- package/transpiled/MCP/index.js +2 -0
- package/transpiled/MCP/index.js.map +1 -0
- package/transpiled/MCP/schema.d.ts +18 -0
- package/transpiled/MCP/schema.js +64 -0
- package/transpiled/MCP/schema.js.map +1 -0
- package/transpiled/MCP/tools.d.ts +31 -0
- package/transpiled/MCP/tools.js +121 -0
- package/transpiled/MCP/tools.js.map +1 -0
- package/transpiled/MCP/types.d.ts +64 -0
- package/transpiled/MCP/types.js +13 -0
- package/transpiled/MCP/types.js.map +1 -0
- package/transpiled/Query.d.ts +7 -0
- package/transpiled/Query.js +38 -7
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RPC/Context.d.ts +11 -0
- package/transpiled/RPC/Context.js +63 -0
- package/transpiled/RPC/Context.js.map +1 -0
- package/transpiled/RPC/Dispatcher.d.ts +19 -0
- package/transpiled/RPC/Dispatcher.js +100 -0
- package/transpiled/RPC/Dispatcher.js.map +1 -0
- package/transpiled/RPC/errors.d.ts +18 -0
- package/transpiled/RPC/errors.js +67 -0
- package/transpiled/RPC/errors.js.map +1 -0
- package/transpiled/RPC/index.d.ts +1 -0
- package/transpiled/RPC/index.js +2 -0
- package/transpiled/RPC/index.js.map +1 -0
- package/transpiled/RPC/names.d.ts +30 -0
- package/transpiled/RPC/names.js +121 -0
- package/transpiled/RPC/names.js.map +1 -0
- package/transpiled/RPC/types.d.ts +27 -0
- package/transpiled/RPC/types.js +8 -0
- package/transpiled/RPC/types.js.map +1 -0
- package/transpiled/RTD/Directives.d.ts +41 -2
- package/transpiled/RTD/Endpoint.d.ts +2 -1
- package/transpiled/RTD/Method.d.ts +8 -3
- package/transpiled/RTD/Method.js +12 -10
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.d.ts +20 -2
- package/transpiled/RTD/Node.js +22 -4
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Route.d.ts +2 -1
- package/transpiled/RTD/Route.js +27 -2
- package/transpiled/RTD/Route.js.map +1 -1
- package/transpiled/RTD/Tree.d.ts +3 -1
- package/transpiled/RTD/Tree.js +26 -0
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/const.d.ts +12 -0
- package/transpiled/const.js +12 -0
- package/transpiled/const.js.map +1 -1
- package/transpiled/deployment.js +6 -0
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.d.ts +6 -0
- package/transpiled/directives/auth/Anonymous.js +10 -0
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Anyone.d.ts +1 -0
- package/transpiled/directives/auth/Anyone.js +3 -0
- package/transpiled/directives/auth/Anyone.js.map +1 -1
- package/transpiled/directives/auth/Authorization.d.ts +28 -2
- package/transpiled/directives/auth/Authorization.js +87 -19
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +5 -0
- package/transpiled/directives/auth/Delegate.js +10 -0
- package/transpiled/directives/auth/Delegate.js.map +1 -1
- package/transpiled/directives/auth/Echo.d.ts +2 -0
- package/transpiled/directives/auth/Echo.js +4 -0
- package/transpiled/directives/auth/Echo.js.map +1 -1
- package/transpiled/directives/auth/Incept.d.ts +1 -1
- package/transpiled/directives/auth/Incept.js +13 -8
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +2 -0
- package/transpiled/directives/auth/Role.js +9 -0
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Rule.d.ts +5 -0
- package/transpiled/directives/auth/Rule.js +20 -0
- package/transpiled/directives/auth/Rule.js.map +1 -1
- package/transpiled/directives/auth/Scheme.d.ts +2 -0
- package/transpiled/directives/auth/Scheme.js +4 -0
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/auth/schemes.d.ts +16 -4
- package/transpiled/directives/auth/schemes.js +20 -8
- package/transpiled/directives/auth/schemes.js.map +1 -1
- package/transpiled/directives/auth/types.d.ts +20 -2
- package/transpiled/directives/cache/Cache.d.ts +1 -1
- package/transpiled/directives/cache/Cache.js +10 -3
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.js +0 -2
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/dev/Development.d.ts +1 -1
- package/transpiled/directives/dev/Development.js +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/flow/Flow.d.ts +1 -1
- package/transpiled/directives/flow/Flow.js +1 -1
- package/transpiled/directives/flow/Flow.js.map +1 -1
- package/transpiled/directives/index.js +4 -2
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/Directive.d.ts +1 -1
- package/transpiled/directives/io/IO.d.ts +7 -1
- package/transpiled/directives/io/IO.js +25 -3
- package/transpiled/directives/io/IO.js.map +1 -1
- package/transpiled/directives/io/Input.d.ts +3 -2
- package/transpiled/directives/io/Input.js +2 -1
- package/transpiled/directives/io/Input.js.map +1 -1
- package/transpiled/directives/io/Output.d.ts +5 -3
- package/transpiled/directives/io/Output.js +8 -3
- package/transpiled/directives/io/Output.js.map +1 -1
- package/transpiled/directives/io/Status.d.ts +19 -0
- package/transpiled/directives/io/Status.js +34 -0
- package/transpiled/directives/io/Status.js.map +1 -0
- package/transpiled/directives/io/Throttle.d.ts +1 -1
- package/transpiled/directives/io/Throttle.js +1 -1
- package/transpiled/directives/io/Throttle.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.d.ts +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.js +2 -2
- package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
- package/transpiled/directives/map/Headers.d.ts +2 -0
- package/transpiled/directives/map/Headers.js +8 -0
- package/transpiled/directives/map/Headers.js.map +1 -1
- package/transpiled/directives/map/Map.d.ts +3 -1
- package/transpiled/directives/map/Map.js +7 -1
- package/transpiled/directives/map/Map.js.map +1 -1
- package/transpiled/directives/map/Mapping.d.ts +13 -0
- package/transpiled/directives/map/Mapping.js +20 -0
- package/transpiled/directives/map/Mapping.js.map +1 -1
- package/transpiled/directives/map/Segments.d.ts +3 -0
- package/transpiled/directives/map/Segments.js +9 -0
- package/transpiled/directives/map/Segments.js.map +1 -1
- package/transpiled/directives/mcp/MCP.d.ts +15 -0
- package/transpiled/directives/mcp/MCP.js +23 -0
- package/transpiled/directives/mcp/MCP.js.map +1 -0
- package/transpiled/directives/mcp/Tool.d.ts +13 -0
- package/transpiled/directives/mcp/Tool.js +23 -0
- package/transpiled/directives/mcp/Tool.js.map +1 -0
- package/transpiled/directives/mcp/index.d.ts +4 -0
- package/transpiled/directives/mcp/index.js +4 -0
- package/transpiled/directives/mcp/index.js.map +1 -0
- package/transpiled/directives/oauth/Discovery.d.ts +23 -0
- package/transpiled/directives/oauth/Discovery.js +55 -0
- package/transpiled/directives/oauth/Discovery.js.map +1 -0
- package/transpiled/directives/oauth/documents.d.ts +9 -0
- package/transpiled/directives/oauth/documents.js +82 -0
- package/transpiled/directives/oauth/documents.js.map +1 -0
- package/transpiled/directives/oauth/index.d.ts +2 -0
- package/transpiled/directives/oauth/index.js +3 -0
- package/transpiled/directives/oauth/index.js.map +1 -0
- package/transpiled/directives/octets/Octets.d.ts +1 -1
- package/transpiled/directives/octets/Octets.js +1 -1
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/require/Directive.d.ts +1 -1
- package/transpiled/directives/require/Headers.d.ts +1 -1
- package/transpiled/directives/require/Headers.js +1 -1
- package/transpiled/directives/require/Headers.js.map +1 -1
- package/transpiled/directives/require/Require.d.ts +1 -1
- package/transpiled/directives/require/Require.js +2 -2
- package/transpiled/directives/require/Require.js.map +1 -1
- package/transpiled/index.d.ts +2 -0
- package/transpiled/schemas.d.ts +2 -0
- package/transpiled/schemas.js +1 -0
- package/transpiled/schemas.js.map +1 -1
- package/transpiled/userland.d.ts +39 -0
- package/transpiled/userland.js +7 -0
- package/transpiled/userland.js.map +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/operations/transit.d.ts +0 -14
- package/components/identity.bans/operations/transit.js.map +0 -1
- package/components/identity.basic/operations/add.d.ts +0 -3
- package/components/identity.basic/operations/add.js.map +0 -1
- package/components/identity.basic/operations/authenticate.d.ts +0 -13
- package/components/identity.basic/operations/authenticate.js.map +0 -1
- package/components/identity.basic/operations/check.d.ts +0 -7
- package/components/identity.basic/operations/check.js.map +0 -1
- package/components/identity.basic/operations/delete.d.ts +0 -7
- package/components/identity.basic/operations/delete.js.map +0 -1
- package/components/identity.basic/operations/incept.d.ts +0 -12
- package/components/identity.basic/operations/incept.js.map +0 -1
- package/components/identity.basic/operations/info.d.ts +0 -10
- package/components/identity.basic/operations/info.js.map +0 -1
- package/components/identity.basic/operations/lib/credentials.d.ts +0 -5
- package/components/identity.basic/operations/lib/credentials.js.map +0 -1
- package/components/identity.basic/operations/transit.d.ts +0 -14
- package/components/identity.basic/operations/transit.js.map +0 -1
- package/components/identity.basic/operations/types.d.ts +0 -61
- package/components/identity.basic/operations/types.js +0 -2
- package/components/identity.basic/operations/types.js.map +0 -1
- package/components/identity.basic/source/types.ts +0 -69
- package/components/identity.credentials/operations/list.d.ts +0 -51
- package/components/identity.credentials/operations/list.js.map +0 -1
- package/components/identity.federation/operations/authenticate.d.ts +0 -16
- package/components/identity.federation/operations/authenticate.js.map +0 -1
- package/components/identity.federation/operations/create.d.ts +0 -8
- package/components/identity.federation/operations/create.js.map +0 -1
- package/components/identity.federation/operations/decode.d.ts +0 -3
- package/components/identity.federation/operations/decode.js.map +0 -1
- package/components/identity.federation/operations/delete.d.ts +0 -8
- package/components/identity.federation/operations/delete.js.map +0 -1
- package/components/identity.federation/operations/incept.d.ts +0 -11
- package/components/identity.federation/operations/incept.js.map +0 -1
- package/components/identity.federation/operations/lib/Configuration.d.ts +0 -39
- package/components/identity.federation/operations/lib/Configuration.js.map +0 -1
- package/components/identity.federation/operations/lib/Ctx.d.ts +0 -8
- package/components/identity.federation/operations/lib/Ctx.js.map +0 -1
- package/components/identity.federation/operations/lib/Payload.d.ts +0 -5
- package/components/identity.federation/operations/lib/Payload.js.map +0 -1
- package/components/identity.federation/operations/lib/decode.d.ts +0 -3
- package/components/identity.federation/operations/lib/decode.js.map +0 -1
- package/components/identity.federation/operations/lib/discovery.d.ts +0 -5
- package/components/identity.federation/operations/lib/discovery.js.map +0 -1
- package/components/identity.federation/operations/lib/errors.d.ts +0 -70
- package/components/identity.federation/operations/lib/errors.js.map +0 -1
- package/components/identity.federation/operations/lib/exchange.d.ts +0 -3
- package/components/identity.federation/operations/lib/exchange.js.map +0 -1
- package/components/identity.federation/operations/lib/index.d.ts +0 -4
- package/components/identity.federation/operations/lib/index.js.map +0 -1
- package/components/identity.federation/operations/lib/jose.d.ts +0 -1
- package/components/identity.federation/operations/lib/jose.js.map +0 -1
- package/components/identity.federation/operations/lib/resolve.d.ts +0 -3
- package/components/identity.federation/operations/lib/resolve.js.map +0 -1
- package/components/identity.federation/operations/list.d.ts +0 -7
- package/components/identity.federation/operations/list.js.map +0 -1
- package/components/identity.federation/operations/types/Scheme.d.ts +0 -1
- package/components/identity.federation/operations/types/Scheme.js.map +0 -1
- package/components/identity.federation/operations/types/configuration.d.ts +0 -22
- package/components/identity.federation/operations/types/configuration.js.map +0 -1
- package/components/identity.federation/operations/types/context.d.ts +0 -35
- package/components/identity.federation/operations/types/context.js.map +0 -1
- package/components/identity.federation/operations/types/entity.d.ts +0 -9
- package/components/identity.federation/operations/types/entity.js.map +0 -1
- package/components/identity.federation/operations/types/index.d.ts +0 -4
- package/components/identity.federation/operations/types/index.js.map +0 -1
- package/components/identity.keys/operations/create.d.ts +0 -22
- package/components/identity.keys/operations/create.js.map +0 -1
- package/components/identity.keys/operations/disable.d.ts +0 -5
- package/components/identity.keys/operations/disable.js.map +0 -1
- package/components/identity.keys/operations/revoke.d.ts +0 -15
- package/components/identity.keys/operations/revoke.js.map +0 -1
- package/components/identity.otp/operations/authenticate.d.ts +0 -12
- package/components/identity.otp/operations/authenticate.js.map +0 -1
- package/components/identity.otp/operations/issue.d.ts +0 -12
- package/components/identity.otp/operations/issue.js.map +0 -1
- package/components/identity.otp/operations/lib/Context.d.ts +0 -14
- package/components/identity.otp/operations/lib/Context.js.map +0 -1
- package/components/identity.otp/operations/lib/Entity.d.ts +0 -6
- package/components/identity.otp/operations/lib/Entity.js.map +0 -1
- package/components/identity.otp/operations/lib/index.d.ts +0 -1
- package/components/identity.otp/operations/lib/index.js.map +0 -1
- package/components/identity.passkeys/operations/authenticate.d.ts +0 -16
- package/components/identity.passkeys/operations/authenticate.js.map +0 -1
- package/components/identity.passkeys/operations/challenge.d.ts +0 -35
- package/components/identity.passkeys/operations/challenge.js.map +0 -1
- package/components/identity.passkeys/operations/create.d.ts +0 -19
- package/components/identity.passkeys/operations/create.js.map +0 -1
- package/components/identity.passkeys/operations/delete.d.ts +0 -8
- package/components/identity.passkeys/operations/delete.js.map +0 -1
- package/components/identity.passkeys/operations/lib/const.d.ts +0 -1
- package/components/identity.passkeys/operations/lib/const.js.map +0 -1
- package/components/identity.passkeys/operations/list.d.ts +0 -7
- package/components/identity.passkeys/operations/list.js.map +0 -1
- package/components/identity.passkeys/operations/types/Configuration.d.ts +0 -6
- package/components/identity.passkeys/operations/types/Configuration.js.map +0 -1
- package/components/identity.passkeys/operations/types/Context.d.ts +0 -15
- package/components/identity.passkeys/operations/types/Context.js.map +0 -1
- package/components/identity.passkeys/operations/types/Passkey.d.ts +0 -12
- package/components/identity.passkeys/operations/types/Passkey.js.map +0 -1
- package/components/identity.passkeys/operations/types/index.d.ts +0 -2
- package/components/identity.passkeys/operations/types/index.js.map +0 -1
- package/components/identity.passkeys/operations/use.d.ts +0 -16
- package/components/identity.passkeys/operations/use.js.map +0 -1
- package/components/identity.roles/operations/grant.d.ts +0 -10
- package/components/identity.roles/operations/grant.js.map +0 -1
- package/components/identity.roles/operations/lib/Entity.d.ts +0 -5
- package/components/identity.roles/operations/lib/Entity.js.map +0 -1
- package/components/identity.roles/operations/list.d.ts +0 -2
- package/components/identity.roles/operations/list.js.map +0 -1
- package/components/identity.roles/operations/principal.d.ts +0 -13
- package/components/identity.roles/operations/principal.js.map +0 -1
- package/components/identity.tokens/operations/authenticate.d.ts +0 -9
- package/components/identity.tokens/operations/authenticate.js.map +0 -1
- package/components/identity.tokens/operations/decrypt.d.ts +0 -15
- package/components/identity.tokens/operations/decrypt.js.map +0 -1
- package/components/identity.tokens/operations/encrypt.d.ts +0 -8
- package/components/identity.tokens/operations/encrypt.js.map +0 -1
- package/components/identity.tokens/operations/issue.d.ts +0 -24
- package/components/identity.tokens/operations/issue.js.map +0 -1
- package/components/identity.tokens/operations/lib/index.d.ts +0 -3
- package/components/identity.tokens/operations/lib/index.js.map +0 -1
- package/components/identity.tokens/operations/lib/jose.d.ts +0 -1
- package/components/identity.tokens/operations/lib/jose.js.map +0 -1
- package/components/identity.tokens/operations/lib/key.d.ts +0 -1
- package/components/identity.tokens/operations/lib/key.js.map +0 -1
- package/components/identity.tokens/operations/lib/pad.d.ts +0 -1
- package/components/identity.tokens/operations/lib/pad.js.map +0 -1
- package/components/identity.tokens/operations/lib/types.d.ts +0 -88
- package/components/identity.tokens/operations/lib/types.js +0 -2
- package/components/identity.tokens/operations/lib/types.js.map +0 -1
- package/components/identity.tokens/operations/revoke.d.ts +0 -2
- package/components/identity.tokens/operations/revoke.js.map +0 -1
- package/components/identity.tokens/source/lib/types.ts +0 -102
package/source/Gateway.ts
CHANGED
|
@@ -3,10 +3,13 @@ import { setTimeout } from 'node:timers/promises'
|
|
|
3
3
|
import { console } from 'openspan'
|
|
4
4
|
import { type bindings, Connector } from '@toa.io/core'
|
|
5
5
|
import * as http from './HTTP/index.js'
|
|
6
|
+
import { MCP, RPC } from './const.js'
|
|
6
7
|
import { rethrow } from './exceptions.js'
|
|
7
8
|
import { decide } from './Branch.js'
|
|
8
9
|
import type { Interception } from './Interception.js'
|
|
9
|
-
import type {
|
|
10
|
+
import type { Dispatcher } from './RPC/index.js'
|
|
11
|
+
import type { Server } from './MCP/index.js'
|
|
12
|
+
import type { DirectiveFactory, Method, Node, Parameter, Tree, Match } from './RTD/index.js'
|
|
10
13
|
import type { Label } from './discovery.js'
|
|
11
14
|
import type { Branch, Exposed } from './Branch.js'
|
|
12
15
|
|
|
@@ -14,6 +17,13 @@ export class Gateway extends Connector {
|
|
|
14
17
|
private readonly broadcast: Broadcast
|
|
15
18
|
private readonly tree: Tree
|
|
16
19
|
private readonly interceptor: Interception
|
|
20
|
+
private readonly directives: DirectiveFactory
|
|
21
|
+
|
|
22
|
+
/** JSON-RPC is served only where the annotation asked for it. */
|
|
23
|
+
private readonly dispatcher: Dispatcher | null
|
|
24
|
+
|
|
25
|
+
/** And the same of MCP. */
|
|
26
|
+
private readonly mcp: Server | null
|
|
17
27
|
private readonly branches = new Map<string, Exposed>()
|
|
18
28
|
private lastMerge = 0
|
|
19
29
|
private widestGap = 0
|
|
@@ -21,12 +31,17 @@ export class Gateway extends Connector {
|
|
|
21
31
|
private stopped = false
|
|
22
32
|
private resolveFirstMerge: (() => void) | null = null
|
|
23
33
|
|
|
24
|
-
|
|
34
|
+
// eslint-disable-next-line max-params
|
|
35
|
+
public constructor (broadcast: Broadcast, tree: Tree, interception: Interception,
|
|
36
|
+
directives: DirectiveFactory, dispatcher: Dispatcher | null, mcp: Server | null) {
|
|
25
37
|
super()
|
|
26
38
|
|
|
27
39
|
this.broadcast = broadcast
|
|
28
40
|
this.tree = tree
|
|
29
41
|
this.interceptor = interception
|
|
42
|
+
this.directives = directives
|
|
43
|
+
this.dispatcher = dispatcher
|
|
44
|
+
this.mcp = mcp
|
|
30
45
|
|
|
31
46
|
this.depends(broadcast)
|
|
32
47
|
}
|
|
@@ -38,10 +53,44 @@ export class Gateway extends Connector {
|
|
|
38
53
|
if (interception !== null)
|
|
39
54
|
return interception
|
|
40
55
|
|
|
56
|
+
// request-scoped, before anything is routed: this is where a credential is read
|
|
57
|
+
await context.timing.capture('preflight',
|
|
58
|
+
this.directives.preflight(context)).catch(rethrow)
|
|
59
|
+
|
|
60
|
+
const response = await this.endpoint(context)
|
|
61
|
+
|
|
62
|
+
// request-scoped, on whatever is going back: this is where a credential is re-issued
|
|
63
|
+
await context.timing.capture('depart',
|
|
64
|
+
this.directives.depart(context, response)).catch(rethrow)
|
|
65
|
+
|
|
66
|
+
return response
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* What answers the request: a pinned endpoint that makes calls of its own, or the route
|
|
71
|
+
* the path names.
|
|
72
|
+
*/
|
|
73
|
+
private async endpoint (context: http.Context): Promise<http.OutgoingMessage> {
|
|
74
|
+
const route: http.Processor = async (call) => await this.route(call)
|
|
75
|
+
|
|
76
|
+
if (this.dispatcher !== null && context.url.pathname === RPC)
|
|
77
|
+
return await context.timing.capture('rpc', this.dispatcher.dispatch(context, route))
|
|
78
|
+
|
|
79
|
+
if (this.mcp !== null && context.url.pathname === MCP)
|
|
80
|
+
return await context.timing.capture('mcp', this.mcp.process(context, route))
|
|
81
|
+
|
|
82
|
+
return await this.route(context)
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* One call: everything that needs a node. A request makes one of these, and a request
|
|
87
|
+
* that carries several calls makes one per call.
|
|
88
|
+
*/
|
|
89
|
+
private async route (context: http.Context): Promise<http.OutgoingMessage> {
|
|
41
90
|
const { node, parameters } = this.match(context)
|
|
42
91
|
|
|
43
92
|
if (context.request.method === 'OPTIONS')
|
|
44
|
-
return await this.explain(node, parameters)
|
|
93
|
+
return await this.explain(context, node, parameters)
|
|
45
94
|
|
|
46
95
|
let verb = context.request.method
|
|
47
96
|
|
|
@@ -53,8 +102,8 @@ export class Gateway extends Connector {
|
|
|
53
102
|
|
|
54
103
|
const method = node.methods[verb]
|
|
55
104
|
|
|
56
|
-
const interruption = await context.timing.capture('
|
|
57
|
-
method.directives.
|
|
105
|
+
const interruption = await context.timing.capture('precall',
|
|
106
|
+
method.directives.precall(context, parameters)).catch(rethrow)
|
|
58
107
|
|
|
59
108
|
const response = interruption ??
|
|
60
109
|
await context.timing.capture('call', this.call(method, context, parameters))
|
|
@@ -68,7 +117,16 @@ export class Gateway extends Connector {
|
|
|
68
117
|
protected override async open (): Promise<void> {
|
|
69
118
|
await this.discover()
|
|
70
119
|
|
|
71
|
-
|
|
120
|
+
// what is served besides the tree, so that turning one on can be seen to have worked
|
|
121
|
+
const pinned: string[] = []
|
|
122
|
+
|
|
123
|
+
if (this.dispatcher !== null)
|
|
124
|
+
pinned.push(RPC)
|
|
125
|
+
|
|
126
|
+
if (this.mcp !== null)
|
|
127
|
+
pinned.push(MCP)
|
|
128
|
+
|
|
129
|
+
console.info('Gateway started', { endpoints: pinned.length === 0 ? 'none' : pinned.join(' ') })
|
|
72
130
|
}
|
|
73
131
|
|
|
74
132
|
/**
|
|
@@ -131,12 +189,16 @@ export class Gateway extends Connector {
|
|
|
131
189
|
.catch(rethrow) as http.OutgoingMessage
|
|
132
190
|
}
|
|
133
191
|
|
|
134
|
-
private async explain (
|
|
135
|
-
|
|
136
|
-
const
|
|
137
|
-
const
|
|
192
|
+
private async explain (context: http.Context, node: Node,
|
|
193
|
+
parameters: Parameter[]): Promise<http.OutgoingMessage> {
|
|
194
|
+
const body = await node.explain(context, parameters)
|
|
195
|
+
const verbs = Object.keys(body)
|
|
196
|
+
|
|
197
|
+
// what a caller may not use is not a resource to them, and describing it would be the leak
|
|
198
|
+
if (verbs.length === 0 && Object.keys(node.methods).length > 0)
|
|
199
|
+
throw new http.Forbidden()
|
|
138
200
|
|
|
139
|
-
return { body, headers }
|
|
201
|
+
return { body, headers: new Headers({ allow: verbs.join(', ') }) }
|
|
140
202
|
}
|
|
141
203
|
|
|
142
204
|
private async discover (): Promise<void> {
|
package/source/HTTP/Context.ts
CHANGED
|
@@ -22,6 +22,13 @@ export class Context {
|
|
|
22
22
|
public readonly timing: Timing
|
|
23
23
|
public readonly debug: boolean
|
|
24
24
|
|
|
25
|
+
/**
|
|
26
|
+
* Whether this is a procedure a request made, rather than the request. What forks one
|
|
27
|
+
* says so, and a directive that answers differently to a procedure than to a request
|
|
28
|
+
* reads it here.
|
|
29
|
+
*/
|
|
30
|
+
public readonly procedural: boolean = false
|
|
31
|
+
|
|
25
32
|
public readonly pipelines: Pipelines = {
|
|
26
33
|
body: [],
|
|
27
34
|
response: []
|
package/source/HTTP/Server.ts
CHANGED
|
@@ -12,12 +12,13 @@ import { ClientError, Exception } from './exceptions.js'
|
|
|
12
12
|
import { Context } from './Context.js'
|
|
13
13
|
import { PROBE, Probe } from './Probe.js'
|
|
14
14
|
import type { IncomingMessage, Protocol, ServerResponse } from './types.js'
|
|
15
|
-
import type { Bouncer } from '../Annotation.js'
|
|
15
|
+
import type { Bouncer, MCP, OAuth, RPC } from '../Annotation.js'
|
|
16
16
|
|
|
17
17
|
export class Server extends Connector {
|
|
18
18
|
private readonly server: http.Server | http2.Http2Server
|
|
19
19
|
private readonly properties: Properties
|
|
20
|
-
|
|
20
|
+
/** Host to authority. A map: a `Host` of `constructor` names what a plain object answers. */
|
|
21
|
+
private readonly authorities: Map<string, string>
|
|
21
22
|
|
|
22
23
|
/** Tracked for the drain: `Http2Server` has no `closeIdleConnections`. */
|
|
23
24
|
private readonly sessions = new Set<http2.ServerHttp2Session>()
|
|
@@ -30,7 +31,7 @@ export class Server extends Connector {
|
|
|
30
31
|
super()
|
|
31
32
|
|
|
32
33
|
this.properties = properties
|
|
33
|
-
this.authorities =
|
|
34
|
+
this.authorities = new Map(Object.entries(properties.authorities).map(([key, value]) => [value, key]))
|
|
34
35
|
this.server = instantiate(properties.protocol)
|
|
35
36
|
this.probe = new Probe(properties.probe)
|
|
36
37
|
|
|
@@ -162,7 +163,7 @@ export class Server extends Connector {
|
|
|
162
163
|
|
|
163
164
|
assert(this.process !== undefined, 'Request processor is not attached')
|
|
164
165
|
|
|
165
|
-
const authority = this.authorities
|
|
166
|
+
const authority = this.authorities.get(host) ?? host
|
|
166
167
|
|
|
167
168
|
// if the request carries no trace context, the trace starts here
|
|
168
169
|
const remote = trace(request.headers)
|
|
@@ -239,7 +240,7 @@ export class Server extends Connector {
|
|
|
239
240
|
if (!response.writableEnded) {
|
|
240
241
|
response.statusCode = status
|
|
241
242
|
|
|
242
|
-
const message: OutgoingMessage = { status: response.statusCode }
|
|
243
|
+
const message: OutgoingMessage = { status: response.statusCode, authentic: true }
|
|
243
244
|
|
|
244
245
|
// eslint-disable-next-line max-depth
|
|
245
246
|
if (exception instanceof Exception && exception.headers !== undefined)
|
|
@@ -385,6 +386,15 @@ interface Properties {
|
|
|
385
386
|
|
|
386
387
|
/** Failed authentications an address may make; none are metered unless set. */
|
|
387
388
|
bouncer?: Bouncer
|
|
389
|
+
|
|
390
|
+
/** The authorization server this context exposes; none is exposed without it. */
|
|
391
|
+
oauth?: OAuth
|
|
392
|
+
|
|
393
|
+
/** JSON-RPC at `/.rpc`; none is served without it. */
|
|
394
|
+
rpc?: RPC
|
|
395
|
+
|
|
396
|
+
/** MCP at `/.mcp`; none is served without it. */
|
|
397
|
+
mcp?: MCP
|
|
388
398
|
}
|
|
389
399
|
|
|
390
400
|
export type Options = { authorities: Properties['authorities'] } & {
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export const type = 'application/x-www-form-urlencoded'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* A form is read and never written: it is what an HTML form and a handful of protocols send,
|
|
5
|
+
* and nothing asks for a reply in it.
|
|
6
|
+
*
|
|
7
|
+
* A name repeated in a form is a list, which is how a form says one — `URLSearchParams` keeps
|
|
8
|
+
* every value, and a name given once stays the string it was written as.
|
|
9
|
+
*/
|
|
10
|
+
export function decode (buffer: Buffer, charset = 'utf-8'): any {
|
|
11
|
+
const params = new URLSearchParams(buffer.toString(charset as BufferEncoding))
|
|
12
|
+
const value: Record<string, string | string[]> = {}
|
|
13
|
+
|
|
14
|
+
for (const name of new Set(params.keys())) {
|
|
15
|
+
const values = params.getAll(name)
|
|
16
|
+
|
|
17
|
+
value[name] = values.length === 1 ? values[0] : values
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return value
|
|
21
|
+
}
|
|
@@ -2,7 +2,9 @@ import * as json from './json.js'
|
|
|
2
2
|
import * as yaml from './yaml.js'
|
|
3
3
|
import * as msgpack from './msgpack.js'
|
|
4
4
|
import * as text from './text.js'
|
|
5
|
+
import * as form from './form.js'
|
|
5
6
|
|
|
7
|
+
/** What a reply may be encoded as, and so what `accept` is negotiated against. */
|
|
6
8
|
export const formats: Record<string, Format> = {
|
|
7
9
|
[json.type]: json,
|
|
8
10
|
[yaml.type]: yaml,
|
|
@@ -12,10 +14,23 @@ export const formats: Record<string, Format> = {
|
|
|
12
14
|
|
|
13
15
|
export const types = Object.keys(formats)
|
|
14
16
|
|
|
15
|
-
|
|
17
|
+
/**
|
|
18
|
+
* What a request body may arrive as. Everything a reply may be, and a form besides — which
|
|
19
|
+
* is read and never written, so it is not something a reply can be asked for.
|
|
20
|
+
*/
|
|
21
|
+
export const decoders: Record<string, Decoder> = {
|
|
22
|
+
...formats,
|
|
23
|
+
[form.type]: form
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export interface Decoder {
|
|
16
27
|
readonly type: string
|
|
28
|
+
|
|
29
|
+
decode: (buffer: Buffer, charset?: string) => any
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface Format extends Decoder {
|
|
17
33
|
readonly multipart: string
|
|
18
34
|
|
|
19
35
|
encode: (value: any) => Buffer
|
|
20
|
-
decode: (buffer: Buffer, charset?: string) => any
|
|
21
36
|
}
|
|
@@ -7,7 +7,7 @@ import { generate } from 'randomstring'
|
|
|
7
7
|
import * as msgpack from 'msgpackr'
|
|
8
8
|
import { multipart, read, type OutgoingMessage } from './messages.js'
|
|
9
9
|
import { BadRequest, UnsupportedMediaType } from './exceptions.js'
|
|
10
|
-
import { formats } from './formats/index.js'
|
|
10
|
+
import { formats, types } from './formats/index.js'
|
|
11
11
|
import { Timing } from './Timing.js'
|
|
12
12
|
import type * as http from 'node:http'
|
|
13
13
|
import type { Context } from './Context.js'
|
|
@@ -87,6 +87,30 @@ describe('read', () => {
|
|
|
87
87
|
await assert.rejects(read(request), BadRequest)
|
|
88
88
|
})
|
|
89
89
|
|
|
90
|
+
it('should parse application/x-www-form-urlencoded', async () => {
|
|
91
|
+
const headers = { 'content-type': 'application/x-www-form-urlencoded' }
|
|
92
|
+
const form = 'grant_type=authorization_code&code=SplxlO&scope=a+b'
|
|
93
|
+
const request = createContext(generate(), headers, form)
|
|
94
|
+
|
|
95
|
+
assert.deepStrictEqual(await read(request), {
|
|
96
|
+
grant_type: 'authorization_code',
|
|
97
|
+
code: 'SplxlO',
|
|
98
|
+
scope: 'a b'
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
|
|
102
|
+
it('should read a repeated form name as the list it is', async () => {
|
|
103
|
+
const headers = { 'content-type': 'application/x-www-form-urlencoded' }
|
|
104
|
+
const request = createContext(generate(), headers, 'resource=one&resource=two')
|
|
105
|
+
|
|
106
|
+
assert.deepStrictEqual(await read(request), { resource: ['one', 'two'] })
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
it('should not offer a form as a reply encoding', () => {
|
|
110
|
+
assert.ok(!types.includes('application/x-www-form-urlencoded'),
|
|
111
|
+
'a form is read and never written')
|
|
112
|
+
})
|
|
113
|
+
|
|
90
114
|
it('should output correct mulitpart format', async () => {
|
|
91
115
|
const response = new class extends PassThrough {
|
|
92
116
|
public readonly headers = new Headers()
|
package/source/HTTP/messages.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { pipeline } from 'node:stream/promises'
|
|
|
4
4
|
import { createHash } from 'node:crypto'
|
|
5
5
|
import * as contentType from 'content-type'
|
|
6
6
|
import { console } from 'openspan'
|
|
7
|
-
import { type Format,
|
|
7
|
+
import { type Format, decoders } from './formats/index.js'
|
|
8
8
|
import { BadRequest, NotAcceptable, UnsupportedMediaType } from './exceptions.js'
|
|
9
9
|
import type { Context } from './Context.js'
|
|
10
10
|
import type { ServerResponse } from './types.js'
|
|
@@ -15,9 +15,18 @@ const server = `Exposition/${JSON.parse(readFileSync(new URL('../../package.json
|
|
|
15
15
|
|
|
16
16
|
const pending = new Map<string, PendingStream>()
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Applies what the request accumulated in `pipelines.response` — an `io:output` restriction,
|
|
20
|
+
* a `vary` a `map` directive owes. Separate from `write` because a message is not always
|
|
21
|
+
* written: one call of several produces a value the reply is assembled from.
|
|
22
|
+
*/
|
|
23
|
+
export async function shape (context: Context, message: OutgoingMessage): Promise<void> {
|
|
19
24
|
for (const transform of context.pipelines.response)
|
|
20
25
|
await transform(message)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export async function write (context: Context, response: ServerResponse, message: OutgoingMessage): Promise<void> {
|
|
29
|
+
await shape(context, message)
|
|
21
30
|
|
|
22
31
|
if (message?.status !== undefined)
|
|
23
32
|
response.statusCode = message.status
|
|
@@ -49,10 +58,10 @@ export async function read (context: Context): Promise<any> {
|
|
|
49
58
|
|
|
50
59
|
const { type, parameters } = contentType.parse(header)
|
|
51
60
|
|
|
52
|
-
if (!(type in
|
|
61
|
+
if (!(type in decoders))
|
|
53
62
|
throw new UnsupportedMediaType()
|
|
54
63
|
|
|
55
|
-
const format =
|
|
64
|
+
const format = decoders[type]
|
|
56
65
|
const buf = await context.buffer()
|
|
57
66
|
|
|
58
67
|
try {
|
|
@@ -201,6 +210,13 @@ export interface OutgoingMessage {
|
|
|
201
210
|
|
|
202
211
|
/** tag the response with a hash of the encoded body, see `conditional` */
|
|
203
212
|
etag?: boolean
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Built by the gateway rather than returned by an operation, as a request is `authentic`
|
|
216
|
+
* when it was made by one: what is in it is the gateway's own, and the checks that answer
|
|
217
|
+
* for what an operation returns have nothing to say about it.
|
|
218
|
+
*/
|
|
219
|
+
authentic?: boolean
|
|
204
220
|
}
|
|
205
221
|
|
|
206
222
|
export interface Query {
|
package/source/Interception.ts
CHANGED
|
@@ -1,15 +1,18 @@
|
|
|
1
|
+
import type * as http from './HTTP/index.js'
|
|
1
2
|
import type { Input, Output } from './io.js'
|
|
2
3
|
|
|
3
4
|
export class Interception implements Interceptor {
|
|
4
5
|
private readonly interceptors: Interceptor[]
|
|
5
6
|
|
|
6
|
-
public constructor (interceptors: Interceptor[]) {
|
|
7
|
+
public constructor (interceptors: Interceptor[], options: http.Options) {
|
|
7
8
|
this.interceptors = interceptors
|
|
8
9
|
|
|
9
10
|
// interceptors are module singletons, so a second gateway in one process —
|
|
10
11
|
// which is how the features run — would otherwise inherit the first one's state
|
|
11
|
-
for (const interceptor of interceptors)
|
|
12
|
+
for (const interceptor of interceptors) {
|
|
12
13
|
interceptor.reset?.()
|
|
14
|
+
interceptor.mount?.(options)
|
|
15
|
+
}
|
|
13
16
|
}
|
|
14
17
|
|
|
15
18
|
public async intercept (input: Input): Promise<Output> {
|
|
@@ -29,4 +32,7 @@ export interface Interceptor {
|
|
|
29
32
|
|
|
30
33
|
/** Discards whatever the interceptor accumulated while serving. */
|
|
31
34
|
reset?: () => void
|
|
35
|
+
|
|
36
|
+
/** What the annotation says, for an interceptor that answers from it. */
|
|
37
|
+
mount?: (options: http.Options) => void
|
|
32
38
|
}
|
package/source/Introspection.ts
CHANGED
|
@@ -1,11 +1,113 @@
|
|
|
1
1
|
import type { Remote } from '@toa.io/core'
|
|
2
2
|
|
|
3
3
|
export interface Introspection {
|
|
4
|
+
/**
|
|
5
|
+
* What the route states this method is. The operation states what it is too, and that is
|
|
6
|
+
* not this: an operation is written without knowledge of any route, and a method is an
|
|
7
|
+
* operation and a route together — the same operation mounted twice is two methods, and
|
|
8
|
+
* one sentence cannot be true of both. The operation's own is for the Introspection.
|
|
9
|
+
*/
|
|
10
|
+
description?: string
|
|
4
11
|
route?: Record<string, Schema>
|
|
5
12
|
query?: Record<string, Schema>
|
|
13
|
+
|
|
14
|
+
/** what a request header carries, which is therefore not the body's to send */
|
|
15
|
+
headers?: Record<string, Sourced>
|
|
6
16
|
input?: Schema
|
|
7
17
|
output?: Schema
|
|
8
18
|
errors?: string[]
|
|
9
19
|
}
|
|
10
20
|
|
|
21
|
+
/** A property the gateway reads from somewhere else, and the schema it was declared with. */
|
|
22
|
+
export interface Sourced {
|
|
23
|
+
header: string
|
|
24
|
+
[keyword: string]: unknown
|
|
25
|
+
}
|
|
26
|
+
|
|
11
27
|
export type Schema = Awaited<ReturnType<Remote['explain']>>['input']
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The same, in the order the shape states — whatever order the families that filled it ran
|
|
31
|
+
* in. What a resource says about itself is read, so it is written the way it is documented.
|
|
32
|
+
*/
|
|
33
|
+
export function order (introspection: Introspection): Introspection {
|
|
34
|
+
const ordered: Introspection = {}
|
|
35
|
+
|
|
36
|
+
for (const key of KEYS)
|
|
37
|
+
if (introspection[key] !== undefined)
|
|
38
|
+
(ordered[key] as unknown) = introspection[key]
|
|
39
|
+
|
|
40
|
+
return ordered
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const KEYS = ['description', 'route', 'query', 'headers', 'input', 'output', 'errors'] as const
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* The schema of one input property, taken out of it: a property another family fills is
|
|
47
|
+
* not the caller's to send, and what took it says where it comes from instead.
|
|
48
|
+
*/
|
|
49
|
+
export function take (carrier: Carrier, property: string): Schema | undefined {
|
|
50
|
+
const input = carrier.input as Shape | null | undefined
|
|
51
|
+
const properties = input?.properties
|
|
52
|
+
|
|
53
|
+
if (input === undefined || input === null || properties === undefined ||
|
|
54
|
+
!(property in properties))
|
|
55
|
+
return undefined
|
|
56
|
+
|
|
57
|
+
const schema = properties[property]
|
|
58
|
+
|
|
59
|
+
delete properties[property]
|
|
60
|
+
|
|
61
|
+
if (input.required !== undefined)
|
|
62
|
+
input.required = input.required.filter((name) => name !== property)
|
|
63
|
+
|
|
64
|
+
return schema
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* A schema restricted to the properties a whitelist admits, and an array's items where it
|
|
69
|
+
* describes an array. What is not an object of properties is left alone: a whitelist has
|
|
70
|
+
* nothing to say about a string.
|
|
71
|
+
*/
|
|
72
|
+
export function restrict (schema: Schema | undefined, allowed: Set<string>): Schema | undefined {
|
|
73
|
+
const shape = schema as Shape | null | undefined
|
|
74
|
+
|
|
75
|
+
if (shape === undefined || shape === null)
|
|
76
|
+
return schema
|
|
77
|
+
|
|
78
|
+
if (shape.items !== undefined)
|
|
79
|
+
return { ...shape, items: restrict(shape.items, allowed) } as unknown as Schema
|
|
80
|
+
|
|
81
|
+
if (shape.properties === undefined)
|
|
82
|
+
return schema
|
|
83
|
+
|
|
84
|
+
const properties: Record<string, Schema> = {}
|
|
85
|
+
|
|
86
|
+
for (const [name, property] of Object.entries(shape.properties))
|
|
87
|
+
if (allowed.has(name))
|
|
88
|
+
properties[name] = property
|
|
89
|
+
|
|
90
|
+
const restricted: Shape = { ...shape, properties }
|
|
91
|
+
|
|
92
|
+
if (shape.required !== undefined)
|
|
93
|
+
restricted.required = shape.required.filter((name) => allowed.has(name))
|
|
94
|
+
|
|
95
|
+
return restricted as unknown as Schema
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* What a schema is read as here: the keywords these narrow, and whatever else it carries.
|
|
100
|
+
* `Schema` as core declares it requires `properties`, which a schema of a string has not,
|
|
101
|
+
* so the two are cast through rather than assigned.
|
|
102
|
+
*/
|
|
103
|
+
/** Whatever states an input: an explanation as the operation gave it, or as a route left it. */
|
|
104
|
+
interface Carrier {
|
|
105
|
+
input?: Schema
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
interface Shape {
|
|
109
|
+
properties?: Record<string, Schema>
|
|
110
|
+
required?: string[]
|
|
111
|
+
items?: Schema
|
|
112
|
+
[keyword: string]: unknown
|
|
113
|
+
}
|