@toa.io/extensions.exposition 1.0.0-alpha.282 → 1.0.0-alpha.284
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/components/exposition.octets/manifest.toa.yaml +11 -0
- package/components/exposition.octets/types/index.d.ts +3 -0
- package/components/exposition.octets/types/toa.d.ts +41 -0
- package/components/identity.bans/operations/transit.js +1 -1
- package/components/identity.bans/tsconfig.json +1 -1
- package/components/identity.bans/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/types/index.d.ts +3 -0
- package/components/identity.bans/types/toa.d.ts +34 -0
- package/components/identity.basic/manifest.toa.yaml +13 -2
- package/components/identity.basic/operations/add.js +1 -1
- package/components/identity.basic/operations/authenticate.js +1 -1
- package/components/identity.basic/operations/check.js +1 -1
- package/components/identity.basic/operations/delete.js +1 -1
- package/components/identity.basic/operations/incept.js +18 -2
- package/components/identity.basic/operations/info.js +1 -1
- package/components/identity.basic/operations/lib/credentials.js +1 -1
- package/components/identity.basic/operations/transit.js +3 -2
- package/components/identity.basic/source/add.ts +3 -3
- package/components/identity.basic/source/authenticate.ts +2 -2
- package/components/identity.basic/source/check.ts +1 -1
- package/components/identity.basic/source/delete.ts +2 -2
- package/components/identity.basic/source/incept.ts +31 -3
- package/components/identity.basic/source/info.ts +1 -1
- package/components/identity.basic/source/transit.ts +6 -4
- package/components/identity.basic/tsconfig.json +1 -1
- package/components/identity.basic/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/types/index.d.ts +22 -0
- package/components/identity.basic/types/toa.d.ts +121 -0
- package/components/identity.clients/manifest.toa.yaml +243 -0
- package/components/identity.clients/operations/describe.js +44 -0
- package/components/identity.clients/operations/lib/Context.js +2 -0
- package/components/identity.clients/operations/lib/Entity.js +2 -0
- package/components/identity.clients/operations/lib/canonical.js +24 -0
- package/components/identity.clients/operations/lib/cimd.js +86 -0
- package/components/identity.clients/operations/lib/errors.js +5 -0
- package/components/identity.clients/operations/lib/index.js +7 -0
- package/components/identity.clients/operations/lib/redirect.js +32 -0
- package/components/identity.clients/operations/register.js +84 -0
- package/components/identity.clients/source/describe.ts +65 -0
- package/components/identity.clients/source/lib/Context.ts +38 -0
- package/components/identity.clients/source/lib/Entity.ts +31 -0
- package/components/identity.clients/source/lib/canonical.test.ts +43 -0
- package/components/identity.clients/source/lib/canonical.ts +27 -0
- package/components/identity.clients/source/lib/cimd.test.ts +120 -0
- package/components/identity.clients/source/lib/cimd.ts +107 -0
- package/components/identity.clients/source/lib/errors.ts +4 -0
- package/components/identity.clients/source/lib/index.ts +6 -0
- package/components/identity.clients/source/lib/redirect.test.ts +41 -0
- package/components/identity.clients/source/lib/redirect.ts +35 -0
- package/components/identity.clients/source/register.ts +125 -0
- package/components/identity.clients/tsconfig.json +10 -0
- package/components/identity.clients/tsconfig.tsbuildinfo +1 -0
- package/components/identity.clients/types/index.d.ts +3 -0
- package/components/identity.clients/types/toa.d.ts +109 -0
- package/components/identity.credentials/operations/list.js +1 -1
- package/components/identity.credentials/source/list.ts +2 -1
- package/components/identity.credentials/tsconfig.json +4 -2
- package/components/identity.credentials/tsconfig.tsbuildinfo +1 -1
- package/components/identity.credentials/types/index.d.ts +3 -0
- package/components/identity.credentials/types/toa.d.ts +30 -0
- package/components/identity.federation/manifest.toa.yaml +37 -1
- package/components/identity.federation/operations/authenticate.js +7 -3
- package/components/identity.federation/operations/create.js +1 -1
- package/components/identity.federation/operations/decode.js +1 -1
- package/components/identity.federation/operations/delete.js +1 -1
- package/components/identity.federation/operations/incept.js +6 -2
- package/components/identity.federation/operations/lib/Configuration.js +1 -1
- package/components/identity.federation/operations/lib/Ctx.js +1 -1
- package/components/identity.federation/operations/lib/Payload.js +1 -1
- package/components/identity.federation/operations/lib/decode.js +23 -9
- package/components/identity.federation/operations/lib/discovery.js +1 -1
- package/components/identity.federation/operations/lib/errors.js +5 -1
- package/components/identity.federation/operations/lib/exchange.js +12 -7
- package/components/identity.federation/operations/lib/index.js +2 -1
- package/components/identity.federation/operations/lib/jose.js +1 -1
- package/components/identity.federation/operations/lib/principal.js +14 -0
- package/components/identity.federation/operations/lib/resolve.js +1 -1
- package/components/identity.federation/operations/list.js +1 -1
- package/components/identity.federation/operations/types/Scheme.js +1 -1
- package/components/identity.federation/operations/types/configuration.js +1 -1
- package/components/identity.federation/operations/types/context.js +1 -1
- package/components/identity.federation/operations/types/entity.js +1 -1
- package/components/identity.federation/operations/types/index.js +1 -1
- package/components/identity.federation/source/authenticate.ts +9 -3
- package/components/identity.federation/source/incept.ts +7 -1
- package/components/identity.federation/source/lib/Ctx.ts +2 -2
- package/components/identity.federation/source/lib/decode.ts +25 -9
- package/components/identity.federation/source/lib/errors.ts +5 -0
- package/components/identity.federation/source/lib/exchange.ts +11 -7
- package/components/identity.federation/source/lib/index.ts +1 -0
- package/components/identity.federation/source/lib/principal.ts +17 -0
- package/components/identity.federation/source/types/configuration.ts +1 -1
- package/components/identity.federation/source/types/context.ts +6 -2
- package/components/identity.federation/tsconfig.json +4 -2
- package/components/identity.federation/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/types/index.d.ts +3 -0
- package/components/identity.federation/types/toa.d.ts +127 -0
- package/components/identity.grants/manifest.toa.yaml +245 -0
- package/components/identity.grants/operations/authorize.js +54 -0
- package/components/identity.grants/operations/exchange.js +89 -0
- package/components/identity.grants/operations/lib/code.js +30 -0
- package/components/identity.grants/operations/lib/identify.js +15 -0
- package/components/identity.grants/operations/lib/index.js +3 -0
- package/components/identity.grants/operations/list.js +18 -0
- package/components/identity.grants/operations/revoke.js +25 -0
- package/components/identity.grants/source/authorize.ts +90 -0
- package/components/identity.grants/source/exchange.ts +130 -0
- package/components/identity.grants/source/lib/code.ts +39 -0
- package/components/identity.grants/source/lib/identify.ts +16 -0
- package/components/identity.grants/source/lib/index.ts +3 -0
- package/components/identity.grants/source/list.ts +28 -0
- package/components/identity.grants/source/revoke.ts +38 -0
- package/components/identity.grants/tsconfig.json +10 -0
- package/components/identity.grants/tsconfig.tsbuildinfo +1 -0
- package/components/identity.grants/types/index.d.ts +60 -0
- package/components/identity.grants/types/toa.d.ts +108 -0
- package/components/identity.keys/manifest.toa.yaml +1 -0
- package/components/identity.keys/operations/create.js +1 -1
- package/components/identity.keys/operations/disable.js +1 -1
- package/components/identity.keys/operations/revoke.js +1 -1
- package/components/identity.keys/source/create.ts +1 -1
- package/components/identity.keys/source/revoke.ts +1 -1
- package/components/identity.keys/tsconfig.json +1 -1
- package/components/identity.keys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.keys/types/index.d.ts +3 -0
- package/components/identity.keys/types/toa.d.ts +47 -0
- package/components/identity.otp/operations/authenticate.js +1 -1
- package/components/identity.otp/operations/issue.js +1 -1
- package/components/identity.otp/operations/lib/Context.js +1 -1
- package/components/identity.otp/operations/lib/Entity.js +1 -1
- package/components/identity.otp/operations/lib/index.js +1 -1
- package/components/identity.otp/source/lib/Context.ts +4 -2
- package/components/identity.otp/tsconfig.json +1 -1
- package/components/identity.otp/tsconfig.tsbuildinfo +1 -1
- package/components/identity.otp/types/index.d.ts +3 -0
- package/components/identity.otp/types/toa.d.ts +56 -0
- package/components/identity.passkeys/manifest.toa.yaml +3 -0
- package/components/identity.passkeys/operations/authenticate.js +1 -1
- package/components/identity.passkeys/operations/challenge.js +1 -1
- package/components/identity.passkeys/operations/create.js +1 -1
- package/components/identity.passkeys/operations/delete.js +1 -1
- package/components/identity.passkeys/operations/lib/const.js +1 -1
- package/components/identity.passkeys/operations/list.js +1 -1
- package/components/identity.passkeys/operations/types/Configuration.js +1 -1
- package/components/identity.passkeys/operations/types/Context.js +1 -1
- package/components/identity.passkeys/operations/types/Passkey.js +1 -1
- package/components/identity.passkeys/operations/types/index.js +1 -1
- package/components/identity.passkeys/operations/use.js +1 -1
- package/components/identity.passkeys/source/authenticate.ts +1 -1
- package/components/identity.passkeys/source/challenge.ts +1 -1
- package/components/identity.passkeys/source/create.ts +1 -1
- package/components/identity.passkeys/source/types/Context.ts +2 -1
- package/components/identity.passkeys/source/use.ts +1 -1
- package/components/identity.passkeys/tsconfig.json +1 -1
- package/components/identity.passkeys/tsconfig.tsbuildinfo +1 -1
- package/components/identity.passkeys/types/index.d.ts +3 -0
- package/components/identity.passkeys/types/toa.d.ts +120 -0
- package/components/identity.roles/operations/grant.js +1 -1
- package/components/identity.roles/operations/lib/Entity.js +1 -1
- package/components/identity.roles/operations/list.js +1 -1
- package/components/identity.roles/operations/principal.js +29 -5
- package/components/identity.roles/source/principal.ts +33 -5
- package/components/identity.roles/tsconfig.json +1 -1
- package/components/identity.roles/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/types/index.d.ts +3 -0
- package/components/identity.roles/types/toa.d.ts +43 -0
- package/components/identity.tokens/manifest.toa.yaml +34 -3
- package/components/identity.tokens/operations/authenticate.js +9 -1
- package/components/identity.tokens/operations/decrypt.js +3 -3
- package/components/identity.tokens/operations/encrypt.js +1 -1
- package/components/identity.tokens/operations/issue.js +3 -2
- package/components/identity.tokens/operations/lib/form.js +24 -0
- package/components/identity.tokens/operations/lib/index.js +2 -2
- package/components/identity.tokens/operations/lib/jose.js +1 -1
- package/components/identity.tokens/operations/lib/key.js +1 -1
- package/components/identity.tokens/operations/lib/pad.js +1 -1
- package/components/identity.tokens/operations/revoke.js +1 -1
- package/components/identity.tokens/source/authenticate.test.ts +8 -5
- package/components/identity.tokens/source/authenticate.ts +12 -1
- package/components/identity.tokens/source/decrypt.test.ts +1 -1
- package/components/identity.tokens/source/decrypt.ts +4 -3
- package/components/identity.tokens/source/encrypt.test.ts +1 -1
- package/components/identity.tokens/source/encrypt.ts +2 -1
- package/components/identity.tokens/source/issue.test.ts +71 -0
- package/components/identity.tokens/source/issue.ts +4 -2
- package/components/identity.tokens/source/lib/form.test.ts +25 -0
- package/components/identity.tokens/source/lib/form.ts +31 -0
- package/components/identity.tokens/source/lib/index.ts +2 -1
- package/components/identity.tokens/tsconfig.json +1 -1
- package/components/identity.tokens/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/types/index.d.ts +61 -0
- package/components/identity.tokens/types/toa.d.ts +113 -0
- package/documentation/access.md +13 -0
- package/documentation/cache.md +10 -1
- package/documentation/components.md +3 -0
- package/documentation/consent.md +101 -0
- package/documentation/identity.md +3 -1
- package/documentation/introspection.md +13 -5
- package/documentation/io.md +42 -2
- package/documentation/map.md +8 -0
- package/documentation/mcp.md +180 -0
- package/documentation/oauth.md +180 -0
- package/documentation/protocol.md +4 -0
- package/documentation/rpc.md +140 -0
- package/documentation/tree.md +3 -0
- package/features/auth.bearer.feature +120 -0
- package/features/cache.feature +46 -0
- package/features/identity.basic.feature +44 -0
- package/features/identity.federation.feature +2 -5
- package/features/introspection.feature +333 -0
- package/features/mcp.feature +687 -0
- package/features/oauth.clients.feature +195 -0
- package/features/oauth.discovery.feature +164 -0
- package/features/oauth.grants.feature +299 -0
- package/features/octets.cloudinary.feature +1 -0
- package/features/rpc.feature +429 -0
- package/features/steps/Cloudinary.ts +13 -0
- package/features/steps/Components.ts +0 -4
- package/features/steps/Gateway.ts +23 -2
- package/features/steps/Parameters.ts +22 -7
- package/features/steps/Realtime.ts +3 -0
- package/features/steps/components/echo/manifest.toa.yaml +3 -0
- package/features/steps/components/octets.tester/manifest.toa.yaml +2 -0
- package/features/steps/components/octets.tester/operations/redirect.js +6 -1
- package/features/steps/components/pots/manifest.toa.yaml +2 -0
- package/features/steps/components/users/manifest.toa.yaml +1 -0
- package/package.json +8 -6
- package/readme.md +6 -0
- package/schemas/annotation.cos.yaml +63 -0
- package/schemas/call.cos.yaml +18 -0
- package/source/Annotation.ts +54 -0
- package/source/Directive.test.ts +15 -15
- package/source/Directive.ts +77 -9
- package/source/Endpoint.test.ts +67 -0
- package/source/Endpoint.ts +31 -11
- package/source/Factory.ts +6 -2
- package/source/Gateway.ts +73 -11
- package/source/HTTP/Context.ts +7 -0
- package/source/HTTP/Server.ts +15 -5
- package/source/HTTP/exceptions.ts +2 -2
- package/source/HTTP/formats/form.ts +21 -0
- package/source/HTTP/formats/index.ts +17 -2
- package/source/HTTP/messages.test.ts +25 -1
- package/source/HTTP/messages.ts +20 -4
- package/source/Interception.ts +8 -2
- package/source/Introspection.ts +102 -0
- package/source/MCP/Server.ts +275 -0
- package/source/MCP/discover.ts +52 -0
- package/source/MCP/errors.ts +81 -0
- package/source/MCP/index.ts +1 -0
- package/source/MCP/schema.test.ts +85 -0
- package/source/MCP/schema.ts +87 -0
- package/source/MCP/tools.ts +156 -0
- package/source/MCP/types.ts +81 -0
- package/source/Query.ts +48 -8
- package/source/RPC/Context.ts +78 -0
- package/source/RPC/Dispatcher.ts +130 -0
- package/source/RPC/errors.test.ts +52 -0
- package/source/RPC/errors.ts +83 -0
- package/source/RPC/index.ts +1 -0
- package/source/RPC/names.test.ts +122 -0
- package/source/RPC/names.ts +182 -0
- package/source/RPC/types.ts +34 -0
- package/source/RTD/Directives.ts +52 -2
- package/source/RTD/Endpoint.ts +2 -1
- package/source/RTD/Method.ts +14 -11
- package/source/RTD/Node.ts +38 -7
- package/source/RTD/Route.ts +30 -3
- package/source/RTD/Tree.ts +37 -1
- package/source/RTD/expiration.test.ts +1 -1
- package/source/RTD/walk.test.ts +110 -0
- package/source/const.ts +15 -0
- package/source/deployment.ts +11 -1
- package/source/directives/auth/Anonymous.test.ts +38 -0
- package/source/directives/auth/Anonymous.ts +12 -0
- package/source/directives/auth/Anyone.ts +4 -0
- package/source/directives/auth/Authorization.ts +108 -22
- package/source/directives/auth/Delegate.test.ts +36 -0
- package/source/directives/auth/Delegate.ts +14 -0
- package/source/directives/auth/Echo.ts +5 -0
- package/source/directives/auth/Incept.ts +16 -10
- package/source/directives/auth/Role.ts +13 -0
- package/source/directives/auth/Rule.ts +29 -0
- package/source/directives/auth/Scheme.ts +5 -0
- package/source/directives/auth/schemes.test.ts +8 -4
- package/source/directives/auth/schemes.ts +22 -9
- package/source/directives/auth/types.ts +26 -2
- package/source/directives/cache/Cache.ts +14 -5
- package/source/directives/cache/Control.ts +0 -3
- package/source/directives/dev/Development.ts +1 -1
- package/source/directives/flow/Fetch.ts +1 -1
- package/source/directives/flow/Flow.ts +1 -1
- package/source/directives/index.ts +5 -2
- package/source/directives/io/Directive.ts +1 -1
- package/source/directives/io/IO.ts +34 -3
- package/source/directives/io/Input.ts +3 -2
- package/source/directives/io/Output.ts +10 -4
- package/source/directives/io/Status.test.ts +84 -0
- package/source/directives/io/Status.ts +46 -0
- package/source/directives/io/Throttle.ts +1 -1
- package/source/directives/io/lib/throttle/Quotas.ts +2 -2
- package/source/directives/map/Headers.ts +11 -0
- package/source/directives/map/Map.ts +10 -1
- package/source/directives/map/Mapping.ts +23 -0
- package/source/directives/map/Segments.ts +12 -0
- package/source/directives/mcp/MCP.ts +33 -0
- package/source/directives/mcp/Tool.test.ts +66 -0
- package/source/directives/mcp/Tool.ts +28 -0
- package/source/directives/mcp/index.ts +6 -0
- package/source/directives/oauth/Discovery.ts +70 -0
- package/source/directives/oauth/documents.ts +113 -0
- package/source/directives/oauth/index.ts +3 -0
- package/source/directives/octets/Delete.ts +1 -1
- package/source/directives/octets/Get.ts +1 -1
- package/source/directives/octets/Octets.ts +1 -1
- package/source/directives/octets/Workflow.ts +1 -1
- package/source/directives/octets/workflows/Execution.ts +1 -1
- package/source/directives/require/Directive.ts +1 -1
- package/source/directives/require/Headers.ts +1 -1
- package/source/directives/require/Require.ts +2 -2
- package/source/index.ts +6 -0
- package/source/octets.d.ts +17 -0
- package/source/schemas.ts +2 -0
- package/source/userland.ts +47 -0
- package/transpiled/Annotation.d.ts +41 -0
- package/transpiled/Directive.d.ts +18 -1
- package/transpiled/Directive.js +50 -6
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +9 -0
- package/transpiled/Endpoint.js +27 -11
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +6 -2
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +19 -2
- package/transpiled/Gateway.js +51 -9
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +6 -0
- package/transpiled/HTTP/Context.js +6 -0
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Server.d.ts +8 -1
- package/transpiled/HTTP/Server.js +4 -3
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/exceptions.d.ts +1 -1
- package/transpiled/HTTP/exceptions.js +2 -2
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/formats/form.d.ts +9 -0
- package/transpiled/HTTP/formats/form.js +18 -0
- package/transpiled/HTTP/formats/form.js.map +1 -0
- package/transpiled/HTTP/formats/index.d.ts +10 -2
- package/transpiled/HTTP/formats/index.js +10 -0
- package/transpiled/HTTP/formats/index.js.map +1 -1
- package/transpiled/HTTP/messages.d.ts +12 -0
- package/transpiled/HTTP/messages.js +12 -4
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Interception.d.ts +4 -1
- package/transpiled/Interception.js +4 -2
- package/transpiled/Interception.js.map +1 -1
- package/transpiled/Introspection.d.ts +40 -0
- package/transpiled/Introspection.js +50 -1
- package/transpiled/Introspection.js.map +1 -1
- package/transpiled/MCP/Server.d.ts +41 -0
- package/transpiled/MCP/Server.js +180 -0
- package/transpiled/MCP/Server.js.map +1 -0
- package/transpiled/MCP/discover.d.ts +13 -0
- package/transpiled/MCP/discover.js +29 -0
- package/transpiled/MCP/discover.js.map +1 -0
- package/transpiled/MCP/errors.d.ts +24 -0
- package/transpiled/MCP/errors.js +67 -0
- package/transpiled/MCP/errors.js.map +1 -0
- package/transpiled/MCP/index.d.ts +1 -0
- package/transpiled/MCP/index.js +2 -0
- package/transpiled/MCP/index.js.map +1 -0
- package/transpiled/MCP/schema.d.ts +18 -0
- package/transpiled/MCP/schema.js +64 -0
- package/transpiled/MCP/schema.js.map +1 -0
- package/transpiled/MCP/tools.d.ts +31 -0
- package/transpiled/MCP/tools.js +121 -0
- package/transpiled/MCP/tools.js.map +1 -0
- package/transpiled/MCP/types.d.ts +64 -0
- package/transpiled/MCP/types.js +13 -0
- package/transpiled/MCP/types.js.map +1 -0
- package/transpiled/Query.d.ts +7 -0
- package/transpiled/Query.js +38 -7
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RPC/Context.d.ts +11 -0
- package/transpiled/RPC/Context.js +63 -0
- package/transpiled/RPC/Context.js.map +1 -0
- package/transpiled/RPC/Dispatcher.d.ts +19 -0
- package/transpiled/RPC/Dispatcher.js +100 -0
- package/transpiled/RPC/Dispatcher.js.map +1 -0
- package/transpiled/RPC/errors.d.ts +18 -0
- package/transpiled/RPC/errors.js +67 -0
- package/transpiled/RPC/errors.js.map +1 -0
- package/transpiled/RPC/index.d.ts +1 -0
- package/transpiled/RPC/index.js +2 -0
- package/transpiled/RPC/index.js.map +1 -0
- package/transpiled/RPC/names.d.ts +30 -0
- package/transpiled/RPC/names.js +121 -0
- package/transpiled/RPC/names.js.map +1 -0
- package/transpiled/RPC/types.d.ts +27 -0
- package/transpiled/RPC/types.js +8 -0
- package/transpiled/RPC/types.js.map +1 -0
- package/transpiled/RTD/Directives.d.ts +41 -2
- package/transpiled/RTD/Endpoint.d.ts +2 -1
- package/transpiled/RTD/Method.d.ts +8 -3
- package/transpiled/RTD/Method.js +12 -10
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.d.ts +20 -2
- package/transpiled/RTD/Node.js +22 -4
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Route.d.ts +2 -1
- package/transpiled/RTD/Route.js +27 -2
- package/transpiled/RTD/Route.js.map +1 -1
- package/transpiled/RTD/Tree.d.ts +3 -1
- package/transpiled/RTD/Tree.js +26 -0
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/const.d.ts +12 -0
- package/transpiled/const.js +12 -0
- package/transpiled/const.js.map +1 -1
- package/transpiled/deployment.js +6 -0
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Anonymous.d.ts +6 -0
- package/transpiled/directives/auth/Anonymous.js +10 -0
- package/transpiled/directives/auth/Anonymous.js.map +1 -1
- package/transpiled/directives/auth/Anyone.d.ts +1 -0
- package/transpiled/directives/auth/Anyone.js +3 -0
- package/transpiled/directives/auth/Anyone.js.map +1 -1
- package/transpiled/directives/auth/Authorization.d.ts +28 -2
- package/transpiled/directives/auth/Authorization.js +87 -19
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +5 -0
- package/transpiled/directives/auth/Delegate.js +10 -0
- package/transpiled/directives/auth/Delegate.js.map +1 -1
- package/transpiled/directives/auth/Echo.d.ts +2 -0
- package/transpiled/directives/auth/Echo.js +4 -0
- package/transpiled/directives/auth/Echo.js.map +1 -1
- package/transpiled/directives/auth/Incept.d.ts +1 -1
- package/transpiled/directives/auth/Incept.js +13 -8
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +2 -0
- package/transpiled/directives/auth/Role.js +9 -0
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/auth/Rule.d.ts +5 -0
- package/transpiled/directives/auth/Rule.js +20 -0
- package/transpiled/directives/auth/Rule.js.map +1 -1
- package/transpiled/directives/auth/Scheme.d.ts +2 -0
- package/transpiled/directives/auth/Scheme.js +4 -0
- package/transpiled/directives/auth/Scheme.js.map +1 -1
- package/transpiled/directives/auth/schemes.d.ts +16 -4
- package/transpiled/directives/auth/schemes.js +20 -8
- package/transpiled/directives/auth/schemes.js.map +1 -1
- package/transpiled/directives/auth/types.d.ts +20 -2
- package/transpiled/directives/cache/Cache.d.ts +1 -1
- package/transpiled/directives/cache/Cache.js +10 -3
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.js +0 -2
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/dev/Development.d.ts +1 -1
- package/transpiled/directives/dev/Development.js +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/flow/Flow.d.ts +1 -1
- package/transpiled/directives/flow/Flow.js +1 -1
- package/transpiled/directives/flow/Flow.js.map +1 -1
- package/transpiled/directives/index.js +4 -2
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/Directive.d.ts +1 -1
- package/transpiled/directives/io/IO.d.ts +7 -1
- package/transpiled/directives/io/IO.js +25 -3
- package/transpiled/directives/io/IO.js.map +1 -1
- package/transpiled/directives/io/Input.d.ts +3 -2
- package/transpiled/directives/io/Input.js +2 -1
- package/transpiled/directives/io/Input.js.map +1 -1
- package/transpiled/directives/io/Output.d.ts +5 -3
- package/transpiled/directives/io/Output.js +8 -3
- package/transpiled/directives/io/Output.js.map +1 -1
- package/transpiled/directives/io/Status.d.ts +19 -0
- package/transpiled/directives/io/Status.js +34 -0
- package/transpiled/directives/io/Status.js.map +1 -0
- package/transpiled/directives/io/Throttle.d.ts +1 -1
- package/transpiled/directives/io/Throttle.js +1 -1
- package/transpiled/directives/io/Throttle.js.map +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.d.ts +1 -1
- package/transpiled/directives/io/lib/throttle/Quotas.js +2 -2
- package/transpiled/directives/io/lib/throttle/Quotas.js.map +1 -1
- package/transpiled/directives/map/Headers.d.ts +2 -0
- package/transpiled/directives/map/Headers.js +8 -0
- package/transpiled/directives/map/Headers.js.map +1 -1
- package/transpiled/directives/map/Map.d.ts +3 -1
- package/transpiled/directives/map/Map.js +7 -1
- package/transpiled/directives/map/Map.js.map +1 -1
- package/transpiled/directives/map/Mapping.d.ts +13 -0
- package/transpiled/directives/map/Mapping.js +20 -0
- package/transpiled/directives/map/Mapping.js.map +1 -1
- package/transpiled/directives/map/Segments.d.ts +3 -0
- package/transpiled/directives/map/Segments.js +9 -0
- package/transpiled/directives/map/Segments.js.map +1 -1
- package/transpiled/directives/mcp/MCP.d.ts +15 -0
- package/transpiled/directives/mcp/MCP.js +23 -0
- package/transpiled/directives/mcp/MCP.js.map +1 -0
- package/transpiled/directives/mcp/Tool.d.ts +13 -0
- package/transpiled/directives/mcp/Tool.js +23 -0
- package/transpiled/directives/mcp/Tool.js.map +1 -0
- package/transpiled/directives/mcp/index.d.ts +4 -0
- package/transpiled/directives/mcp/index.js +4 -0
- package/transpiled/directives/mcp/index.js.map +1 -0
- package/transpiled/directives/oauth/Discovery.d.ts +23 -0
- package/transpiled/directives/oauth/Discovery.js +55 -0
- package/transpiled/directives/oauth/Discovery.js.map +1 -0
- package/transpiled/directives/oauth/documents.d.ts +9 -0
- package/transpiled/directives/oauth/documents.js +82 -0
- package/transpiled/directives/oauth/documents.js.map +1 -0
- package/transpiled/directives/oauth/index.d.ts +2 -0
- package/transpiled/directives/oauth/index.js +3 -0
- package/transpiled/directives/oauth/index.js.map +1 -0
- package/transpiled/directives/octets/Octets.d.ts +1 -1
- package/transpiled/directives/octets/Octets.js +1 -1
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/require/Directive.d.ts +1 -1
- package/transpiled/directives/require/Headers.d.ts +1 -1
- package/transpiled/directives/require/Headers.js +1 -1
- package/transpiled/directives/require/Headers.js.map +1 -1
- package/transpiled/directives/require/Require.d.ts +1 -1
- package/transpiled/directives/require/Require.js +2 -2
- package/transpiled/directives/require/Require.js.map +1 -1
- package/transpiled/index.d.ts +2 -0
- package/transpiled/schemas.d.ts +2 -0
- package/transpiled/schemas.js +1 -0
- package/transpiled/schemas.js.map +1 -1
- package/transpiled/userland.d.ts +39 -0
- package/transpiled/userland.js +7 -0
- package/transpiled/userland.js.map +1 -0
- package/tsconfig.tsbuildinfo +1 -1
- package/components/identity.bans/operations/transit.d.ts +0 -14
- package/components/identity.bans/operations/transit.js.map +0 -1
- package/components/identity.basic/operations/add.d.ts +0 -3
- package/components/identity.basic/operations/add.js.map +0 -1
- package/components/identity.basic/operations/authenticate.d.ts +0 -13
- package/components/identity.basic/operations/authenticate.js.map +0 -1
- package/components/identity.basic/operations/check.d.ts +0 -7
- package/components/identity.basic/operations/check.js.map +0 -1
- package/components/identity.basic/operations/delete.d.ts +0 -7
- package/components/identity.basic/operations/delete.js.map +0 -1
- package/components/identity.basic/operations/incept.d.ts +0 -12
- package/components/identity.basic/operations/incept.js.map +0 -1
- package/components/identity.basic/operations/info.d.ts +0 -10
- package/components/identity.basic/operations/info.js.map +0 -1
- package/components/identity.basic/operations/lib/credentials.d.ts +0 -5
- package/components/identity.basic/operations/lib/credentials.js.map +0 -1
- package/components/identity.basic/operations/transit.d.ts +0 -14
- package/components/identity.basic/operations/transit.js.map +0 -1
- package/components/identity.basic/operations/types.d.ts +0 -61
- package/components/identity.basic/operations/types.js +0 -2
- package/components/identity.basic/operations/types.js.map +0 -1
- package/components/identity.basic/source/types.ts +0 -69
- package/components/identity.credentials/operations/list.d.ts +0 -51
- package/components/identity.credentials/operations/list.js.map +0 -1
- package/components/identity.federation/operations/authenticate.d.ts +0 -16
- package/components/identity.federation/operations/authenticate.js.map +0 -1
- package/components/identity.federation/operations/create.d.ts +0 -8
- package/components/identity.federation/operations/create.js.map +0 -1
- package/components/identity.federation/operations/decode.d.ts +0 -3
- package/components/identity.federation/operations/decode.js.map +0 -1
- package/components/identity.federation/operations/delete.d.ts +0 -8
- package/components/identity.federation/operations/delete.js.map +0 -1
- package/components/identity.federation/operations/incept.d.ts +0 -11
- package/components/identity.federation/operations/incept.js.map +0 -1
- package/components/identity.federation/operations/lib/Configuration.d.ts +0 -39
- package/components/identity.federation/operations/lib/Configuration.js.map +0 -1
- package/components/identity.federation/operations/lib/Ctx.d.ts +0 -8
- package/components/identity.federation/operations/lib/Ctx.js.map +0 -1
- package/components/identity.federation/operations/lib/Payload.d.ts +0 -5
- package/components/identity.federation/operations/lib/Payload.js.map +0 -1
- package/components/identity.federation/operations/lib/decode.d.ts +0 -3
- package/components/identity.federation/operations/lib/decode.js.map +0 -1
- package/components/identity.federation/operations/lib/discovery.d.ts +0 -5
- package/components/identity.federation/operations/lib/discovery.js.map +0 -1
- package/components/identity.federation/operations/lib/errors.d.ts +0 -70
- package/components/identity.federation/operations/lib/errors.js.map +0 -1
- package/components/identity.federation/operations/lib/exchange.d.ts +0 -3
- package/components/identity.federation/operations/lib/exchange.js.map +0 -1
- package/components/identity.federation/operations/lib/index.d.ts +0 -4
- package/components/identity.federation/operations/lib/index.js.map +0 -1
- package/components/identity.federation/operations/lib/jose.d.ts +0 -1
- package/components/identity.federation/operations/lib/jose.js.map +0 -1
- package/components/identity.federation/operations/lib/resolve.d.ts +0 -3
- package/components/identity.federation/operations/lib/resolve.js.map +0 -1
- package/components/identity.federation/operations/list.d.ts +0 -7
- package/components/identity.federation/operations/list.js.map +0 -1
- package/components/identity.federation/operations/types/Scheme.d.ts +0 -1
- package/components/identity.federation/operations/types/Scheme.js.map +0 -1
- package/components/identity.federation/operations/types/configuration.d.ts +0 -22
- package/components/identity.federation/operations/types/configuration.js.map +0 -1
- package/components/identity.federation/operations/types/context.d.ts +0 -35
- package/components/identity.federation/operations/types/context.js.map +0 -1
- package/components/identity.federation/operations/types/entity.d.ts +0 -9
- package/components/identity.federation/operations/types/entity.js.map +0 -1
- package/components/identity.federation/operations/types/index.d.ts +0 -4
- package/components/identity.federation/operations/types/index.js.map +0 -1
- package/components/identity.keys/operations/create.d.ts +0 -22
- package/components/identity.keys/operations/create.js.map +0 -1
- package/components/identity.keys/operations/disable.d.ts +0 -5
- package/components/identity.keys/operations/disable.js.map +0 -1
- package/components/identity.keys/operations/revoke.d.ts +0 -15
- package/components/identity.keys/operations/revoke.js.map +0 -1
- package/components/identity.otp/operations/authenticate.d.ts +0 -12
- package/components/identity.otp/operations/authenticate.js.map +0 -1
- package/components/identity.otp/operations/issue.d.ts +0 -12
- package/components/identity.otp/operations/issue.js.map +0 -1
- package/components/identity.otp/operations/lib/Context.d.ts +0 -14
- package/components/identity.otp/operations/lib/Context.js.map +0 -1
- package/components/identity.otp/operations/lib/Entity.d.ts +0 -6
- package/components/identity.otp/operations/lib/Entity.js.map +0 -1
- package/components/identity.otp/operations/lib/index.d.ts +0 -1
- package/components/identity.otp/operations/lib/index.js.map +0 -1
- package/components/identity.passkeys/operations/authenticate.d.ts +0 -16
- package/components/identity.passkeys/operations/authenticate.js.map +0 -1
- package/components/identity.passkeys/operations/challenge.d.ts +0 -35
- package/components/identity.passkeys/operations/challenge.js.map +0 -1
- package/components/identity.passkeys/operations/create.d.ts +0 -19
- package/components/identity.passkeys/operations/create.js.map +0 -1
- package/components/identity.passkeys/operations/delete.d.ts +0 -8
- package/components/identity.passkeys/operations/delete.js.map +0 -1
- package/components/identity.passkeys/operations/lib/const.d.ts +0 -1
- package/components/identity.passkeys/operations/lib/const.js.map +0 -1
- package/components/identity.passkeys/operations/list.d.ts +0 -7
- package/components/identity.passkeys/operations/list.js.map +0 -1
- package/components/identity.passkeys/operations/types/Configuration.d.ts +0 -6
- package/components/identity.passkeys/operations/types/Configuration.js.map +0 -1
- package/components/identity.passkeys/operations/types/Context.d.ts +0 -15
- package/components/identity.passkeys/operations/types/Context.js.map +0 -1
- package/components/identity.passkeys/operations/types/Passkey.d.ts +0 -12
- package/components/identity.passkeys/operations/types/Passkey.js.map +0 -1
- package/components/identity.passkeys/operations/types/index.d.ts +0 -2
- package/components/identity.passkeys/operations/types/index.js.map +0 -1
- package/components/identity.passkeys/operations/use.d.ts +0 -16
- package/components/identity.passkeys/operations/use.js.map +0 -1
- package/components/identity.roles/operations/grant.d.ts +0 -10
- package/components/identity.roles/operations/grant.js.map +0 -1
- package/components/identity.roles/operations/lib/Entity.d.ts +0 -5
- package/components/identity.roles/operations/lib/Entity.js.map +0 -1
- package/components/identity.roles/operations/list.d.ts +0 -2
- package/components/identity.roles/operations/list.js.map +0 -1
- package/components/identity.roles/operations/principal.d.ts +0 -13
- package/components/identity.roles/operations/principal.js.map +0 -1
- package/components/identity.tokens/operations/authenticate.d.ts +0 -9
- package/components/identity.tokens/operations/authenticate.js.map +0 -1
- package/components/identity.tokens/operations/decrypt.d.ts +0 -15
- package/components/identity.tokens/operations/decrypt.js.map +0 -1
- package/components/identity.tokens/operations/encrypt.d.ts +0 -8
- package/components/identity.tokens/operations/encrypt.js.map +0 -1
- package/components/identity.tokens/operations/issue.d.ts +0 -24
- package/components/identity.tokens/operations/issue.js.map +0 -1
- package/components/identity.tokens/operations/lib/index.d.ts +0 -3
- package/components/identity.tokens/operations/lib/index.js.map +0 -1
- package/components/identity.tokens/operations/lib/jose.d.ts +0 -1
- package/components/identity.tokens/operations/lib/jose.js.map +0 -1
- package/components/identity.tokens/operations/lib/key.d.ts +0 -1
- package/components/identity.tokens/operations/lib/key.js.map +0 -1
- package/components/identity.tokens/operations/lib/pad.d.ts +0 -1
- package/components/identity.tokens/operations/lib/pad.js.map +0 -1
- package/components/identity.tokens/operations/lib/types.d.ts +0 -88
- package/components/identity.tokens/operations/lib/types.js +0 -2
- package/components/identity.tokens/operations/lib/types.js.map +0 -1
- package/components/identity.tokens/operations/revoke.d.ts +0 -2
- package/components/identity.tokens/operations/revoke.js.map +0 -1
- package/components/identity.tokens/source/lib/types.ts +0 -102
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, it, mock } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import { Tree } from './Tree.js'
|
|
5
|
+
import { address, name } from '../RPC/names.js'
|
|
6
|
+
import type { EndpointsFactory } from '../Endpoint.js'
|
|
7
|
+
import type { DirectiveFactory } from './Directives.js'
|
|
8
|
+
import type * as syntax from './syntax/index.js'
|
|
9
|
+
|
|
10
|
+
const endpoints = {} as unknown as EndpointsFactory
|
|
11
|
+
|
|
12
|
+
const directives = {
|
|
13
|
+
create: () => ({
|
|
14
|
+
precall: async () => null,
|
|
15
|
+
settle: async () => undefined,
|
|
16
|
+
dispose: () => undefined
|
|
17
|
+
}),
|
|
18
|
+
dispose: mock.fn()
|
|
19
|
+
} as unknown as DirectiveFactory
|
|
20
|
+
|
|
21
|
+
const node = (path: string, verbs: string[] = [], routes: syntax.Route[] = []): syntax.Route => ({
|
|
22
|
+
path,
|
|
23
|
+
node: {
|
|
24
|
+
routes,
|
|
25
|
+
methods: verbs.map((verb) => ({ verb, directives: [] })),
|
|
26
|
+
directives: []
|
|
27
|
+
}
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
const trunk = (routes: syntax.Route[], verbs: string[] = []): syntax.Node => ({
|
|
31
|
+
routes,
|
|
32
|
+
methods: verbs.map((verb) => ({ verb, directives: [] })),
|
|
33
|
+
directives: []
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
/** What a walk names, which is what a caller of `/.rpc` would write. */
|
|
37
|
+
function names (tree: Tree): string[] {
|
|
38
|
+
return [...tree.walk()].map(({ segments, verb }) => name(segments, verb))
|
|
39
|
+
.filter((named): named is string => named !== null)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
describe('walk', () => {
|
|
43
|
+
it('should name the trunk by its verb alone', () => {
|
|
44
|
+
const tree = new Tree(trunk([], ['GET']), endpoints, directives)
|
|
45
|
+
|
|
46
|
+
assert.deepEqual(names(tree), ['GET'])
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it('should name every method of every route', () => {
|
|
50
|
+
const tree = new Tree(trunk([
|
|
51
|
+
node('/pots', ['GET', 'POST'], [node('/:id', ['GET', 'DELETE'])])
|
|
52
|
+
]), endpoints, directives)
|
|
53
|
+
|
|
54
|
+
assert.deepEqual(names(tree).sort(), [
|
|
55
|
+
'pots/GET', 'pots/POST', 'pots/_id/DELETE', 'pots/_id/GET'
|
|
56
|
+
])
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it('should walk a branch that was merged', () => {
|
|
60
|
+
const tree = new Tree(trunk([]), endpoints, directives)
|
|
61
|
+
|
|
62
|
+
tree.merge(trunk([node('/pots', ['GET'])]), { namespace: 'default', component: 'pots' })
|
|
63
|
+
|
|
64
|
+
assert.deepEqual(names(tree), ['pots/GET'])
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
it('should name a tail', () => {
|
|
68
|
+
const tree = new Tree(trunk([node('/files', [], [node('/**', ['GET'])])]),
|
|
69
|
+
endpoints, directives)
|
|
70
|
+
|
|
71
|
+
assert.deepEqual(names(tree), ['files/__/GET'])
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
it('should skip an intermediate node, whose route answers in its place', () => {
|
|
75
|
+
const tree = new Tree(trunk([
|
|
76
|
+
// `/posts` is intermediate: `/posts/` is answered by its `/` route, not by itself
|
|
77
|
+
node('/posts', ['PATCH'], [node('/', ['PUT'])])
|
|
78
|
+
]), endpoints, directives)
|
|
79
|
+
|
|
80
|
+
assert.deepEqual(names(tree), ['posts/PUT'])
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
it('should name nothing where a segment cannot be spelled', () => {
|
|
84
|
+
const tree = new Tree(trunk([node('/v1.0', ['GET']), node('/pots', ['GET'])]),
|
|
85
|
+
endpoints, directives)
|
|
86
|
+
|
|
87
|
+
assert.deepEqual(names(tree), ['pots/GET'])
|
|
88
|
+
})
|
|
89
|
+
|
|
90
|
+
it('should name what the tree then matches', () => {
|
|
91
|
+
const tree = new Tree(trunk([
|
|
92
|
+
node('/pots', ['GET'], [node('/:id', ['GET']), node('/hot', ['GET'])]),
|
|
93
|
+
node('/files', [], [node('/**', ['GET'])])
|
|
94
|
+
], ['GET']), endpoints, directives)
|
|
95
|
+
|
|
96
|
+
const params = { id: 'a1b2', '**': 'a/b/c' }
|
|
97
|
+
|
|
98
|
+
for (const { segments, verb } of tree.walk()) {
|
|
99
|
+
const named = name(segments, verb)
|
|
100
|
+
|
|
101
|
+
assert.notStrictEqual(named, null, 'every walked method has a name')
|
|
102
|
+
|
|
103
|
+
const { path } = address(named!, params)
|
|
104
|
+
const match = tree.match(path)
|
|
105
|
+
|
|
106
|
+
assert.notStrictEqual(match, null, `'${named!}' resolves to '${path}', which matches`)
|
|
107
|
+
assert.ok(verb in match!.node.methods, `'${named!}' matches a node that answers ${verb}`)
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
})
|
package/source/const.ts
CHANGED
|
@@ -2,3 +2,18 @@ export const BRANCH_TTL = 1_800_000
|
|
|
2
2
|
|
|
3
3
|
/** The replicas of the gateway decide together, whatever context they serve. */
|
|
4
4
|
export const ATOM_GROUP = 'exposition'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Where JSON-RPC is served, for every procedure at once. Pinned rather than configured: a
|
|
8
|
+
* path an application could choose is a path it could collide with a route of its own.
|
|
9
|
+
*/
|
|
10
|
+
export const RPC = '/.rpc'
|
|
11
|
+
|
|
12
|
+
/** Calls one request may carry where the annotation does not say. */
|
|
13
|
+
export const BATCH = 32
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Where the Model Context Protocol is served. Pinned for the reason `/.rpc` is: a path an
|
|
17
|
+
* application could choose is a path it could collide with a route of its own.
|
|
18
|
+
*/
|
|
19
|
+
export const MCP = '/.mcp'
|
package/source/deployment.ts
CHANGED
|
@@ -67,6 +67,15 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
67
67
|
if (annotation.bouncer !== undefined)
|
|
68
68
|
properties.bouncer = annotation.bouncer
|
|
69
69
|
|
|
70
|
+
if (annotation.oauth !== undefined)
|
|
71
|
+
properties.oauth = annotation.oauth
|
|
72
|
+
|
|
73
|
+
if (annotation.rpc !== undefined)
|
|
74
|
+
properties.rpc = annotation.rpc
|
|
75
|
+
|
|
76
|
+
if (annotation.mcp !== undefined)
|
|
77
|
+
properties.mcp = annotation.mcp
|
|
78
|
+
|
|
70
79
|
service.variables!.push({
|
|
71
80
|
name: 'TOA_EXPOSITION_PROPERTIES',
|
|
72
81
|
value: JSON.stringify(properties)
|
|
@@ -83,4 +92,5 @@ export function deployment (_: unknown, annotation?: Annotation): Dependency {
|
|
|
83
92
|
return { services: [service] }
|
|
84
93
|
}
|
|
85
94
|
|
|
86
|
-
type Properties = Pick<Annotation,
|
|
95
|
+
type Properties = Pick<Annotation,
|
|
96
|
+
'authorities' | 'debug' | 'protocol' | 'bouncer' | 'ip' | 'oauth' | 'rpc' | 'mcp'>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { describe, it } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
|
|
4
|
+
import { Anonymous } from './Anonymous.js'
|
|
5
|
+
import type { Context } from './types.js'
|
|
6
|
+
|
|
7
|
+
const context = (headers: Record<string, string>, procedural = false): Context =>
|
|
8
|
+
({ request: { headers }, procedural }) as unknown as Context
|
|
9
|
+
|
|
10
|
+
describe('anonymous', () => {
|
|
11
|
+
it('should admit a request that presents nothing', () => {
|
|
12
|
+
assert.equal(new Anonymous(true).authorize(null, context({})), true)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('should refuse a request that presents a credential', () => {
|
|
16
|
+
// it would make the reply uncacheable, which is the whole of the rule
|
|
17
|
+
assert.equal(new Anonymous(true).authorize(null, context({ authorization: 'Token x' })), false)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should admit a procedure whatever the request presented', () => {
|
|
21
|
+
// what a procedure answers is a value in an envelope, and the envelope is `no-store`
|
|
22
|
+
const procedural = context({ authorization: 'Token x' }, true)
|
|
23
|
+
|
|
24
|
+
assert.equal(new Anonymous(true).authorize(null, procedural), true)
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
it('should refuse where it admits nobody', () => {
|
|
28
|
+
assert.equal(new Anonymous(false).authorize(null, context({})), false)
|
|
29
|
+
assert.equal(new Anonymous(false).authorize(null, context({}, true)), false)
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
it('should describe a method as it authorizes one', () => {
|
|
33
|
+
const directive = new Anonymous(true)
|
|
34
|
+
|
|
35
|
+
assert.equal(directive.admits(null, context({ authorization: 'Token x' })), false)
|
|
36
|
+
assert.equal(directive.admits(null, context({ authorization: 'Token x' }, true)), true)
|
|
37
|
+
})
|
|
38
|
+
})
|
|
@@ -7,9 +7,21 @@ export class Anonymous implements Directive {
|
|
|
7
7
|
this.allow = allow
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* A credential refuses, because it would make the reply uncacheable — which is the whole
|
|
12
|
+
* of the rule, and none of it applies to a procedure: what a procedure answers is a value
|
|
13
|
+
* in an envelope, and the envelope is the one thing that is cached or not.
|
|
14
|
+
*/
|
|
10
15
|
public authorize (_: any, context: Context): boolean {
|
|
16
|
+
if (context.procedural)
|
|
17
|
+
return this.allow
|
|
18
|
+
|
|
11
19
|
return 'authorization' in context.request.headers
|
|
12
20
|
? false
|
|
13
21
|
: this.allow
|
|
14
22
|
}
|
|
23
|
+
|
|
24
|
+
public admits (_: any, context: Context): boolean {
|
|
25
|
+
return this.authorize(_, context)
|
|
26
|
+
}
|
|
15
27
|
}
|
|
@@ -16,11 +16,12 @@ import { Federation } from './Federation.js'
|
|
|
16
16
|
import { Anyone } from './Anyone.js'
|
|
17
17
|
import { Input, type Declaration } from './Input.js'
|
|
18
18
|
import { split } from './split.js'
|
|
19
|
-
import { PRIMARY,
|
|
19
|
+
import { PRIMARY, UNRECOGNIZED, providers as providersOf } from './schemes.js'
|
|
20
20
|
import { ATOM_GROUP } from '../../const.js'
|
|
21
21
|
import { Quotas, Sync } from '../io/lib/throttle/index.js'
|
|
22
22
|
import { Keys } from '../io/lib/throttle/Keys.js'
|
|
23
23
|
import type { Output } from '../../io.js'
|
|
24
|
+
import type { Introspection } from '../../Introspection.js'
|
|
24
25
|
import type { Component } from '@toa.io/core'
|
|
25
26
|
import type { Remotes } from '../../Remotes.js'
|
|
26
27
|
import type { Parameter, DirectiveFamily } from '../../RTD/index.js'
|
|
@@ -34,7 +35,7 @@ import type {
|
|
|
34
35
|
Identity,
|
|
35
36
|
Context,
|
|
36
37
|
Remote,
|
|
37
|
-
|
|
38
|
+
Components
|
|
38
39
|
} from './types.js'
|
|
39
40
|
|
|
40
41
|
export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
@@ -42,7 +43,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
42
43
|
public readonly name: string = 'auth'
|
|
43
44
|
public readonly mandatory: boolean = true
|
|
44
45
|
|
|
45
|
-
private readonly
|
|
46
|
+
private readonly components: Components = {}
|
|
46
47
|
private readonly discovery = {} as unknown as Discovery
|
|
47
48
|
private tokens: Component | null = null
|
|
48
49
|
private bans: Component | null = null
|
|
@@ -100,11 +101,18 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
100
101
|
directives.sort((a, b) => (a.priority ?? 1) - (b.priority ?? 1))
|
|
101
102
|
}
|
|
102
103
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Authentication: who the credential names, if one is presented. A credential belongs to
|
|
106
|
+
* the request, so it is read once however many calls the request carries.
|
|
107
|
+
*/
|
|
108
|
+
public async preflight (context: Context): Promise<void> {
|
|
106
109
|
context.identity = await this.resolve(context)
|
|
110
|
+
}
|
|
107
111
|
|
|
112
|
+
/** Authorization: whether that identity may make this call, which every call asks anew. */
|
|
113
|
+
public async precall (directives: Directive[],
|
|
114
|
+
context: Context,
|
|
115
|
+
parameters: Parameter[]): Promise<Output> {
|
|
108
116
|
for (const directive of directives) {
|
|
109
117
|
const allow = await directive.authorize(context.identity, context, parameters)
|
|
110
118
|
|
|
@@ -121,18 +129,69 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
121
129
|
throw new http.Forbidden()
|
|
122
130
|
}
|
|
123
131
|
|
|
132
|
+
/**
|
|
133
|
+
* The same disjunction as `precall`, over what can be told without a request. A method no
|
|
134
|
+
* directive admits, and none is undecided about, is not this caller's to be told about —
|
|
135
|
+
* `null` takes it out of the answer.
|
|
136
|
+
*
|
|
137
|
+
* A permission is matched against a path, and a description is not a request to one, so
|
|
138
|
+
* `permits` has no say here. The call it describes is still checked, which is where a
|
|
139
|
+
* token's permissions belong.
|
|
140
|
+
*
|
|
141
|
+
* A method that is described is then described by each of them, which is a separate pass:
|
|
142
|
+
* admission is a disjunction and stops at the first that admits, while what the directives
|
|
143
|
+
* fill is not any one of them's to state alone.
|
|
144
|
+
*/
|
|
145
|
+
public async explain (directives: Directive[], context: Context,
|
|
146
|
+
introspection: Introspection): Promise<Introspection | null> {
|
|
147
|
+
let untold = false
|
|
148
|
+
let admitted = false
|
|
149
|
+
|
|
150
|
+
for (const directive of directives) {
|
|
151
|
+
const admits = await directive.admits?.(context.identity, context)
|
|
152
|
+
|
|
153
|
+
if (admits === undefined) {
|
|
154
|
+
untold = true
|
|
155
|
+
|
|
156
|
+
continue
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (admits) {
|
|
160
|
+
admitted = true
|
|
161
|
+
|
|
162
|
+
break
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
if (!admitted && !untold)
|
|
167
|
+
return null
|
|
168
|
+
|
|
169
|
+
// whichever of them admitted, a property any of them fills from the identity is filled
|
|
170
|
+
// from the identity: what a caller sent there would be overwritten or forged
|
|
171
|
+
for (const directive of directives)
|
|
172
|
+
introspection = directive.describe?.(introspection) ?? introspection
|
|
173
|
+
|
|
174
|
+
return introspection
|
|
175
|
+
}
|
|
176
|
+
|
|
124
177
|
public async settle (directives: Directive[],
|
|
125
178
|
context: Context,
|
|
126
179
|
response: http.OutgoingMessage): Promise<void> {
|
|
127
180
|
await Promise.all(directives.map(async (directive) =>
|
|
128
181
|
directive.settle?.(context, response)))
|
|
182
|
+
}
|
|
129
183
|
|
|
184
|
+
/**
|
|
185
|
+
* Re-issuing a credential, and refusing a ban, are the request's business: the header
|
|
186
|
+
* carries one token however many calls were made, and a ban refuses all of them.
|
|
187
|
+
*/
|
|
188
|
+
public async depart (context: Context, response: http.OutgoingMessage): Promise<void> {
|
|
130
189
|
const identity = context.identity
|
|
131
190
|
|
|
132
191
|
if (identity === null)
|
|
133
192
|
return
|
|
134
193
|
|
|
135
|
-
if (identity.
|
|
194
|
+
if (identity.provider === PRIMARY && !identity.refresh)
|
|
136
195
|
return
|
|
137
196
|
|
|
138
197
|
if (await this.banned(identity))
|
|
@@ -140,7 +199,7 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
140
199
|
|
|
141
200
|
// a token carries the roles it was issued with, and the refresh is where they are read again;
|
|
142
201
|
// any other scheme has just read them, unless a Role directive already did
|
|
143
|
-
if (identity.
|
|
202
|
+
if (identity.provider === PRIMARY)
|
|
144
203
|
identity.roles = await Role.get(identity, this.discovery.roles)
|
|
145
204
|
else
|
|
146
205
|
identity.roles ??= await Role.get(identity, this.discovery.roles)
|
|
@@ -170,25 +229,40 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
170
229
|
throw new http.TooManyRequests(retry)
|
|
171
230
|
|
|
172
231
|
const [scheme, credentials] = split(authorization)
|
|
173
|
-
const
|
|
232
|
+
const candidates = providersOf(scheme)
|
|
174
233
|
|
|
175
|
-
if (
|
|
234
|
+
if (candidates === undefined)
|
|
176
235
|
throw new http.Unauthorized(`Unknown authentication scheme '${scheme}'`)
|
|
177
236
|
|
|
178
|
-
|
|
237
|
+
let provider: Remote | null = null
|
|
238
|
+
let result: AuthenticationResult | null = null
|
|
179
239
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
240
|
+
// the first provider that does not decline has claimed the credentials, and answers
|
|
241
|
+
// for them: a rejection from one that never recognized them is not the rejection
|
|
242
|
+
for (const candidate of candidates) {
|
|
243
|
+
this.components[candidate] ??= await this.discovery[candidate]
|
|
244
|
+
|
|
245
|
+
const answer = await this.components[candidate]!.invoke<AuthenticationResult>('authenticate', {
|
|
246
|
+
input: {
|
|
247
|
+
scheme,
|
|
248
|
+
authority,
|
|
249
|
+
credentials
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
|
|
253
|
+
if (declined(answer))
|
|
254
|
+
continue
|
|
187
255
|
|
|
188
|
-
|
|
189
|
-
|
|
256
|
+
provider = candidate
|
|
257
|
+
result = answer
|
|
190
258
|
|
|
191
|
-
|
|
259
|
+
break
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (result === null || result instanceof Error) {
|
|
263
|
+
const code = result === null ? UNRECOGNIZED : codeOf(result)
|
|
264
|
+
|
|
265
|
+
if (code !== undefined) {
|
|
192
266
|
console.info('Authentication failed', { code })
|
|
193
267
|
|
|
194
268
|
context.rejection = code
|
|
@@ -201,9 +275,10 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
201
275
|
|
|
202
276
|
const identity = result.identity
|
|
203
277
|
|
|
204
|
-
if (
|
|
278
|
+
if (provider !== PRIMARY && (await this.banned(identity))) throw new http.Unauthorized()
|
|
205
279
|
|
|
206
280
|
identity.scheme = scheme
|
|
281
|
+
identity.provider = provider!
|
|
207
282
|
identity.refresh = result.refresh
|
|
208
283
|
|
|
209
284
|
return identity
|
|
@@ -228,6 +303,17 @@ export class Authorization implements DirectiveFamily<Directive, Extension> {
|
|
|
228
303
|
}
|
|
229
304
|
}
|
|
230
305
|
|
|
306
|
+
/** Whether a provider says the credentials are not of its kind, so the next is asked. */
|
|
307
|
+
function declined (result: AuthenticationResult): boolean {
|
|
308
|
+
return result instanceof Error && codeOf(result) === UNRECOGNIZED
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
function codeOf (result: Error): string | undefined {
|
|
312
|
+
const code: string | unknown = (result as unknown as { code: string }).code
|
|
313
|
+
|
|
314
|
+
return typeof code === 'string' ? code : undefined
|
|
315
|
+
}
|
|
316
|
+
|
|
231
317
|
/** Whether the permissions admit the method on the path the request is routed by. */
|
|
232
318
|
export function permits (permissions: Record<string, string[]>, method: string, pathname: string): boolean {
|
|
233
319
|
return Object.entries(permissions).some(([pattern, methods]) =>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { describe, it } from 'node:test'
|
|
3
|
+
import { Delegate } from './Delegate.js'
|
|
4
|
+
import type { Introspection } from '../../Introspection.js'
|
|
5
|
+
|
|
6
|
+
describe('auth:delegate', () => {
|
|
7
|
+
function explanation (): Introspection {
|
|
8
|
+
return {
|
|
9
|
+
input: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
identity: { type: 'object' },
|
|
13
|
+
title: { type: 'string' }
|
|
14
|
+
},
|
|
15
|
+
required: ['identity', 'title']
|
|
16
|
+
}
|
|
17
|
+
} as unknown as Introspection
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
it('should take the property it embeds out of the input', () => {
|
|
21
|
+
const delegate = new Delegate('identity', null as never)
|
|
22
|
+
const described = delegate.describe(explanation())
|
|
23
|
+
const input = described.input as { properties: object, required: string[] }
|
|
24
|
+
|
|
25
|
+
assert.deepStrictEqual(Object.keys(input.properties), ['title'])
|
|
26
|
+
assert.deepStrictEqual(input.required, ['title'])
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
it('should leave an input that does not declare it alone', () => {
|
|
30
|
+
const delegate = new Delegate('originator', null as never)
|
|
31
|
+
const described = delegate.describe(explanation())
|
|
32
|
+
const input = described.input as { properties: object }
|
|
33
|
+
|
|
34
|
+
assert.deepStrictEqual(Object.keys(input.properties), ['identity', 'title'])
|
|
35
|
+
})
|
|
36
|
+
})
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { BadRequest } from '../../HTTP/index.js'
|
|
2
|
+
import { take } from '../../Introspection.js'
|
|
2
3
|
import { Role } from './Role.js'
|
|
4
|
+
import type { Introspection } from '../../Introspection.js'
|
|
3
5
|
import type { Context, Directive, Identity } from './types.js'
|
|
4
6
|
import type { Component } from '@toa.io/core'
|
|
5
7
|
|
|
@@ -22,6 +24,18 @@ export class Delegate implements Directive {
|
|
|
22
24
|
return true
|
|
23
25
|
}
|
|
24
26
|
|
|
27
|
+
/** It admits whoever there is, and embedding the identity is the request's business. */
|
|
28
|
+
public admits (identity: Identity | null): boolean {
|
|
29
|
+
return identity !== null
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** The property it embeds is the identity's, so a caller has nothing to put there. */
|
|
33
|
+
public describe (introspection: Introspection): Introspection {
|
|
34
|
+
take(introspection, this.property)
|
|
35
|
+
|
|
36
|
+
return introspection
|
|
37
|
+
}
|
|
38
|
+
|
|
25
39
|
private embed (body: unknown, identity: Identity): Record<string, unknown> {
|
|
26
40
|
if (body === undefined)
|
|
27
41
|
body = {}
|
|
@@ -12,6 +12,11 @@ export class Echo implements Directive {
|
|
|
12
12
|
return true
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
+
/** What `authorize` answers, without inventing the identity it would go on to invent. */
|
|
16
|
+
public admits (identity: Identity | null, context: Context): boolean {
|
|
17
|
+
return !(identity === null && 'authorization' in context.request.headers)
|
|
18
|
+
}
|
|
19
|
+
|
|
15
20
|
public reply (context: Context): OutgoingMessage {
|
|
16
21
|
const body = context.identity!
|
|
17
22
|
|
|
@@ -3,14 +3,14 @@ import { console } from 'openspan'
|
|
|
3
3
|
import * as http from '../../HTTP/index.js'
|
|
4
4
|
import { split } from './split.js'
|
|
5
5
|
import { create } from './create.js'
|
|
6
|
-
import { INCEPTION, UNKNOWN,
|
|
6
|
+
import { INCEPTION, UNKNOWN, providers as providersOf } from './schemes.js'
|
|
7
7
|
import { Role } from './Role.js'
|
|
8
8
|
import type { Component } from '@toa.io/core'
|
|
9
|
-
import type { Maybe } from '@toa.io/
|
|
10
|
-
import type { Directive, Discovery, Identity, Context,
|
|
9
|
+
import type { Maybe } from '@toa.io/core'
|
|
10
|
+
import type { Directive, Discovery, Identity, Context, Components, Ban } from './types.js'
|
|
11
11
|
|
|
12
12
|
export class Incept implements Directive {
|
|
13
|
-
private static readonly
|
|
13
|
+
private static readonly components: Components = {}
|
|
14
14
|
private static discovery: Discovery
|
|
15
15
|
private static bans: Component | null = null
|
|
16
16
|
|
|
@@ -26,12 +26,17 @@ export class Incept implements Directive {
|
|
|
26
26
|
|
|
27
27
|
public static async incept (context: Context, id: string): Promise<Identity> {
|
|
28
28
|
const [scheme, credentials] = split(context.request.headers.authorization!)
|
|
29
|
-
const
|
|
29
|
+
const candidates = providersOf(scheme)
|
|
30
30
|
|
|
31
|
-
if (
|
|
31
|
+
if (candidates === undefined)
|
|
32
32
|
throw new http.BadRequest('Authentication scheme is not supported')
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
// a scheme several providers claim is incepted by the one that incepts; `Bearer`
|
|
35
|
+
// carries an access token this gateway issued, and an identity cannot be incepted
|
|
36
|
+
// from a credential it would itself have to exist to hold
|
|
37
|
+
const provider = candidates.find((candidate) => INCEPTION.includes(candidate))
|
|
38
|
+
|
|
39
|
+
if (provider === undefined)
|
|
35
40
|
throw new http.Unauthorized()
|
|
36
41
|
|
|
37
42
|
Incept.bans ??= await Incept.discovery.bans
|
|
@@ -41,9 +46,9 @@ export class Incept implements Directive {
|
|
|
41
46
|
if (ban.banned)
|
|
42
47
|
throw new http.Unauthorized()
|
|
43
48
|
|
|
44
|
-
Incept.
|
|
49
|
+
Incept.components[provider] ??= await Incept.discovery[provider]
|
|
45
50
|
|
|
46
|
-
const identity = await Incept.
|
|
51
|
+
const identity = await Incept.components[provider]!.invoke<Maybe<Identity>>('incept', {
|
|
47
52
|
input: {
|
|
48
53
|
scheme,
|
|
49
54
|
authority: context.authority,
|
|
@@ -56,8 +61,9 @@ export class Incept implements Directive {
|
|
|
56
61
|
throw new http.UnprocessableEntity(identity)
|
|
57
62
|
|
|
58
63
|
identity.scheme = scheme
|
|
59
|
-
identity.roles = []
|
|
60
64
|
|
|
65
|
+
// the roles are read where the token is minted: an Identity incepted as the principal
|
|
66
|
+
// has one already
|
|
61
67
|
return identity
|
|
62
68
|
}
|
|
63
69
|
|
|
@@ -36,6 +36,19 @@ export class Role implements Directive {
|
|
|
36
36
|
return this.match(identity.roles, parameters)
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/** A role naming a route variable cannot be told from a description, which has no values. */
|
|
40
|
+
public async admits (identity: Identity | null): Promise<boolean | undefined> {
|
|
41
|
+
if (this.dynamic)
|
|
42
|
+
return undefined
|
|
43
|
+
|
|
44
|
+
if (identity === null)
|
|
45
|
+
return false
|
|
46
|
+
|
|
47
|
+
identity.roles ??= await Role.get(identity, this.discovery)
|
|
48
|
+
|
|
49
|
+
return this.match(identity.roles, [])
|
|
50
|
+
}
|
|
51
|
+
|
|
39
52
|
private match (roles: string[], parameters: Parameter[]): boolean {
|
|
40
53
|
const required = this.dynamic ? this.substitute(parameters) : this.roles
|
|
41
54
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Parameter } from '../../RTD/index.js'
|
|
2
|
+
import type { Introspection } from '../../Introspection.js'
|
|
2
3
|
import type { Context, Directive, Identity, Create } from './types.js'
|
|
3
4
|
|
|
4
5
|
export class Rule implements Directive {
|
|
@@ -22,4 +23,32 @@ export class Rule implements Directive {
|
|
|
22
23
|
|
|
23
24
|
return true
|
|
24
25
|
}
|
|
26
|
+
|
|
27
|
+
/** Whatever each of them makes of it, in the order they were declared. */
|
|
28
|
+
public describe (introspection: Introspection): Introspection {
|
|
29
|
+
for (const directive of this.directives)
|
|
30
|
+
introspection = directive.describe?.(introspection) ?? introspection
|
|
31
|
+
|
|
32
|
+
return introspection
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** All of them, so one that refuses ends it and one that cannot tell leaves it untold. */
|
|
36
|
+
public async admits (identity: Identity | null, context: Context): Promise<boolean | undefined> {
|
|
37
|
+
let untold = false
|
|
38
|
+
|
|
39
|
+
for (const directive of this.directives) {
|
|
40
|
+
const admits = await directive.admits?.(identity, context)
|
|
41
|
+
|
|
42
|
+
if (admits === undefined) {
|
|
43
|
+
untold = true
|
|
44
|
+
|
|
45
|
+
continue
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (!admits)
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return untold ? undefined : true
|
|
53
|
+
}
|
|
25
54
|
}
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import { it } from 'node:test'
|
|
2
2
|
import assert from 'node:assert/strict'
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { providers } from './schemes.js'
|
|
5
5
|
|
|
6
6
|
it('should resolve a known scheme', () => {
|
|
7
|
-
assert.
|
|
8
|
-
assert.
|
|
7
|
+
assert.deepEqual(providers('basic'), ['basic'])
|
|
8
|
+
assert.deepEqual(providers('code'), ['federation'])
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('should resolve every provider claiming a scheme, in order', () => {
|
|
12
|
+
assert.deepEqual(providers('bearer'), ['tokens', 'federation'])
|
|
9
13
|
})
|
|
10
14
|
|
|
11
15
|
it('should not resolve a property of Object.prototype', () => {
|
|
12
16
|
for (const name of ['constructor', '__proto__', 'toString', 'hasOwnProperty'])
|
|
13
|
-
assert.equal(
|
|
17
|
+
assert.equal(providers(name), undefined)
|
|
14
18
|
})
|