@toa.io/extensions.exposition 1.0.0-alpha.4 → 1.0.0-alpha.40
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/context.toa.yaml +2 -2
- package/components/identity.bans/manifest.toa.yaml +15 -7
- package/components/identity.bans/operations/transit.d.ts +14 -0
- package/components/identity.bans/operations/transit.js +11 -0
- package/components/identity.bans/operations/transit.js.map +1 -0
- package/components/identity.bans/operations/tsconfig.tsbuildinfo +1 -0
- package/components/identity.bans/source/transit.ts +21 -0
- package/components/identity.bans/tsconfig.json +9 -0
- package/components/identity.basic/manifest.toa.yaml +22 -9
- package/components/identity.basic/operations/authenticate.d.ts +5 -1
- package/components/identity.basic/operations/authenticate.js +5 -2
- package/components/identity.basic/operations/authenticate.js.map +1 -1
- package/components/identity.basic/operations/incept.d.ts +12 -0
- package/components/identity.basic/operations/incept.js +26 -0
- package/components/identity.basic/operations/incept.js.map +1 -0
- package/components/identity.basic/operations/transit.d.ts +4 -4
- package/components/identity.basic/operations/transit.js +5 -3
- package/components/identity.basic/operations/transit.js.map +1 -1
- package/components/identity.basic/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/operations/types.d.ts +8 -4
- package/components/identity.basic/source/authenticate.ts +16 -5
- package/components/identity.basic/source/incept.ts +38 -0
- package/components/identity.basic/source/transit.ts +8 -6
- package/components/identity.basic/source/types.ts +8 -4
- package/components/identity.federation/manifest.toa.yaml +28 -22
- package/components/identity.federation/operations/authenticate.d.ts +2 -2
- package/components/identity.federation/operations/authenticate.js +3 -10
- package/components/identity.federation/operations/authenticate.js.map +1 -1
- package/components/identity.federation/operations/incept.d.ts +11 -0
- package/components/identity.federation/operations/{create.js → incept.js} +6 -7
- package/components/identity.federation/operations/incept.js.map +1 -0
- package/components/identity.federation/operations/lib/jwt.d.ts +4 -5
- package/components/identity.federation/operations/lib/jwt.js +3 -3
- package/components/identity.federation/operations/lib/jwt.js.map +1 -1
- package/components/identity.federation/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.federation/operations/types/configuration.d.ts +14 -0
- package/components/identity.federation/operations/types/configuration.js +3 -0
- package/components/identity.federation/operations/types/configuration.js.map +1 -0
- package/components/identity.federation/operations/{types.d.ts → types/context.d.ts} +13 -6
- package/components/identity.federation/operations/types/context.js +3 -0
- package/components/identity.federation/operations/types/context.js.map +1 -0
- package/components/identity.federation/operations/types/entity.d.ts +6 -0
- package/components/identity.federation/operations/{types.js → types/entity.js} +1 -1
- package/components/identity.federation/operations/types/entity.js.map +1 -0
- package/components/identity.federation/operations/types/index.d.ts +3 -0
- package/components/identity.federation/operations/types/index.js +20 -0
- package/components/identity.federation/operations/types/index.js.map +1 -0
- package/components/identity.federation/source/authenticate.ts +5 -18
- package/components/identity.federation/source/{create.ts → incept.ts} +10 -9
- package/components/identity.federation/source/lib/jwt.test.ts +2 -2
- package/components/identity.federation/source/lib/jwt.ts +7 -8
- package/components/identity.federation/source/types/configuration.ts +15 -0
- package/components/identity.federation/source/{types.ts → types/context.ts} +15 -5
- package/components/identity.federation/source/types/entity.ts +6 -0
- package/components/identity.federation/source/types/index.ts +3 -0
- package/components/identity.federation/tsconfig.json +2 -2
- package/components/identity.roles/manifest.toa.yaml +18 -6
- package/components/identity.roles/operations/grant.d.ts +10 -0
- package/components/identity.roles/operations/grant.js +21 -0
- package/components/identity.roles/operations/grant.js.map +1 -0
- package/components/identity.roles/operations/lib/Entity.d.ts +5 -0
- package/components/identity.roles/operations/lib/Entity.js +3 -0
- package/components/identity.roles/operations/lib/Entity.js.map +1 -0
- package/components/identity.roles/operations/list.d.ts +1 -4
- package/components/identity.roles/operations/list.js.map +1 -1
- package/components/identity.roles/operations/principal.d.ts +4 -6
- package/components/identity.roles/operations/principal.js +6 -1
- package/components/identity.roles/operations/principal.js.map +1 -1
- package/components/identity.roles/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.roles/source/grant.ts +32 -0
- package/components/identity.roles/source/lib/Entity.ts +5 -0
- package/components/identity.roles/source/list.ts +2 -4
- package/components/identity.roles/source/principal.ts +10 -8
- package/components/identity.tokens/manifest.toa.yaml +19 -5
- package/components/identity.tokens/operations/authenticate.d.ts +2 -2
- package/components/identity.tokens/operations/authenticate.js +10 -4
- package/components/identity.tokens/operations/authenticate.js.map +1 -1
- package/components/identity.tokens/operations/decrypt.js +1 -0
- package/components/identity.tokens/operations/decrypt.js.map +1 -1
- package/components/identity.tokens/operations/encrypt.js +5 -1
- package/components/identity.tokens/operations/encrypt.js.map +1 -1
- package/components/identity.tokens/operations/tsconfig.tsbuildinfo +1 -1
- package/components/identity.tokens/operations/types.d.ts +8 -2
- package/components/identity.tokens/receivers/identity.bans.created.js +3 -0
- package/components/identity.tokens/source/authenticate.test.ts +11 -4
- package/components/identity.tokens/source/authenticate.ts +12 -5
- package/components/identity.tokens/source/decrypt.test.ts +5 -3
- package/components/identity.tokens/source/decrypt.ts +9 -8
- package/components/identity.tokens/source/encrypt.test.ts +26 -2
- package/components/identity.tokens/source/encrypt.ts +5 -1
- package/components/identity.tokens/source/types.ts +9 -2
- package/components/octets.storage/manifest.toa.yaml +0 -7
- package/documentation/access.md +27 -16
- package/documentation/authorities.md +53 -0
- package/documentation/cache.md +8 -1
- package/documentation/components.md +47 -22
- package/documentation/identity.md +17 -22
- package/documentation/io.md +56 -0
- package/documentation/protocol.md +3 -0
- package/documentation/query.md +17 -11
- package/documentation/require.md +15 -0
- package/documentation/tree.md +22 -4
- package/documentation/vary.md +14 -14
- package/features/access.feature +89 -47
- package/features/annotation.feature +2 -0
- package/features/authorities.basic.feature +141 -0
- package/features/authorities.feature +32 -0
- package/features/authorities.federation.feature +99 -0
- package/features/authorities.tokens.feature +118 -0
- package/features/body.feature +4 -0
- package/features/cache.feature +112 -5
- package/features/cors.feature +7 -2
- package/features/debug.feature +34 -0
- package/features/directives.feature +5 -0
- package/features/dynamic.feature +18 -7
- package/features/errors.feature +18 -4
- package/features/etag.feature +18 -1
- package/features/identity.bans.feature +137 -0
- package/features/identity.basic.feature +142 -19
- package/features/identity.feature +7 -2
- package/features/identity.federation.feature +67 -14
- package/features/identity.roles.feature +220 -4
- package/features/identity.tokens.feature +57 -4
- package/features/io.feature +205 -0
- package/features/octets.entries.feature +10 -0
- package/features/octets.feature +60 -64
- package/features/octets.meta.feature +7 -3
- package/features/octets.workflows.feature +14 -0
- package/features/probes.feature +14 -0
- package/features/{queries.feature → query.feature} +50 -3
- package/features/require.feature +67 -0
- package/features/response.feature +12 -3
- package/features/routes.feature +25 -12
- package/features/steps/Database.ts +17 -10
- package/features/steps/Gateway.ts +23 -6
- package/features/steps/IdP.ts +28 -23
- package/features/steps/components/echo/manifest.toa.yaml +5 -1
- package/features/steps/components/echo/operations/identity.js +7 -0
- package/features/steps/components/pots/manifest.toa.yaml +2 -0
- package/features/steps/components/users.properties/manifest.toa.yaml +2 -1
- package/features/streams.feature +1 -0
- package/features/timing.feature +27 -1
- package/features/vary.feature +105 -3
- package/package.json +12 -11
- package/readme.md +19 -14
- package/schemas/annotation.cos.yaml +1 -1
- package/schemas/io/input.cos.yaml +3 -0
- package/schemas/io/message.cos.yaml +5 -0
- package/schemas/io/output.cos.yaml +5 -0
- package/source/Annotation.ts +3 -3
- package/source/Context.ts +6 -4
- package/source/Directive.test.ts +4 -4
- package/source/Directive.ts +11 -38
- package/source/Endpoint.ts +43 -8
- package/source/Factory.ts +11 -7
- package/source/Gateway.ts +16 -44
- package/source/HTTP/Context.ts +24 -2
- package/source/HTTP/Server.ts +56 -43
- package/source/HTTP/exceptions.ts +7 -1
- package/source/HTTP/messages.ts +1 -1
- package/source/Mapping.ts +6 -1
- package/source/Query.test.ts +1 -1
- package/source/Query.ts +35 -24
- package/source/RTD/Context.ts +7 -10
- package/source/RTD/Directives.ts +28 -4
- package/source/RTD/Endpoint.ts +6 -4
- package/source/RTD/Match.ts +2 -7
- package/source/RTD/Method.ts +7 -13
- package/source/RTD/Node.ts +13 -14
- package/source/RTD/Tree.ts +17 -16
- package/source/RTD/factory.ts +3 -6
- package/source/Tenant.ts +0 -8
- package/source/deployment.ts +32 -22
- package/source/directives/auth/Authorization.ts +38 -19
- package/source/directives/auth/Delegate.ts +42 -0
- package/source/directives/auth/Incept.ts +3 -2
- package/source/directives/auth/Role.test.ts +53 -6
- package/source/directives/auth/Role.ts +22 -14
- package/source/directives/auth/types.ts +1 -1
- package/source/directives/cache/Cache.ts +15 -8
- package/source/directives/cache/Control.ts +42 -16
- package/source/directives/cors/CORS.ts +13 -7
- package/source/directives/dev/Development.ts +4 -4
- package/source/directives/index.ts +6 -4
- package/source/directives/io/Directive.ts +11 -0
- package/source/directives/io/IO.ts +43 -0
- package/source/directives/io/Input.ts +50 -0
- package/source/directives/io/Message.ts +1 -0
- package/source/directives/io/Output.ts +69 -0
- package/source/directives/io/index.ts +3 -0
- package/source/directives/io/schemas.ts +12 -0
- package/source/directives/octets/Context.ts +4 -3
- package/source/directives/octets/Delete.ts +4 -2
- package/source/directives/octets/Directive.ts +10 -0
- package/source/directives/octets/Fetch.ts +4 -3
- package/source/directives/octets/List.ts +4 -2
- package/source/directives/octets/Octets.ts +6 -8
- package/source/directives/octets/Store.ts +12 -4
- package/source/directives/octets/Workflow.ts +10 -3
- package/source/directives/octets/types.ts +0 -7
- package/source/directives/require/Directive.ts +5 -0
- package/source/directives/require/Headers.ts +20 -0
- package/source/directives/require/Require.ts +28 -0
- package/source/directives/require/index.ts +3 -0
- package/source/directives/vary/Directive.ts +2 -1
- package/source/directives/vary/Embed.ts +14 -8
- package/source/directives/vary/Vary.ts +7 -5
- package/source/directives/vary/embeddings/Authority.ts +8 -0
- package/source/directives/vary/embeddings/Embedding.ts +2 -1
- package/source/directives/vary/embeddings/Header.ts +8 -6
- package/source/directives/vary/embeddings/Language.ts +1 -1
- package/source/directives/vary/embeddings/Parameter.ts +14 -0
- package/source/directives/vary/embeddings/index.ts +6 -4
- package/source/exceptions.ts +22 -11
- package/source/root.ts +5 -0
- package/source/schemas.ts +1 -1
- package/transpiled/Annotation.d.ts +3 -3
- package/transpiled/Context.d.ts +6 -4
- package/transpiled/Directive.d.ts +4 -17
- package/transpiled/Directive.js +4 -7
- package/transpiled/Directive.js.map +1 -1
- package/transpiled/Endpoint.d.ts +5 -3
- package/transpiled/Endpoint.js +30 -5
- package/transpiled/Endpoint.js.map +1 -1
- package/transpiled/Factory.js +9 -4
- package/transpiled/Factory.js.map +1 -1
- package/transpiled/Gateway.d.ts +1 -4
- package/transpiled/Gateway.js +10 -26
- package/transpiled/Gateway.js.map +1 -1
- package/transpiled/HTTP/Context.d.ts +8 -1
- package/transpiled/HTTP/Context.js +15 -2
- package/transpiled/HTTP/Context.js.map +1 -1
- package/transpiled/HTTP/Server.d.ts +13 -2
- package/transpiled/HTTP/Server.js +41 -35
- package/transpiled/HTTP/Server.js.map +1 -1
- package/transpiled/HTTP/exceptions.d.ts +4 -1
- package/transpiled/HTTP/exceptions.js +7 -1
- package/transpiled/HTTP/exceptions.js.map +1 -1
- package/transpiled/HTTP/messages.js +1 -1
- package/transpiled/HTTP/messages.js.map +1 -1
- package/transpiled/Mapping.js +4 -1
- package/transpiled/Mapping.js.map +1 -1
- package/transpiled/Query.d.ts +1 -0
- package/transpiled/Query.js +21 -20
- package/transpiled/Query.js.map +1 -1
- package/transpiled/RTD/Context.d.ts +7 -6
- package/transpiled/RTD/Directives.d.ts +19 -4
- package/transpiled/RTD/Endpoint.d.ts +6 -4
- package/transpiled/RTD/Match.d.ts +2 -4
- package/transpiled/RTD/Method.d.ts +7 -7
- package/transpiled/RTD/Method.js.map +1 -1
- package/transpiled/RTD/Node.d.ts +4 -6
- package/transpiled/RTD/Node.js +2 -1
- package/transpiled/RTD/Node.js.map +1 -1
- package/transpiled/RTD/Tree.d.ts +6 -6
- package/transpiled/RTD/Tree.js +4 -1
- package/transpiled/RTD/Tree.js.map +1 -1
- package/transpiled/RTD/factory.d.ts +2 -4
- package/transpiled/RTD/factory.js +1 -1
- package/transpiled/RTD/factory.js.map +1 -1
- package/transpiled/Tenant.d.ts +0 -1
- package/transpiled/Tenant.js +0 -6
- package/transpiled/Tenant.js.map +1 -1
- package/transpiled/deployment.d.ts +1 -1
- package/transpiled/deployment.js +28 -20
- package/transpiled/deployment.js.map +1 -1
- package/transpiled/directives/auth/Authorization.d.ts +2 -3
- package/transpiled/directives/auth/Authorization.js +26 -12
- package/transpiled/directives/auth/Authorization.js.map +1 -1
- package/transpiled/directives/auth/Delegate.d.ts +10 -0
- package/transpiled/directives/auth/Delegate.js +34 -0
- package/transpiled/directives/auth/Delegate.js.map +1 -0
- package/transpiled/directives/auth/Incept.js +3 -2
- package/transpiled/directives/auth/Incept.js.map +1 -1
- package/transpiled/directives/auth/Role.d.ts +4 -1
- package/transpiled/directives/auth/Role.js +20 -14
- package/transpiled/directives/auth/Role.js.map +1 -1
- package/transpiled/directives/cache/Cache.d.ts +5 -5
- package/transpiled/directives/cache/Cache.js +10 -4
- package/transpiled/directives/cache/Cache.js.map +1 -1
- package/transpiled/directives/cache/Control.d.ts +2 -1
- package/transpiled/directives/cache/Control.js +29 -12
- package/transpiled/directives/cache/Control.js.map +1 -1
- package/transpiled/directives/cors/CORS.d.ts +2 -3
- package/transpiled/directives/cors/CORS.js +13 -7
- package/transpiled/directives/cors/CORS.js.map +1 -1
- package/transpiled/directives/dev/Development.d.ts +3 -3
- package/transpiled/directives/dev/Development.js +1 -1
- package/transpiled/directives/dev/Development.js.map +1 -1
- package/transpiled/directives/index.d.ts +2 -2
- package/transpiled/directives/index.js +5 -3
- package/transpiled/directives/index.js.map +1 -1
- package/transpiled/directives/io/Directive.d.ts +8 -0
- package/transpiled/directives/io/Directive.js +3 -0
- package/transpiled/directives/io/Directive.js.map +1 -0
- package/transpiled/directives/io/IO.d.ts +9 -0
- package/transpiled/directives/io/IO.js +33 -0
- package/transpiled/directives/io/IO.js.map +1 -0
- package/transpiled/directives/io/Input.d.ts +11 -0
- package/transpiled/directives/{octets/Permute.js → io/Input.js} +33 -26
- package/transpiled/directives/io/Input.js.map +1 -0
- package/transpiled/directives/io/Message.d.ts +1 -0
- package/transpiled/directives/io/Message.js +3 -0
- package/transpiled/directives/io/Message.js.map +1 -0
- package/transpiled/directives/io/Output.d.ts +13 -0
- package/transpiled/directives/io/Output.js +76 -0
- package/transpiled/directives/io/Output.js.map +1 -0
- package/transpiled/directives/io/index.d.ts +2 -0
- package/transpiled/directives/io/index.js +6 -0
- package/transpiled/directives/io/index.js.map +1 -0
- package/transpiled/directives/io/schemas.d.ts +7 -0
- package/transpiled/directives/io/schemas.js +14 -0
- package/transpiled/directives/io/schemas.js.map +1 -0
- package/transpiled/directives/octets/Context.d.ts +3 -3
- package/transpiled/directives/octets/Context.js +4 -2
- package/transpiled/directives/octets/Context.js.map +1 -1
- package/transpiled/directives/octets/Delete.d.ts +3 -2
- package/transpiled/directives/octets/Delete.js +3 -1
- package/transpiled/directives/octets/Delete.js.map +1 -1
- package/transpiled/directives/octets/Directive.d.ts +8 -0
- package/transpiled/directives/octets/Directive.js +8 -0
- package/transpiled/directives/octets/Directive.js.map +1 -0
- package/transpiled/directives/octets/Fetch.d.ts +3 -2
- package/transpiled/directives/octets/Fetch.js +3 -1
- package/transpiled/directives/octets/Fetch.js.map +1 -1
- package/transpiled/directives/octets/List.d.ts +3 -2
- package/transpiled/directives/octets/List.js +3 -1
- package/transpiled/directives/octets/List.js.map +1 -1
- package/transpiled/directives/octets/Octets.d.ts +4 -4
- package/transpiled/directives/octets/Octets.js +2 -4
- package/transpiled/directives/octets/Octets.js.map +1 -1
- package/transpiled/directives/octets/Store.d.ts +3 -2
- package/transpiled/directives/octets/Store.js +10 -3
- package/transpiled/directives/octets/Store.js.map +1 -1
- package/transpiled/directives/octets/Workflow.d.ts +3 -2
- package/transpiled/directives/octets/Workflow.js +9 -2
- package/transpiled/directives/octets/Workflow.js.map +1 -1
- package/transpiled/directives/octets/types.d.ts +0 -5
- package/transpiled/directives/require/Directive.d.ts +4 -0
- package/transpiled/directives/require/Directive.js +3 -0
- package/transpiled/directives/require/Directive.js.map +1 -0
- package/transpiled/directives/require/Headers.d.ts +7 -0
- package/transpiled/directives/require/Headers.js +19 -0
- package/transpiled/directives/require/Headers.js.map +1 -0
- package/transpiled/directives/require/Require.d.ts +9 -0
- package/transpiled/directives/require/Require.js +27 -0
- package/transpiled/directives/require/Require.js.map +1 -0
- package/transpiled/directives/require/index.d.ts +2 -0
- package/transpiled/directives/require/index.js +6 -0
- package/transpiled/directives/require/index.js.map +1 -0
- package/transpiled/directives/vary/Directive.d.ts +2 -1
- package/transpiled/directives/vary/Embed.d.ts +2 -1
- package/transpiled/directives/vary/Embed.js +8 -6
- package/transpiled/directives/vary/Embed.js.map +1 -1
- package/transpiled/directives/vary/Vary.d.ts +3 -3
- package/transpiled/directives/vary/Vary.js +3 -3
- package/transpiled/directives/vary/Vary.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Authority.d.ts +5 -0
- package/transpiled/directives/vary/embeddings/Authority.js +10 -0
- package/transpiled/directives/vary/embeddings/Authority.js.map +1 -0
- package/transpiled/directives/vary/embeddings/Embedding.d.ts +2 -1
- package/transpiled/directives/vary/embeddings/Header.js +8 -6
- package/transpiled/directives/vary/embeddings/Header.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Language.js +1 -1
- package/transpiled/directives/vary/embeddings/Language.js.map +1 -1
- package/transpiled/directives/vary/embeddings/Parameter.d.ts +7 -0
- package/transpiled/directives/vary/embeddings/Parameter.js +14 -0
- package/transpiled/directives/vary/embeddings/Parameter.js.map +1 -0
- package/transpiled/directives/vary/embeddings/index.d.ts +2 -2
- package/transpiled/directives/vary/embeddings/index.js +8 -4
- package/transpiled/directives/vary/embeddings/index.js.map +1 -1
- package/transpiled/exceptions.d.ts +3 -2
- package/transpiled/exceptions.js +13 -7
- package/transpiled/exceptions.js.map +1 -1
- package/transpiled/root.js +5 -0
- package/transpiled/root.js.map +1 -1
- package/transpiled/schemas.d.ts +1 -1
- package/transpiled/schemas.js +2 -2
- package/transpiled/schemas.js.map +1 -1
- package/transpiled/tsconfig.tsbuildinfo +1 -1
- package/components/identity.basic/operations/create.d.ts +0 -10
- package/components/identity.basic/operations/create.js +0 -10
- package/components/identity.basic/operations/create.js.map +0 -1
- package/components/identity.basic/source/create.ts +0 -18
- package/components/identity.federation/operations/create.d.ts +0 -10
- package/components/identity.federation/operations/create.js.map +0 -1
- package/components/identity.federation/operations/schemas.d.ts +0 -59
- package/components/identity.federation/operations/schemas.js +0 -9
- package/components/identity.federation/operations/schemas.js.map +0 -1
- package/components/identity.federation/operations/types.js.map +0 -1
- package/components/identity.federation/source/schemas.ts +0 -61
- package/components/octets.storage/operations/permute.js +0 -7
- package/source/HTTP/Server.test.ts +0 -126
- package/source/directives/octets/Permute.ts +0 -43
- package/transpiled/directives/octets/Permute.d.ts +0 -10
- package/transpiled/directives/octets/Permute.js.map +0 -1
package/features/timing.feature
CHANGED
|
@@ -12,6 +12,7 @@ Feature: Server timing
|
|
|
12
12
|
When the following request is received:
|
|
13
13
|
"""
|
|
14
14
|
POST /pots/ HTTP/1.1
|
|
15
|
+
host: nex.toa.io
|
|
15
16
|
content-type: application/yaml
|
|
16
17
|
|
|
17
18
|
title: Hello
|
|
@@ -22,7 +23,7 @@ Feature: Server timing
|
|
|
22
23
|
server-timing:
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
|
-
Scenario: Server timing is sent when
|
|
26
|
+
Scenario: Server timing is sent when `trace` is enabled
|
|
26
27
|
Given the annotation:
|
|
27
28
|
"""
|
|
28
29
|
trace: true
|
|
@@ -30,6 +31,7 @@ Feature: Server timing
|
|
|
30
31
|
When the following request is received:
|
|
31
32
|
"""
|
|
32
33
|
POST /pots/ HTTP/1.1
|
|
34
|
+
host: nex.toa.io
|
|
33
35
|
content-type: application/yaml
|
|
34
36
|
|
|
35
37
|
title: Hello
|
|
@@ -41,3 +43,27 @@ Feature: Server timing
|
|
|
41
43
|
201 Created
|
|
42
44
|
server-timing:
|
|
43
45
|
"""
|
|
46
|
+
|
|
47
|
+
Scenario: Octets timing
|
|
48
|
+
Given the annotation:
|
|
49
|
+
"""yaml
|
|
50
|
+
trace: true
|
|
51
|
+
/:
|
|
52
|
+
io:output: true
|
|
53
|
+
auth:anonymous: true
|
|
54
|
+
octets:context: octets
|
|
55
|
+
POST:
|
|
56
|
+
octets:store: ~
|
|
57
|
+
"""
|
|
58
|
+
When the stream of `lenna.png` is received with the following headers:
|
|
59
|
+
"""
|
|
60
|
+
POST / HTTP/1.1
|
|
61
|
+
host: nex.toa.io
|
|
62
|
+
content-type: application/octet-stream
|
|
63
|
+
"""
|
|
64
|
+
# to debug, break it and look at the console
|
|
65
|
+
Then the following reply is sent:
|
|
66
|
+
"""
|
|
67
|
+
201 Created
|
|
68
|
+
server-timing:
|
|
69
|
+
"""
|
package/features/vary.feature
CHANGED
|
@@ -5,6 +5,7 @@ Feature: The Vary directive family
|
|
|
5
5
|
"""yaml
|
|
6
6
|
exposition:
|
|
7
7
|
/:
|
|
8
|
+
io:output: true
|
|
8
9
|
vary:languages: [en, fr]
|
|
9
10
|
GET:
|
|
10
11
|
vary:embed:
|
|
@@ -14,6 +15,7 @@ Feature: The Vary directive family
|
|
|
14
15
|
When the following request is received:
|
|
15
16
|
"""
|
|
16
17
|
GET /echo/ HTTP/1.1
|
|
18
|
+
host: nex.toa.io
|
|
17
19
|
accept: application/yaml
|
|
18
20
|
accept-language: <accept>
|
|
19
21
|
"""
|
|
@@ -43,6 +45,7 @@ Feature: The Vary directive family
|
|
|
43
45
|
"""yaml
|
|
44
46
|
exposition:
|
|
45
47
|
/:
|
|
48
|
+
io:output: true
|
|
46
49
|
GET:
|
|
47
50
|
anonymous: true
|
|
48
51
|
vary:embed:
|
|
@@ -52,6 +55,7 @@ Feature: The Vary directive family
|
|
|
52
55
|
When the following request is received:
|
|
53
56
|
"""
|
|
54
57
|
GET /echo/ HTTP/1.1
|
|
58
|
+
host: nex.toa.io
|
|
55
59
|
accept: application/yaml
|
|
56
60
|
accept-language: fr
|
|
57
61
|
"""
|
|
@@ -62,12 +66,12 @@ Feature: The Vary directive family
|
|
|
62
66
|
content-language: fr
|
|
63
67
|
"""
|
|
64
68
|
|
|
65
|
-
|
|
66
69
|
Scenario: Embedding a value of an arbitrary header
|
|
67
70
|
Given the `echo` is running with the following manifest:
|
|
68
71
|
"""yaml
|
|
69
72
|
exposition:
|
|
70
73
|
/:
|
|
74
|
+
io:output: true
|
|
71
75
|
GET:
|
|
72
76
|
vary:embed:
|
|
73
77
|
name: :foo
|
|
@@ -76,6 +80,7 @@ Feature: The Vary directive family
|
|
|
76
80
|
When the following request is received:
|
|
77
81
|
"""
|
|
78
82
|
GET /echo/ HTTP/1.1
|
|
83
|
+
host: nex.toa.io
|
|
79
84
|
accept: application/yaml
|
|
80
85
|
foo: bar
|
|
81
86
|
"""
|
|
@@ -88,11 +93,39 @@ Feature: The Vary directive family
|
|
|
88
93
|
Hello bar
|
|
89
94
|
"""
|
|
90
95
|
|
|
96
|
+
Scenario: Embedding a `host` header value
|
|
97
|
+
Given the `echo` is running with the following manifest:
|
|
98
|
+
"""yaml
|
|
99
|
+
exposition:
|
|
100
|
+
/:
|
|
101
|
+
io:output: true
|
|
102
|
+
GET:
|
|
103
|
+
vary:embed:
|
|
104
|
+
name: :Host
|
|
105
|
+
endpoint: compute
|
|
106
|
+
"""
|
|
107
|
+
When the following request is received:
|
|
108
|
+
"""
|
|
109
|
+
GET /echo/ HTTP/1.1
|
|
110
|
+
host: nex.toa.io
|
|
111
|
+
accept: application/yaml
|
|
112
|
+
foo: bar
|
|
113
|
+
"""
|
|
114
|
+
Then the following reply is sent:
|
|
115
|
+
"""
|
|
116
|
+
200 OK
|
|
117
|
+
content-type: application/yaml
|
|
118
|
+
vary: accept
|
|
119
|
+
|
|
120
|
+
Hello 127.0.0.1:8000
|
|
121
|
+
"""
|
|
122
|
+
|
|
91
123
|
Scenario Outline: Embedding a value from the list of options
|
|
92
124
|
Given the `echo` is running with the following manifest:
|
|
93
125
|
"""yaml
|
|
94
126
|
exposition:
|
|
95
127
|
/:
|
|
128
|
+
io:output: true
|
|
96
129
|
vary:languages: [en, fr]
|
|
97
130
|
GET:
|
|
98
131
|
vary:embed:
|
|
@@ -105,6 +138,7 @@ Feature: The Vary directive family
|
|
|
105
138
|
When the following request is received:
|
|
106
139
|
"""
|
|
107
140
|
GET /echo/ HTTP/1.1
|
|
141
|
+
host: nex.toa.io
|
|
108
142
|
accept: application/yaml
|
|
109
143
|
<header>: <value>
|
|
110
144
|
"""
|
|
@@ -122,11 +156,36 @@ Feature: The Vary directive family
|
|
|
122
156
|
| bar | baz |
|
|
123
157
|
| accept-language | en |
|
|
124
158
|
|
|
159
|
+
Scenario: Embedding route parameter
|
|
160
|
+
Given the `echo` is running with the following manifest:
|
|
161
|
+
"""yaml
|
|
162
|
+
exposition:
|
|
163
|
+
/:friend:
|
|
164
|
+
io:output: true
|
|
165
|
+
GET:
|
|
166
|
+
vary:embed:
|
|
167
|
+
name: /:friend
|
|
168
|
+
endpoint: compute
|
|
169
|
+
"""
|
|
170
|
+
When the following request is received:
|
|
171
|
+
"""
|
|
172
|
+
GET /echo/Ken/ HTTP/1.1
|
|
173
|
+
host: nex.toa.io
|
|
174
|
+
accept: text/plain
|
|
175
|
+
"""
|
|
176
|
+
Then the following reply is sent:
|
|
177
|
+
"""
|
|
178
|
+
200 OK
|
|
179
|
+
|
|
180
|
+
Hello Ken
|
|
181
|
+
"""
|
|
182
|
+
|
|
125
183
|
Scenario: Adding headers used by defined embeddings to CORS permissions
|
|
126
184
|
Given the `echo` is running with the following manifest:
|
|
127
185
|
"""yaml
|
|
128
186
|
exposition:
|
|
129
187
|
/:
|
|
188
|
+
io:output: true
|
|
130
189
|
vary:languages: [en, fr]
|
|
131
190
|
GET:
|
|
132
191
|
vary:embed:
|
|
@@ -140,11 +199,54 @@ Feature: The Vary directive family
|
|
|
140
199
|
When the following request is received:
|
|
141
200
|
"""
|
|
142
201
|
OPTIONS / HTTP/1.1
|
|
143
|
-
|
|
202
|
+
host: nex.toa.io
|
|
203
|
+
origin: https://example.com
|
|
144
204
|
access-control-request-headers: whatever
|
|
145
205
|
"""
|
|
146
206
|
Then the following reply is sent:
|
|
147
207
|
"""
|
|
148
208
|
204 No Content
|
|
149
|
-
access-control-allow-headers: accept, authorization, content-type, accept-language, foo, bar
|
|
209
|
+
access-control-allow-headers: accept, authorization, content-type, etag, if-match, if-none-match, accept-language, foo, bar
|
|
150
210
|
"""
|
|
211
|
+
|
|
212
|
+
Scenario: Embedding authority
|
|
213
|
+
Given the annotation:
|
|
214
|
+
"""yaml
|
|
215
|
+
authorities:
|
|
216
|
+
one: the.one.com
|
|
217
|
+
two: the.two.com
|
|
218
|
+
"""
|
|
219
|
+
Given the `echo` is running with the following manifest:
|
|
220
|
+
"""yaml
|
|
221
|
+
exposition:
|
|
222
|
+
/:
|
|
223
|
+
io:output: true
|
|
224
|
+
GET:
|
|
225
|
+
vary:embed:
|
|
226
|
+
name: authority
|
|
227
|
+
endpoint: compute
|
|
228
|
+
"""
|
|
229
|
+
When the following request is received:
|
|
230
|
+
"""
|
|
231
|
+
GET /echo/ HTTP/1.1
|
|
232
|
+
host: the.one.com
|
|
233
|
+
accept: text/plain
|
|
234
|
+
"""
|
|
235
|
+
Then the following reply is sent:
|
|
236
|
+
"""
|
|
237
|
+
200 OK
|
|
238
|
+
|
|
239
|
+
Hello one
|
|
240
|
+
"""
|
|
241
|
+
When the following request is received:
|
|
242
|
+
"""
|
|
243
|
+
GET /echo/ HTTP/1.1
|
|
244
|
+
host: the.two.com
|
|
245
|
+
accept: text/plain
|
|
246
|
+
"""
|
|
247
|
+
Then the following reply is sent:
|
|
248
|
+
"""
|
|
249
|
+
200 OK
|
|
250
|
+
|
|
251
|
+
Hello two
|
|
252
|
+
"""
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@toa.io/extensions.exposition",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.40",
|
|
4
4
|
"description": "Toa Exposition",
|
|
5
5
|
"author": "temich <tema.gurtovoy@gmail.com>",
|
|
6
6
|
"homepage": "https://github.com/toa-io/toa#readme",
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@toa.io/core": "1.0.0-alpha.
|
|
21
|
-
"@toa.io/generic": "1.0.0-alpha.
|
|
22
|
-
"@toa.io/schemas": "1.0.0-alpha.
|
|
20
|
+
"@toa.io/core": "1.0.0-alpha.40",
|
|
21
|
+
"@toa.io/generic": "1.0.0-alpha.40",
|
|
22
|
+
"@toa.io/schemas": "1.0.0-alpha.40",
|
|
23
23
|
"bcryptjs": "2.4.3",
|
|
24
24
|
"error-value": "0.3.0",
|
|
25
25
|
"js-yaml": "4.1.0",
|
|
@@ -34,20 +34,21 @@
|
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"test": "jest",
|
|
37
|
-
"transpile": "tsc && npm run transpile:basic && npm run transpile:tokens && npm run transpile:roles && npm run transpile:federation",
|
|
37
|
+
"transpile": "tsc && npm run transpile:bans && npm run transpile:basic && npm run transpile:tokens && npm run transpile:roles && npm run transpile:federation",
|
|
38
|
+
"transpile:bans": "tsc -p ./components/identity.bans",
|
|
38
39
|
"transpile:basic": "tsc -p ./components/identity.basic",
|
|
39
|
-
"pretranspile:federation": "js-yaml components/identity.federation/manifest.toa.yaml | jq -M '{ type: \"object\", properties: {configuration: .configuration.schema, entity: .entity.schema }, additionalProperties: false}' > schemas.json && json2ts -i schemas.json -o components/identity.federation/source/schemas.ts && rm schemas.json",
|
|
40
|
-
"transpile:federation": "tsc -p ./components/identity.federation",
|
|
41
40
|
"transpile:tokens": "tsc -p ./components/identity.tokens",
|
|
42
41
|
"transpile:roles": "tsc -p ./components/identity.roles",
|
|
43
|
-
"
|
|
42
|
+
"transpile:federation": "tsc -p ./components/identity.federation",
|
|
43
|
+
"features": "cucumber-js",
|
|
44
|
+
"features:security": "cucumber-js --tags @security"
|
|
44
45
|
},
|
|
45
46
|
"devDependencies": {
|
|
46
|
-
"@toa.io/agent": "1.0.0-alpha.
|
|
47
|
-
"@toa.io/extensions.storages": "1.0.0-alpha.
|
|
47
|
+
"@toa.io/agent": "1.0.0-alpha.40",
|
|
48
|
+
"@toa.io/extensions.storages": "1.0.0-alpha.40",
|
|
48
49
|
"@types/bcryptjs": "2.4.3",
|
|
49
50
|
"@types/cors": "2.8.13",
|
|
50
51
|
"@types/negotiator": "0.6.1"
|
|
51
52
|
},
|
|
52
|
-
"gitHead": "
|
|
53
|
+
"gitHead": "973a253abb982ddd6cdd7427ef98331d1157180d"
|
|
53
54
|
}
|
package/readme.md
CHANGED
|
@@ -20,7 +20,8 @@ exposition:
|
|
|
20
20
|
# context.toa.yaml
|
|
21
21
|
|
|
22
22
|
exposition:
|
|
23
|
-
|
|
23
|
+
authorities:
|
|
24
|
+
example: api.example.com
|
|
24
25
|
```
|
|
25
26
|
|
|
26
27
|
```http
|
|
@@ -117,33 +118,36 @@ The Exposition annotation declares options for its deployment.
|
|
|
117
118
|
```yaml
|
|
118
119
|
annotations:
|
|
119
120
|
'@toa.io/extensions.exposition':
|
|
120
|
-
|
|
121
|
+
authorities:
|
|
122
|
+
example: the.example.com
|
|
121
123
|
```
|
|
122
124
|
|
|
123
125
|
A shortcut is also available.
|
|
124
126
|
|
|
125
127
|
```yaml
|
|
126
128
|
exposition:
|
|
127
|
-
|
|
129
|
+
authorities:
|
|
130
|
+
example: the.example.com
|
|
128
131
|
```
|
|
129
132
|
|
|
130
|
-
| Option |
|
|
131
|
-
|
|
132
|
-
| `
|
|
133
|
-
| `class` |
|
|
134
|
-
| `annotations` |
|
|
135
|
-
| `debug` |
|
|
136
|
-
| `trace` |
|
|
133
|
+
| Option | Description |
|
|
134
|
+
|---------------|-------------------------------------------------------------------------------------------------------------------|
|
|
135
|
+
| `auhorities` | Mapping of authority identifiers to domain names. See [Authorities](documentation/authorities.md). |
|
|
136
|
+
| `class` | Ingress class. |
|
|
137
|
+
| `annotations` | Ingress annotations. |
|
|
138
|
+
| `debug` | Output server errors. Default `false`. |
|
|
139
|
+
| `trace` | Output [server timing](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Server-Timing). Default `false`. |
|
|
137
140
|
|
|
138
141
|
### Context resources
|
|
139
142
|
|
|
140
|
-
Exposition
|
|
143
|
+
Exposition annotation can contain [resource declaration](documentation/tree.md) under the `/` key.
|
|
141
144
|
|
|
142
145
|
```yaml
|
|
143
146
|
# context.toa.yaml
|
|
144
147
|
|
|
145
148
|
exposition:
|
|
146
|
-
|
|
149
|
+
authorities:
|
|
150
|
+
example: the.example.com
|
|
147
151
|
/:
|
|
148
152
|
/code:
|
|
149
153
|
GET:
|
|
@@ -162,8 +166,9 @@ If component resource branch conflicts with an annotation, the annotation takes
|
|
|
162
166
|
|
|
163
167
|
```yaml
|
|
164
168
|
exposition:
|
|
165
|
-
|
|
166
|
-
|
|
169
|
+
authorities:
|
|
170
|
+
example: the.example.com
|
|
171
|
+
example@staging: the.example.dev
|
|
167
172
|
class: alb
|
|
168
173
|
debug@staging: true
|
|
169
174
|
annotations:
|
package/source/Annotation.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export interface Annotation {
|
|
2
|
-
|
|
2
|
+
authorities: Record<string, string>
|
|
3
3
|
class?: string
|
|
4
4
|
annotations?: Record<string, string>
|
|
5
|
-
debug
|
|
6
|
-
trace
|
|
5
|
+
debug?: boolean
|
|
6
|
+
trace?: boolean
|
|
7
7
|
'/'?: object // parsed and validated by RTD.syntax.parse
|
|
8
8
|
}
|
package/source/Context.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { type Endpoint } from './Endpoint'
|
|
2
|
-
import { type Directives } from './Directive'
|
|
3
|
-
import { type Branch } from './Branch'
|
|
4
1
|
import type * as RTD from './RTD'
|
|
5
2
|
|
|
6
|
-
export type Context = RTD.Context<
|
|
3
|
+
export type Context = RTD.Context<Extension>
|
|
4
|
+
|
|
5
|
+
interface Extension {
|
|
6
|
+
namespace: string
|
|
7
|
+
component: string
|
|
8
|
+
}
|
package/source/Directive.test.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import assert from 'node:assert'
|
|
2
2
|
import { generate } from 'randomstring'
|
|
3
|
-
import { DirectivesFactory
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { DirectivesFactory } from './Directive'
|
|
4
|
+
import type { syntax, DirectiveFamily } from './RTD'
|
|
5
|
+
import type { Remotes } from './Remotes'
|
|
6
6
|
import type { Context } from './HTTP'
|
|
7
7
|
|
|
8
|
-
const families: Array<jest.MockedObjectDeep<
|
|
8
|
+
const families: Array<jest.MockedObjectDeep<DirectiveFamily>> = [
|
|
9
9
|
{
|
|
10
10
|
name: 'foo',
|
|
11
11
|
mandatory: true,
|
package/source/Directive.ts
CHANGED
|
@@ -3,10 +3,10 @@ import type { Remotes } from './Remotes'
|
|
|
3
3
|
import type { Output } from './io'
|
|
4
4
|
import type * as RTD from './RTD'
|
|
5
5
|
|
|
6
|
-
export class Directives implements RTD.Directives
|
|
7
|
-
private readonly sets: DirectiveSet[]
|
|
6
|
+
export class Directives implements RTD.Directives {
|
|
7
|
+
private readonly sets: RTD.DirectiveSet[]
|
|
8
8
|
|
|
9
|
-
public constructor (sets: DirectiveSet[]) {
|
|
9
|
+
public constructor (sets: RTD.DirectiveSet[]) {
|
|
10
10
|
this.sets = sets
|
|
11
11
|
}
|
|
12
12
|
|
|
@@ -17,11 +17,8 @@ export class Directives implements RTD.Directives<Directives> {
|
|
|
17
17
|
|
|
18
18
|
const output = await set.family.preflight(set.directives, context, parameters)
|
|
19
19
|
|
|
20
|
-
if (output !== null)
|
|
21
|
-
await this.settle(context, output)
|
|
22
|
-
|
|
20
|
+
if (output !== null)
|
|
23
21
|
return output
|
|
24
|
-
}
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
return null
|
|
@@ -32,18 +29,14 @@ export class Directives implements RTD.Directives<Directives> {
|
|
|
32
29
|
if (set.family.settle !== undefined)
|
|
33
30
|
await set.family.settle(set.directives, context, response)
|
|
34
31
|
}
|
|
35
|
-
|
|
36
|
-
public merge (directives: Directives): void {
|
|
37
|
-
this.sets.push(...directives.sets)
|
|
38
|
-
}
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
export class DirectivesFactory implements RTD.
|
|
34
|
+
export class DirectivesFactory implements RTD.DirectiveFactory {
|
|
42
35
|
private readonly remotes: Remotes
|
|
43
|
-
private readonly families: Record<string,
|
|
36
|
+
private readonly families: Record<string, RTD.DirectiveFamily> = {}
|
|
44
37
|
private readonly mandatory: string[] = []
|
|
45
38
|
|
|
46
|
-
public constructor (families:
|
|
39
|
+
public constructor (families: RTD.DirectiveFamily[], remotes: Remotes) {
|
|
47
40
|
for (const family of families) {
|
|
48
41
|
this.families[family.name] = family
|
|
49
42
|
|
|
@@ -74,7 +67,7 @@ export class DirectivesFactory implements RTD.DirectivesFactory<Directives> {
|
|
|
74
67
|
mandatory.delete(family.name)
|
|
75
68
|
}
|
|
76
69
|
|
|
77
|
-
const sets: DirectiveSet[] = []
|
|
70
|
+
const sets: RTD.DirectiveSet[] = []
|
|
78
71
|
|
|
79
72
|
for (const family of mandatory)
|
|
80
73
|
sets.push({
|
|
@@ -97,27 +90,7 @@ export const shortcuts: RTD.syntax.Shortcuts = new Map([
|
|
|
97
90
|
['id', 'auth:id'],
|
|
98
91
|
['role', 'auth:role'],
|
|
99
92
|
['rule', 'auth:rule'],
|
|
100
|
-
['incept', 'auth:incept']
|
|
93
|
+
['incept', 'auth:incept'],
|
|
94
|
+
['input', 'io:input'],
|
|
95
|
+
['output', 'io:output']
|
|
101
96
|
])
|
|
102
|
-
|
|
103
|
-
export interface Family<TDirective = any, TExtension = any> {
|
|
104
|
-
readonly name: string
|
|
105
|
-
readonly mandatory: boolean
|
|
106
|
-
|
|
107
|
-
// produce: (declarations: RTD.syntax.Directive[], remotes: Remotes) => TDirective[]
|
|
108
|
-
|
|
109
|
-
create: (name: string, value: any, remotes: Remotes) => TDirective
|
|
110
|
-
|
|
111
|
-
preflight?: (directives: TDirective[],
|
|
112
|
-
request: Context & TExtension,
|
|
113
|
-
parameters: RTD.Parameter[]) => Output | Promise<Output>
|
|
114
|
-
|
|
115
|
-
settle?: (directives: TDirective[],
|
|
116
|
-
request: Context & TExtension,
|
|
117
|
-
response: OutgoingMessage) => void | Promise<void>
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
interface DirectiveSet {
|
|
121
|
-
family: Family
|
|
122
|
-
directives: any[]
|
|
123
|
-
}
|
package/source/Endpoint.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type Context } from './Context'
|
|
|
5
5
|
import * as http from './HTTP'
|
|
6
6
|
import type * as RTD from './RTD'
|
|
7
7
|
|
|
8
|
-
export class Endpoint implements RTD.Endpoint
|
|
8
|
+
export class Endpoint implements RTD.Endpoint {
|
|
9
9
|
private readonly endpoint: string
|
|
10
10
|
private readonly mapping: Mapping
|
|
11
11
|
private readonly discovery: Promise<Component>
|
|
@@ -17,25 +17,39 @@ export class Endpoint implements RTD.Endpoint<Endpoint> {
|
|
|
17
17
|
this.discovery = discovery
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
public async call
|
|
21
|
-
|
|
20
|
+
public async call (context: http.Context, parameters: RTD.Parameter[]): Promise<http.OutgoingMessage> {
|
|
21
|
+
const body = await context.body()
|
|
22
|
+
const query = this.query(context)
|
|
22
23
|
const request = this.mapping.fit(body, query, parameters)
|
|
23
24
|
|
|
24
25
|
this.remote ??= await this.discovery
|
|
25
26
|
|
|
27
|
+
if (context.debug)
|
|
28
|
+
console.debug('Call', `${this.remote.locator.id}.${this.endpoint}`, request)
|
|
29
|
+
|
|
26
30
|
const reply = await this.remote.invoke(this.endpoint, request)
|
|
27
31
|
|
|
28
32
|
if (reply instanceof Error)
|
|
29
|
-
throw new http.
|
|
33
|
+
throw new http.UnprocessableEntity(reply)
|
|
30
34
|
|
|
31
|
-
const message: http.OutgoingMessage = {
|
|
35
|
+
const message: http.OutgoingMessage = {}
|
|
32
36
|
|
|
33
37
|
if (typeof reply === 'object' && reply !== null && '_version' in reply) {
|
|
38
|
+
const etag = context.request.headers['if-none-match']
|
|
39
|
+
|
|
34
40
|
message.headers ??= new Headers()
|
|
35
|
-
|
|
36
|
-
|
|
41
|
+
|
|
42
|
+
if (etag !== undefined && reply._version === this.version(etag)) {
|
|
43
|
+
message.status = 304
|
|
44
|
+
message.headers.set('etag', etag)
|
|
45
|
+
|
|
46
|
+
return message
|
|
47
|
+
} else
|
|
48
|
+
message.headers.set('etag', `"${reply._version.toString()}"`)
|
|
37
49
|
}
|
|
38
50
|
|
|
51
|
+
message.body = reply
|
|
52
|
+
|
|
39
53
|
return message
|
|
40
54
|
}
|
|
41
55
|
|
|
@@ -44,9 +58,28 @@ export class Endpoint implements RTD.Endpoint<Endpoint> {
|
|
|
44
58
|
|
|
45
59
|
await this.remote.disconnect(INTERRUPT)
|
|
46
60
|
}
|
|
61
|
+
|
|
62
|
+
private query (context: http.Context): http.Query {
|
|
63
|
+
const query: http.Query = Object.fromEntries(context.url.searchParams)
|
|
64
|
+
const etag = context.request.headers['if-match']
|
|
65
|
+
|
|
66
|
+
if (etag !== undefined)
|
|
67
|
+
query.version = this.version(etag)
|
|
68
|
+
|
|
69
|
+
return query
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
private version (etag: string): number {
|
|
73
|
+
const match = etag.match(ETAG)
|
|
74
|
+
|
|
75
|
+
if (match === null)
|
|
76
|
+
throw new http.BadRequest('Invalid ETag.')
|
|
77
|
+
|
|
78
|
+
return Number.parseInt(match.groups!.version)
|
|
79
|
+
}
|
|
47
80
|
}
|
|
48
81
|
|
|
49
|
-
export class EndpointsFactory implements RTD.EndpointsFactory
|
|
82
|
+
export class EndpointsFactory implements RTD.EndpointsFactory {
|
|
50
83
|
private readonly remotes: Remotes
|
|
51
84
|
|
|
52
85
|
public constructor (remotes: Remotes) {
|
|
@@ -70,4 +103,6 @@ export class EndpointsFactory implements RTD.EndpointsFactory<Endpoint> {
|
|
|
70
103
|
}
|
|
71
104
|
}
|
|
72
105
|
|
|
106
|
+
const ETAG = /^"(?<version>\d{1,32})"$/
|
|
107
|
+
|
|
73
108
|
const INTERRUPT = true
|
package/source/Factory.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { decode } from '@toa.io/generic'
|
|
1
3
|
import { Tenant } from './Tenant'
|
|
2
4
|
import { Gateway } from './Gateway'
|
|
3
5
|
import { Remotes } from './Remotes'
|
|
4
6
|
import { Tree, syntax } from './RTD'
|
|
5
|
-
import {
|
|
6
|
-
import { type Endpoint, EndpointsFactory } from './Endpoint'
|
|
7
|
+
import { EndpointsFactory } from './Endpoint'
|
|
7
8
|
import { families, interceptors } from './directives'
|
|
8
|
-
import {
|
|
9
|
+
import { DirectivesFactory } from './Directive'
|
|
9
10
|
import { Composition } from './Composition'
|
|
10
11
|
import * as root from './root'
|
|
11
12
|
import { Interception } from './Interception'
|
|
13
|
+
import * as http from './HTTP'
|
|
12
14
|
import type { Broadcast } from './Gateway'
|
|
13
15
|
import type { Connector, Locator, extensions } from '@toa.io/core'
|
|
14
16
|
|
|
@@ -26,16 +28,18 @@ export class Factory implements extensions.Factory {
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
public service (): Connector | null {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
assert.ok(process.env.TOA_EXPOSITION_PROPERTIES,
|
|
32
|
+
'TOA_EXPOSITION_PROPERTIES is undefined')
|
|
33
|
+
|
|
34
|
+
const options = decode<http.Options>(process.env.TOA_EXPOSITION_PROPERTIES)
|
|
31
35
|
const broadcast: Broadcast = this.boot.bindings.broadcast(CHANNEL)
|
|
32
|
-
const server = Server.create({ methods: syntax.verbs
|
|
36
|
+
const server = http.Server.create({ ...options, methods: syntax.verbs })
|
|
33
37
|
const remotes = new Remotes(this.boot)
|
|
34
38
|
const node = root.resolve()
|
|
35
39
|
const methods = new EndpointsFactory(remotes)
|
|
36
40
|
const directives = new DirectivesFactory(families, remotes)
|
|
37
41
|
const interception = new Interception(interceptors)
|
|
38
|
-
const tree = new Tree
|
|
42
|
+
const tree = new Tree(node, methods, directives)
|
|
39
43
|
|
|
40
44
|
const composition = new Composition(this.boot)
|
|
41
45
|
const gateway = new Gateway(broadcast, tree, interception)
|