@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/MCP/tools.ts
CHANGED
|
@@ -20,7 +20,7 @@ import type { Params, Result, Tool } from './types.js'
|
|
|
20
20
|
*
|
|
21
21
|
* Sorted, because the revision asks for an order a client can cache on.
|
|
22
22
|
*/
|
|
23
|
-
export async function list
|
|
23
|
+
export async function list(tree: Tree, context: http.Context): Promise<Tool[]> {
|
|
24
24
|
const tools: Tool[] = []
|
|
25
25
|
|
|
26
26
|
/*
|
|
@@ -28,24 +28,22 @@ export async function list (tree: Tree, context: http.Context): Promise<Tool[]>
|
|
|
28
28
|
* refuses a credentialed request at an `anonymous` route does not refuse the call a tool
|
|
29
29
|
* makes, and a list that says otherwise disagrees with what `tools/call` then does.
|
|
30
30
|
*/
|
|
31
|
-
const describing: http.Context = Object.create(context,
|
|
32
|
-
|
|
31
|
+
const describing: http.Context = Object.create(context, {
|
|
32
|
+
procedural: { value: true, enumerable: true }
|
|
33
|
+
})
|
|
33
34
|
|
|
34
35
|
for (const { segments, verb, method } of tree.walk()) {
|
|
35
|
-
if (MCP.published(method.directives.declared<Declaration>(FAMILY)) === null)
|
|
36
|
-
continue
|
|
36
|
+
if (MCP.published(method.directives.declared<Declaration>(FAMILY)) === null) continue
|
|
37
37
|
|
|
38
38
|
const named = name(segments, verb)
|
|
39
39
|
|
|
40
40
|
// a route a name cannot spell is a route nothing addresses, here or at `/.rpc`
|
|
41
|
-
if (named === null)
|
|
42
|
-
continue
|
|
41
|
+
if (named === null) continue
|
|
43
42
|
|
|
44
43
|
const variables = parameters(segments)
|
|
45
44
|
const introspection = await method.explain(describing, variables)
|
|
46
45
|
|
|
47
|
-
if (introspection === null)
|
|
48
|
-
continue
|
|
46
|
+
if (introspection === null) continue
|
|
49
47
|
|
|
50
48
|
const described = introspection.description
|
|
51
49
|
const schema = output(introspection)
|
|
@@ -54,17 +52,20 @@ export async function list (tree: Tree, context: http.Context): Promise<Tool[]>
|
|
|
54
52
|
// in the order the revision documents one, which is the order it is read in
|
|
55
53
|
const tool: Tool = {
|
|
56
54
|
name: named,
|
|
57
|
-
...introspection.title === undefined ? {} : { title: introspection.title },
|
|
58
|
-
...described === undefined ? {} : { description: described },
|
|
59
|
-
inputSchema: input(
|
|
60
|
-
|
|
61
|
-
|
|
55
|
+
...(introspection.title === undefined ? {} : { title: introspection.title }),
|
|
56
|
+
...(described === undefined ? {} : { description: described }),
|
|
57
|
+
inputSchema: input(
|
|
58
|
+
introspection,
|
|
59
|
+
variables.map((variable) => variable.name)
|
|
60
|
+
),
|
|
61
|
+
...(schema === undefined ? {} : { outputSchema: schema }),
|
|
62
|
+
...(hints === undefined ? {} : { annotations: hints })
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
tools.push(tool)
|
|
65
66
|
}
|
|
66
67
|
|
|
67
|
-
return tools.sort((one, other) => one.name < other.name ? -1 : 1)
|
|
68
|
+
return tools.sort((one, other) => (one.name < other.name ? -1 : 1))
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
/**
|
|
@@ -75,10 +76,14 @@ export async function list (tree: Tree, context: http.Context): Promise<Tool[]>
|
|
|
75
76
|
* would have taken it: what an application did not publish is not reachable here by guessing
|
|
76
77
|
* its name. What the caller may then do with one that is published is still `auth`'s to say.
|
|
77
78
|
*/
|
|
78
|
-
export async function call
|
|
79
|
+
export async function call(scope: Scope, named: string, args: Params): Promise<Result> {
|
|
79
80
|
if (!published(scope.tree, named))
|
|
80
|
-
throw new http.NotFound(
|
|
81
|
-
|
|
81
|
+
throw new http.NotFound(
|
|
82
|
+
response(
|
|
83
|
+
null,
|
|
84
|
+
failure(METHOD_NOT_FOUND, `'${named}' is not a tool this server publishes`)
|
|
85
|
+
)
|
|
86
|
+
)
|
|
82
87
|
|
|
83
88
|
const { path, verb, variables } = address(named, args)
|
|
84
89
|
const { query, input: body } = split(args, variables)
|
|
@@ -99,7 +104,10 @@ export async function call (scope: Scope, named: string, args: Params): Promise<
|
|
|
99
104
|
* — that is the client's to fix and not the model's, so it is answered as it is — and
|
|
100
105
|
* neither is a fault of this server, which is a protocol error and stays one.
|
|
101
106
|
*/
|
|
102
|
-
if (
|
|
107
|
+
if (
|
|
108
|
+
exception instanceof http.ClientError &&
|
|
109
|
+
!(exception instanceof http.Unauthorized)
|
|
110
|
+
)
|
|
103
111
|
return { content: [{ type: 'text', text: refusal(exception) }], isError: true }
|
|
104
112
|
|
|
105
113
|
throw exception
|
|
@@ -118,7 +126,7 @@ export interface Scope {
|
|
|
118
126
|
* asked here — the declaration is the route's and does not vary by who is calling, and the
|
|
119
127
|
* call that follows is authorized as any request to that route is.
|
|
120
128
|
*/
|
|
121
|
-
function published
|
|
129
|
+
function published(tree: Tree, named: string): boolean {
|
|
122
130
|
for (const { segments, verb, method } of tree.walk())
|
|
123
131
|
if (name(segments, verb) === named)
|
|
124
132
|
return MCP.published(method.directives.declared<Declaration>(FAMILY)) !== null
|
|
@@ -126,9 +134,8 @@ function published (tree: Tree, named: string): boolean {
|
|
|
126
134
|
return false
|
|
127
135
|
}
|
|
128
136
|
|
|
129
|
-
function result
|
|
130
|
-
if (body === undefined || body === null)
|
|
131
|
-
return { content: [] }
|
|
137
|
+
function result(body: unknown): Result {
|
|
138
|
+
if (body === undefined || body === null) return { content: [] }
|
|
132
139
|
|
|
133
140
|
return {
|
|
134
141
|
content: [{ type: 'text', text: JSON.stringify(body) }],
|
|
@@ -140,15 +147,13 @@ function result (body: unknown): Result {
|
|
|
140
147
|
* What a route template takes, by name. Describing has no values for them — a template is
|
|
141
148
|
* not a path — and nothing that describes a method reads one.
|
|
142
149
|
*/
|
|
143
|
-
function parameters
|
|
150
|
+
function parameters(segments: Segment[]): Parameter[] {
|
|
144
151
|
const params: Parameter[] = []
|
|
145
152
|
|
|
146
153
|
for (const segment of segments) {
|
|
147
|
-
if (segment.fragment !== null)
|
|
148
|
-
continue
|
|
154
|
+
if (segment.fragment !== null) continue
|
|
149
155
|
|
|
150
|
-
if (segment.wildcard === true)
|
|
151
|
-
params.push({ name: '**', value: '' })
|
|
156
|
+
if (segment.wildcard === true) params.push({ name: '**', value: '' })
|
|
152
157
|
else if (segment.placeholder !== null)
|
|
153
158
|
params.push({ name: segment.placeholder, value: '' })
|
|
154
159
|
}
|
package/source/Mapping.ts
CHANGED
|
@@ -4,29 +4,27 @@ import type { Introspection, Schema } from './Introspection.js'
|
|
|
4
4
|
import type { QueryString } from './Query.js'
|
|
5
5
|
import type * as http from './HTTP/index.js'
|
|
6
6
|
import type * as syntax from './RTD/syntax/index.js'
|
|
7
|
-
import type * as core from '@toa.io/core'
|
|
7
|
+
import type * as core from '@toa.io/core/types'
|
|
8
8
|
|
|
9
9
|
export abstract class Mapping {
|
|
10
10
|
protected readonly query: Query
|
|
11
11
|
public abstract readonly queryable: boolean
|
|
12
12
|
|
|
13
|
-
public constructor
|
|
13
|
+
public constructor(query: Query) {
|
|
14
14
|
this.query = query
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
public static create
|
|
18
|
-
const q = new Query(query
|
|
17
|
+
public static create(query?: syntax.Query | null, paged?: boolean): Mapping {
|
|
18
|
+
const q = new Query(query!, paged)
|
|
19
19
|
|
|
20
|
-
return queryable(query)
|
|
21
|
-
? new QueryableMapping(q)
|
|
22
|
-
: new InputMapping(q)
|
|
20
|
+
return queryable(query) ? new QueryableMapping(q) : new InputMapping(q)
|
|
23
21
|
}
|
|
24
22
|
|
|
25
|
-
public explain
|
|
23
|
+
public explain(introspection: Introspection): Record<string, Schema> | null {
|
|
26
24
|
return this.query.explain(introspection)
|
|
27
25
|
}
|
|
28
26
|
|
|
29
|
-
protected assign
|
|
27
|
+
protected assign(input: any, qs: QueryString): void {
|
|
30
28
|
if (qs.parameters !== null) {
|
|
31
29
|
if (typeof input !== 'object' || input === null)
|
|
32
30
|
throw new Error('Input must be an object to embed query parameters')
|
|
@@ -35,26 +33,27 @@ export abstract class Mapping {
|
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
35
|
|
|
38
|
-
public abstract fit
|
|
36
|
+
public abstract fit(
|
|
37
|
+
input: any,
|
|
38
|
+
query: http.Query,
|
|
39
|
+
parameters: Parameter[]
|
|
40
|
+
): core.Request
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
class QueryableMapping extends Mapping {
|
|
42
44
|
public override readonly queryable = true
|
|
43
45
|
|
|
44
|
-
public fit
|
|
46
|
+
public fit(input: any, query: http.Query, parameters: Parameter[]): core.Request {
|
|
45
47
|
const request: core.Request = {}
|
|
46
48
|
const qs = this.query.fit(query, parameters)
|
|
47
49
|
|
|
48
|
-
if (input === undefined && qs.parameters !== null)
|
|
49
|
-
input = {}
|
|
50
|
+
if (input === undefined && qs.parameters !== null) input = {}
|
|
50
51
|
|
|
51
52
|
this.assign(input, qs)
|
|
52
53
|
|
|
53
|
-
if (input !== undefined)
|
|
54
|
-
request.input = input
|
|
54
|
+
if (input !== undefined) request.input = input
|
|
55
55
|
|
|
56
|
-
if (qs.query !== null)
|
|
57
|
-
request.query = qs.query
|
|
56
|
+
if (qs.query !== null) request.query = qs.query
|
|
58
57
|
|
|
59
58
|
return request
|
|
60
59
|
}
|
|
@@ -63,34 +62,33 @@ class QueryableMapping extends Mapping {
|
|
|
63
62
|
class InputMapping extends Mapping {
|
|
64
63
|
public override readonly queryable = false
|
|
65
64
|
|
|
66
|
-
public fit
|
|
65
|
+
public fit(input: any, query: http.Query, parameters: Parameter[]): core.Request {
|
|
67
66
|
const request: core.Request = {}
|
|
68
67
|
const qs = this.query.fit(query, parameters)
|
|
69
68
|
|
|
70
|
-
if (
|
|
71
|
-
|
|
69
|
+
if (
|
|
70
|
+
input === undefined &&
|
|
71
|
+
(this.query.parameterized || parameters.length > 0 || qs.parameters !== null)
|
|
72
|
+
)
|
|
72
73
|
input = {}
|
|
73
74
|
|
|
74
75
|
if (parameters.length > 0) {
|
|
75
76
|
if (typeof input !== 'object' || input === null)
|
|
76
77
|
throw new Error('Input must be an object to embed parameters')
|
|
77
78
|
|
|
78
|
-
for (const parameter of parameters)
|
|
79
|
-
input[parameter.name] = parameter.value
|
|
79
|
+
for (const parameter of parameters) input[parameter.name] = parameter.value
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
this.assign(input, qs)
|
|
83
83
|
|
|
84
|
-
if (input !== undefined)
|
|
85
|
-
request.input = input
|
|
84
|
+
if (input !== undefined) request.input = input
|
|
86
85
|
|
|
87
86
|
return request
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
|
|
91
|
-
export function queryable
|
|
92
|
-
if (query === undefined || query === null)
|
|
93
|
-
return false
|
|
90
|
+
export function queryable(query?: syntax.Query | null): boolean {
|
|
91
|
+
if (query === undefined || query === null) return false
|
|
94
92
|
|
|
95
93
|
const keys = Object.keys(query)
|
|
96
94
|
|
package/source/Query.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { queryable } from './Mapping.js'
|
|
|
7
7
|
import { take } from './Introspection.js'
|
|
8
8
|
import type { Introspection, Schema } from './Introspection.js'
|
|
9
9
|
import type * as syntax from './RTD/syntax/index.js'
|
|
10
|
-
import type * as core from '@toa.io/core'
|
|
10
|
+
import type * as core from '@toa.io/core/types'
|
|
11
11
|
|
|
12
12
|
export class Query {
|
|
13
13
|
public readonly parameterized: boolean
|
|
@@ -18,21 +18,25 @@ export class Query {
|
|
|
18
18
|
private readonly queryable: boolean
|
|
19
19
|
private readonly searchable: boolean
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
/** whether a page is taken of what this answers, and so whether `omit` and `limit` apply */
|
|
22
|
+
private readonly paged: boolean
|
|
23
|
+
|
|
24
|
+
public constructor(query: syntax.Query, paged = true) {
|
|
22
25
|
this.parameterized = query?.parameters !== undefined
|
|
23
26
|
this.queryable = queryable(query)
|
|
24
27
|
this.searchable = query?.search === true
|
|
28
|
+
this.paged = paged
|
|
25
29
|
|
|
26
30
|
if (this.queryable) {
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
if (this.paged) {
|
|
32
|
+
query.omit ??= { value: 0, range: [0, 1000] }
|
|
33
|
+
query.limit ??= { value: 10, range: [1, 100] }
|
|
34
|
+
}
|
|
29
35
|
|
|
30
36
|
if (query.criteria !== undefined) {
|
|
31
37
|
// eslint-disable-next-line max-depth
|
|
32
|
-
if (query.criteria.endsWith(';'))
|
|
33
|
-
|
|
34
|
-
else
|
|
35
|
-
this.closed = true
|
|
38
|
+
if (query.criteria.endsWith(';')) query.criteria = query.criteria.slice(0, -1)
|
|
39
|
+
else this.closed = true
|
|
36
40
|
|
|
37
41
|
// eslint-disable-next-line max-depth
|
|
38
42
|
if (query.criteria.startsWith(',') || query.criteria.startsWith(';')) {
|
|
@@ -46,17 +50,19 @@ export class Query {
|
|
|
46
50
|
this.query = query
|
|
47
51
|
}
|
|
48
52
|
|
|
49
|
-
public fit
|
|
53
|
+
public fit(query: http.Query, parameters: Parameter[]): QueryString {
|
|
50
54
|
const qs = this.split(query)
|
|
51
55
|
|
|
52
56
|
if (qs.query !== null) {
|
|
53
57
|
const error = schemas.querystring.fit(qs.query)
|
|
54
58
|
|
|
55
|
-
if (error !== null)
|
|
56
|
-
throw new http.BadRequest('Query ' + error.message)
|
|
59
|
+
if (error !== null) throw new http.BadRequest('Query ' + error.message)
|
|
57
60
|
|
|
58
61
|
this.fitCriteria(qs.query, parameters)
|
|
59
|
-
|
|
62
|
+
|
|
63
|
+
if (this.paged) this.fitRanges(qs.query)
|
|
64
|
+
else this.refuseRanges(qs.query)
|
|
65
|
+
|
|
60
66
|
this.fitSort(qs.query)
|
|
61
67
|
|
|
62
68
|
if (this.query.deleted !== undefined)
|
|
@@ -76,7 +82,7 @@ export class Query {
|
|
|
76
82
|
* Only what it actually accepts — a criteria the declaration closes is refused, and so is
|
|
77
83
|
* a search where none was asked for.
|
|
78
84
|
*/
|
|
79
|
-
public explain
|
|
85
|
+
public explain(introspection: Introspection): Record<string, Schema> | null {
|
|
80
86
|
let query: Record<string, Schema> | null = null
|
|
81
87
|
|
|
82
88
|
if (this.query?.parameters !== undefined)
|
|
@@ -84,25 +90,31 @@ export class Query {
|
|
|
84
90
|
const schema = take(introspection, parameter)
|
|
85
91
|
|
|
86
92
|
// eslint-disable-next-line max-depth
|
|
87
|
-
if (schema === undefined)
|
|
88
|
-
continue
|
|
93
|
+
if (schema === undefined) continue
|
|
89
94
|
|
|
90
95
|
query ??= {}
|
|
91
96
|
query[parameter] = schema
|
|
92
97
|
}
|
|
93
98
|
|
|
94
|
-
if (!this.queryable)
|
|
95
|
-
return query
|
|
99
|
+
if (!this.queryable) return query
|
|
96
100
|
|
|
97
101
|
query ??= {}
|
|
98
102
|
|
|
99
103
|
if (!this.closed)
|
|
100
|
-
query.criteria = keyword(
|
|
101
|
-
'
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
query.
|
|
104
|
+
query.criteria = keyword(
|
|
105
|
+
'string',
|
|
106
|
+
'What to match, in RSQL: `state==hot`, `rank=gt=5;name==*tea*`.'
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
query.sort = keyword(
|
|
110
|
+
'string',
|
|
111
|
+
'What to order by: `rank:desc`, or `rank` for ascending.'
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
if (this.paged) {
|
|
115
|
+
query.limit = bounded('How many at once.', this.query.limit!)
|
|
116
|
+
query.omit = bounded('How many to skip.', this.query.omit!)
|
|
117
|
+
}
|
|
106
118
|
|
|
107
119
|
if (this.searchable)
|
|
108
120
|
query.search = keyword('string', 'What to search the text index for.')
|
|
@@ -110,7 +122,7 @@ export class Query {
|
|
|
110
122
|
return query
|
|
111
123
|
}
|
|
112
124
|
|
|
113
|
-
private split
|
|
125
|
+
private split(query: http.Query): {
|
|
114
126
|
query: http.Query | null
|
|
115
127
|
parameters: Record<string, string> | null
|
|
116
128
|
} {
|
|
@@ -144,7 +156,7 @@ export class Query {
|
|
|
144
156
|
}
|
|
145
157
|
}
|
|
146
158
|
|
|
147
|
-
private fitCriteria
|
|
159
|
+
private fitCriteria(query: http.Query, parameters: Parameter[]): void {
|
|
148
160
|
const groups: CriteriaGroup[] = []
|
|
149
161
|
const idx = parameters.findIndex((parameter) => parameter.name === 'id')
|
|
150
162
|
|
|
@@ -167,10 +179,8 @@ export class Query {
|
|
|
167
179
|
groups.push({ criteria: this.query.criteria, operator: ';' })
|
|
168
180
|
|
|
169
181
|
if (query.criteria !== undefined)
|
|
170
|
-
if (this.closed)
|
|
171
|
-
|
|
172
|
-
else
|
|
173
|
-
groups.push({ criteria: query.criteria, operator: WHATEVER })
|
|
182
|
+
if (this.closed) throw new http.BadRequest('Query criteria is closed')
|
|
183
|
+
else groups.push({ criteria: query.criteria, operator: WHATEVER })
|
|
174
184
|
|
|
175
185
|
if (groups.length > 0)
|
|
176
186
|
query.criteria = groups.reduce((acc, { criteria, operator }, i) => {
|
|
@@ -180,7 +190,14 @@ export class Query {
|
|
|
180
190
|
}, '')
|
|
181
191
|
}
|
|
182
192
|
|
|
183
|
-
|
|
193
|
+
/** A route that answers one object is not paged, so a request that pages it is a mistake. */
|
|
194
|
+
private refuseRanges(qs: http.Query): void {
|
|
195
|
+
for (const name of ['omit', 'limit'] as const)
|
|
196
|
+
if (qs[name] !== undefined)
|
|
197
|
+
throw new http.BadRequest(`Query ${name} is not allowed`)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private fitRanges(qs: http.Query): void {
|
|
184
201
|
const query = qs as core.Query
|
|
185
202
|
|
|
186
203
|
assert.ok(this.query.limit !== undefined, 'Query limit must be defined')
|
|
@@ -188,18 +205,15 @@ export class Query {
|
|
|
188
205
|
|
|
189
206
|
if (qs.limit !== undefined)
|
|
190
207
|
query.limit = fit(qs.limit, this.query.limit.range, 'limit')
|
|
191
|
-
else
|
|
192
|
-
query.limit = this.query.limit.value
|
|
208
|
+
else query.limit = this.query.limit.value
|
|
193
209
|
|
|
194
|
-
if (qs.omit !== undefined)
|
|
195
|
-
query.omit = fit(qs.omit, this.query.omit.range, 'omit')
|
|
210
|
+
if (qs.omit !== undefined) query.omit = fit(qs.omit, this.query.omit.range, 'omit')
|
|
196
211
|
}
|
|
197
212
|
|
|
198
|
-
private fitSort
|
|
213
|
+
private fitSort(qs: http.Query): void {
|
|
199
214
|
const query = qs as core.Query
|
|
200
215
|
|
|
201
|
-
if (qs.sort === undefined && this.query.sort === undefined)
|
|
202
|
-
return
|
|
216
|
+
if (qs.sort === undefined && this.query.sort === undefined) return
|
|
203
217
|
|
|
204
218
|
const sort = (this.query.sort ?? '') + (qs.sort ?? '')
|
|
205
219
|
|
|
@@ -207,12 +221,13 @@ export class Query {
|
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
223
|
|
|
210
|
-
function fit
|
|
224
|
+
function fit(string: string, range: [number, number], name: string): number {
|
|
211
225
|
const number = parseInt(string)
|
|
212
226
|
|
|
213
227
|
if (number < range[0] || number > range[1])
|
|
214
|
-
throw new http.BadRequest(
|
|
215
|
-
|
|
228
|
+
throw new http.BadRequest(
|
|
229
|
+
`Query ${name} must be between ${range[0]} and ${range[1]} inclusive`
|
|
230
|
+
)
|
|
216
231
|
|
|
217
232
|
return number
|
|
218
233
|
}
|
|
@@ -224,11 +239,11 @@ interface CriteriaGroup {
|
|
|
224
239
|
operator: ',' | ';'
|
|
225
240
|
}
|
|
226
241
|
|
|
227
|
-
function keyword
|
|
242
|
+
function keyword(type: string, description: string): Schema {
|
|
228
243
|
return { type, description } as unknown as Schema
|
|
229
244
|
}
|
|
230
245
|
|
|
231
|
-
function bounded
|
|
246
|
+
function bounded(description: string, bounds: syntax.Range): Schema {
|
|
232
247
|
const schema: Record<string, unknown> = {
|
|
233
248
|
type: 'integer',
|
|
234
249
|
description,
|
|
@@ -236,8 +251,7 @@ function bounded (description: string, bounds: syntax.Range): Schema {
|
|
|
236
251
|
maximum: bounds.range[1]
|
|
237
252
|
}
|
|
238
253
|
|
|
239
|
-
if (bounds.value !== undefined)
|
|
240
|
-
schema.default = bounds.value
|
|
254
|
+
if (bounds.value !== undefined) schema.default = bounds.value
|
|
241
255
|
|
|
242
256
|
return schema as unknown as Schema
|
|
243
257
|
}
|
package/source/RPC/Context.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import * as http from '../HTTP/index.js'
|
|
2
|
-
import { Timing } from '../HTTP/Timing.js'
|
|
3
2
|
import type { Params } from './types.js'
|
|
4
3
|
|
|
5
4
|
/**
|
|
@@ -11,8 +10,13 @@ import type { Params } from './types.js'
|
|
|
11
10
|
* here, `identity` included, is read through.
|
|
12
11
|
*/
|
|
13
12
|
// eslint-disable-next-line max-params
|
|
14
|
-
export function fork
|
|
15
|
-
|
|
13
|
+
export function fork(
|
|
14
|
+
context: http.Context,
|
|
15
|
+
path: string,
|
|
16
|
+
verb: string,
|
|
17
|
+
query: Params | undefined,
|
|
18
|
+
input: unknown
|
|
19
|
+
): http.Context {
|
|
16
20
|
const url = new URL(path, context.url)
|
|
17
21
|
|
|
18
22
|
if (query !== undefined)
|
|
@@ -43,18 +47,11 @@ export function fork (context: http.Context, path: string, verb: string,
|
|
|
43
47
|
url: { value: url, enumerable: true },
|
|
44
48
|
request: { value: request, enumerable: true },
|
|
45
49
|
pipelines: { value: pipelines, enumerable: true },
|
|
46
|
-
/*
|
|
47
|
-
* Its own, so that what the stages of a call take is measured per call and stays there.
|
|
48
|
-
* `server-timing` is a header, and a request carrying thirty-two calls would otherwise
|
|
49
|
-
* write ninety-six values into one — where a trace says the same thing, per call.
|
|
50
|
-
*/
|
|
51
|
-
timing: { value: new Timing(), enumerable: true },
|
|
52
50
|
body: {
|
|
53
51
|
value: async () => {
|
|
54
52
|
let value = input
|
|
55
53
|
|
|
56
|
-
for (const transform of pipelines.body)
|
|
57
|
-
value = await transform(value)
|
|
54
|
+
for (const transform of pipelines.body) value = await transform(value)
|
|
58
55
|
|
|
59
56
|
return value
|
|
60
57
|
}
|
package/source/RPC/Dispatcher.ts
CHANGED
|
@@ -4,7 +4,14 @@ import * as schemas from '../schemas.js'
|
|
|
4
4
|
import { BATCH } from '../const.js'
|
|
5
5
|
import { address, split } from './names.js'
|
|
6
6
|
import { fork } from './Context.js'
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
BATCH_TOO_LARGE,
|
|
9
|
+
INVALID_REQUEST,
|
|
10
|
+
PARSE,
|
|
11
|
+
failure,
|
|
12
|
+
of,
|
|
13
|
+
response
|
|
14
|
+
} from './errors.js'
|
|
8
15
|
import { VERSION, type Call, type Response } from './types.js'
|
|
9
16
|
import type { RPC } from '../Annotation.js'
|
|
10
17
|
|
|
@@ -19,12 +26,14 @@ import type { RPC } from '../Annotation.js'
|
|
|
19
26
|
export class Dispatcher {
|
|
20
27
|
private readonly batch: number
|
|
21
28
|
|
|
22
|
-
public constructor
|
|
29
|
+
public constructor(options: RPC) {
|
|
23
30
|
this.batch = options.batch ?? BATCH
|
|
24
31
|
}
|
|
25
32
|
|
|
26
|
-
public async dispatch
|
|
27
|
-
|
|
33
|
+
public async dispatch(
|
|
34
|
+
context: http.Context,
|
|
35
|
+
route: http.Processor
|
|
36
|
+
): Promise<http.OutgoingMessage> {
|
|
28
37
|
if (context.request.method !== 'POST')
|
|
29
38
|
throw new http.MethodNotAllowed(new Headers({ allow: 'POST' }))
|
|
30
39
|
|
|
@@ -33,12 +42,17 @@ export class Dispatcher {
|
|
|
33
42
|
const calls = batched ? envelope : [envelope]
|
|
34
43
|
|
|
35
44
|
if (calls.length === 0)
|
|
36
|
-
throw new http.BadRequest(
|
|
37
|
-
failure(INVALID_REQUEST, 'A request carries at least one call'))
|
|
45
|
+
throw new http.BadRequest(
|
|
46
|
+
response(null, failure(INVALID_REQUEST, 'A request carries at least one call'))
|
|
47
|
+
)
|
|
38
48
|
|
|
39
49
|
if (calls.length > this.batch)
|
|
40
|
-
throw new http.BadRequest(
|
|
41
|
-
|
|
50
|
+
throw new http.BadRequest(
|
|
51
|
+
response(
|
|
52
|
+
null,
|
|
53
|
+
failure(BATCH_TOO_LARGE, `A request carries at most ${this.batch} calls`)
|
|
54
|
+
)
|
|
55
|
+
)
|
|
42
56
|
|
|
43
57
|
const answers: Response[] = []
|
|
44
58
|
|
|
@@ -46,13 +60,11 @@ export class Dispatcher {
|
|
|
46
60
|
for (const call of calls) {
|
|
47
61
|
const answer = await this.answer(call, context, route)
|
|
48
62
|
|
|
49
|
-
if (answer !== null)
|
|
50
|
-
answers.push(answer)
|
|
63
|
+
if (answer !== null) answers.push(answer)
|
|
51
64
|
}
|
|
52
65
|
|
|
53
66
|
// every call was a notification, and a notification is answered by not answering
|
|
54
|
-
if (answers.length === 0)
|
|
55
|
-
return { status: NO_CONTENT }
|
|
67
|
+
if (answers.length === 0) return { status: NO_CONTENT }
|
|
56
68
|
|
|
57
69
|
// a reply assembled from several is not one of them, and is not stored as if it were
|
|
58
70
|
return {
|
|
@@ -62,19 +74,24 @@ export class Dispatcher {
|
|
|
62
74
|
}
|
|
63
75
|
}
|
|
64
76
|
|
|
65
|
-
private async answer
|
|
66
|
-
|
|
77
|
+
private async answer(
|
|
78
|
+
input: unknown,
|
|
79
|
+
context: http.Context,
|
|
80
|
+
route: http.Processor
|
|
81
|
+
): Promise<Response | null> {
|
|
67
82
|
const invalid = schemas.call.fit(input)
|
|
68
83
|
|
|
69
84
|
// it may have carried an id, but nothing about it is trustworthy enough to answer to
|
|
70
|
-
if (invalid !== null)
|
|
71
|
-
return response(null, failure(INVALID_REQUEST, invalid.message))
|
|
85
|
+
if (invalid !== null) return response(null, failure(INVALID_REQUEST, invalid.message))
|
|
72
86
|
|
|
73
87
|
return await this.call(input as Call, context, route)
|
|
74
88
|
}
|
|
75
89
|
|
|
76
|
-
private async call
|
|
77
|
-
|
|
90
|
+
private async call(
|
|
91
|
+
call: Call,
|
|
92
|
+
context: http.Context,
|
|
93
|
+
route: http.Processor
|
|
94
|
+
): Promise<Response | null> {
|
|
78
95
|
const notification = call.id === undefined
|
|
79
96
|
|
|
80
97
|
try {
|
|
@@ -84,14 +101,15 @@ export class Dispatcher {
|
|
|
84
101
|
const clone = fork(context, path, verb, query, input)
|
|
85
102
|
|
|
86
103
|
// one span per call, so what the directives of that call open has somewhere to hang
|
|
87
|
-
const message = await console.span(
|
|
88
|
-
|
|
104
|
+
const message = await console.span(
|
|
105
|
+
{ name: call.method, attributes: { id: call.id } },
|
|
106
|
+
async () => await route(clone)
|
|
107
|
+
)
|
|
89
108
|
|
|
90
109
|
// what `io:output` restricts, over this call's reply rather than the envelope
|
|
91
110
|
await http.shape(clone, message)
|
|
92
111
|
|
|
93
|
-
if (notification)
|
|
94
|
-
return null
|
|
112
|
+
if (notification) return null
|
|
95
113
|
|
|
96
114
|
return { jsonrpc: VERSION, id: call.id!, result: message.body ?? null }
|
|
97
115
|
} catch (exception) {
|
|
@@ -100,11 +118,13 @@ export class Dispatcher {
|
|
|
100
118
|
* reply a 200, and the challenge that tells a client where to authenticate is
|
|
101
119
|
* attached to a 401 — so the whole envelope is refused instead.
|
|
102
120
|
*/
|
|
103
|
-
if (exception instanceof http.Unauthorized)
|
|
104
|
-
throw exception
|
|
121
|
+
if (exception instanceof http.Unauthorized) throw exception
|
|
105
122
|
|
|
106
123
|
if (notification) {
|
|
107
|
-
console.debug('Notification failed', {
|
|
124
|
+
console.debug('Notification failed', {
|
|
125
|
+
method: call.method,
|
|
126
|
+
error: of(exception)
|
|
127
|
+
})
|
|
108
128
|
|
|
109
129
|
return null
|
|
110
130
|
}
|
|
@@ -114,7 +134,7 @@ export class Dispatcher {
|
|
|
114
134
|
}
|
|
115
135
|
|
|
116
136
|
/** A body the decoder refuses is a parse error; a media type it does not know is not. */
|
|
117
|
-
private async read
|
|
137
|
+
private async read(context: http.Context): Promise<unknown> {
|
|
118
138
|
try {
|
|
119
139
|
return await context.body()
|
|
120
140
|
} catch (exception) {
|