@toa.io/extensions.exposition 1.0.0-alpha.285 → 1.0.0-alpha.286
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/components/exposition.octets/operations/delete.js +1 -1
- package/components/exposition.octets/operations/get.js +5 -2
- package/components/exposition.octets/operations/head.js +1 -1
- package/components/exposition.octets/operations/put.js +29 -37
- package/components/exposition.octets/types/toa.d.ts +1 -1
- package/components/identity.bans/manifest.toa.yaml +12 -13
- package/components/identity.bans/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.bans/operations/transit.js +1 -1
- package/components/identity.bans/source/transit.ts +1 -1
- package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/types/toa.d.ts +5 -5
- package/components/identity.basic/events/principal.js +3 -1
- package/components/identity.basic/manifest.toa.yaml +17 -23
- package/components/identity.basic/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.basic/migrations/0002-indexes.yaml +13 -0
- package/components/identity.basic/operations/add.js +1 -1
- package/components/identity.basic/operations/authenticate.js +2 -2
- package/components/identity.basic/operations/check.js +4 -2
- package/components/identity.basic/operations/delete.js +1 -1
- package/components/identity.basic/operations/incept.js +1 -1
- 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 +7 -8
- package/components/identity.basic/source/add.ts +5 -2
- package/components/identity.basic/source/authenticate.ts +11 -13
- package/components/identity.basic/source/check.ts +9 -6
- package/components/identity.basic/source/delete.ts +4 -1
- package/components/identity.basic/source/incept.ts +13 -10
- package/components/identity.basic/source/info.ts +4 -1
- package/components/identity.basic/source/lib/credentials.ts +2 -3
- package/components/identity.basic/source/transit.ts +27 -21
- package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/types/index.d.ts +7 -3
- package/components/identity.basic/types/toa.d.ts +5 -5
- package/components/identity.clients/manifest.toa.yaml +36 -40
- package/components/identity.clients/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.clients/migrations/0002-indexes.yaml +4 -0
- package/components/identity.clients/operations/describe.js +1 -1
- package/components/identity.clients/operations/lib/canonical.js +1 -1
- package/components/identity.clients/operations/lib/cimd.js +3 -2
- package/components/identity.clients/operations/lib/redirect.js +7 -4
- package/components/identity.clients/operations/register.js +2 -2
- package/components/identity.clients/source/describe.ts +6 -8
- package/components/identity.clients/source/lib/Context.ts +6 -3
- package/components/identity.clients/source/lib/Entity.ts +1 -1
- package/components/identity.clients/source/lib/canonical.ts +1 -1
- package/components/identity.clients/source/lib/cimd.test.ts +8 -6
- package/components/identity.clients/source/lib/cimd.ts +24 -19
- package/components/identity.clients/source/lib/redirect.test.ts +8 -2
- package/components/identity.clients/source/lib/redirect.ts +12 -8
- package/components/identity.clients/source/register.ts +18 -18
- package/components/identity.clients/tsconfig.tsbuildinfo +1 -1
- package/components/identity.clients/types/toa.d.ts +5 -5
- package/components/identity.credentials/manifest.toa.yaml +4 -4
- package/components/identity.credentials/operations/list.js +8 -4
- package/components/identity.credentials/source/list.test.ts +39 -20
- package/components/identity.credentials/source/list.ts +12 -8
- package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
- package/components/identity.credentials/types/toa.d.ts +2 -2
- package/components/identity.federation/manifest.toa.yaml +23 -32
- package/components/identity.federation/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.federation/migrations/0002-indexes.yaml +25 -0
- package/components/identity.federation/operations/authenticate.js +4 -2
- package/components/identity.federation/operations/create.js +2 -2
- 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 +1 -1
- package/components/identity.federation/operations/lib/decode.js +1 -1
- package/components/identity.federation/operations/lib/discovery.js +2 -2
- package/components/identity.federation/operations/lib/exchange.js +8 -4
- package/components/identity.federation/operations/lib/principal.js +1 -1
- package/components/identity.federation/operations/lib/resolve.js +1 -1
- package/components/identity.federation/operations/list.js +2 -2
- package/components/identity.federation/source/authenticate.ts +19 -17
- package/components/identity.federation/source/create.ts +6 -7
- package/components/identity.federation/source/decode.ts +4 -1
- package/components/identity.federation/source/delete.ts +4 -1
- package/components/identity.federation/source/incept.ts +2 -3
- package/components/identity.federation/source/lib/decode.ts +4 -7
- package/components/identity.federation/source/lib/discovery.test.ts +15 -5
- package/components/identity.federation/source/lib/discovery.ts +10 -9
- package/components/identity.federation/source/lib/exchange.ts +18 -15
- package/components/identity.federation/source/lib/jose.d.ts +1 -1
- package/components/identity.federation/source/lib/principal.ts +5 -3
- package/components/identity.federation/source/lib/resolve.ts +5 -1
- package/components/identity.federation/source/list.test.ts +26 -10
- package/components/identity.federation/source/list.ts +5 -2
- package/components/identity.federation/source/types/context.ts +5 -2
- package/components/identity.federation/source/types/entity.ts +2 -2
- package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/types/toa.d.ts +5 -5
- package/components/identity.grants/manifest.toa.yaml +27 -31
- package/components/identity.grants/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.grants/migrations/0002-indexes.yaml +5 -0
- package/components/identity.grants/operations/authorize.js +1 -1
- package/components/identity.grants/operations/exchange.js +5 -2
- package/components/identity.grants/operations/lib/code.js +1 -1
- package/components/identity.grants/operations/lib/identify.js +1 -1
- package/components/identity.grants/operations/list.js +1 -1
- package/components/identity.grants/operations/revoke.js +3 -2
- package/components/identity.grants/source/authorize.ts +27 -19
- package/components/identity.grants/source/exchange.ts +15 -11
- package/components/identity.grants/source/lib/code.ts +20 -8
- package/components/identity.grants/source/lib/identify.ts +1 -1
- package/components/identity.grants/source/list.ts +2 -2
- package/components/identity.grants/source/revoke.ts +9 -7
- package/components/identity.grants/tsconfig.tsbuildinfo +1 -1
- package/components/identity.grants/types/index.d.ts +3 -3
- package/components/identity.grants/types/toa.d.ts +5 -5
- package/components/identity.keys/manifest.toa.yaml +18 -23
- package/components/identity.keys/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.keys/migrations/0002-indexes.yaml +4 -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 +2 -3
- package/components/identity.keys/source/disable.ts +1 -1
- package/components/identity.keys/source/revoke.ts +2 -2
- package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.keys/types/toa.d.ts +5 -5
- package/components/identity.otp/manifest.toa.yaml +16 -24
- package/components/identity.otp/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.otp/migrations/0002-indexes.yaml +5 -0
- package/components/identity.otp/operations/authenticate.js +1 -1
- package/components/identity.otp/operations/issue.js +1 -1
- package/components/identity.otp/source/authenticate.ts +4 -7
- package/components/identity.otp/source/issue.ts +1 -1
- package/components/identity.otp/source/lib/Context.ts +1 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/types/toa.d.ts +5 -5
- package/components/identity.passkeys/manifest.toa.yaml +45 -53
- package/components/identity.passkeys/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.passkeys/migrations/0002-indexes.yaml +11 -0
- package/components/identity.passkeys/operations/authenticate.js +1 -1
- package/components/identity.passkeys/operations/challenge.js +6 -3
- package/components/identity.passkeys/operations/create.js +1 -1
- package/components/identity.passkeys/operations/delete.js +1 -1
- package/components/identity.passkeys/operations/list.js +1 -1
- package/components/identity.passkeys/operations/use.js +1 -1
- package/components/identity.passkeys/source/authenticate.ts +3 -4
- package/components/identity.passkeys/source/challenge.ts +29 -25
- package/components/identity.passkeys/source/create.ts +8 -6
- package/components/identity.passkeys/source/delete.ts +4 -1
- package/components/identity.passkeys/source/list.ts +4 -1
- package/components/identity.passkeys/source/types/Context.ts +1 -1
- package/components/identity.passkeys/source/use.ts +12 -10
- package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/types/toa.d.ts +5 -5
- package/components/identity.roles/manifest.toa.yaml +12 -16
- package/components/identity.roles/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.roles/migrations/0002-indexes.yaml +8 -0
- package/components/identity.roles/operations/grant.js +1 -1
- package/components/identity.roles/operations/list.js +1 -1
- package/components/identity.roles/operations/principal.js +2 -2
- package/components/identity.roles/source/grant.ts +7 -6
- package/components/identity.roles/source/list.ts +1 -1
- package/components/identity.roles/source/principal.ts +5 -7
- package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/types/toa.d.ts +5 -5
- package/components/identity.tokens/manifest.toa.yaml +17 -15
- package/components/identity.tokens/migrations/0001-system-properties.yaml +14 -0
- package/components/identity.tokens/operations/authenticate.js +2 -2
- package/components/identity.tokens/operations/decrypt.js +11 -5
- package/components/identity.tokens/operations/encrypt.js +2 -2
- package/components/identity.tokens/operations/issue.js +2 -4
- package/components/identity.tokens/operations/lib/form.js +1 -1
- package/components/identity.tokens/operations/lib/key.js +1 -1
- package/components/identity.tokens/operations/revoke.js +1 -1
- package/components/identity.tokens/source/authenticate.test.ts +22 -16
- package/components/identity.tokens/source/authenticate.ts +7 -10
- package/components/identity.tokens/source/decrypt.test.ts +62 -29
- package/components/identity.tokens/source/decrypt.ts +30 -27
- package/components/identity.tokens/source/encrypt.test.ts +21 -16
- package/components/identity.tokens/source/encrypt.ts +8 -11
- package/components/identity.tokens/source/issue.test.ts +4 -2
- package/components/identity.tokens/source/issue.ts +6 -8
- package/components/identity.tokens/source/lib/form.ts +5 -9
- package/components/identity.tokens/source/lib/jose.d.ts +1 -1
- package/components/identity.tokens/source/lib/key.ts +1 -1
- package/components/identity.tokens/source/lib/paseto.test.ts +17 -6
- package/components/identity.tokens/source/revoke.ts +1 -1
- package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/types/index.d.ts +13 -4
- package/components/identity.tokens/types/toa.d.ts +5 -5
- package/context.toa.yaml +2 -2
- package/cucumber.mjs +3 -0
- package/documentation/access.md +4 -3
- package/documentation/cache.md +17 -3
- package/documentation/components.md +2 -2
- package/documentation/credentials.md +2 -2
- package/documentation/identity.md +7 -9
- package/documentation/map.md +2 -2
- package/documentation/mcp.md +16 -16
- package/documentation/notes/peers.md +1 -1
- package/documentation/notes/throttling.md +1 -1
- package/documentation/octets.md +4 -4
- package/documentation/protocol.md +3 -3
- package/documentation/query.md +14 -8
- package/documentation/rpc.md +31 -21
- package/documentation/tracing.md +3 -3
- package/documentation/tree.md +1 -1
- package/features/auth.assert.feature +2 -2
- package/features/auth.bearer.feature +1 -1
- package/features/auth.claims.feature +5 -5
- package/features/auth.incept.feature +2 -2
- package/features/authorities.federation.feature +1 -1
- package/features/configuration.feature +3 -4
- package/features/credentials.feature +9 -9
- package/features/dev.feature +1 -0
- package/features/dynamic.feature +1 -0
- package/features/errors.feature +21 -0
- package/features/etag.feature +0 -86
- package/features/identity.bans.feature +3 -3
- package/features/identity.basic.feature +9 -9
- package/features/identity.federation.feature +11 -11
- package/features/identity.tokens.custom.feature +5 -5
- package/features/identity.tokens.feature +2 -2
- package/features/interruptions.feature +1 -0
- package/features/introspection.map.feature +4 -4
- package/features/io.throttle.feature +1 -0
- package/features/map.feature +2 -2
- package/features/octets.cloudinary.feature +1 -1
- package/features/octets.download.feature +1 -0
- package/features/require.feature +1 -2
- package/features/steps/Captures.ts +1 -1
- package/features/steps/Cloudinary.ts +1 -2
- package/features/steps/Common.ts +4 -5
- package/features/steps/Components.ts +17 -12
- package/features/steps/Database.ts +42 -23
- package/features/steps/Gateway.ts +55 -72
- package/features/steps/HTTP.ts +12 -15
- package/features/steps/IDP.ts +118 -94
- package/features/steps/Identity.ts +3 -3
- package/features/steps/OTP.ts +3 -3
- package/features/steps/Parameters.ts +20 -10
- package/features/steps/Probe.ts +9 -7
- package/features/steps/Realtime.ts +40 -22
- package/features/steps/Workspace.ts +10 -7
- package/features/steps/components/audit/operations/record.js +1 -1
- package/features/steps/components/echo/operations/affect.js +1 -1
- package/features/steps/components/echo/operations/compute.js +1 -1
- package/features/steps/components/echo/operations/echo.js +1 -1
- package/features/steps/components/echo/operations/error.js +1 -1
- package/features/steps/components/echo/operations/identity.js +1 -1
- package/features/steps/components/echo/operations/parameters.js +1 -1
- package/features/steps/components/echo/operations/ping.js +1 -1
- package/features/steps/components/echo/operations/unwrap.js +1 -1
- package/features/steps/components/greeter/operations/greet.js +1 -1
- package/features/steps/components/notify/operations/send.js +1 -1
- package/features/steps/components/octets.tester/operations/authority.js +1 -1
- package/features/steps/components/octets.tester/operations/bar.js +1 -1
- package/features/steps/components/octets.tester/operations/baz.js +1 -1
- package/features/steps/components/octets.tester/operations/concat.js +1 -1
- package/features/steps/components/octets.tester/operations/echo.js +1 -1
- package/features/steps/components/octets.tester/operations/err.js +1 -1
- package/features/steps/components/octets.tester/operations/foo.js +1 -1
- package/features/steps/components/octets.tester/operations/id.js +1 -1
- package/features/steps/components/octets.tester/operations/identity.js +1 -1
- package/features/steps/components/octets.tester/operations/redirect.js +6 -4
- package/features/steps/components/octets.tester/operations/yex.js +1 -1
- package/features/steps/components/octets.tester/operations/yield.js +1 -1
- package/features/steps/components/orders/manifest.toa.yaml +10 -12
- package/features/steps/components/orders/operations/create.js +4 -2
- package/features/steps/components/pots/manifest.toa.yaml +15 -20
- package/features/steps/components/pots/migrations/0002-indexes.yaml +4 -0
- package/features/steps/components/pricing/operations/quote.js +1 -1
- package/features/steps/components/sequences/manifest.toa.yaml +0 -1
- package/features/steps/components/sequences/operations/numbers.js +1 -1
- package/features/steps/components/sequences/operations/tokens.js +3 -3
- package/features/steps/components/users/manifest.toa.yaml +3 -5
- package/features/steps/components/users/operations/create.js +1 -1
- package/features/steps/components/users.properties/manifest.toa.yaml +5 -6
- package/features/steps/map.ts +2 -2
- package/features/timestamps.feature +1 -1
- package/package.json +7 -7
- package/readme.md +11 -11
- package/schemas/annotation.cos.yaml +1 -3
- package/schemas/method.cos.yaml +2 -0
- package/source/Branch.test.ts +2 -2
- package/source/Branch.ts +3 -5
- package/source/Composition.ts +5 -5
- package/source/Directive.test.ts +38 -20
- package/source/Directive.ts +61 -47
- package/source/Endpoint.test.ts +1 -1
- package/source/Endpoint.ts +27 -92
- package/source/Factory.ts +26 -12
- package/source/Gateway.ts +87 -76
- package/source/HTTP/Context.ts +23 -30
- package/source/HTTP/Probe.ts +7 -9
- package/source/HTTP/Server.ts +88 -69
- package/source/HTTP/Timing.ts +6 -21
- package/source/HTTP/address.test.ts +8 -2
- package/source/HTTP/address.ts +2 -3
- package/source/HTTP/exceptions.ts +20 -18
- package/source/HTTP/formats/form.ts +1 -1
- package/source/HTTP/formats/json.ts +2 -2
- package/source/HTTP/formats/msgpack.ts +3 -4
- package/source/HTTP/formats/text.ts +2 -2
- package/source/HTTP/formats/yaml.test.ts +4 -1
- package/source/HTTP/formats/yaml.ts +14 -11
- package/source/HTTP/messages.test.ts +38 -28
- package/source/HTTP/messages.ts +44 -98
- package/source/Interception.ts +3 -4
- package/source/Introspection.ts +26 -14
- package/source/MCP/Server.ts +114 -54
- package/source/MCP/discover.ts +6 -7
- package/source/MCP/errors.ts +7 -8
- package/source/MCP/schema.test.ts +9 -3
- package/source/MCP/schema.ts +12 -16
- package/source/MCP/tools.ts +33 -28
- package/source/Mapping.ts +25 -27
- package/source/Query.ts +58 -44
- package/source/RPC/Context.ts +8 -11
- package/source/RPC/Dispatcher.ts +46 -26
- package/source/RPC/errors.test.ts +41 -16
- package/source/RPC/errors.ts +9 -10
- package/source/RPC/names.test.ts +35 -16
- package/source/RPC/names.ts +22 -29
- package/source/RTD/Directives.ts +21 -10
- package/source/RTD/Endpoint.ts +4 -1
- package/source/RTD/Method.ts +8 -6
- package/source/RTD/Node.ts +32 -34
- package/source/RTD/Route.ts +18 -21
- package/source/RTD/Tree.ts +18 -18
- package/source/RTD/factory.ts +13 -16
- package/source/RTD/segment.ts +12 -10
- package/source/RTD/syntax/parse.test.ts +12 -6
- package/source/RTD/syntax/parse.ts +30 -26
- package/source/RTD/syntax/types.ts +17 -1
- package/source/RTD/walk.test.ts +59 -22
- package/source/Remotes.test.ts +25 -4
- package/source/Remotes.ts +9 -4
- package/source/Tenant.ts +12 -12
- package/source/deployment.ts +20 -20
- package/source/directives/auth/Anonymous.test.ts +8 -2
- package/source/directives/auth/Anonymous.ts +5 -8
- package/source/directives/auth/Anyone.ts +3 -3
- package/source/directives/auth/Assert.ts +10 -10
- package/source/directives/auth/Authorization.ts +83 -69
- package/source/directives/auth/Delegate.test.ts +2 -2
- package/source/directives/auth/Delegate.ts +8 -10
- package/source/directives/auth/Echo.ts +5 -8
- package/source/directives/auth/Federation.ts +30 -21
- package/source/directives/auth/Id.ts +7 -4
- package/source/directives/auth/Incept.ts +32 -26
- package/source/directives/auth/Input.ts +36 -20
- package/source/directives/auth/Role.test.ts +49 -23
- package/source/directives/auth/Role.ts +29 -22
- package/source/directives/auth/Rule.ts +13 -8
- package/source/directives/auth/Scheme.ts +7 -7
- package/source/directives/auth/create.ts +1 -1
- package/source/directives/auth/schemes.ts +1 -1
- package/source/directives/auth/split.ts +2 -3
- package/source/directives/auth/types.ts +5 -2
- package/source/directives/cache/Cache.ts +44 -9
- package/source/directives/cache/Control.ts +25 -26
- package/source/directives/cache/Exact.ts +1 -1
- package/source/directives/cache/etag.ts +38 -0
- package/source/directives/cors/CORS.ts +9 -7
- package/source/directives/dev/Development.ts +3 -4
- package/source/directives/dev/Faulty.ts +11 -6
- package/source/directives/dev/Sleep.ts +5 -7
- package/source/directives/dev/Stub.ts +2 -2
- package/source/directives/dev/Throw.ts +2 -2
- package/source/directives/flow/Compose.ts +26 -20
- package/source/directives/flow/Fetch.ts +15 -15
- package/source/directives/flow/Flow.ts +9 -8
- package/source/directives/index.ts +11 -2
- package/source/directives/io/IO.ts +29 -20
- package/source/directives/io/Input.ts +9 -12
- package/source/directives/io/Output.ts +20 -23
- package/source/directives/io/Status.test.ts +12 -8
- package/source/directives/io/Status.ts +9 -8
- package/source/directives/io/Throttle.ts +6 -7
- package/source/directives/io/lib/throttle/Configuration.test.ts +32 -23
- package/source/directives/io/lib/throttle/Configuration.ts +14 -9
- package/source/directives/io/lib/throttle/Keys.ts +15 -10
- package/source/directives/io/lib/throttle/Quotas.test.ts +33 -17
- package/source/directives/io/lib/throttle/Quotas.ts +20 -26
- package/source/directives/io/lib/throttle/Sync.test.ts +14 -10
- package/source/directives/io/lib/throttle/Sync.ts +9 -12
- package/source/directives/io/lib/throttle/Warning.ts +3 -4
- package/source/directives/io/lib/throttle/components/IP.ts +4 -5
- package/source/directives/io/lib/throttle/components/Identity.ts +1 -1
- package/source/directives/io/lib/throttle/components/Path.ts +1 -1
- package/source/directives/io/lib/throttle/components/Route.ts +2 -2
- package/source/directives/io/lib/throttle/components/Segment.ts +2 -2
- package/source/directives/io/lib/throttle/conditions/Status.ts +2 -2
- package/source/directives/io/schemas.test.ts +12 -6
- package/source/directives/map/Authority.ts +2 -2
- package/source/directives/map/Buffer.ts +2 -2
- package/source/directives/map/Claims.ts +25 -20
- package/source/directives/map/Headers.ts +17 -13
- package/source/directives/map/Language.ts +8 -5
- package/source/directives/map/Languages.ts +9 -3
- package/source/directives/map/Map.ts +25 -12
- package/source/directives/map/Mapping.ts +9 -6
- package/source/directives/map/Properties.ts +1 -1
- package/source/directives/map/Segments.ts +22 -15
- package/source/directives/mcp/MCP.ts +9 -7
- package/source/directives/mcp/Tool.test.ts +21 -9
- package/source/directives/mcp/Tool.ts +23 -11
- package/source/directives/oauth/Discovery.ts +7 -11
- package/source/directives/oauth/documents.ts +11 -14
- package/source/directives/octets/Context.ts +6 -3
- package/source/directives/octets/Delete.ts +33 -25
- package/source/directives/octets/Directive.ts +5 -1
- package/source/directives/octets/Get.ts +13 -21
- package/source/directives/octets/Octets.ts +20 -15
- package/source/directives/octets/Put.ts +62 -27
- package/source/directives/octets/Workflow.ts +18 -12
- package/source/directives/octets/bytes.ts +1 -1
- package/source/directives/octets/schemas.test.ts +8 -14
- package/source/directives/octets/workflows/Execution.ts +19 -21
- package/source/directives/octets/workflows/Workflow.ts +10 -7
- package/source/directives/require/Headers.ts +3 -4
- package/source/directives/require/Require.ts +3 -4
- package/source/exceptions.ts +19 -12
- package/source/index.ts +1 -1
- package/source/manifest.test.ts +4 -1
- package/source/manifest.ts +19 -13
- package/source/octets.d.ts +1 -1
- package/source/root.ts +3 -2
- package/source/schemas.test.ts +17 -3
- package/transpiled/Branch.js.map +1 -1
- package/transpiled/Composition.js.map +1 -1
- package/transpiled/Directive.js +6 -2
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +0 -2
- package/transpiled/Endpoint.js +11 -52
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.d.ts +2 -1
- package/transpiled/Factory.js +1 -0
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +2 -1
- package/transpiled/Gateway.js +24 -15
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +0 -3
- package/transpiled/HTTP/Context.js +7 -9
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Probe.js.map +1 -1
- package/transpiled/HTTP/Server.js +19 -4
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/Timing.d.ts +1 -2
- package/transpiled/HTTP/Timing.js +2 -10
- package/transpiled/HTTP/Timing.js.map +1 -1
- package/transpiled/HTTP/address.js.map +1 -1
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/formats/form.js.map +1 -1
- package/transpiled/HTTP/formats/json.js.map +1 -1
- package/transpiled/HTTP/formats/msgpack.js.map +1 -1
- package/transpiled/HTTP/formats/text.js.map +1 -1
- package/transpiled/HTTP/formats/yaml.js +4 -1
- package/transpiled/HTTP/formats/yaml.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +3 -2
- package/transpiled/HTTP/messages.js +1 -43
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Interception.js.map +1 -1
- package/transpiled/Introspection.js +13 -2
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/Server.js +15 -4
- package/transpiled/MCP/Server.js.map +1 -1
- package/transpiled/MCP/discover.js.map +1 -1
- package/transpiled/MCP/errors.js.map +1 -1
- package/transpiled/MCP/schema.js +1 -1
- package/transpiled/MCP/schema.js.map +1 -1
- package/transpiled/MCP/tools.js +10 -7
- package/transpiled/MCP/tools.js.map +1 -1
- package/transpiled/Mapping.d.ts +2 -2
- package/transpiled/Mapping.js +3 -5
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/Query.d.ts +6 -2
- package/transpiled/Query.js +23 -8
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RPC/Context.js +0 -7
- package/transpiled/RPC/Context.js.map +1 -1
- package/transpiled/RPC/Dispatcher.js +4 -1
- package/transpiled/RPC/Dispatcher.js.map +1 -1
- package/transpiled/RPC/errors.js.map +1 -1
- package/transpiled/RPC/names.js.map +1 -1
- package/transpiled/RTD/Directives.d.ts +1 -1
- package/transpiled/RTD/Method.js +1 -3
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.js +5 -4
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Route.js +4 -1
- package/transpiled/RTD/Route.js.map +1 -1
- package/transpiled/RTD/Tree.js +1 -1
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/RTD/segment.js.map +1 -1
- package/transpiled/RTD/syntax/parse.js.map +1 -1
- package/transpiled/RTD/syntax/types.d.ts +6 -0
- package/transpiled/RTD/syntax/types.js +10 -1
- package/transpiled/RTD/syntax/types.js.map +1 -1
- package/transpiled/Remotes.js.map +1 -1
- package/transpiled/Tenant.d.ts +1 -1
- package/transpiled/Tenant.js.map +1 -1
- package/transpiled/deployment.d.ts +3 -0
- package/transpiled/deployment.js +6 -1
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.js +1 -3
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Anyone.js.map +1 -1
- package/transpiled/directives/auth/Assert.js.map +1 -1
- package/transpiled/directives/auth/Authorization.js +7 -3
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.js.map +1 -1
- package/transpiled/directives/auth/Echo.js +1 -3
- package/transpiled/directives/auth/Echo.js.map +1 -1
- package/transpiled/directives/auth/Federation.js +3 -7
- package/transpiled/directives/auth/Federation.js.map +1 -1
- package/transpiled/directives/auth/Id.js.map +1 -1
- package/transpiled/directives/auth/Incept.js +1 -1
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Input.js.map +1 -1
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Rule.js.map +1 -1
- package/transpiled/directives/auth/Scheme.js +1 -2
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/auth/create.js.map +1 -1
- package/transpiled/directives/auth/schemes.js.map +1 -1
- package/transpiled/directives/auth/split.js.map +1 -1
- package/transpiled/directives/auth/types.d.ts +3 -1
- package/transpiled/directives/cache/Cache.js +28 -2
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.js +1 -1
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/cache/etag.d.ts +10 -0
- package/transpiled/directives/cache/etag.js +30 -0
- package/transpiled/directives/cache/etag.js.map +1 -0
- package/transpiled/directives/cors/CORS.js.map +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/dev/Faulty.js.map +1 -1
- package/transpiled/directives/dev/Sleep.js.map +1 -1
- package/transpiled/directives/dev/Stub.js.map +1 -1
- package/transpiled/directives/dev/Throw.js.map +1 -1
- package/transpiled/directives/flow/Compose.js +7 -3
- package/transpiled/directives/flow/Compose.js.map +1 -1
- package/transpiled/directives/flow/Fetch.js.map +1 -1
- package/transpiled/directives/flow/Flow.js.map +1 -1
- package/transpiled/directives/index.js +11 -1
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/IO.d.ts +1 -1
- package/transpiled/directives/io/IO.js.map +1 -1
- package/transpiled/directives/io/Input.js +1 -1
- package/transpiled/directives/io/Input.js.map +1 -1
- package/transpiled/directives/io/Output.js +3 -3
- package/transpiled/directives/io/Output.js.map +1 -1
- package/transpiled/directives/io/Status.js.map +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/Configuration.js +8 -2
- package/transpiled/directives/io/lib/throttle/Configuration.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Keys.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.js +4 -3
- package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Sync.d.ts +1 -1
- package/transpiled/directives/io/lib/throttle/Sync.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Warning.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/IP.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Identity.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Path.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Route.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/components/Segment.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/conditions/Status.js.map +1 -1
- package/transpiled/directives/map/Authority.js.map +1 -1
- package/transpiled/directives/map/Buffer.js.map +1 -1
- package/transpiled/directives/map/Claims.js.map +1 -1
- package/transpiled/directives/map/Headers.js.map +1 -1
- package/transpiled/directives/map/Language.js.map +1 -1
- package/transpiled/directives/map/Languages.js.map +1 -1
- package/transpiled/directives/map/Map.js.map +1 -1
- package/transpiled/directives/map/Mapping.js.map +1 -1
- package/transpiled/directives/map/Properties.js.map +1 -1
- package/transpiled/directives/map/Segments.js.map +1 -1
- package/transpiled/directives/mcp/MCP.js +1 -1
- package/transpiled/directives/mcp/MCP.js.map +1 -1
- package/transpiled/directives/mcp/Tool.js +3 -1
- package/transpiled/directives/mcp/Tool.js.map +1 -1
- package/transpiled/directives/oauth/Discovery.js.map +1 -1
- package/transpiled/directives/oauth/documents.js.map +1 -1
- package/transpiled/directives/octets/Context.js +1 -1
- package/transpiled/directives/octets/Context.js.map +1 -1
- package/transpiled/directives/octets/Delete.js.map +1 -1
- package/transpiled/directives/octets/Directive.js.map +1 -1
- package/transpiled/directives/octets/Get.js.map +1 -1
- package/transpiled/directives/octets/Octets.js +1 -1
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/octets/Put.js.map +1 -1
- package/transpiled/directives/octets/Workflow.js.map +1 -1
- package/transpiled/directives/octets/bytes.js.map +1 -1
- package/transpiled/directives/octets/workflows/Execution.js +1 -2
- package/transpiled/directives/octets/workflows/Execution.js.map +1 -1
- package/transpiled/directives/octets/workflows/Workflow.js.map +1 -1
- package/transpiled/directives/require/Headers.js.map +1 -1
- package/transpiled/directives/require/Require.js.map +1 -1
- package/transpiled/exceptions.js.map +1 -1
- package/transpiled/index.d.ts +1 -1
- package/transpiled/index.js +1 -1
- package/transpiled/index.js.map +1 -1
- package/transpiled/manifest.js +5 -1
- package/transpiled/manifest.js.map +1 -1
- package/transpiled/root.js.map +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/CHANGELOG.md +0 -552
- package/source/redact.test.ts +0 -27
- package/source/redact.ts +0 -21
- package/transpiled/redact.d.ts +0 -5
- package/transpiled/redact.js +0 -17
- package/transpiled/redact.js.map +0 -1
package/source/Endpoint.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { Readable } from 'node:stream'
|
|
2
|
-
import { console } from 'openspan'
|
|
3
2
|
import { Mapping } from './Mapping.js'
|
|
4
3
|
import { take } from './Introspection.js'
|
|
5
|
-
import {
|
|
4
|
+
import { parse } from './directives/cache/etag.js'
|
|
6
5
|
import * as http from './HTTP/index.js'
|
|
7
6
|
import type { Introspection, Schema } from './Introspection.js'
|
|
8
7
|
import type { Remote } from '@toa.io/core'
|
|
@@ -19,56 +18,41 @@ export class Endpoint implements RTD.Endpoint {
|
|
|
19
18
|
/** What the operation says, with what the route takes already split out of it. */
|
|
20
19
|
private introspection: Introspection | null = null
|
|
21
20
|
|
|
22
|
-
public constructor
|
|
21
|
+
public constructor(endpoint: string, mapping: Mapping, discovery: Promise<Remote>) {
|
|
23
22
|
this.endpoint = endpoint
|
|
24
23
|
this.mapping = mapping
|
|
25
24
|
this.discovery = discovery
|
|
26
25
|
}
|
|
27
26
|
|
|
28
|
-
public async call
|
|
27
|
+
public async call(
|
|
28
|
+
context: http.Context,
|
|
29
|
+
parameters: RTD.Parameter[]
|
|
30
|
+
): Promise<http.OutgoingMessage> {
|
|
29
31
|
const body = await context.body()
|
|
30
32
|
const query = this.query(context)
|
|
31
33
|
const request = this.mapping.fit(body, query, parameters)
|
|
32
34
|
|
|
33
35
|
this.remote ??= await this.discovery
|
|
34
36
|
|
|
35
|
-
const endpoint = this.remote.locator.id + '.' + this.endpoint
|
|
36
|
-
|
|
37
|
-
console.debug('Calling operation', { endpoint, request: redact(request) })
|
|
38
|
-
|
|
39
37
|
const reply = await this.remote.invoke(this.endpoint, request)
|
|
40
38
|
|
|
41
|
-
|
|
42
|
-
{ endpoint, reply: reply instanceof Readable ? '[Readable stream]' : redact(reply) })
|
|
43
|
-
|
|
44
|
-
if (reply instanceof Error)
|
|
45
|
-
throw new http.UnprocessableEntity(reply)
|
|
39
|
+
if (reply instanceof Error) throw new http.UnprocessableEntity(reply)
|
|
46
40
|
|
|
47
|
-
const message: http.OutgoingMessage = {}
|
|
41
|
+
const message: http.OutgoingMessage = { body: reply }
|
|
48
42
|
|
|
49
|
-
//
|
|
50
|
-
if (reply !== null && reply
|
|
51
|
-
|
|
43
|
+
// what the reply carries for a cache to validate by; the `cache` family sets the headers
|
|
44
|
+
if (typeof reply === 'object' && reply !== null && !(reply instanceof Readable)) {
|
|
45
|
+
if ('VERSION' in reply) message.version = reply.VERSION
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
return message
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// last-modified
|
|
58
|
-
if (typeof reply === 'object' && reply !== null && ('_updated' in reply || '_created' in reply)) {
|
|
59
|
-
const timestamp: string = reply._updated ?? reply._created
|
|
60
|
-
const date = new Date(timestamp)
|
|
47
|
+
const modified = reply.UPDATED ?? reply.CREATED
|
|
61
48
|
|
|
62
|
-
message.
|
|
63
|
-
message.headers.set('last-modified', date.toUTCString())
|
|
49
|
+
if (modified !== undefined) message.modified = modified
|
|
64
50
|
}
|
|
65
51
|
|
|
66
|
-
message.body = reply
|
|
67
|
-
|
|
68
52
|
return message
|
|
69
53
|
}
|
|
70
54
|
|
|
71
|
-
public async explain
|
|
55
|
+
public async explain(parameters: RTD.Parameter[]): Promise<Introspection> {
|
|
72
56
|
this.introspection ??= await this.introspect(parameters)
|
|
73
57
|
|
|
74
58
|
// what a directive narrows is this caller's answer, not the next caller's
|
|
@@ -81,7 +65,7 @@ export class Endpoint implements RTD.Endpoint {
|
|
|
81
65
|
* share one remote — so the copy is what keeps the second from describing what the first
|
|
82
66
|
* took away.
|
|
83
67
|
*/
|
|
84
|
-
private async introspect
|
|
68
|
+
private async introspect(parameters: RTD.Parameter[]): Promise<Introspection> {
|
|
85
69
|
this.remote ??= await this.discovery
|
|
86
70
|
|
|
87
71
|
const operation = structuredClone(await this.remote.explain(this.endpoint))
|
|
@@ -97,8 +81,7 @@ export class Endpoint implements RTD.Endpoint {
|
|
|
97
81
|
for (const parameter of parameters) {
|
|
98
82
|
const schema = take(operation, parameter.name)
|
|
99
83
|
|
|
100
|
-
if (schema === undefined)
|
|
101
|
-
continue
|
|
84
|
+
if (schema === undefined) continue
|
|
102
85
|
|
|
103
86
|
route ??= {}
|
|
104
87
|
route[parameter.name] = schema
|
|
@@ -107,80 +90,34 @@ export class Endpoint implements RTD.Endpoint {
|
|
|
107
90
|
const query = this.mapping.explain(operation)
|
|
108
91
|
const introspection: Introspection = {}
|
|
109
92
|
|
|
110
|
-
if (route !== null)
|
|
111
|
-
introspection.route = route
|
|
93
|
+
if (route !== null) introspection.route = route
|
|
112
94
|
|
|
113
|
-
if (query !== null)
|
|
114
|
-
introspection.query = query
|
|
95
|
+
if (query !== null) introspection.query = query
|
|
115
96
|
|
|
116
97
|
Object.assign(introspection, operation)
|
|
117
98
|
|
|
118
99
|
return introspection
|
|
119
100
|
}
|
|
120
101
|
|
|
121
|
-
public async close
|
|
102
|
+
public async close(): Promise<void> {
|
|
122
103
|
this.remote ??= await this.discovery
|
|
123
104
|
|
|
124
105
|
await this.remote.disconnect(INTERRUPT)
|
|
125
106
|
}
|
|
126
107
|
|
|
127
|
-
private
|
|
128
|
-
message.headers ??= new Headers()
|
|
129
|
-
|
|
130
|
-
if (typeof reply === 'object' && reply !== null && '_version' in reply) {
|
|
131
|
-
const version = reply._version as number
|
|
132
|
-
const matched = etag === undefined ? null : this.matchVersion(etag)
|
|
133
|
-
|
|
134
|
-
if (etag !== undefined && matched !== null && version === matched) {
|
|
135
|
-
message.status = 304
|
|
136
|
-
message.headers.set('etag', etag)
|
|
137
|
-
|
|
138
|
-
return true
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
message.headers.set('etag', `"${version.toString()}"`)
|
|
142
|
-
|
|
143
|
-
return false
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
if (reply instanceof Readable)
|
|
147
|
-
return false
|
|
148
|
-
|
|
149
|
-
/*
|
|
150
|
-
* A reply that carries no version is tagged with a hash of its body. The body is
|
|
151
|
-
* serialized anyway when the response is written, so the tag is computed from what
|
|
152
|
-
* is actually sent rather than from a second serialization of the reply — which
|
|
153
|
-
* makes it specific to the negotiated representation, hence `vary: accept`.
|
|
154
|
-
*/
|
|
155
|
-
message.etag = true
|
|
156
|
-
|
|
157
|
-
return false
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
private query (context: http.Context): http.Query {
|
|
108
|
+
private query(context: http.Context): http.Query {
|
|
161
109
|
const query: http.Query = Object.fromEntries(context.url.searchParams)
|
|
162
110
|
const etag = context.request.headers['if-match']
|
|
163
111
|
|
|
164
|
-
if (etag !== undefined && this.mapping.queryable)
|
|
165
|
-
query.version = this.version(etag)
|
|
112
|
+
if (etag !== undefined && this.mapping.queryable) query.version = this.version(etag)
|
|
166
113
|
|
|
167
114
|
return query
|
|
168
115
|
}
|
|
169
116
|
|
|
170
|
-
private
|
|
171
|
-
const
|
|
117
|
+
private version(etag: string): number {
|
|
118
|
+
const version = parse(etag)
|
|
172
119
|
|
|
173
|
-
if (
|
|
174
|
-
return null
|
|
175
|
-
|
|
176
|
-
return Number.parseInt(match.groups!.version)
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
private version (etag: string): number {
|
|
180
|
-
const version = this.matchVersion(etag)
|
|
181
|
-
|
|
182
|
-
if (version === null)
|
|
183
|
-
throw new http.BadRequest('Invalid ETag')
|
|
120
|
+
if (version === null) throw new http.BadRequest('Invalid ETag')
|
|
184
121
|
|
|
185
122
|
return version
|
|
186
123
|
}
|
|
@@ -189,15 +126,15 @@ export class Endpoint implements RTD.Endpoint {
|
|
|
189
126
|
export class EndpointsFactory implements RTD.EndpointsFactory {
|
|
190
127
|
private readonly remotes: Remotes
|
|
191
128
|
|
|
192
|
-
public constructor
|
|
129
|
+
public constructor(remotes: Remotes) {
|
|
193
130
|
this.remotes = remotes
|
|
194
131
|
}
|
|
195
132
|
|
|
196
|
-
public create
|
|
133
|
+
public create(method: RTD.syntax.Method, context: Context): Endpoint {
|
|
197
134
|
if (method.mapping === undefined)
|
|
198
135
|
throw new Error('Cannot create Endpoint without mapping')
|
|
199
136
|
|
|
200
|
-
const mapping = Mapping.create(method.mapping.query)
|
|
137
|
+
const mapping = Mapping.create(method.mapping.query, method.mapping.paged)
|
|
201
138
|
|
|
202
139
|
const branch = context.extension
|
|
203
140
|
|
|
@@ -213,6 +150,4 @@ export class EndpointsFactory implements RTD.EndpointsFactory {
|
|
|
213
150
|
}
|
|
214
151
|
}
|
|
215
152
|
|
|
216
|
-
const ETAG = /^(W\/)?"(?<version>\d{1,32})"$/
|
|
217
|
-
|
|
218
153
|
const INTERRUPT = true
|
package/source/Factory.ts
CHANGED
|
@@ -18,22 +18,24 @@ import * as http from './HTTP/index.js'
|
|
|
18
18
|
import type { Branch } from './Branch.js'
|
|
19
19
|
import type { syntax } from './RTD/index.js'
|
|
20
20
|
import type { Broadcast } from './Gateway.js'
|
|
21
|
-
import type { Connector, Locator
|
|
21
|
+
import type { Connector, Locator } from '@toa.io/core'
|
|
22
|
+
import type { extensions } from '@toa.io/core/types'
|
|
22
23
|
|
|
23
24
|
export class Factory implements extensions.Factory {
|
|
24
25
|
private readonly host: Host
|
|
25
26
|
|
|
26
|
-
public constructor
|
|
27
|
+
public constructor(host: Host) {
|
|
27
28
|
this.host = host
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
public async tenant
|
|
31
|
+
public async tenant(locator: Locator, node: syntax.Node): Promise<Connector> {
|
|
31
32
|
const broadcast: Broadcast = await this.host.broadcast(CHANNEL, locator.id)
|
|
32
33
|
const hash = createHash('sha256').update(JSON.stringify(node)).digest('hex')
|
|
33
34
|
|
|
34
35
|
// no timestamp: the tenant stamps each announcement with its own start time
|
|
35
36
|
const branch: Omit<Branch, 'timestamp'> = {
|
|
36
|
-
|
|
37
|
+
// boot only ever hands a tenant a component's locator, which always has a namespace
|
|
38
|
+
namespace: locator.namespace!,
|
|
37
39
|
component: locator.name,
|
|
38
40
|
isolated: locator.namespace === 'identity',
|
|
39
41
|
node,
|
|
@@ -43,9 +45,11 @@ export class Factory implements extensions.Factory {
|
|
|
43
45
|
return new Tenant(broadcast, branch)
|
|
44
46
|
}
|
|
45
47
|
|
|
46
|
-
public async service
|
|
47
|
-
assert.ok(
|
|
48
|
-
|
|
48
|
+
public async service(): Promise<Connector | null> {
|
|
49
|
+
assert.ok(
|
|
50
|
+
process.env.TOA_EXPOSITION_PROPERTIES,
|
|
51
|
+
'TOA_EXPOSITION_PROPERTIES is undefined'
|
|
52
|
+
)
|
|
49
53
|
|
|
50
54
|
configureLogs()
|
|
51
55
|
|
|
@@ -62,7 +66,14 @@ export class Factory implements extensions.Factory {
|
|
|
62
66
|
const composition = new Composition(this.host)
|
|
63
67
|
const dispatcher = options.rpc === undefined ? null : new Dispatcher(options.rpc)
|
|
64
68
|
const mcp = options.mcp === undefined ? null : new Model(options.mcp, tree)
|
|
65
|
-
const gateway = new Gateway(
|
|
69
|
+
const gateway = new Gateway(
|
|
70
|
+
broadcast,
|
|
71
|
+
tree,
|
|
72
|
+
interception,
|
|
73
|
+
directives,
|
|
74
|
+
dispatcher,
|
|
75
|
+
mcp
|
|
76
|
+
)
|
|
66
77
|
|
|
67
78
|
gateway.depends(remotes)
|
|
68
79
|
gateway.depends(composition)
|
|
@@ -80,16 +91,19 @@ const CHANNEL = 'exposition'
|
|
|
80
91
|
const LOGS_PREFIX = 'TOA_TELEMETRY_LOGS'
|
|
81
92
|
const TRACES_ENV = 'TOA_TELEMETRY_TRACES'
|
|
82
93
|
|
|
83
|
-
function configureLogs
|
|
94
|
+
function configureLogs(): void {
|
|
84
95
|
const globEnv = process.env[LOGS_PREFIX]
|
|
85
96
|
const level: LevelName = process.env.TOA_DEV === '1' ? 'trace' : 'info'
|
|
86
|
-
const options =
|
|
97
|
+
const options =
|
|
98
|
+
globEnv === undefined ? { level } : (JSON.parse(globEnv) as { level?: LevelName })
|
|
87
99
|
|
|
88
100
|
console.configure({ level: options.level ?? level })
|
|
89
101
|
|
|
90
102
|
const tracesEnv = process.env[TRACES_ENV]
|
|
91
103
|
|
|
92
|
-
traces(
|
|
104
|
+
traces(
|
|
105
|
+
tracesEnv === undefined ? development() : (JSON.parse(tracesEnv) as TracesOptions)
|
|
106
|
+
)
|
|
93
107
|
}
|
|
94
108
|
|
|
95
109
|
/**
|
|
@@ -101,7 +115,7 @@ function configureLogs (): void {
|
|
|
101
115
|
* The gateway boots without the telemetry extension, hence the copy of
|
|
102
116
|
* `extensions/telemetry/source/extension.ts`.
|
|
103
117
|
*/
|
|
104
|
-
function development
|
|
118
|
+
function development(): TracesOptions {
|
|
105
119
|
const local = process.env.TOA_DEV === '1' || process.env.TOA_BOOT_TRACE === '1'
|
|
106
120
|
|
|
107
121
|
return local ? { exporters: { console: {} } } : {}
|
package/source/Gateway.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
2
|
import { setTimeout } from 'node:timers/promises'
|
|
3
3
|
import { console } from 'openspan'
|
|
4
|
-
import {
|
|
4
|
+
import { Connector } from '@toa.io/core'
|
|
5
|
+
import type { bindings } from '@toa.io/core/types'
|
|
5
6
|
import * as http from './HTTP/index.js'
|
|
6
7
|
import { MCP, RPC } from './const.js'
|
|
7
8
|
import { rethrow } from './exceptions.js'
|
|
@@ -9,7 +10,14 @@ import { decide } from './Branch.js'
|
|
|
9
10
|
import type { Interception } from './Interception.js'
|
|
10
11
|
import type { Dispatcher } from './RPC/index.js'
|
|
11
12
|
import type { Server } from './MCP/index.js'
|
|
12
|
-
import type {
|
|
13
|
+
import type {
|
|
14
|
+
DirectiveFactory,
|
|
15
|
+
Method,
|
|
16
|
+
Node,
|
|
17
|
+
Parameter,
|
|
18
|
+
Tree,
|
|
19
|
+
Match
|
|
20
|
+
} from './RTD/index.js'
|
|
13
21
|
import type { Label } from './discovery.js'
|
|
14
22
|
import type { Branch, Exposed } from './Branch.js'
|
|
15
23
|
|
|
@@ -32,8 +40,14 @@ export class Gateway extends Connector {
|
|
|
32
40
|
private resolveFirstMerge: (() => void) | null = null
|
|
33
41
|
|
|
34
42
|
// eslint-disable-next-line max-params
|
|
35
|
-
public constructor
|
|
36
|
-
|
|
43
|
+
public constructor(
|
|
44
|
+
broadcast: Broadcast,
|
|
45
|
+
tree: Tree,
|
|
46
|
+
interception: Interception,
|
|
47
|
+
directives: DirectiveFactory,
|
|
48
|
+
dispatcher: Dispatcher | null,
|
|
49
|
+
mcp: Server | null
|
|
50
|
+
) {
|
|
37
51
|
super()
|
|
38
52
|
|
|
39
53
|
this.broadcast = broadcast
|
|
@@ -46,22 +60,18 @@ export class Gateway extends Connector {
|
|
|
46
60
|
this.depends(broadcast)
|
|
47
61
|
}
|
|
48
62
|
|
|
49
|
-
public async process
|
|
50
|
-
const interception = await
|
|
51
|
-
this.interceptor.intercept(context))
|
|
63
|
+
public async process(context: http.Context): Promise<http.OutgoingMessage> {
|
|
64
|
+
const interception = await this.interceptor.intercept(context)
|
|
52
65
|
|
|
53
|
-
if (interception !== null)
|
|
54
|
-
return interception
|
|
66
|
+
if (interception !== null) return interception
|
|
55
67
|
|
|
56
68
|
// request-scoped, before anything is routed: this is where a credential is read
|
|
57
|
-
await
|
|
58
|
-
this.directives.preflight(context)).catch(rethrow)
|
|
69
|
+
await this.directives.preflight(context).catch(rethrow)
|
|
59
70
|
|
|
60
71
|
const response = await this.endpoint(context)
|
|
61
72
|
|
|
62
73
|
// request-scoped, on whatever is going back: this is where a credential is re-issued
|
|
63
|
-
await
|
|
64
|
-
this.directives.depart(context, response)).catch(rethrow)
|
|
74
|
+
await this.directives.depart(context, response).catch(rethrow)
|
|
65
75
|
|
|
66
76
|
return response
|
|
67
77
|
}
|
|
@@ -70,14 +80,14 @@ export class Gateway extends Connector {
|
|
|
70
80
|
* What answers the request: a pinned endpoint that makes calls of its own, or the route
|
|
71
81
|
* the path names.
|
|
72
82
|
*/
|
|
73
|
-
private async endpoint
|
|
83
|
+
private async endpoint(context: http.Context): Promise<http.OutgoingMessage> {
|
|
74
84
|
const route: http.Processor = async (call) => await this.route(call)
|
|
75
85
|
|
|
76
86
|
if (this.dispatcher !== null && context.url.pathname === RPC)
|
|
77
|
-
return await
|
|
87
|
+
return await this.dispatcher.dispatch(context, route)
|
|
78
88
|
|
|
79
89
|
if (this.mcp !== null && context.url.pathname === MCP)
|
|
80
|
-
return await
|
|
90
|
+
return await this.mcp.process(context, route)
|
|
81
91
|
|
|
82
92
|
return await this.route(context)
|
|
83
93
|
}
|
|
@@ -86,7 +96,7 @@ export class Gateway extends Connector {
|
|
|
86
96
|
* One call: everything that needs a node. A request makes one of these, and a request
|
|
87
97
|
* that carries several calls makes one per call.
|
|
88
98
|
*/
|
|
89
|
-
private async route
|
|
99
|
+
private async route(context: http.Context): Promise<http.OutgoingMessage> {
|
|
90
100
|
const { node, parameters } = this.match(context)
|
|
91
101
|
|
|
92
102
|
if (context.request.method === 'OPTIONS')
|
|
@@ -94,39 +104,35 @@ export class Gateway extends Connector {
|
|
|
94
104
|
|
|
95
105
|
let verb = context.request.method
|
|
96
106
|
|
|
97
|
-
if (!(verb in node.methods) && verb === 'HEAD' && 'GET' in node.methods)
|
|
98
|
-
verb = 'GET'
|
|
107
|
+
if (!(verb in node.methods) && verb === 'HEAD' && 'GET' in node.methods) verb = 'GET'
|
|
99
108
|
|
|
100
|
-
if (!(verb in node.methods))
|
|
101
|
-
throw new http.MethodNotAllowed()
|
|
109
|
+
if (!(verb in node.methods)) throw new http.MethodNotAllowed()
|
|
102
110
|
|
|
103
111
|
const method = node.methods[verb]
|
|
104
112
|
|
|
105
|
-
const interruption = await
|
|
106
|
-
|
|
113
|
+
const interruption = await method.directives
|
|
114
|
+
.precall(context, parameters)
|
|
115
|
+
.catch(rethrow)
|
|
116
|
+
const response = interruption ?? (await this.call(method, context, parameters))
|
|
107
117
|
|
|
108
|
-
|
|
109
|
-
await context.timing.capture('call', this.call(method, context, parameters))
|
|
110
|
-
|
|
111
|
-
await context.timing.capture('settle',
|
|
112
|
-
method.directives.settle(context, response)).catch(rethrow)
|
|
118
|
+
await method.directives.settle(context, response).catch(rethrow)
|
|
113
119
|
|
|
114
120
|
return response
|
|
115
121
|
}
|
|
116
122
|
|
|
117
|
-
protected override async open
|
|
123
|
+
protected override async open(): Promise<void> {
|
|
118
124
|
await this.discover()
|
|
119
125
|
|
|
120
126
|
// what is served besides the tree, so that turning one on can be seen to have worked
|
|
121
127
|
const pinned: string[] = []
|
|
122
128
|
|
|
123
|
-
if (this.dispatcher !== null)
|
|
124
|
-
pinned.push(RPC)
|
|
129
|
+
if (this.dispatcher !== null) pinned.push(RPC)
|
|
125
130
|
|
|
126
|
-
if (this.mcp !== null)
|
|
127
|
-
pinned.push(MCP)
|
|
131
|
+
if (this.mcp !== null) pinned.push(MCP)
|
|
128
132
|
|
|
129
|
-
console.info('Gateway started', {
|
|
133
|
+
console.info('Gateway started', {
|
|
134
|
+
endpoints: pinned.length === 0 ? 'none' : pinned.join(' ')
|
|
135
|
+
})
|
|
130
136
|
}
|
|
131
137
|
|
|
132
138
|
/**
|
|
@@ -135,17 +141,17 @@ export class Gateway extends Connector {
|
|
|
135
141
|
* ticker firing in between calls an endpoint that has just been unbound, and reports the
|
|
136
142
|
* refusal as a failure to reconcile.
|
|
137
143
|
*/
|
|
138
|
-
protected override async close
|
|
144
|
+
protected override async close(): Promise<void> {
|
|
139
145
|
this.stopped = true
|
|
140
146
|
|
|
141
147
|
this.tree.dispose()
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
protected override dispose
|
|
150
|
+
protected override dispose(): void {
|
|
145
151
|
console.info('Gateway is closed')
|
|
146
152
|
}
|
|
147
153
|
|
|
148
|
-
private match
|
|
154
|
+
private match(context: http.Context): Match {
|
|
149
155
|
const match = this.tree.match(context.url.pathname)
|
|
150
156
|
|
|
151
157
|
if (match === null) {
|
|
@@ -155,17 +161,15 @@ export class Gateway extends Connector {
|
|
|
155
161
|
throw new http.NotFound('Route not found')
|
|
156
162
|
}
|
|
157
163
|
|
|
158
|
-
if (match.node.forward === null)
|
|
159
|
-
return match
|
|
164
|
+
if (match.node.forward === null) return match
|
|
160
165
|
|
|
161
|
-
const destination = match.node.forward.replace(/\/:([^/]+)/g,
|
|
162
|
-
(
|
|
163
|
-
const value = match.parameters.find((parameter) => parameter.name === name)?.value
|
|
166
|
+
const destination = match.node.forward.replace(/\/:([^/]+)/g, (_, name) => {
|
|
167
|
+
const value = match.parameters.find((parameter) => parameter.name === name)?.value
|
|
164
168
|
|
|
165
|
-
|
|
169
|
+
assert.ok(value !== undefined, `Forwarded parameter '${name}' not found`)
|
|
166
170
|
|
|
167
|
-
|
|
168
|
-
|
|
171
|
+
return `/${value}`
|
|
172
|
+
})
|
|
169
173
|
|
|
170
174
|
const forward = this.tree.match(destination)
|
|
171
175
|
|
|
@@ -174,23 +178,28 @@ export class Gateway extends Connector {
|
|
|
174
178
|
return forward
|
|
175
179
|
}
|
|
176
180
|
|
|
177
|
-
private async call
|
|
181
|
+
private async call(
|
|
182
|
+
method: Method,
|
|
183
|
+
context: http.Context,
|
|
184
|
+
parameters: Parameter[]
|
|
185
|
+
): Promise<http.OutgoingMessage> {
|
|
178
186
|
if (context.url.pathname[context.url.pathname.length - 1] !== '/')
|
|
179
187
|
throw new http.NotFound('Trailing slash is required')
|
|
180
188
|
|
|
181
|
-
if (context.encoder === null)
|
|
182
|
-
throw new http.NotAcceptable()
|
|
189
|
+
if (context.encoder === null) throw new http.NotAcceptable()
|
|
183
190
|
|
|
184
|
-
if (method.endpoint === null)
|
|
185
|
-
throw new http.MethodNotAllowed()
|
|
191
|
+
if (method.endpoint === null) throw new http.MethodNotAllowed()
|
|
186
192
|
|
|
187
|
-
return await method.endpoint
|
|
193
|
+
return (await method.endpoint
|
|
188
194
|
.call(context, parameters)
|
|
189
|
-
.catch(rethrow) as http.OutgoingMessage
|
|
195
|
+
.catch(rethrow)) as http.OutgoingMessage
|
|
190
196
|
}
|
|
191
197
|
|
|
192
|
-
private async explain
|
|
193
|
-
|
|
198
|
+
private async explain(
|
|
199
|
+
context: http.Context,
|
|
200
|
+
node: Node,
|
|
201
|
+
parameters: Parameter[]
|
|
202
|
+
): Promise<http.OutgoingMessage> {
|
|
194
203
|
const body = await node.explain(context, parameters)
|
|
195
204
|
const verbs = Object.keys(body)
|
|
196
205
|
|
|
@@ -201,7 +210,7 @@ export class Gateway extends Connector {
|
|
|
201
210
|
return { body, headers: new Headers({ allow: verbs.join(', ') }) }
|
|
202
211
|
}
|
|
203
212
|
|
|
204
|
-
private async discover
|
|
213
|
+
private async discover(): Promise<void> {
|
|
205
214
|
const first = new Promise<void>((resolve) => {
|
|
206
215
|
this.resolveFirstMerge = resolve
|
|
207
216
|
})
|
|
@@ -217,43 +226,46 @@ export class Gateway extends Connector {
|
|
|
217
226
|
* A single ping is enough only if every tenant is listening by then, which is
|
|
218
227
|
* not the case while the deployment is still rolling out.
|
|
219
228
|
*/
|
|
220
|
-
private async knock
|
|
229
|
+
private async knock(): Promise<void> {
|
|
221
230
|
for (const delay of KNOCK_DELAYS) {
|
|
222
|
-
if (this.stopped)
|
|
223
|
-
return
|
|
231
|
+
if (this.stopped) return
|
|
224
232
|
|
|
225
|
-
if (delay > 0)
|
|
226
|
-
await setTimeout(delay, undefined, { ref: false })
|
|
233
|
+
if (delay > 0) await setTimeout(delay, undefined, { ref: false })
|
|
227
234
|
|
|
228
235
|
await this.ping()
|
|
229
236
|
}
|
|
230
237
|
}
|
|
231
238
|
|
|
232
|
-
private async ping
|
|
233
|
-
if (this.stopped)
|
|
234
|
-
return
|
|
239
|
+
private async ping(): Promise<void> {
|
|
240
|
+
if (this.stopped) return
|
|
235
241
|
|
|
236
242
|
this.lastPing = Date.now()
|
|
237
243
|
|
|
238
|
-
await this.broadcast
|
|
239
|
-
.
|
|
240
|
-
|
|
244
|
+
await this.broadcast
|
|
245
|
+
.transmit<null>('ping', null)
|
|
246
|
+
.catch((exception: Error) =>
|
|
247
|
+
console.error('Discovery ping failed', { message: exception.message })
|
|
248
|
+
)
|
|
241
249
|
}
|
|
242
250
|
|
|
243
|
-
private reping
|
|
244
|
-
if (Date.now() - this.lastPing < PING_COOLDOWN)
|
|
245
|
-
return
|
|
251
|
+
private reping(): void {
|
|
252
|
+
if (Date.now() - this.lastPing < PING_COOLDOWN) return
|
|
246
253
|
|
|
247
254
|
void this.ping()
|
|
248
255
|
}
|
|
249
256
|
|
|
250
|
-
private async settled
|
|
257
|
+
private async settled(first: Promise<void>): Promise<void> {
|
|
251
258
|
const deadline = Date.now() + SETTLE_TIMEOUT
|
|
252
259
|
const abort = new AbortController()
|
|
253
260
|
|
|
254
261
|
// an uncancelled timer keeps the process alive long after the race is won
|
|
255
|
-
await Promise.race([
|
|
256
|
-
|
|
262
|
+
await Promise.race([
|
|
263
|
+
first,
|
|
264
|
+
setTimeout(SETTLE_TIMEOUT, undefined, { signal: abort.signal })
|
|
265
|
+
])
|
|
266
|
+
.finally(() => {
|
|
267
|
+
abort.abort()
|
|
268
|
+
})
|
|
257
269
|
.catch(() => {})
|
|
258
270
|
|
|
259
271
|
if (this.lastMerge === 0) {
|
|
@@ -263,8 +275,7 @@ export class Gateway extends Connector {
|
|
|
263
275
|
}
|
|
264
276
|
|
|
265
277
|
while (Date.now() - this.lastMerge < this.quiet()) {
|
|
266
|
-
if (Date.now() >= deadline)
|
|
267
|
-
break
|
|
278
|
+
if (Date.now() >= deadline) break
|
|
268
279
|
|
|
269
280
|
await setTimeout(SETTLE_POLL)
|
|
270
281
|
}
|
|
@@ -277,13 +288,13 @@ export class Gateway extends Connector {
|
|
|
277
288
|
* is enough; a rolling deployment brings them up seconds apart, and the window grows with
|
|
278
289
|
* the widest gap seen so far to keep waiting for the ones still starting.
|
|
279
290
|
*/
|
|
280
|
-
private quiet
|
|
291
|
+
private quiet(): number {
|
|
281
292
|
const adaptive = this.widestGap * SETTLE_QUIET_FACTOR
|
|
282
293
|
|
|
283
294
|
return Math.min(Math.max(adaptive, SETTLE_QUIET_MIN), SETTLE_QUIET_MAX)
|
|
284
295
|
}
|
|
285
296
|
|
|
286
|
-
private merge
|
|
297
|
+
private merge(branch: Branch): void {
|
|
287
298
|
const id = branch.namespace + '.' + branch.component
|
|
288
299
|
|
|
289
300
|
const attributes = {
|