@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/HTTP/Context.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import crypto from 'node:crypto'
|
|
2
1
|
import { buffer } from 'node:stream/consumers'
|
|
3
2
|
import Negotiator from 'negotiator'
|
|
4
3
|
import { console } from 'openspan'
|
|
@@ -10,7 +9,6 @@ import type { OutgoingMessage } from './messages.js'
|
|
|
10
9
|
import type { IncomingMessage } from './types.js'
|
|
11
10
|
|
|
12
11
|
export class Context {
|
|
13
|
-
public readonly id: string
|
|
14
12
|
public readonly authority: string
|
|
15
13
|
public readonly request: IncomingMessage
|
|
16
14
|
|
|
@@ -20,7 +18,6 @@ export class Context {
|
|
|
20
18
|
public readonly subtype: string | null = null
|
|
21
19
|
public readonly encoder: Format | null = null
|
|
22
20
|
public readonly timing: Timing
|
|
23
|
-
public readonly debug: boolean
|
|
24
21
|
|
|
25
22
|
/**
|
|
26
23
|
* Whether this is a procedure a request made, rather than the request. What forks one
|
|
@@ -37,17 +34,19 @@ export class Context {
|
|
|
37
34
|
private consumed = false
|
|
38
35
|
|
|
39
36
|
// eslint-disable-next-line max-params
|
|
40
|
-
public constructor
|
|
41
|
-
|
|
37
|
+
public constructor(
|
|
38
|
+
authority: string,
|
|
39
|
+
request: IncomingMessage,
|
|
40
|
+
properties: Properties,
|
|
41
|
+
url: URL
|
|
42
|
+
) {
|
|
42
43
|
this.authority = authority
|
|
43
44
|
this.request = request
|
|
44
45
|
this.ip = address(request, properties.ip)
|
|
45
46
|
|
|
46
|
-
this.id = crypto.randomUUID()
|
|
47
47
|
// parsed by the server, which had to parse it anyway to know the request is valid
|
|
48
48
|
this.url = url
|
|
49
49
|
this.timing = new Timing()
|
|
50
|
-
this.debug = properties.debug
|
|
51
50
|
this.log(request)
|
|
52
51
|
|
|
53
52
|
const accept = this.request.headers.accept
|
|
@@ -56,11 +55,7 @@ export class Context {
|
|
|
56
55
|
const match = SUBTYPE.exec(accept)
|
|
57
56
|
|
|
58
57
|
if (match !== null) {
|
|
59
|
-
const {
|
|
60
|
-
type,
|
|
61
|
-
subtype,
|
|
62
|
-
suffix
|
|
63
|
-
} = match.groups!
|
|
58
|
+
const { type, subtype, suffix } = match.groups!
|
|
64
59
|
|
|
65
60
|
this.request.headers.accept = `${type}/${suffix}`
|
|
66
61
|
this.subtype = subtype
|
|
@@ -69,11 +64,10 @@ export class Context {
|
|
|
69
64
|
|
|
70
65
|
const encoder = negotiate(this.request)
|
|
71
66
|
|
|
72
|
-
if (encoder !== undefined)
|
|
73
|
-
this.encoder = encoder
|
|
67
|
+
if (encoder !== undefined) this.encoder = encoder
|
|
74
68
|
}
|
|
75
69
|
|
|
76
|
-
public async buffer
|
|
70
|
+
public async buffer(): Promise<Buffer> {
|
|
77
71
|
this.consumed = true
|
|
78
72
|
|
|
79
73
|
return await buffer(this.request)
|
|
@@ -82,19 +76,21 @@ export class Context {
|
|
|
82
76
|
public async body<T>(): Promise<T> {
|
|
83
77
|
let value = this.consumed ? null : await read(this)
|
|
84
78
|
|
|
85
|
-
for (const transform of this.pipelines.body)
|
|
86
|
-
value = await transform(value)
|
|
79
|
+
for (const transform of this.pipelines.body) value = await transform(value)
|
|
87
80
|
|
|
88
81
|
return value
|
|
89
82
|
}
|
|
90
83
|
|
|
91
|
-
private log
|
|
92
|
-
|
|
84
|
+
private log(request: IncomingMessage): void {
|
|
85
|
+
// built only when the line is written, which at `info` it is not
|
|
86
|
+
console.debug('Received request', () => {
|
|
87
|
+
const headers = { ...request.headers }
|
|
93
88
|
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
if (headers.authorization !== undefined)
|
|
90
|
+
headers.authorization = SCHEME.exec(headers.authorization)?.[1] ?? '[malformed]'
|
|
96
91
|
|
|
97
|
-
|
|
92
|
+
return { method: request.method, url: request.url, headers }
|
|
93
|
+
})
|
|
98
94
|
}
|
|
99
95
|
}
|
|
100
96
|
|
|
@@ -107,8 +103,6 @@ interface Pipelines {
|
|
|
107
103
|
}
|
|
108
104
|
|
|
109
105
|
interface Properties {
|
|
110
|
-
debug: boolean
|
|
111
|
-
|
|
112
106
|
/** the header the client address is read from; the connection's without one */
|
|
113
107
|
ip?: string
|
|
114
108
|
}
|
|
@@ -117,18 +111,16 @@ interface Properties {
|
|
|
117
111
|
* Negotiation parses the header and sorts the candidates, and the value repeats:
|
|
118
112
|
* clients send one of a handful of `accept` strings. Bounded, the header is theirs.
|
|
119
113
|
*/
|
|
120
|
-
function negotiate
|
|
114
|
+
function negotiate(request: IncomingMessage): Format | undefined {
|
|
121
115
|
const accept = request.headers.accept ?? ''
|
|
122
116
|
const known = NEGOTIATED.get(accept)
|
|
123
117
|
|
|
124
|
-
if (known !== undefined)
|
|
125
|
-
return known === NONE ? undefined : known
|
|
118
|
+
if (known !== undefined) return known === NONE ? undefined : known
|
|
126
119
|
|
|
127
120
|
const mediaType = new Negotiator(request).mediaType(types)
|
|
128
121
|
const encoder = mediaType === undefined ? undefined : formats[mediaType]
|
|
129
122
|
|
|
130
|
-
if (NEGOTIATED.size >= NEGOTIATED_LIMIT)
|
|
131
|
-
NEGOTIATED.clear()
|
|
123
|
+
if (NEGOTIATED.size >= NEGOTIATED_LIMIT) NEGOTIATED.clear()
|
|
132
124
|
|
|
133
125
|
NEGOTIATED.set(accept, encoder ?? NONE)
|
|
134
126
|
|
|
@@ -140,4 +132,5 @@ const NONE = Symbol('not acceptable') as unknown as Format
|
|
|
140
132
|
const NEGOTIATED = new Map<string, Format>()
|
|
141
133
|
const NEGOTIATED_LIMIT = 1024
|
|
142
134
|
|
|
143
|
-
const SUBTYPE =
|
|
135
|
+
const SUBTYPE =
|
|
136
|
+
/^(?<type>\w{1,32})\/(vnd\.toa\.(?<subtype>\S{1,32})\+)(?<suffix>\S{1,32})$/
|
package/source/HTTP/Probe.ts
CHANGED
|
@@ -21,14 +21,14 @@ export class Probe {
|
|
|
21
21
|
private listening = false
|
|
22
22
|
private skipped = false
|
|
23
23
|
|
|
24
|
-
public constructor
|
|
24
|
+
public constructor(port: number, path: string = PATH) {
|
|
25
25
|
this.port = port
|
|
26
26
|
this.path = path
|
|
27
27
|
|
|
28
28
|
this.server.on('request', (request, response) => this.listener(request, response))
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
public async listen
|
|
31
|
+
public async listen(): Promise<void> {
|
|
32
32
|
this.startedAt = Date.now()
|
|
33
33
|
|
|
34
34
|
try {
|
|
@@ -59,7 +59,7 @@ export class Probe {
|
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
/** The gateway is listening and has routes: answer `200`. */
|
|
62
|
-
public complete
|
|
62
|
+
public complete(): void {
|
|
63
63
|
this.ready = true
|
|
64
64
|
|
|
65
65
|
// the IPC signal is not tied to the probe: a process that gave up the shared port is
|
|
@@ -67,11 +67,10 @@ export class Probe {
|
|
|
67
67
|
process.send?.('ready')
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
public async close
|
|
70
|
+
public async close(): Promise<void> {
|
|
71
71
|
this.ready = false
|
|
72
72
|
|
|
73
|
-
if (!this.listening || this.skipped)
|
|
74
|
-
return
|
|
73
|
+
if (!this.listening || this.skipped) return
|
|
75
74
|
|
|
76
75
|
this.listening = false
|
|
77
76
|
|
|
@@ -81,15 +80,14 @@ export class Probe {
|
|
|
81
80
|
await new Promise<void>((resolve) => this.server.close(() => resolve()))
|
|
82
81
|
}
|
|
83
82
|
|
|
84
|
-
private listener
|
|
83
|
+
private listener(request: http.IncomingMessage, response: http.ServerResponse): void {
|
|
85
84
|
if (request.url !== this.path) {
|
|
86
85
|
response.writeHead(404).end()
|
|
87
86
|
|
|
88
87
|
return
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
if (this.ready)
|
|
92
|
-
response.writeHead(200, { 'cache-control': 'no-store' }).end()
|
|
90
|
+
if (this.ready) response.writeHead(200, { 'cache-control': 'no-store' }).end()
|
|
93
91
|
else {
|
|
94
92
|
const remaining = Math.ceil((Date.now() - this.startedAt) / 1000).toString()
|
|
95
93
|
|
package/source/HTTP/Server.ts
CHANGED
|
@@ -27,32 +27,35 @@ export class Server extends Connector {
|
|
|
27
27
|
|
|
28
28
|
private process?: Processor
|
|
29
29
|
|
|
30
|
-
private constructor
|
|
30
|
+
private constructor(properties: Properties) {
|
|
31
31
|
super()
|
|
32
32
|
|
|
33
33
|
this.properties = properties
|
|
34
|
-
this.authorities = new Map(
|
|
34
|
+
this.authorities = new Map(
|
|
35
|
+
Object.entries(properties.authorities).map(([key, value]) => [value, key])
|
|
36
|
+
)
|
|
35
37
|
this.server = instantiate(properties.protocol)
|
|
36
38
|
this.probe = new Probe(properties.probe)
|
|
37
39
|
|
|
38
40
|
this.server.on('request', (req, res) =>
|
|
39
|
-
this.listener(req as unknown as IncomingMessage, res as unknown as ServerResponse)
|
|
41
|
+
this.listener(req as unknown as IncomingMessage, res as unknown as ServerResponse)
|
|
42
|
+
)
|
|
40
43
|
|
|
41
44
|
if (properties.protocol === 'h1') this.h1(this.server as http.Server)
|
|
42
45
|
else this.h2(this.server as http2.Http2Server)
|
|
43
46
|
}
|
|
44
47
|
|
|
45
|
-
public static create
|
|
48
|
+
public static create(options: Options): Server {
|
|
46
49
|
const properties: Properties = { ...DEFAULTS, ...options }
|
|
47
50
|
|
|
48
51
|
return new Server(properties)
|
|
49
52
|
}
|
|
50
53
|
|
|
51
|
-
public attach
|
|
54
|
+
public attach(process: Processor): void {
|
|
52
55
|
this.process = process
|
|
53
56
|
}
|
|
54
57
|
|
|
55
|
-
protected override async open
|
|
58
|
+
protected override async open(): Promise<void> {
|
|
56
59
|
// answers 503 from here; the gateway's dependencies have settled by the time `open` runs
|
|
57
60
|
await this.probe.listen()
|
|
58
61
|
|
|
@@ -67,7 +70,7 @@ export class Server extends Connector {
|
|
|
67
70
|
console.info('Ready')
|
|
68
71
|
}
|
|
69
72
|
|
|
70
|
-
protected override async close
|
|
73
|
+
protected override async close(): Promise<void> {
|
|
71
74
|
await this.probe.close()
|
|
72
75
|
|
|
73
76
|
this.server.close()
|
|
@@ -75,8 +78,7 @@ export class Server extends Connector {
|
|
|
75
78
|
// GOAWAY lets in-flight streams finish; `Http2Server` has no `closeIdleConnections`
|
|
76
79
|
if (this.properties.protocol === 'h1')
|
|
77
80
|
(this.server as http.Server).closeIdleConnections()
|
|
78
|
-
else
|
|
79
|
-
for (const session of this.sessions) session.close()
|
|
81
|
+
else for (const session of this.sessions) session.close()
|
|
80
82
|
|
|
81
83
|
console.info('Stopped accepting new connections')
|
|
82
84
|
|
|
@@ -88,14 +90,13 @@ export class Server extends Connector {
|
|
|
88
90
|
|
|
89
91
|
if (this.properties.protocol === 'h1')
|
|
90
92
|
(this.server as http.Server).closeAllConnections()
|
|
91
|
-
else
|
|
92
|
-
for (const session of this.sessions) session.destroy()
|
|
93
|
+
else for (const session of this.sessions) session.destroy()
|
|
93
94
|
|
|
94
95
|
console.info('Stopped')
|
|
95
96
|
}
|
|
96
97
|
|
|
97
98
|
/** A malformed HTTP/1.1 request has no framing to answer in, so the status line is written by hand. */
|
|
98
|
-
private h1
|
|
99
|
+
private h1(server: http.Server): void {
|
|
99
100
|
server.on('clientError', (error, socket) => {
|
|
100
101
|
console.warn('Client connection error', error)
|
|
101
102
|
|
|
@@ -105,7 +106,7 @@ export class Server extends Connector {
|
|
|
105
106
|
}
|
|
106
107
|
|
|
107
108
|
/** HTTP/2 has no `clientError`: failures surface per session, per stream, or per frame. */
|
|
108
|
-
private h2
|
|
109
|
+
private h2(server: http2.Http2Server): void {
|
|
109
110
|
server.on('session', (session) => {
|
|
110
111
|
this.sessions.add(session)
|
|
111
112
|
session.on('close', () => this.sessions.delete(session))
|
|
@@ -120,12 +121,11 @@ export class Server extends Connector {
|
|
|
120
121
|
})
|
|
121
122
|
}
|
|
122
123
|
|
|
123
|
-
private listener
|
|
124
|
+
private listener(request: IncomingMessage, response: ServerResponse): void {
|
|
124
125
|
request.once('error', (error) => {
|
|
125
126
|
console.warn('Request error', errorAttributes(request, error))
|
|
126
127
|
|
|
127
|
-
if (!response.writableEnded)
|
|
128
|
-
response.destroy()
|
|
128
|
+
if (!response.writableEnded) response.destroy()
|
|
129
129
|
})
|
|
130
130
|
|
|
131
131
|
// no listener on `request.socket`: under HTTP/2 it is the session's socket, shared by
|
|
@@ -134,7 +134,10 @@ export class Server extends Connector {
|
|
|
134
134
|
const host = authorityOf(request)?.toLowerCase()
|
|
135
135
|
|
|
136
136
|
if (host === undefined || !HOST.test(host)) {
|
|
137
|
-
console.warn(
|
|
137
|
+
console.warn(
|
|
138
|
+
'Request without a valid authority',
|
|
139
|
+
errorAttributes(request, new Error('Invalid authority'))
|
|
140
|
+
)
|
|
138
141
|
|
|
139
142
|
response.writeHead(400).end()
|
|
140
143
|
|
|
@@ -168,53 +171,55 @@ export class Server extends Connector {
|
|
|
168
171
|
// if the request carries no trace context, the trace starts here
|
|
169
172
|
const remote = trace(request.headers)
|
|
170
173
|
|
|
171
|
-
const processing =
|
|
172
|
-
|
|
173
|
-
|
|
174
|
+
const processing =
|
|
175
|
+
remote === null
|
|
176
|
+
? this.serve(request, response, authority, url)
|
|
177
|
+
: run(remote, async () => await this.serve(request, response, authority, url))
|
|
174
178
|
|
|
175
179
|
processing.catch((error) => {
|
|
176
180
|
console.error('Request processing failed', error)
|
|
177
181
|
|
|
178
|
-
if (!response.writableEnded)
|
|
179
|
-
response.writeHead(500).end()
|
|
182
|
+
if (!response.writableEnded) response.writeHead(500).end()
|
|
180
183
|
})
|
|
181
184
|
}
|
|
182
185
|
|
|
183
186
|
// eslint-disable-next-line max-params
|
|
184
|
-
private async serve
|
|
187
|
+
private async serve(
|
|
188
|
+
request: IncomingMessage,
|
|
185
189
|
response: ServerResponse,
|
|
186
190
|
authority: string,
|
|
187
|
-
url: URL
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
191
|
+
url: URL
|
|
192
|
+
): Promise<void> {
|
|
193
|
+
await console.span(
|
|
194
|
+
{
|
|
195
|
+
name: `${request.method} ${request.url}`,
|
|
196
|
+
kind: 'server',
|
|
197
|
+
service: 'exposition',
|
|
198
|
+
attributes: { method: request.method, url: request.url, authority }
|
|
199
|
+
},
|
|
200
|
+
async () => {
|
|
201
|
+
response.setHeader('ray', current()!.traceId)
|
|
202
|
+
|
|
203
|
+
const context = new Context(authority, request, this.properties, url)
|
|
204
|
+
|
|
205
|
+
await this.process!(context)
|
|
206
|
+
.then(this.success(context, response))
|
|
207
|
+
.catch(this.fail(context, response))
|
|
208
|
+
.finally(() => request.removeAllListeners('error'))
|
|
209
|
+
}
|
|
210
|
+
)
|
|
203
211
|
}
|
|
204
212
|
|
|
205
|
-
private success
|
|
213
|
+
private success(context: Context, response: ServerResponse) {
|
|
206
214
|
return async (message: OutgoingMessage) => {
|
|
207
215
|
let status = message.status
|
|
208
216
|
|
|
209
217
|
if (status === undefined)
|
|
210
|
-
if (message.body === null)
|
|
211
|
-
|
|
212
|
-
else if (context.request.method === 'POST')
|
|
213
|
-
status = 201
|
|
218
|
+
if (message.body === null) status = 404
|
|
219
|
+
else if (context.request.method === 'POST') status = 201
|
|
214
220
|
else if (message.body === undefined && context.request.method !== 'HEAD')
|
|
215
221
|
status = 204
|
|
216
|
-
else
|
|
217
|
-
status = 200
|
|
222
|
+
else status = 200
|
|
218
223
|
|
|
219
224
|
message.status = status
|
|
220
225
|
|
|
@@ -222,7 +227,7 @@ export class Server extends Connector {
|
|
|
222
227
|
}
|
|
223
228
|
}
|
|
224
229
|
|
|
225
|
-
private fail
|
|
230
|
+
private fail(context: Context, response: ServerResponse) {
|
|
226
231
|
return async (exception: Error) => {
|
|
227
232
|
try {
|
|
228
233
|
// Over HTTP/2 the reply is followed by RST_STREAM(NO_ERROR), which tells the client
|
|
@@ -234,26 +239,27 @@ export class Server extends Connector {
|
|
|
234
239
|
const span = current()
|
|
235
240
|
|
|
236
241
|
// https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status
|
|
237
|
-
if (status >= 500 && span !== undefined)
|
|
238
|
-
span.status = 'error'
|
|
242
|
+
if (status >= 500 && span !== undefined) span.status = 'error'
|
|
239
243
|
|
|
240
244
|
if (!response.writableEnded) {
|
|
241
245
|
response.statusCode = status
|
|
242
246
|
|
|
243
|
-
const message: OutgoingMessage = {
|
|
247
|
+
const message: OutgoingMessage = {
|
|
248
|
+
status: response.statusCode,
|
|
249
|
+
authentic: true
|
|
250
|
+
}
|
|
244
251
|
|
|
245
252
|
// eslint-disable-next-line max-depth
|
|
246
253
|
if (exception instanceof Exception && exception.headers !== undefined)
|
|
247
254
|
message.headers = exception.headers
|
|
248
255
|
|
|
249
256
|
// eslint-disable-next-line max-depth
|
|
250
|
-
if (context.encoder === null)
|
|
251
|
-
message.body = undefined
|
|
257
|
+
if (context.encoder === null) message.body = undefined
|
|
252
258
|
else if (exception instanceof ClientError || this.properties.debug)
|
|
253
259
|
message.body =
|
|
254
260
|
exception instanceof Exception
|
|
255
261
|
? exception.body
|
|
256
|
-
: (this.properties.debug && exception.stack) ?? exception.message
|
|
262
|
+
: ((this.properties.debug && exception.stack) ?? exception.message)
|
|
257
263
|
|
|
258
264
|
await write(context, response, message)
|
|
259
265
|
}
|
|
@@ -271,9 +277,8 @@ export class Server extends Connector {
|
|
|
271
277
|
}
|
|
272
278
|
}
|
|
273
279
|
|
|
274
|
-
function instantiate
|
|
275
|
-
if (protocol === 'h1')
|
|
276
|
-
return http.createServer()
|
|
280
|
+
function instantiate(protocol: Protocol): http.Server | http2.Http2Server {
|
|
281
|
+
if (protocol === 'h1') return http.createServer()
|
|
277
282
|
|
|
278
283
|
return http2.createServer({
|
|
279
284
|
// realtime pins one stream per subscription, and they all share a session
|
|
@@ -286,12 +291,12 @@ function instantiate (protocol: Protocol): http.Server | http2.Http2Server {
|
|
|
286
291
|
* The authority the request is addressed to. HTTP/2 carries it in `:authority` and omits
|
|
287
292
|
* `host` entirely, so reading `host` alone would leave every HTTP/2 request unattributed.
|
|
288
293
|
*/
|
|
289
|
-
function authorityOf
|
|
294
|
+
function authorityOf(request: IncomingMessage): string | undefined {
|
|
290
295
|
return request.headers[':authority'] ?? request.headers.host
|
|
291
296
|
}
|
|
292
297
|
|
|
293
298
|
/** Parsing the URL is how a request is validated, so the `Context` is handed the result. */
|
|
294
|
-
function parse
|
|
299
|
+
function parse(request: IncomingMessage, authority: string): URL | Error {
|
|
295
300
|
try {
|
|
296
301
|
return new URL(request.url, `https://${authority}`)
|
|
297
302
|
} catch (error) {
|
|
@@ -300,7 +305,7 @@ function parse (request: IncomingMessage, authority: string): URL | Error {
|
|
|
300
305
|
}
|
|
301
306
|
|
|
302
307
|
// https://github.com/whatwg/fetch/issues/1254
|
|
303
|
-
async function adam
|
|
308
|
+
async function adam(request: IncomingMessage): Promise<void> {
|
|
304
309
|
const devnull = fs.createWriteStream(os.devNull)
|
|
305
310
|
|
|
306
311
|
devnull.on('error', () => undefined)
|
|
@@ -309,18 +314,19 @@ async function adam (request: IncomingMessage): Promise<void> {
|
|
|
309
314
|
await once(request, 'end')
|
|
310
315
|
}
|
|
311
316
|
|
|
312
|
-
function errorAttributes
|
|
317
|
+
function errorAttributes(
|
|
318
|
+
request: IncomingMessage,
|
|
319
|
+
error: Error & any
|
|
320
|
+
): RequestErrorAttributes {
|
|
313
321
|
const attributes: RequestErrorAttributes = {
|
|
314
322
|
path: request.url,
|
|
315
323
|
method: request.method,
|
|
316
324
|
name: error.name
|
|
317
325
|
}
|
|
318
326
|
|
|
319
|
-
if (typeof error.code === 'string')
|
|
320
|
-
attributes.code = error.code
|
|
327
|
+
if (typeof error.code === 'string') attributes.code = error.code
|
|
321
328
|
|
|
322
|
-
if (typeof error.stack === 'string')
|
|
323
|
-
attributes.stack = error.stack
|
|
329
|
+
if (typeof error.stack === 'string') attributes.stack = error.stack
|
|
324
330
|
|
|
325
331
|
return attributes
|
|
326
332
|
}
|
|
@@ -341,12 +347,15 @@ const WINDOW = 1024 * 1024
|
|
|
341
347
|
* The `ray` header adopts the trace by ID only and does not bypass sampling:
|
|
342
348
|
* the sampling decision is made by the server.
|
|
343
349
|
*/
|
|
344
|
-
function trace
|
|
345
|
-
if (typeof headers.traceparent === 'string')
|
|
346
|
-
return decode(headers.traceparent)
|
|
350
|
+
function trace(headers: IncomingMessage['headers']): SpanContext | null {
|
|
351
|
+
if (typeof headers.traceparent === 'string') return decode(headers.traceparent)
|
|
347
352
|
|
|
348
353
|
// adopting a trace by ID does not bypass sampling
|
|
349
|
-
if (
|
|
354
|
+
if (
|
|
355
|
+
typeof headers.ray === 'string' &&
|
|
356
|
+
RAY.test(headers.ray) &&
|
|
357
|
+
headers.ray !== ZERO_RAY
|
|
358
|
+
)
|
|
350
359
|
return { traceId: headers.ray.toLowerCase(), sampled: decide() }
|
|
351
360
|
|
|
352
361
|
return null
|
|
@@ -362,7 +371,17 @@ const RAY = /^[\da-f]{32}$/i
|
|
|
362
371
|
const ZERO_RAY = '0'.repeat(32)
|
|
363
372
|
|
|
364
373
|
const DEFAULTS: Omit<Properties, 'authorities'> = {
|
|
365
|
-
methods: new Set<string>([
|
|
374
|
+
methods: new Set<string>([
|
|
375
|
+
'OPTIONS',
|
|
376
|
+
'GET',
|
|
377
|
+
'HEAD',
|
|
378
|
+
'POST',
|
|
379
|
+
'PUT',
|
|
380
|
+
'PATCH',
|
|
381
|
+
'DELETE',
|
|
382
|
+
'LOCK',
|
|
383
|
+
'UNLOCK'
|
|
384
|
+
]),
|
|
366
385
|
debug: false,
|
|
367
386
|
port: PORT,
|
|
368
387
|
drain: DRAIN * 1000,
|
package/source/HTTP/Timing.ts
CHANGED
|
@@ -1,29 +1,14 @@
|
|
|
1
1
|
import { performance } from 'node:perf_hooks'
|
|
2
2
|
import type { ServerResponse } from './types.js'
|
|
3
3
|
|
|
4
|
+
/** How long the request took, from received to written: one number, the header's. */
|
|
4
5
|
export class Timing {
|
|
5
6
|
private readonly start = performance.now()
|
|
6
|
-
private readonly breakpoints: Breakpoint[] = []
|
|
7
7
|
|
|
8
|
-
public
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return result
|
|
8
|
+
public append(response: ServerResponse): void {
|
|
9
|
+
response.setHeader(
|
|
10
|
+
'server-timing',
|
|
11
|
+
`total;dur=${(performance.now() - this.start).toFixed(3)}`
|
|
12
|
+
)
|
|
15
13
|
}
|
|
16
|
-
|
|
17
|
-
public append (response: ServerResponse): void {
|
|
18
|
-
this.breakpoints.push({ id: 'total', duration: performance.now() - this.start })
|
|
19
|
-
|
|
20
|
-
for (const breakpoint of this.breakpoints)
|
|
21
|
-
response.appendHeader('server-timing',
|
|
22
|
-
`${breakpoint.id};dur=${breakpoint.duration.toFixed(3)}`)
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
interface Breakpoint {
|
|
27
|
-
id: string
|
|
28
|
-
duration: number
|
|
29
14
|
}
|
|
@@ -12,8 +12,14 @@ it('should be nothing without a header named', () => {
|
|
|
12
12
|
})
|
|
13
13
|
|
|
14
14
|
it('should be the last value of the named header', () => {
|
|
15
|
-
assert.equal(
|
|
16
|
-
|
|
15
|
+
assert.equal(
|
|
16
|
+
address(request({ 'x-forwarded-for': '1.1.1.1, 2.2.2.2' }), 'x-forwarded-for'),
|
|
17
|
+
'2.2.2.2'
|
|
18
|
+
)
|
|
19
|
+
assert.equal(
|
|
20
|
+
address(request({ 'cf-connecting-ip': '3.3.3.3' }), 'cf-connecting-ip'),
|
|
21
|
+
'3.3.3.3'
|
|
22
|
+
)
|
|
17
23
|
})
|
|
18
24
|
|
|
19
25
|
it('should be nothing when the named header is absent or empty', () => {
|
package/source/HTTP/address.ts
CHANGED
|
@@ -5,9 +5,8 @@ import type { IncomingMessage } from './types.js'
|
|
|
5
5
|
* Of a header holding a list, the last value is the one the edge in front appended. The
|
|
6
6
|
* connection's address is never it: behind an edge it is the edge's.
|
|
7
7
|
*/
|
|
8
|
-
export function address
|
|
9
|
-
if (header === undefined)
|
|
10
|
-
return
|
|
8
|
+
export function address(request: IncomingMessage, header?: string): string | undefined {
|
|
9
|
+
if (header === undefined) return
|
|
11
10
|
|
|
12
11
|
const value = request.headers[header]
|
|
13
12
|
const raw = Array.isArray(value) ? value[value.length - 1] : value
|